在数据仓库中使用标识或序列
Using Identity or sequence in data warehouse
我是数据仓库的新手,所以我尝试遵循最佳实践,模仿 Microsoft Demo DB WideWorldImportersDW 中的一些实现细节,我注意到的一件事是使用 Sequence
作为 PK 超过 Identity
.
的默认值
请问,一般来说,在数据仓库中使用 Sequence
比 Identity
更好吗?哪个更方便,尤其是在 ETL 过程中?
序列比标识列有更多保证。特别是,每次调用序列都保证为序列生成 next 值。
但是,identity
列可能存在间隙和其他不一致之处。这都记录在案 here.
由于对序列的额外保证,我怀疑它们更慢。特别是,我怀疑数据库无法批量预分配值。这意味着在多线程环境中,序列会对事务施加序列化,从而减慢速度。
一般来说,我看到 identity
用于标识表中的列。虽然可能有性能比较,但我还没有看到。但我怀疑在某些情况下序列会慢一点。
Sequence 和 Identity 都是为 OLTP
table 设计的,以实现唯一键的有效分配在多会话环境中。
需要意识到的重要一点是,在数据仓库环境中,您通常有不同的设置,并且只有 一个作业 填充特定的 table。
在单用户环境中,您根本不需要上述功能,您可以简单地分配键手动从max(id) +1
开始,每行递增1。
数据仓库的一般规则是你不应该搜索silver bullet recommendation而是检查你onw中的功能和性能测试。
如果您对 SQL 服务器身份与序列 进行了一些研究,例如here or here 你会得到不同的结果,部分偏爱前者,部分偏爱后者。
因此,我的建议是使用手动分配的ID
s(即没有开销)进行测试,以获得预期的基线。
然后用 identity 和 sequence 重复它 - 比较并选择。
SQL服务器中的sequence
是后来添加的,是基于Oracle Sequence的,所以我不认为它有一些基本问题。
Oracle 的经验告诉我们,序列中需要有足够大的 cache
才能支持有效的批量插入。
同时 identity
也可以定义为 cached, (IDENTITY_CACHE = { ON | OFF }) 所以再一次,尝试所有三种可能性(顺序,恒等式) , nothing) 然后选择最好的一个。
身份限定为单个 table,是 table 定义 (DDL) 的一部分,并在截断时重置。身份在 table 内是唯一的。每个 table 在配置时都有自己的标识值,不能在 table 之间共享。在一般用法中,当 table.+
上发生插入时,SQL 服务器使用“下一个”值
序列是第一个 class 对象,作用域为数据库。使用 Sequence 时会消耗“下一个”值 (NEXT VALUE FOR)。
当您需要跨多个 table 存储一个人可读的唯一标识符时,使用序列最有效。例如,在不同 table 中存储票证类型的票务系统可以使用一个序列来确保没有票证收到相同的号码,而不管它存储在 table 中,并且一个人可以合理地参考数字(不是 GUID)。
在数据仓库中,维度 table 需要一个在 table 中唯一的行标识符。一般来说,OLTP 主键是不够的,因为它可能在维度 table 中重复,具体取决于维度的类型,并且您不想冒险为 OLTP PK 分配额外的上下文,因为这可能会带来挑战当源数据改变时。维度行标识符应该只对与其关联的非度量事实列有意义。事实列未跨不同维度连接。++
由于维度 table 标识符的范围仅限于维度 table,因此标识键是理想的行标识符。创建简单,存储紧凑,在空间之外没有意义。您不会在报表上使用维度标识。 (真的,请不要成为那个开发者。)
+ 您很少需要知道下一个值而不需要分配给行。如果您试图在赋值之前操纵标识值,则可能是一个危险信号
++ 维度视图可以联合不同的 tables 来提供 OLAP 多维数据集,在这种情况下,应该从基础数据中生成一个持久的 repeatable 键,通常通过将字符串文字与规范化格式的每个 table 键连接起来。
我是数据仓库的新手,所以我尝试遵循最佳实践,模仿 Microsoft Demo DB WideWorldImportersDW 中的一些实现细节,我注意到的一件事是使用 Sequence
作为 PK 超过 Identity
.
请问,一般来说,在数据仓库中使用 Sequence
比 Identity
更好吗?哪个更方便,尤其是在 ETL 过程中?
序列比标识列有更多保证。特别是,每次调用序列都保证为序列生成 next 值。
但是,identity
列可能存在间隙和其他不一致之处。这都记录在案 here.
由于对序列的额外保证,我怀疑它们更慢。特别是,我怀疑数据库无法批量预分配值。这意味着在多线程环境中,序列会对事务施加序列化,从而减慢速度。
一般来说,我看到 identity
用于标识表中的列。虽然可能有性能比较,但我还没有看到。但我怀疑在某些情况下序列会慢一点。
Sequence 和 Identity 都是为 OLTP
table 设计的,以实现唯一键的有效分配在多会话环境中。
需要意识到的重要一点是,在数据仓库环境中,您通常有不同的设置,并且只有 一个作业 填充特定的 table。
在单用户环境中,您根本不需要上述功能,您可以简单地分配键手动从max(id) +1
开始,每行递增1。
数据仓库的一般规则是你不应该搜索silver bullet recommendation而是检查你onw中的功能和性能测试。
如果您对 SQL 服务器身份与序列 进行了一些研究,例如here or here 你会得到不同的结果,部分偏爱前者,部分偏爱后者。
因此,我的建议是使用手动分配的ID
s(即没有开销)进行测试,以获得预期的基线。
然后用 identity 和 sequence 重复它 - 比较并选择。
SQL服务器中的sequence
是后来添加的,是基于Oracle Sequence的,所以我不认为它有一些基本问题。
Oracle 的经验告诉我们,序列中需要有足够大的 cache
才能支持有效的批量插入。
同时 identity
也可以定义为 cached, (IDENTITY_CACHE = { ON | OFF }) 所以再一次,尝试所有三种可能性(顺序,恒等式) , nothing) 然后选择最好的一个。
身份限定为单个 table,是 table 定义 (DDL) 的一部分,并在截断时重置。身份在 table 内是唯一的。每个 table 在配置时都有自己的标识值,不能在 table 之间共享。在一般用法中,当 table.+
上发生插入时,SQL 服务器使用“下一个”值序列是第一个 class 对象,作用域为数据库。使用 Sequence 时会消耗“下一个”值 (NEXT VALUE FOR)。
当您需要跨多个 table 存储一个人可读的唯一标识符时,使用序列最有效。例如,在不同 table 中存储票证类型的票务系统可以使用一个序列来确保没有票证收到相同的号码,而不管它存储在 table 中,并且一个人可以合理地参考数字(不是 GUID)。
在数据仓库中,维度 table 需要一个在 table 中唯一的行标识符。一般来说,OLTP 主键是不够的,因为它可能在维度 table 中重复,具体取决于维度的类型,并且您不想冒险为 OLTP PK 分配额外的上下文,因为这可能会带来挑战当源数据改变时。维度行标识符应该只对与其关联的非度量事实列有意义。事实列未跨不同维度连接。++
由于维度 table 标识符的范围仅限于维度 table,因此标识键是理想的行标识符。创建简单,存储紧凑,在空间之外没有意义。您不会在报表上使用维度标识。 (真的,请不要成为那个开发者。)
+ 您很少需要知道下一个值而不需要分配给行。如果您试图在赋值之前操纵标识值,则可能是一个危险信号
++ 维度视图可以联合不同的 tables 来提供 OLAP 多维数据集,在这种情况下,应该从基础数据中生成一个持久的 repeatable 键,通常通过将字符串文字与规范化格式的每个 table 键连接起来。