Tes*_*son 58 mysql sql-server database-design
我被分配将数据库迁移到中产阶级ERP.新系统在这里和那里使用复合主键,从实用的角度来看,为什么?
与自动生成的ID相比,我只能看到消极方面;
它正在回归到候选键的设计概念,我没有看到它的意义.
它是软盘日的习惯/神器(最小化空间/索引),还是我错过了什么?
//编辑//刚发现好的SO帖子:复合主键与唯一对象ID字段 //
Qua*_*noi 57
当主键是非代理的时,复合键是必需的,并且固有的,嗯,复合键,即可分解为几个不相关的部分.
一些现实世界的例子:
多对多链接表,其中主键由相关实体的键组成.
多租户应用程序何时tenant_id是每个实体的主键的一部分,并且实体仅可在同一租户内链接(受外键约束).
处理第三方数据的应用程序(已提供主键)
请注意,逻辑上,所有这些都可以使用UNIQUE约束(除了代理PRIMARY KEY)来实现.
但是,有一些实现特定的东西:
有些系统不允许FOREIGN KEY引用任何不是a的东西PRIMARY KEY.
有些系统只会在a上对表进行聚类PRIMARY KEY,因此使得组合PRIMARY KEY可以提高连接到组合上的查询的性能.
Ali*_*tad 40
复合主键在将其用作其他表中的外键时会提供更好的性能,并减少表读取 - 有时它们可以节省生命.如果使用代理键,则必须转到该表以获取自然密钥信息.
例如(纯粹的例子 - 所以我们不在这里谈论数据库设计),让我们说你有一个ORDER表和ORDER_ITEM.如果您使用ProductId和LineNumber(更新:并且正如Pedro提到的OrderId甚至更好OrderNumber)作为复合主键ORDER_ITEM,那么在您的交叉表中SHIPPING,您将能够拥有ProductId SHIPPING_ORDERITEM.这可以大大提高您的性能,例如,如果您已经用完该产品,并且需要找出ProductId需要在不需要加入的情况下发货的所有产品.
另一方面,如果使用代理键,则必须加入并最终得到效率非常低的SQL执行计划,它必须在多个索引上进行书签查找.
查看有关使用代理键成为主要问题的书签查找的更多信息.
HLG*_*GEM 40
我个人更喜欢使用代理键.但是,在连接仅包含来自其他两个表的ID的表(以创建多对多关系)时,复合键是可行的方式,因此将它们取出会使事情变得更加困难.
有一种观念认为代理键总是很糟糕,如果你没有通过使用自然键进行记录的独特性,那么你的设计就会很糟糕.我强烈不同意这一点(如果你没有存储SSN或其他一些独特的价值,我会藐视你为个人桌子提供一个自然键.)但是很多人觉得有必要进行适当的规范化.
有时使用复合键可以减少加入另一个表的需要.有时却没有.因此,有时复合键可以提高性能以及可能会损害性能的时间.如果密钥相对稳定,那么在选择查询时性能会更快.但是,如果它可能会像公司名称那样发生变化,那么当公司A更改其名称并且您必须更新一百万条相关记录时,您可能会受到伤害.
在数据库设计中没有一种尺寸适合所有.有时间复合键是有用的,有时它们是可怕的.有时代理键是有用的,有些时候不是.
自然主键很脆弱.
假设我们在自然PK(CountryCode,PhoneNumber)周围构建了一个系统,并且在未来几年我们需要添加Extension,或者将PK更改为一列:Email.如果将这些PK列传播到所有子表,则会变得非常昂贵.
几年前,有些系统是在假设社会安全号码是自然PK的情况下构建的,并且当SSN变得非独特且可以为空时,必须重新设计以使用身份.
因为我们无法预测未来,我们不知道后来的某些变化是否会过时,这是一个完全正确和完整的模型.
非常简单的答案是数据完整性.如果数据有用且准确,则可能需要密钥.具有"自动生成的id"也不会删除对其他键的要求.另一种方法是不强制执行唯一性并接受数据将被复制并且几乎不可避免地包含异常并导致错误.你为什么要那样?
简而言之,组合键的目的是使用数据库来强制执行一个或多个业务规则.换句话说:保护数据的完整性.
防爆.您有从供应商处购买的零件清单.您可以创建供应商和零件表,如下所示:
SUPPLIER
SupplierId
SupplierName
PART
PartId
PartName
SupplierId
Run Code Online (Sandbox Code Playgroud)
哦,哦.零件表允许重复数据.由于您使用了自动生成的代理键,因此您不会强制执行供应商的零件只需输入一次这一事实.相反,您应该像这样创建PART表:
PART
SupplierId
SupplierPartId
PartName
Run Code Online (Sandbox Code Playgroud)
在此示例中,您的部件来自特定供应商,并且您希望强制执行规则:"单个供应商只能在PARTS表中提供一次".因此,复合键.复合键可防止意外重复输入零件.
您始终可以将业务规则保留在数据库之外并将其保留在应用程序中,但通过将规则保留在数据库中(通过组合密钥),可以确保业务规则在所有地方都得到强制执行,尤其是在您决定允许的情况下多个应用程序来访问数据.