优化分层数据集以读取整个层次结构

Posted

技术标签:

【中文标题】优化分层数据集以读取整个层次结构【英文标题】:Optimizing hierarchical data sets for reads of whole hierarchies 【发布时间】:2018-08-08 16:27:16 【问题描述】:

我正在将一个应用从 Oracle 迁移到 Google Spanner。 我们遇到的一种情况是同一张表中的行之间的关系。

这些关系具有树状结构,始终具有层次结构的一个父级和一个根。自下而上和自上而下的查询模式都是可能的。

在某些情况下,我们希望有效地访问整个记录树。这种数据访问模式对延迟至关重要。

该应用程序以前使用 Oracle 及其分层查询 (connect by),并针对该供应商进行了高度优化。

一次树提取中的行数将在 1-2000 之间。 表将有数百万个 sych 行。

该表的行中确实有交错的子表行。

通过非规范化模型和冗余添加根记录的 id 来优化表以获得更好的数据局部性是否有意义? 作为该表的主键的第一列以实现更快的自上而下查询?

应该是这样的: root_id | own_id | parent_id 1 | 1 | 1 1 | 2 | 1 1 | 3 | 2 4 | 4 | 4 4 | 5 | 4 4 | 5 | 4

即。我们正在考虑在这里使 PK 由 (root_id, own_id) 组成。 (数值是肤浅的,我们可以在实际场景中展开)。

包含相同 PK 的第一个元素的此类行进入相同拆分的机会是多少?这样做会有实际好处吗?

【问题讨论】:

【参考方案1】:

Cloud Spanner 支持父子表关系来声明两个逻辑上独立的表之间的数据局部性关系,并在物理上将它们的行放在一起以实现高效检索。 更多信息请查看此链接:https://cloud.google.com/spanner/docs/schema-and-data-model#parent-child_table_relationships

例如,假设我们有一个主键为“root_id”的表“Root”,我们可以将表“Own”声明为“Root”表的子表。父表的主键成为子表主键的前缀。所以表'Own'可以有一个主键(root_id,own_id)。具有相同 'root_id' 的表 'Own' 的所有行都将位于同一拆分中。

拆分确实有最大大小限制。根据经验,父子表层次结构中每组相关行的大小应小于几个 GiB。

【讨论】:

谢谢,是的,我知道这种情况,但我认为它对我所描述的情况没有反应:多级、不同深度的引用行层次结构(具有相同的结构,因此在单个表),我们要在单个查询中从上到下查询。有什么方法可以帮助此类查询的数据局部性? 子表中主键的设计可以用来控制子表内的局部性。似乎您有正确的想法将根记录的 id 添加为该表的主键的第一列,但您需要在主键为 root_id 的父表中交错该(子)表。这将导致具有相同 root_id 的子表的所有行都在同一个拆分中。为了防止分片的大小变得过大,可以在parent的主键上加一个shard_id。

以上是关于优化分层数据集以读取整个层次结构的主要内容,如果未能解决你的问题,请参考以下文章

PYOMO:使用集合和参数定义数据集以解决优化问题

如何在谷歌 colab 中读取图像数据集以进行深度学习?

使用 MS SQL Server Analysis Services 在分层数据上创建多维数据集

Google Appengine 数据存储的层次结构优化

存储结果集以供以后获取

Apache Spark 中的分层数据操作