1

我们希望将数据仓库从 MySQL 数据库迁移到 Redshift 或 BigQuery。

虽然针对 OLAP 操作进行了优化,但这些基于列的数据库的缺点之一是它们不强制执行唯一约束。

因此,您的表格中存在重复的订单/产品并非不可能。我们工作的行业是零售业,我们使用标准的 Kimball 事实和维度(星型模式)数据库设计。

提出的一种潜在解决方案是在 MySQL 中构建数据库,并使用第三方复制工具将数据同步到 Redshift/BigQuery。这样,我们将在原始 MySQL 数据库中强制执行键约束,并且我们将仅将 Redshift/BigQuery 用于读取查询。

但是,在 MySQL 中强制执行约束并设置到 Redshift/BigQuery 的 bin 日志复制将保持数据与 MySQL 中的数据相同,从而强制执行唯一约束?

4

2 回答 2

0

您提出的解决方案将允许:

  • 对源 MySQL 数据库强制执行唯一键约束
  • 将该数据库发生的所有更改复制/捕获到您的数据仓库

话虽如此,您最终在数据仓库中得到的是所有已更改 MySQL 数据库的事件(插入、更新、(删除:并非所有 SaaS 产品支持...))的视图。因此,您的仓库中的“原始”表将为您的 MySQL 的每个唯一键具有多个事件,然后您需要重新处理这些事件以最终得到与 MySQL 中相同的表。

为了进一步说明这一点:就像您的 MySQL 表在每个时间点都是快照或冻结的图片/状态,而您从 binlog 复制中获得的是数据库所有连续状态更改的“电影”。如果您想在仓库中创建快照,则需要“重播”所有更改,直到您想要快照的位置。

这非常强大,因为您永远不会丢失数据库上发生的任何更改,并且总能找回它。但它确实需要额外的工作来使您的数据仓库表与输入数据库的“快照”形状相同。

这通常可以通过 CTE 在您的仓库上完成,该 CTE 添加row_number() over (partition by id order by updated_at desc) as rn然后过滤该 CTE where rn = 1 and deleted_at is nullid作为具有唯一约束的列,如果您的唯一约束是复合的(在多个键上)并且updated_at是每个的时间戳,则可以列出多个更改数据捕获事件并deleted_at作为删除事件的时间戳(如果给定键没有发生删除事件,则为 null)。

对于开源和自托管变更数据捕获,您还可以查看在 Kafka Connect(或 AWS Kinesis 或其他...)上运行的 Debezium 之类的东西,如果这是您的客户愿意投资的基础设施...或者只是在您选择的数据库引擎/lib 中查看您首选数据库的逻辑复制连接(例如,我在 Python 上对 PostgreSQL 使用psycopg2(with extras) ...)

于 2020-12-22T11:58:50.957 回答
0

首先,您不能从 MySQL 复制到 RedShift/BigQuery。

请理解 BigQuery 是一个分析型数据库。

建议您在 Cloud SQL 中从 MySQL 设置复制。然后在 BigQuery 中,您现在可以运行 EXTERNAL_QUERY,这意味着您可以使用 Cloud SQL MySQL 数据库查询/加入您的 BQ 数据库。

  1. 将当前实例的副本设置为 Cloud SQL 实例,请遵循本指南
  2. 了解Cloud SQL 联合查询如何让您从 BigQuery Cloud SQL 实例中进行查询。

您可以通过这种方式实时访问您的关系数据库:

您在 BigQuery 上运行的示例查询:

SELECT * EXTERNAL_QUERY(
'connection_id',
'''SELECT * FROM mysqltable AS c ORDER BY c.customer_id'');

您甚至可以将 Bigquery 表与 SQL 表连接起来:

例子:

SELECT c.customer_id, c.name, SUM(t.amount) AS total_revenue,
rq.first_order_date
FROM customers AS c
INNER JOIN transaction_fact AS t ON c.customer_id = t.customer_id
LEFT OUTER JOIN EXTERNAL_QUERY(
  'connection_id',
  '''SELECT customer_id, MIN(order_date) AS first_order_date
  FROM orders
  GROUP BY customer_id''') AS rq ON rq.customer_id = c.customer_id
GROUP BY c.customer_id, c.name, rq.first_order_date;
于 2019-10-01T10:24:22.710 回答