2

我们正在研究涉及大量数据的项目。现在我们最近阅读了关于Google BigQuery的内容。但我们如何将数据导出到这个平台?我们已经看到了将输入日志导入Google BigQuery的示例。但是这并不包含有关更新和删除数据(仅插入)的信息。如何让Firebase数据库与BigQuery保持同步?

所以我们的对象能够更新他们的数据。我们对BigQuery表的查询数量有限。我们如何在不超过BigQuery配额限制的情况下同步我们的数据。

我们当前的功能代码:

'use strict'; 

// Default imports. 

const functions = require('firebase-functions'); 
const bigQuery = require('@google-cloud/bigquery')(); 

// If you want to change the nodes to listen to REMEMBER TO change the constants below. 
// The 'id' field is AUTOMATICALLY added to the values, so you CANNOT add it. 

const ROOT_NODE = 'categories'; 
const VALUES = [ 
    'name' 
]; 

// This function listens to the supplied root node. 
// When the root node is completed empty all of the Google BigQuery rows will be removed. 
// This function should only activate when the root node is deleted. 

exports.root = functions.database.ref(ROOT_NODE).onWrite(event => { 
    if (event.data.exists()) { 
     return; 
    } 

    return bigQuery.query({ 
     query: [ 
      'DELETE FROM `stampwallet.' + ROOT_NODE + '`', 
      'WHERE true' 
     ].join(' '), 
     params: [] 
    }); 
}); 

// This function listens to the supplied root node, but on child added/removed/changed. 
// When an object is inserted/deleted/updated the appropriate action will be taken. 

exports.children = functions.database.ref(ROOT_NODE + '/{id}').onWrite(event => { 
    const id = event.params.id; 

    if (!event.data.exists()) { 
     return bigQuery.query({ 
      query: [ 
       'DELETE FROM `stampwallet.' + ROOT_NODE + '`', 
       'WHERE id = ?' 
      ].join(' '), 
      params: [ 
       id 
      ] 
     }); 
    } 

    const item = event.data.val(); 

    if (event.data.previous.exists()) { 
     let update = []; 
     for (let index = 0; index < VALUES.length; index++) { 
      const value = VALUES[index]; 

      update.push(item[value]); 
     } 
     update.push(id); 

     return bigQuery.query({ 
      query: [ 
       'UPDATE `stampwallet.' + ROOT_NODE + '`', 
       'SET ' + VALUES.join(' = ?, ') + ' = ?', 
       'WHERE id = ?' 
      ].join(' '), 
      params: update 
     }); 
    } 

    let template = []; 
    for (let index = 0; index < VALUES.length; index++) { 
     template.push('?'); 
    } 

    let create = []; 
    create.push(id); 
    for (let index = 0; index < VALUES.length; index++) { 
     const value = VALUES[index]; 

     create.push(item[value]); 
    } 

    return bigQuery.query({ 
     query: [ 
      'INSERT INTO `stampwallet.' + ROOT_NODE + '` (id, ' + VALUES.join(', ') + ')', 
      'VALUES (?, ' + template.join(', ') + ')' 
     ].join(' '), 
     params: create 
    }); 
}); 

什么是同步火力点至BigQuery的最佳方式?

回答

1

...将firebase同步到bigquery的方法?

我建议考虑将streaming作为历史数据存入BigQuery。您可以将条目标记为新(插入),更新或删除。然后,在BigQuery方面,您可以编写查询,根据您拥有的任何逻辑来解析特定记录的最新值。
所以,你的代码可以被重用几乎100% - 只要解决的UPDATE/DELETE逻辑把它作为INSERT

//当一个对象被插入/删除/更新相应的操作将采取

所以我们的对象能够更新他们的数据。我们对BigQuery表的查询数量有限。我们如何在不超过BigQuery配额限制的情况下同步数据?

是,BigQuery支援UPDATEDELETEINSERT作为Data Manipulation Language的一部分。
总可用性是BigQuery中的标准SQL announced在2017年3月8日

之前使用此功能与事务数据同步BigQuery的考虑 - 请看看QuotasPricingKnown Issues

下面是一些摘录!

Quotas(摘录)
DML语句比SELECT语句的处理成本要高得多。
•最大UPDATE/DELETE每天陈述每个表:96
•最大UPDATE/DELETE每个项目每天声明:对于DML查询基于1000

​​(摘编,额外的高亮+加评论)
的BigQuery费用关于查询处理的字节数。
处理被计算为字节数如下:

UPDATE Bytes processed =在所扫描的表+ 用于在UPDATE开始时在更新后的表所有字段的字节的总和中引用的字段的字节总和。
DELETE Bytes processed =扫描表中引用字段的字节总和+ DELETE开始时修改表中所有字段的字节总和。

发表评论文章作者:正如你所看到的,即使你只更新一行,你将被收取整个表扫描!这是决策的关键,我想!

Known Issues(节选)
•DML语句不能用于修改表在其架构所需的字段。
•每个DML语句启动一个隐式事务,这意味着该语句所做的更改会在每个成功的DML语句结束时自动提交。不支持多语句事务。
•DML语句的下列组合被允许同时在一个表上运行:

  • UPDATE否则和INSERT
  • 删除和插入
  • INSERT和INSERT

    DML语句之一将被中止。
    例如,如果两个UPDATE语句同时对该表执行,那么只有其中一个会成功。

•已通过的BigQuery流(tabledata.insertall)写入到最近的表不能使用UPDATE或DELETE语句来修改。要检查表是否有流缓冲区,请检查名为streamingBuffer的节的tables.get响应。如果不存在,则可以使用UPDATE或DELETE语句修改该表。

+0

@stanvanheumen - 如果我的回答对您有帮助,并且您接受了它,也请考虑投票。有关http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work#5235中的http://stackoverflow.com/help/someone-answers和Upvote部分的详情,请参阅 –

0

您在BigQuery中没有找到更新和删除功能的原因是它们不受BigQuery支持。 BigQuery只追加和截断操作。如果您想更新或删除BigQuery中的行,则需要删除整个数据库,然后使用修改后的行重新写入或不使用它。这不是一个好主意。

BigQuery用于存储大量数据并且可以快速访问它,例如,它适用于从不同传感器收集数据。但对于您的客户数据库,您需要使用MySQL或NoSQL数据库。

+1

Hi Yevgen - 以前是真的,但BigQuery现在支持UPDATE和DELETE:https://cloud.google.com/bigquery/docs/reference/standard-sql/dml-syntax –

2

BigQuery支持更新和删除,但不是频繁的 - BigQuery是一个分析数据库,而不是事务性的。

要同步与BigQuery您可以像使用方法事务数据库:

+0

有没有一种方法可以实现与Firebase合作? –

+0

这是一个很好的问题 - 也许发布了一个新的问题,就像“如何保持Firebase数据库与BigQuery同步?”一样。吸引可能有完整技巧的人们的注意力。但是这是可以肯定的。 –

+1

请参阅https://firebase.googleblog.com/2016/10/announcing-automated-daily-backups-for-the-firebase-database.html进行日常备份 –

相关问题