Nat*_*ate 6 sql database-design
所以我最近看到了几个提到代理键的提示,我不确定它是什么以及它与主键的区别.
我总是认为ID是我在这样的表中的主键:
Users
ID, Guid
FirstName, Text
LastName, Text
SSN, Int
Run Code Online (Sandbox Code Playgroud)
但是,维基百科将代理键定义为"数据库中的代理键是建模世界中的实体或数据库中的对象的唯一标识符.代理键不是从应用程序数据派生的."
根据维基百科,看起来ID是我的代理键,我的主键可能是SSN + ID?这是正确的吗?这是一个糟糕的桌子设计吗?
假设表格设计合理,那么这样的表格是不是很糟糕,对于一个数据没有任何独特之处的表格呢?
LogEntry
ID, Guid
LogEntryID, Int [sql identity field +1 every time]
LogType, Int
Message, Text
Run Code Online (Sandbox Code Playgroud)
mar*_*c_s 13
不,你的ID既可以是一个代理键(这只是意味着,如人工键它不是"从应用数据导出"),并且它应该是你的主键,太.
主键用于唯一且安全地标识表中的任何行.它必须是稳定的,唯一的,并且是非空的 - "人工"ID通常具有这些属性.
我通常建议不要使用"自然"或真实数据作为主键 - 真的 不是150%确定它永远不会改变?? 例如,每当女性结婚(或离婚)时,瑞士相当于SSN的变化 - 几乎不是理想的候选人.它不能保证是独一无二的......
为了免除所有这些悲伤,只需使用系统定义,唯一且永不改变的代理(人工)ID,并且永远不会有任何应用含义(除了作为您的唯一ID).
Scott Ambler在这里有一篇非常好的文章,其中包含所有各种键的"词汇表"及其含义 - 您将找到自然,代理,主键等等.
首先,Surrogate键是在数据库中人工生成的键,作为表中每行的唯一值,并且对表中的任何其他属性没有任何依赖性.
现在,短语Primary Key是一个红鲱鱼.密钥是主密钥还是备用密钥并不意味着什么.重要的是密钥的用途.键可以提供两个功能,这两个功能彼此之间不相容.
所以答案很简单...... 总是(在您关心数据完整性/一致性的任何地方)使用自然密钥,并在必要时使用两者!当自然键是复合,或长或不够稳定时,添加备用代理键(例如,自动递增整数),以用作子表中FK的目标.但是存在丢失表的数据一致性的风险,请勿从主表中删除自然键.
为了使这个晶莹剔透,让我们举个例子吧.假设您有一个包含银行账户的表...自然密钥可能是银行路由号码和银行账号.为避免在事务表中的每个事务记录中使用此双复合键,您可能决定在BankAccount表上放置一个人为生成的代理键,该表只是一个整数.但你最好保持自然的钥匙!如果你没有,如果你没有复合自然键,你可以很容易地在表格中得到两行,如下所示
id BankRoutingNumber BankAccountNumber BankBalance
1 12345678932154 9876543210123 $123.12
2 12345678932154 9876543210123 ($3,291.62)
Run Code Online (Sandbox Code Playgroud)
现在,哪一个是对的?
从下面的评论来看,有什么好处能够"识别行 "?在我看来,没有任何好处,因为我们需要能够确定的是该行所代表的银行账户! 识别行仅对内部数据库技术功能很重要,例如查询中的连接或FK约束操作,如果/必要时,它们应该使用代理键,而不是自然键.
你是对的,一个自然键的糟糕选择,有时甚至是自然键的最佳选择,可能不是真正独特的,或保证防止重复.但是任何选择都比没有选择更好,因为它至少会阻止选择作为自然键的属性中相同值的重复行.通过适当选择关键属性可以将这些问题保持在最低限度,但有时它们是不可避免的,必须加以处理.但这样做仍然比允许不正确的不准确或冗余数据进入数据库更好.
关于"易用性"如果您使用自然键的所有方法是约束重复行的插入,并且您使用另一个,代理,键作为FK约束的目标,我看不出任何易用性问题关注的.
| 归档时间: |
|
| 查看次数: |
3888 次 |
| 最近记录: |