Существуют ограничения на количество заданий загрузки и запросов DML (1000 в день), поэтому вам необходимо использовать потоковые вставки для такого типа приложений. Обратите внимание, что потоковые вставки отличаются от загрузки данных из потока Java.
TableId tableId = TableId.of(datasetName, tableName);
// Values of the row to insert
Map<String, Object> rowContent = new HashMap<>();
rowContent.put("booleanField", true);
// Bytes are passed in base64
rowContent.put("bytesField", "Cg0NDg0="); // 0xA, 0xD, 0xD, 0xE, 0xD in base64
// Records are passed as a map
Map<String, Object> recordsContent = new HashMap<>();
recordsContent.put("stringField", "Hello, World!");
rowContent.put("recordField", recordsContent);
InsertAllResponse response =
bigquery.insertAll(
InsertAllRequest.newBuilder(tableId)
.addRow("rowId", rowContent)
// More rows can be added in the same RPC by invoking .addRow() on the builder
.build());
if (response.hasErrors()) {
// If any of the insertions failed, this lets you inspect the errors
for (Entry<Long, List<BigQueryError>> entry : response.getInsertErrors().entrySet()) {
// inspect row error
}
}
(из примера на https://cloud.google.com/bigquery/streaming-data-into-bigquery#bigquery-stream-data-java)
Обратите внимание, что при неудачной вставке не всегда вызывает исключение. Вы также должны проверить объект ответа на наличие ошибок.
Является ли хорошей практикой вставлять в большой запрос по одной строке каждый раз, когда пользовательское действие инициируется?
Да, довольно типично передавать потоки событий в BigQuery для аналитики. Вы могли бы получить более высокую производительность, если бы вы буферировали несколько событий в одном запросе на вставку в BigQuery, но определенно поддерживается одна строка за раз.