多列主键?

Ray*_*Ray 7 database-design

例如,我有2个表,Users并且UserRelations,它是一对多的关系.

对于UserRelations表,我可以有一个标识列,并使其成为主键:

[RelationID] [int] IDENTITY(1,1) NOT NULL,
[UserID] [int] NOT NULL,
[TargetID] [int] NOT NULL,
Run Code Online (Sandbox Code Playgroud)

或者我可以设计表格如下:

[UserID] [int] NOT NULL,
[TargetID] [int] NOT NULL,
Run Code Online (Sandbox Code Playgroud)

并使UserID+ TargetID主键.

我的问题是每种设计的含义是什么,哪种性能更好?

Bil*_*win 9

如果您使用以前的设计,使用多余的标识列,则不会限制插入具有相同UserID和TargetID的两行.您必须UNIQUE在其他两列上创建约束,无论如何都会创建复合索引.

另一方面,一些框架(例如Rails)坚持认为每个表都有一个名为的代理键,id因此"正确"的设计可能不起作用.这取决于您使用此表设计编写的代码.


Roa*_*ior 7

这几乎是一个宗教问题.对于每个说使用非智能代理键的人,其他人指出代理键可以被认为是多余的等等,所以做对你和你的团队最舒服的事情.

如果您决定使用代理键,则还应在自然(在本例中为多列)键上设置唯一约束,以保持数据的完整性.

我通常会寻找额外的代理键,因为自然键有时缺少许多理想的(不一定是必需的)主键特征:

  • 唯一值:主键必须唯一标识表中的每一行.
  • 非智能:主键最好不具有嵌入的语义含义.换句话说,它不应该描述实体的特征.客户ID 12345通常优于RoadWarrior.
  • 随时间不变:主键的值通常不会改变.更改主键值意味着您正在更改实体的标识,这通常没有意义.我更喜欢非智能键,因为它们不太可能改变.
  • 单属性:主键应具有可能的最小属性数.单属性主键是可取的,因为它们更容易使应用程序使用,并且它们简化了外键的实现.
  • 数字:当它们是数字时,通常更容易管理唯一值.大多数数据库系统都具有内部例程,可以自动递增主键属性.

从性能的角度来看,我怀疑大多数情况下差别不大.但与任何性能问题一样,您应该衡量您所关注的问题.