例如,我有2个表,Users
并且UserRelations
,它是一对多的关系.
对于UserRelations
表,我可以有一个标识列,并使其成为主键:
[RelationID] [int] IDENTITY(1,1) NOT NULL, [UserID] [int] NOT NULL, [TargetID] [int] NOT NULL,
或者我可以设计表格如下:
[UserID] [int] NOT NULL, [TargetID] [int] NOT NULL,
并使UserID
+ TargetID
主键.
我的问题是每种设计的含义是什么,哪种性能更好?
如果您使用以前的设计,使用多余的标识列,则不会限制插入具有相同UserID和TargetID的两行.您必须UNIQUE
在其他两列上创建约束,无论如何都会创建复合索引.
另一方面,一些框架(例如Rails)坚持认为每个表都有一个名为的代理键,id
因此"正确"的设计可能不起作用.这取决于您使用此表设计编写的代码.
这几乎是一个宗教问题.对于每个说使用非智能代理键的人,其他人指出代理键可以被认为是多余的等等,所以做对你和你的团队最舒服的事情.
如果您决定使用代理键,则还应在自然(在本例中为多列)键上设置唯一约束,以保持数据的完整性.
我通常会寻找额外的代理键,因为自然键有时缺少许多理想的(不一定是必需的)主键特征:
唯一值:主键必须唯一标识表中的每一行.
非智能:主键最好不具有嵌入的语义含义.换句话说,它不应该描述实体的特征.客户ID 12345通常优于RoadWarrior.
随时间不变:主键的值通常不会改变.更改主键值意味着您正在更改实体的标识,这通常没有意义.我更喜欢非智能键,因为它们不太可能改变.
单属性:主键应具有可能的最小属性数.单属性主键是可取的,因为它们更容易使应用程序使用,并且它们简化了外键的实现.
数字:当它们是数字时,通常更容易管理唯一值.大多数数据库系统都具有内部例程,可以自动递增主键属性.
从性能的角度来看,我怀疑大多数情况下差别不大.但与任何性能问题一样,您应该衡量您所关注的问题.