阅读建议:
本文是根据TD的一篇英文文章自己翻译而来的。对于代理主键和自然键的选择没有统一的标准,也没有选谁而不能选谁。文章最后提供了可参考的选择标准。可以忽略前文所有的文字,直接看最后的表格。
-----------------------------------------------------------------
企业数据仓库中代理主键使用
目的
本文建立了关于在数据仓库中使用代理主键的指导方针。
代理键在RDBMS环境中的使用是个典型的专题伴随着支持和反对的观点,每个都有大量的支持的理由。在企业数据仓库舞台上,模型和设计决策而不是性能决策是主要的考虑。在Teradata环境中,配套使用代理主键几乎没有(即便有也是很少)性能优势。
主键回顾
定义
主键(PK)定义为最小的特征(或者列)的集合,这个集合可以用于唯一的标识每个元组(或者行)在每个实体(或者表)。
主键特征
主键是一致的、稳定的、持久的、通用的。
主键是一致的,如果这个主键属性有相同的数据类型和域,忽略数据呈现的业务功能职责。
AccountNumber是一个一致性的主键,如果所有的行用7位数字编号,然而,如果一行用5位数字后面接2个字母的9位编号就不是一致性的主键了。
主键是稳定的,如果主键永远不改变。
AccountNumber 是稳定的主键,如果每个账户在整个生命周期中保持相同的编号。然而,如果一个账户曾经被给了一个不同的编号,比如,一个账户管理系统被另外一个账户管理系统替换时,就不是稳定的主键了。
主键是持续的,如果主键的值永远不会被一个新的实体事例再次用到。
AccountNumber 是持续的主键,如果当一个账户被关闭时,主键将“退休”,并且在一个新的账户永远不会重新发行。然而,如果退休的编号,在一段时间后,在一个新的账户重新发行就不是持续的主键了。
主键是通用的,如果所有业务记录用相同的主键值去标识一个实体的实例。
AccountNumber 是通用主键,如果所有业务记录都用相同的编号(6632917)去标识业务记录并且有一个不同的编号对应其他的就不是通用的主键了。
尽管当一个主键不是一致、稳定、持续、或者通用,最好的解决方案可能不是代理主键,而是ETL过程中的改变或者使用额外的列给输入的主键值他们需要的完整性(比如在顾客表增加source_sys_id列,当customer_number不是通用的)。另外可选的方案应该在使用代理前经常被评估。
代理键
代理键回顾
代理键是一个虚拟的主键,它要么是自然键的替代,要么当比表没有自然主键时充当主键。代理主键的值是在ETL过程中生成的,或者在数据库它本身使用继承或者特别的功能时生成的。
代理主键可以有意或无意是智能的。当使用序列号方案,作为分析时推测更高的号码就是最近的事务时是很自然的。例如,一个代理主键可能由序列化的数字组成,一天新的记录附加数字化形式的加载时间,创建一个单一的、智能的代理主键。结果可能是‘05231000001’(yydddnnnnnn)的数字,它代表2015年第231天中第一条记录。这个案例中的智能包含加载日期、订单日期和序列号。
像这个例子,终端用户很有可能为数据库创建额外的开销。如果智能的代理主键诱使业务分析师去解析它,例如很可能在连接到其他表时使用部分代理主键,之后更多的全表扫描将发生,增加数据库的负担。如果代理主键使用简单的智能,比如排序是更好的。在这个例子中,终端用户可能仅仅推测更高的号码很可能是最近的数据并且部分键是没有意义的。
相对于代理主键引用数据应该被管理来允许一致性的便于记忆的代码被使用。便于记忆的代码经常是熟悉的,被终端用户使用来代替真正的描述,能减少当助记码被传播到外键关系时,生成有意义的信息被需要的连接次数。当代理主键在关系表中(在外键关系中)经常被使用去替换自然键,一个指向关系表的连接几乎一直被需要。
代理主键不能被任意的使用。对于没关联数据,自然键相对于代理键是更可取,除非自然键不是一致的、稳定的、持续的、通用的。任何时候去使用代理键的决定,这个决定后面的基本原理应该仔细地被回顾和评价去决定使用代理主键的益处是否超过复杂的、抽象的并且维护不仅仅是一天的操作,也包括开发和测试阶段的额外的开销。代理主键的使用应该是例外而不是规定,当开发者应该有能力去证明使用代理主键是合理的,当他们想要使用代理主键时。
尽管当一个主键不是一致、稳定、持续、或者通用,最好的解决方案可能不是代理主键,而是ETL过程中的改变或者使用额外的列给输入的主键值他们需要的完整性(比如在顾客表增加source_sys_id列,当customer_number不是通用的)。另外可选的方案应该在使用代理前经常被评估。
代理键议题
智能和相关
智能键最大的优势是终端用户通常能理解它们的意义,而代理主键没有业务相关性。然而自定义的应用、商业智能、报表具能从终端用户屏蔽代理主键,特别的数据库工具是不能的。因此一些终端用户派系(特别那些不能通过一个商业智能应用从数据库中分离的用户)必须学会那些列代表什么,怎样去使用它们编写合适的和有意义的SQL 连接。
ETL注意事项
一些数据库设计者教条式地使用代理主键而忽略其他自然候选键的适用性。然而,如果一个好的键已经存在,额外的增加代理主键可能足以减慢访问速度,不必要的空间开销并且创建会显著的增加了ETL过程中额外的开销。
应用代理键的额外的维护开销是值得考虑的。如果一个人选择这样做,另外一个就立刻面临生成值得任务。为这个目的很多数据库提供“自增”或者“标识”特性。这种特性为一个表插入表现是令人满意的,但是当一整层父和子行都必须在一个业务事务中被插入不是很有效。通常,定制化的复杂的过程必须被创建用以在一个批次的环境中实现代理键。
相似的,在复制或者接近复制的数据仓库系统情况中,比如在双重作业环境中,额外的考虑在每个系统中保持代理主键生成过程同步是更加复杂的。
使用代理键一直被联系在一起的缺点是它们需要的额外的维护工作。当代理键是主键并且它被作为外键使用时,搜寻和分配必须被执行。额外的代码必须被编写和执行用以维护代理键、代理键和相应的自然键之间的完整性。那意味着增加的维护和复杂性在ETL过程中,它当然转变为额为的处理时间(以及额外的开发、测试的复杂、时间)。
访问注意事项
自然键能减少一个查询中涉及的连接次数。在很多情况下,特别的使用代理键的查询比同样的使用自然键的查询需要更多的连接。例如,当代理键被使用,一个子表连接它的祖表需要一个额外的连接,因为一个必须通过介于中间的父表连接(图3)。
然而,当用户使用自然键时,直接连接在祖表和子表是可能的(图4)。
另外的访问优势支持自然键是列中有意义的、被检索的值在特定的环境中能使分析执行变得容易和简化。一个也是主索引的代理键通常不适合直接主索引访问,因为对于行的代理键值,终端用户的兴趣程度是不知道的。在自然主键上没有一个二级索引,对于一个查询查找表的一小部分行,全表扫描经常被需要。
同样的,在一个特定的分析环境中,查询将在使用SQL的数据库中的原始数据上直接运行,拥有自然和意义的键来连接是有利的。
空间和性能考虑
当使用代理主键时,在业务列上额外的(二级)索引可能被需要,否则它们将是主键的一部分,在大部分情况下,是主索引。那些索引可能对保证唯一性和满足查询是必要的,但是它们降低更新性能。二级索引需要空间,在Teradata中是索引子表的形式。
相反的,代理键经常被吹捧为一个节约空间的特性,特别的在替代多列或者复杂的自然键中。然而,这种优势已经随着时间的推移被更好的更完整的数据库压缩方案所减轻。此外,由于在存储空间上成本戏剧性地减少,放置在高效存储上的费用更少了,现在,这种优势赋予更少的优先级。
代理键使用
部分、不完整、或者丢失主键
有时候人工的或者代理键从商业的角度的确有意义。这是事实,每当一个自然的智能主键不存在时,或者在完整的智能键被知道前,部分数据必须被捕获和存储。在最初就使用“所有数据在数据仓库中”哲理的数据仓库环境中,这通常不是一个问题。
复杂,多列主键
当主键有所有或者超过几列的表所有的列组成时,一个代理主键是有意义的。如果自然键有超过5列并且在其他几个数据库表中作为外键,一个坚实的理由使用代理键是存在的。
地址表可能是一个例子。而不是传播被顾客地址唯一的需要的所有的列到每一个外键实例,一个简单的代理“address ID”主键是一个有效的替代。在这个案例中,在有效的空间使用是额外的开销情况下,如果这个代理主键在其他表中出现很多次,而不是多列自然键,节约空间是能被实现的。
重复的行
有时候,重复的行是存在的,因为源系统没有所有的需要的信息来区分行。如果有业务需要去保留那些重复的行,代理主键在维持关系完整性是有意义的。
安全问题
不断增加安全约束在企业数据仓库环境中已经是常见的考虑。在行业中对所有人需要去隐藏敏感客户或者财务数据,除了被授权的用户,这存在有效的需要为自然数据去去隐藏、加密甚至替代代理值。如果这些数据是自然主键的部分,代理主键去遵守规章制度是有必要的。
引用数据
助记吗是虚拟的主键,它们是名称或者描述的缩写。它们唯一的并且被设计去映射真正的名字或者描述。传统的,助记码已经被当作代理键使用来引用数据。然而它们通常是被源头提供的而不是在ETL过程中生成的。因此它们不适合正式的代理键的定义。因为这些原因,它们或许能被视为代理键的一个特例。
源-内部和外部-通常选择这样的代码去节省磁盘空间和减少数据录入错误。如果一个用户必须重复键入长的引用数据字符串,相对于短的代码,长得字符串录入错误的可能性更加的大。便于记忆的代理键维持了足够的含义来容易被记住。
为引用数据使用真正的代理键的这个传统争论是,引用数据可能不是一直都是一致性、稳定的、持续的和通用的。如果引用数据合适的被维护和控制,所有的那些异议都能被减轻。因此,引用数据应该被设法去减轻对代理键的需要。同形的助记码对于引用数据相对于代理键是被推荐的。当查询时,这允许助记码作为外键在其他表中露面来提供信息,没有链接相关的引用表的必要。这是很大的优势在探索性的特定的环境中-数据能用更少的连接被检索。
建议
在Teradata数据仓库中,代理键通常不被实现,除非被缺少有效的自然键的相关性理论所特别地需求。因此用笼统的概念,我们不建议使用代理键,但是也的确流出余地基于在此描述的例外。
一个有效的方法在未来开发中去帮助模型者做出“键”的决定是被需要的。下页的表中能帮助设计者做出代理键的决策。
Question | Answer1 | Action or Follow-up Question | Answer2 | Action |
1. 表的自然键是否一致的 | Yes | 转到问题2 | Yes | 转到问题2 |
No | 能否使用ECTL过程来规范数据类 | Yes | 转到问题2 | |
No | 使用数字型代理键 | |||
2. 表的自然键是否稳定的 | Yes | 转到问题3 | Yes | 转到问题3 |
No | 永远不改变值的业务流程能否被实现? | Yes | 转到问题3 | |
No | 使用数字型代理键 | |||
3. 表的自然键是否持续的 | Yes | 转到问题4 | Yes | 转到问题4 |
No | 永远不重用值得业务流程能否被实 | Yes | 转到问题4 | |
No | 使用数字型代理键 | |||
4. 表的自然键是否通用的 | Yes | 转到问题5 | Yes | 转到问题5 |
No | 标准化值得ECTL过程能否被使用 | Yes | 转到问题5 | |
No | 使用数字型代理键 | |||
5. 自然键是否超过5列并且 | Yes | 使用数字型代理键 | NA | NA |
No | 使用自然键 |
当引用表编码不是持续性时的决策矩阵
大部分编码列值被创建充当便于记忆的代理值。然而他们被源头提供的,而不是在ETL过程中生成的。因此,设计者必须确认为何他们想要创建一个额外的数字代理键。
一个关于引用表普遍的问题是这个助记键偶尔不是持续的。业务可能调整名字或者描述的错误拼写;可能改变一个事物的描述,使之更有意义;或者他重用编码来代码完全其他的东西。
业务分析人员必须提供设计的反馈—重运行报告的历史准确性是否是一个要求?如果不是,描述能够被更新,助记键刚刚好。如果用户需要历史的准确,然后设计者有两个选择—使用有效的标注日期或者数字型代理键。
下面的矩阵被提供来帮助对不持续的助记键的做决策。
Question | Answer | Action |
1. 是否任何子表,里面的编码是外键,有效的被标注了日期? | Yes | 使用助记键,但是对引用表增加有效日期标注 |
No | 转到问题2 | |
2. 业务分析需要知道编码的意义什么时候改变的吗? | Yes | 使用数字型代理键和有效的日期标注 |
No | 使用没有有效日期标注的数字型代理键 |