从定义上讲个关系数据库必须包含规则化表并且每表都包含个主键数据库开发人员通常都不赞同使用无意义数值作为个表主键在技术上而言这没有对与错之分——这只是种意见然而我们却强烈建议从无意义数值建立主键即我们使之作为代理键 在本文中我们将讨论代理键强大功能和自然键固有缺欠
主键定义
在讨论之前我们将定义下主键(primary key)词个主键是唯识别个表每记录但这只是其作用部分主键主要作用是将记录和存放在其他表中数据进行关联在这点上主键是不同表中各记录之间简单指针所以主键值对用户而言是没有什么意义并且和它要赋予值也没有什么非凡联系
当从每表中选择个主键时开发人员必须遵循以下几条规则:
主键必须唯识别每记录
个记录主键不能为空
当生成记录时主键值必须存在
主键必须保持稳定——你不能更改主键域
主键必须简洁不要包含过分属性
主键值不能改变
请注重到以上列表中“必须”不是“可能”或者“绝大多数情况下” ——“必须”是绝对但这并不意味着你不能打破这规则假如你要打破这规则只是意味着你不能和关系数据库进行连接对于关系数据库模型、主键、标准化等方面更多信息请访问以下网站:
Database Normalization – Definitions(关系数据库标准化——定义)
The University of Texas at Austin
自然键违反了规则
现在让我们看看自然键如何违反以上规则为了执行关系数据库规则个表不能包含多个记录这就意味着个属性必须也只能唯识别个记录假设个表存放职工信息包括职工名字出生日期社会保险号以及雇用日期对于每个职工都只有个记录与之对应
最初职工名字是自然主键最合适候选但是让我们作深入研究在开始建立数据库时你不能等到知道职工名字才建立个记录自然主键不能为空所以只有知道职工正确名字后你才能输入职工所有信息
主键答应包含多个域所以单独存储姓和名都不是问题然而个公司职工名字可能有相同这方法即不成立只要公司里有相同名字主键就会扩展为至少有三个域这样你会发觉违反了规则
纠正
现在让我们把以上例子复杂化假设你输入名字有起初这看起来并不是个很重要你只要修改值就可以了但是请注重你是不答应修改主键值而且这样做也通常会破坏完整性可以这样可以更新主键值数据引擎即会自动更新相关值但这方法对于个新手显然是不合适
在我们范例中修正个拼写名字也不会有太多反应但假如主键与个购买顺序号相关联当主键输入值有时相关联购买顺序号值也会出现混乱这对完整性有很大影响
代理键能遵循规则
显然使用自然键作为主键会产生很多问题现在将个递增值作为职工表主键然后看看结果会是怎么样最重要是递增值必须是唯由于系统能够自动生成这递增值可以避免了数据输入除此之外当记录有输入时递增值定会存在所以主键定不会为空
个代理键是不会改变而且只依靠于个域所以它非凡简洁自动递增域提供了个唯稳定简洁主键
其他争论
很多数据库开发系统把唯索引应用到主键这就消除了多个记录——系统不能接受多个记录然而你可以人为使用个唯索引而不需要将个主键作为个索引人为处理会消耗更多资源
些开发人员认为主键应该识别相关记录也就是说用户应该识别值为“Jane Smith”主键与职工Jane Smith记录相关联假如值为“Jane Smith”主键没有什么意义比如只是个递增值这就与职工Jane Smith信息毫无关系事实是这样没有什么规则确保主键值与记录有什么关联
在个设计合理数据库中用户是无法看到主键值实际上用户也不需要知道主键是否存在有时候主键对用户没有什么用处代理键运行得很好数值与记录之间存在isno关系
自然键与代理键比较
当把这两种主键作比较自然主键将会处于劣势如表A所示数据还是数据数据不会成为系统指针这些选项不能受开发人员所控制在中或系统自生成键都是稳定它们也不能为空值
表 A
对于数据库开发人员来说最重要是在于良好设计为了避免出现开发之后和过多修补我们建议采用代理键这简单方法将为你在开发中提供坚固稳定灵活基础
最新评论