知识卡片
有意义键与无意义键的选择
内容
标识域是为了在内存对象和数据库行之间维护标识而存进对象里的一个数据库主键值——内存对象本身不需要这种键(对象系统靠内存地址就能保证身份唯一),但要把数据顺序写回数据库,就必须借助这样一个桥梁。选键时首先要面对的问题是用”有意义的键”还是”无意义的键”。有意义的键类似身份证号、社会保险号这类现实世界里天然存在、承载某种含义的标识——听起来很理想,实际却不可靠:键值要能正常工作必须唯一,要能好好工作还必须恒定不变,但由人来指派或录入的数字总会出错(比如手误把一个人的身份证号录成了他配偶的),一旦出错就同时破坏了唯一性和恒定性;数据库能探测出唯一性冲突,但只能等错误数据已经进入系统之后才发现,为时已晚。相比之下,无意义的键——纯粹由数据库自己构造、不打算给人使用的随机数或自增数——恰恰因为不承载任何现实含义,才不会被人为录入错误连累。可迁移启发:”有意义”与”可靠”是两个独立的维度:越贴近现实世界语义的标识符,越容易被现实世界的人为差错污染;工程上追求的键的核心属性是唯一且恒定,这两者反而更容易靠一个纯人造、无实际意义的标识符来保证。
参考来源
- 位置:《企业应用架构模式》第二部分"模式"之"第12章 对象-关系结构模式"之"12.1 标识域"(源文件:_epub-src/OEBPS/Text/000104.html)
- 结论依据:原文说明"使用有意义键的危险在于,理论上这样的键非常好,但实际上却并非如此。为了能正常工作,键值应该是唯一的;为了能很好地工作,键值又应该是恒定不变的……由人来指派的数字似乎应该是唯一、恒定的,但人会犯错误,结果是经常使得键值无法满足这两个要求……那么,我们可以说:有意义的键是不可信的",直接支撑本卡结论。
- 原始内容:假如你在录入时错把我的SSN当成我妻子的SSN,那么产生的记录将既不唯一,也不恒定……那么,我们可以说:有意义的键是不可信的。