【问题标题】:How to keep a Firebase database sync with BigQuery?如何使 Firebase 数据库与 BigQuery 保持同步?
【发布时间】:2017-09-01 22:38:44
【问题描述】:

我们正在开展一个涉及大量数据的项目。现在我们最近了解了 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 的最佳方式是什么?

【问题讨论】:

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


    【解决方案1】:

    BigQuery 支持 UPDATE 和 DELETE,但不支持常用的 - BigQuery 是一种分析型数据库,而不是事务型数据库。

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

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

    【讨论】:

    • 这是一个很好的问题 - 可能会发布一个新问题,措辞为“如何使 Firebase 数据库与 BigQuery 保持同步?”吸引那些可能有完整操作方法的人的注意力。但这是有可能的。
    • 查看firebase.googleblog.com/2016/10/…了解每日备份
    【解决方案2】:

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

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

    // 当一个对象被插入/删除/更新时,将采取适当的行动

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

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

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

    以下是部分摘录!

    Quotas(摘录)
    DML 语句的处理成本明显高于 SELECT 语句。
    • 每个表每天最多 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 语句组合:

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

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

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

    【讨论】:

    【解决方案3】:

    您没有在 BigQuery 中找到更新和删除函数的原因是 BigQuery 不支持它们。 BigQuery 只有追加和截断操作。如果您想更新或删除 BigQuery 中的行,您需要删除整个数据库并在修改后的行或没有修改行的情况下再次写入。这不是一个好主意。

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

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-14
    • 2010-10-29
    • 2021-01-10
    • 1970-01-01
    • 1970-01-01
    • 2021-01-03
    • 2011-07-14
    • 1970-01-01
    相关资源
    最近更新 更多