假设我已将实体A
,B
和C
与one-to-many
关系存储在BigQuery中。
A -- (one to many) --> B --- (one to many) --> C
对于"常规" SQL数据库我根据主键在A
和B
创建表C
,A
和B
及其主键和外键B
和C
。
它适用于BigQuery吗?是否可以更好地对该结构进行反规范化并将所有A
,B
和C
存储在一个表中?
答案 0 :(得分:4)
让我们说每种农产品都可以在不同的农场生产,每个农场都有不同的员工。
在BigQuery中,有3个表和它们之间的关系并没有错 - 但您可能还想利用BigQuery的嵌套和重复列支持。
对于这个组成的例子,我们可以按如下方式对其进行建模:
SELECT 'tomato' produce, STRUCT<farm ARRAY<STRUCT<farm_id string, employee ARRAY<STRUCT<name string>>>>>(
[
STRUCT('farm1' AS farm_id, [STRUCT('employee1' AS name), STRUCT('employee2')] AS employee )
, ('farm2', [STRUCT('employee3' AS name), STRUCT('employee4')])
, ('farm3', [STRUCT('employee5' AS name), STRUCT('employee6')])
]) AS farms
UNION ALL
SELECT 'lettuce', STRUCT<ARRAY<STRUCT<farm_id string, employee ARRAY<STRUCT<name string>>>>>(
[
STRUCT('farm4' AS farm_id, [STRUCT('employee7' AS name), STRUCT('employee8')] AS employee )
, ('farm5', [STRUCT('employee9' AS name)])
]) AS farms
问:像这样建模是否有意义?
答:取决于。
正如劳埃德所说:
嵌套记录在扫描分布式数据集时有一些优势。首先,它们不需要连接。这意味着与每次使用时必须重新加入额外数据相比,计算速度更快,扫描数据更少。
嵌套结构本质上是预先连接的表。并且,由于数据是以柱状方式存储的,因此如果您不引用嵌套列,则查询不会增加任何费用。如果您确实引用了嵌套列,则逻辑与共置连接相同。
嵌套结构带来的另一个好处是它们避免重复必须在宽的非规范化表中重复的数据。换句话说,对于住在五个城市的人来说,一个宽的非规范化表格将包含他们所有的五行信息(他们居住的每个城市都有一个)。在嵌套结构中,重复信息只占用一行,因为五个城市的数组可以包含在一行中,并且只在需要时才会被取消。
同时,对于不习惯处理嵌套数据的用户和工具,查询将更加困难。