通过在Google BigQuery上加入2个表而无需导入/导出来删除/更新表条目

时间:2016-01-17 13:04:43

标签: google-bigquery

我们有一个用例,我们在一个表中有数亿个条目,并且在将其进一步拆分时会出现问题。 99%的操作仅附加。但是,我们偶尔会更新和删除Google本身所说的只能通过删除表格并使用最新数据创建新表格来实现。

因为它包含大量数据,我们希望在30秒左右更新表格,我们考虑了使用复习表加入原始表格的可能性,我们只有条目出现在原始表中而不是在刷新表(删除的情况下)中,或者如果找到则使用来自刷新表的数据写入项目(更新的情况)。输出/目标应为新表,然后我们将使用WRITE_TRUNCATE(覆盖)将其复制回原始表。如果更新似乎过于复杂,我们可以使用仅删除逻辑并重新插入更新的项目。

这可能吗?什么类型的连接似乎最合适?我们将我们的更新流插入到刷新表中,并定期清理原始表。我们不必为重新插入整个原始表(无论是时间还是金钱)而付费,而只是为了查询'曾经和那些少数流插入更新表。

编辑:我们可以查询陈旧数据,直到定期合并发生。我们还可以在维护期间停止查询很短的时间。

欢迎任何想法。

2 个答案:

答案 0 :(得分:2)

所以要在我的评论中添加更多内容:

  

为什么不接受更新作为表格中的新行,以及   有查询只读取表中的最后一行?那太多了   更容易。

创建一个这样的视图:

select * from (
SELECT 
rank() over (partition by user_id order by timestamp desc) as _rank,
*
FROM [db.userupdate_last] 
) where _rank=1

并更新您的查询以查询视图表和基本表,您就完成了。

我们如何使用它。我们有一个包含用户个人资料数据的事件表。在每次更新时,我们都会在BQ中再次附加完整的配置文件数据行。这意味着我们最终拥有一个版本化的内容,其中包含与user_id一样多的行,因为他们已完成了多少次更新。这都在同一张表中,通过查看我们知道更新顺序的时间。我们来说吧:[userupdate]。如果我们做了

select * from userupdate where user_id=10

它会以随机顺序返回此用户对其个人资料所做的所有更新。

但我们创建了一个视图,我们只创建了一次,语法在上面。而现在我们:

select * from userupdate_last where user_id=10 #notice the table name changed to view name

它只返回1行,即用户的最后一行。我们有查询,我们只是将表名交换到视图名称,如果我们想要从一个只有最后一行的追加行的表中查询。

答案 1 :(得分:0)

我们在BigQuery的类似场景中找到了相对简单的选项 它允许基于任何基于时间的快照处理查询 - 以及查询当前快照

简而言之,想法是拥有一个主表和每日历史表
在白天 - 当前每日表用于插入(新建,更新,删除),然后每日进程将最后完成的每日表与主表合并,将其写回同一主表。当然,首先,通过最新主表的副本(自由操作)进行备份。

每日主表更新过程允许在最后一天保持主表清洁和新鲜 现在,在任何特定时刻,您都可以通过仅查询(无垃圾)主表和今天的表来获取最新数据。
同时,由于您拥有所有日常表,因此可以查询任何历史数据

当然,将所有数据(新的,更新的,删除的)添加到具有相应限定符的主表中的经典选项在价格和性能方面仍然看起来很好,因为您的主要(99%)数据是新条目!

在您的情况下,就我个人而言,我会投票支持经典方法,定期清理历史条目

最后,在我看来,它不是关于加入,而是关于使用uniontable wildcard函数的window