Google cloud platform &引用;“组合键”;使用insertAll进行流式处理时在BigQuery中

Google cloud platform &引用;“组合键”;使用insertAll进行流式处理时在BigQuery中,google-cloud-platform,google-bigquery,Google Cloud Platform,Google Bigquery,我正在将数据流式传输到BigQuery表中,构建一个InsertAllRequest,然后使用com.google.cloud.BigQuery.BigQuery中的insertAll-方法插入该请求。我希望这一切都能正常工作,因为我可以将数据插入表中,但我需要一个特定的行为:我想在表中实现某种“复合键” 下面是该表的外观: Field name | Type | Mode -------------------------------------- order_id

我正在将数据流式传输到BigQuery表中,构建一个
InsertAllRequest
,然后使用
com.google.cloud.BigQuery.BigQuery
中的
insertAll
-方法插入该请求。我希望这一切都能正常工作,因为我可以将数据插入表中,但我需要一个特定的行为:我想在表中实现某种“复合键”

下面是该表的外观:

Field name      | Type      | Mode
--------------------------------------
order_id        | STRING    | REQUIRED
modified_ts     | TIMESTAMP | REQUIRED
order_sum       | INTEGER   | NULLABLE
order_reference | STRING    | NULLABLE
因此,我希望键是
order\u id
modified\u ts
;换句话说,我希望能够跟踪订单随时间的变化。如果再次插入现有的键,我希望会出现一些错误,或者忽略这一新行(将其视为重复项)对我来说也可以

不幸的是,我还没有成功地告诉BigQuery这样做。以下是我测试的代码:

String rowId = String.valueOf("order_id, modified_ts");

InsertAllRequest req = InsertAllRequest.newBuilder(ORDER)
        .addRow(rowId, mapOrder(o, modifiedTs))
        .build();

InsertAllResponse resp = bigQuery.insertAll(req);
log.info("response was: {}", resp.toString());
newBuilder
中的ORDER是一个
TableId
-对象,
mapOrder(o,modifiedTs)
将传入对象映射到一个
Map
。 如果我将
rowId
定义为
String.valueOf(“order\u id”)
,则所有操作都可以正常进行,但显然,订单的所有更新都只更新现有行,而不生成任何历史记录。上面使用逗号分隔列名的解决方案的行为与此相同,只是忽略
modified\u ts

所以,我的问题很简单:我如何才能让它工作?我想要的是——稍微简化一下——以下内容:

order_id | modified_ts | data
------------------------------------------
    1    | 2020-12-10  | some data
    1    | 2020-12-15  | some changed data
    2    | 2020-12-15  | some more data

BigQuery中不存在复合键或唯一概念。没有键和索引

对应用程序进行工程设计,以允许插入副本。
在您的表格顶部创建一个视图,该视图根据您已经布置好的概念读取


通过这种方式,您也可以访问版本化数据,并且在查询中始终可以使用view as from子句获得最新版本。

BigQuery中不存在复合键或唯一概念。没有键和索引

对应用程序进行工程设计,以允许插入副本。
在您的表格顶部创建一个视图,该视图根据您已经布置好的概念读取


通过这种方式,您也可以访问版本化数据,并且在查询中始终可以使用view as from子句获得最新版本。

正如奔腾10s答案评论中所述,与谷歌代表的一次会议确认了其内容

基本上,我误解了在我的行中添加一个“rowId”表示其键的功能:
String rowId=String.valueOf(“order_id,modified_ts”)
这只不过是谷歌所说的,只是一种努力,没有任何保证。我误以为这是一种可以依靠的技术,我的坏习惯

处理这个问题的推荐方法是在您自己的代码中,在流式处理BigQuery之前或之后。“之前”意味着在你的应用程序中实现逻辑,在将数据写入BQ之前处理重复数据,这包括一些将你识别为密钥的内容保存在内存中的方法。“之后”是奔腾10的建议:将所有数据流式传输到BigQuery并持久化,然后处理其余的数据

有3种方法可以解决这个问题:使用(非常方便的!)窗口函数的视图可能是一种方法(但请记住,每次查询视图时都需要整个底层查询的处理能力),物化视图可能是一种解决方案(如果/当Google在这些视图中支持窗口函数时)或者您自己用所需的数据创建和更新一个表,管理一些调度


我希望这个答案有助于澄清一些问题,并作为对所提供答案的补充。

正如奔腾10答案的评论中所述,与谷歌代表的一次会议确认了其内容

基本上,我误解了在我的行中添加一个“rowId”表示其键的功能:
String rowId=String.valueOf(“order_id,modified_ts”)
这只不过是谷歌所说的,只是一种努力,没有任何保证。我误以为这是一种可以依靠的技术,我的坏习惯

处理这个问题的推荐方法是在您自己的代码中,在流式处理BigQuery之前或之后。“之前”意味着在你的应用程序中实现逻辑,在将数据写入BQ之前处理重复数据,这包括一些将你识别为密钥的内容保存在内存中的方法。“之后”是奔腾10的建议:将所有数据流式传输到BigQuery并持久化,然后处理其余的数据

有3种方法可以解决这个问题:使用(非常方便的!)窗口函数的视图可能是一种方法(但请记住,每次查询视图时都需要整个底层查询的处理能力),物化视图可能是一种解决方案(如果/当Google在这些视图中支持窗口函数时)或者您自己用所需的数据创建和更新一个表,管理一些调度


我希望这个答案有助于澄清一些问题,并作为对所提供答案的补充。

昨天与谷歌就此事举行了一次会议,基本上证实了你的说法。关于此评论中字符的限制,我将用我得到的信息回答我自己的问题。谢谢昨天与谷歌就此事举行了一次会议,基本上证实了你所说的。关于此评论中字符的限制,我将用我得到的信息回答我自己的问题。谢谢