如何使Firebase数据库与BigQuery保持同步?

时间:2017-04-06 18:21:42

标签: node.js firebase firebase-realtime-database google-bigquery google-cloud-functions

我们正在开展涉及大量数据的项目。现在我们最近阅读了有关Google BigQuery的内容。但是我们如何将数据导出到这个平台呢?我们已经看到了将日志导入Google 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
    });
});

将firebase同步到bigquery的最佳方式是什么?

3 个答案:

答案 0 :(得分:2)

BigQuery支持UPDATE和DELETE,但不常见 - BigQuery是一个分析数据库,而不是事务性数据库。

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

使用Firebase,您可以从日常备份中安排每日加载BigQuery:

答案 1 :(得分:1)

  

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

我建议将streaming所有数据作为历史数据考虑到BigQuery中。您可以将条目标记为新(插入),更新或删除。然后,在BigQuery方面,您可以编写查询,根据您拥有的逻辑解析特定记录的最新值 因此,您的代码几乎可以100%重复使用 - 只需修复UPDATE / DELETE的逻辑即可将其设为INSERT

  

//插入/删除/更新对象时,将采取适当的操作

     

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

是的,BigQuery支持UPDATEDELETEINSERT作为Data Manipulation Language的一部分。
2017年3月8日,BigQuery Standard SQL中的一般可用性为announced

在考虑使用此功能将BigQuery与交易数据同步之前,请先查看QuotasPricingKnown Issues

以下是一些摘录!

Quotas(摘录)
SELECT语句相比,DML语句的处理成本要高得多 •每个表每天最大UPDATE / DELETE语句:96
•每个项目每天的最大UPDATE / DELETE语句:1,000

Pricing(摘录,额外突出显示+评论添加)
BigQuery根据查询处理的字节数收取DML查询费用 处理的字节数计算如下:

UPDATE Bytes processed =扫描表中引用字段的字节总数+ UPDATE启动时更新表中所有字段的字节总数DELETE Bytes processed =扫描表中引用字段的字节总数+ DELETE启动时修改表中所有字段的字节总数

帖子作者评论:正如您所看到的那样,即使您只更新了一行,您也需要支付全桌扫描的费用!我认为这是制定决策的关键!

Known Issues(摘录)
•DML语句不能用于修改其模式中具有REQUIRED字段的表 •每个DML语句都会启动一个隐式事务,这意味着语句所做的更改会在每个成功的DML语句结束时自动提交。不支持多语句交易 •允许以下DML语句组合在表上并发运行:

  • 更新和插入
  • 删除并插入
  • INSERT和INSERT

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

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

答案 2 :(得分:0)

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

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