gpt4 book ai didi

database-design - 如何在 Spanner 中高效地创建强有序序列?

转载 作者:行者123 更新时间:2023-12-05 01:25:49 24 4
gpt4 key购买 nike

Google Spanner 建议不要使用时间戳或序列号之类的东西作为主键或索引的初始部分,这基于架构是有意义的。但是,根据我的要求,我确实需要一些方法来确保行的严格“仅附加”顺序。

我正在使用 Spanner 为事件建模(如事件溯源)。每个事件都有一个类别、一个标识序列的流 ID,其中事件之间的关系需要严格排序,以及一些有效负载字段 - 从这里开始我将忽略实际有效负载。

天真地,这将被建模为:

| Category    | STRING       |
| Stream Id | STRING |
| Sequence Nr | INT64 |

(使用由类别、流 ID、序列号组成的主键。)这将确保一个流的事件的强排序。现在,由于某些类别有很多与之关联的事件,而 Spanner 最佳实践是在高位上有差异,因此最好将其翻转过来。每个“流”将包含数量相当少的事件(几千而不是数百万),并将一起读取以便更好地分发数据并鼓励属于一个流的事件的局部性:

| Stream Id   | STRING       |
| Category | STRING |
| Sequence Nr | INT64 |

但是,由于我希望能够附加事件而不必读取当前状态来找出当前序列号,所以我宁愿使用时间戳。

| Aggregate Id | STRING      |                         | 
| Category | STRING | |
| Timestamp | TIMESTAMP | allow_commit_timestamp |

Spanner 有一个内置的提交时间戳,可以在实际处理事务时对其进行标记。但最后的问题是:

是否可以像上面那样表示数据并获得唯一的提交时间戳,即使我在一个事务中提交多个事件?

如果不是,是否可以通过添加额外的列来确保顺序来确保严格排序?

documentation指出“不能保证提交时间戳值是唯一的。写入非重叠字段集的事务可能具有相同的时间戳。写入重叠字段集的事务具有唯一的时间戳。” - 但我不太清楚在这种情况下什么是“字段集”。

该文档还指出“提交时间戳使创建变更日志更容易,因为时间戳可以强制对变更日志条目进行排序。”但不清楚在多个并发编写器或同时写入多个事件的上下文中,提交时间戳具有强制顺序的保证是什么。

最佳答案

如果您在同一事务 中有多个事件,那么它们都将具有相同的提交时间戳。

字段是一个表格单元格(一行中有一个 col 值)。因此,在此上下文中的“非重叠字段集”基本上意味着单独的行,因为其中一个字段提交时间戳!

两个独立的事务,同一张表上的一个更新行“R1”和一个更新行“R2”理论上可以具有相同的提交时间戳,因为它们不重叠。

Is it possible to represent data as above and get unique commit timestamps even if I commit multiple events in one transaction?

在您给出的示例中,您在主键中使用提交时间戳,那么不,您将无法在单个事务中将多个事件添加到同一 stream_id/category 对,因为它们具有相同的时间戳-- 因此主键相同。

If not, is it possible to ensure strict ordering some other way, by adding additional columns to ensure order?

如果您为每个(stream_id、类别、时间戳)元组使用提交时间戳 sequence_number 的组合,那么您可以在单个事务中保持严格的顺序:

为同一事务中的每个 (stream_id, category) 对增加一个序列号,从 0 开始。提交时间戳将确保跨不同事务的顺序,而序列号将确保事务的顺序...

关于database-design - 如何在 Spanner 中高效地创建强有序序列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53632448/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com