复合主键或单主键

时间:2010-10-06 22:17:03

标签: database database-design

使用单个主键或使用复合主键(通常是一个主键和外键的组合)是否更好?我有以下示例:

复合主键示例:

AMTA
--- AMetaId - 主键
--- AMetaText

BMeta

--- BMetaId - 主键
--- AMetaID - 表AMeta的外键 --- BMetaText

A

--- AId - 主键
--- AMetaId - 表AMeta的主键和外键 --- AText

B

--- BId - 主键
--- BMetaId - 表BMeta的主键外键
--- AId - 表A的主键和外键 --- BText


单个主键示例:

AMTA
--- AMetaId - 主键
--- AMetaText

BMeta

--- BMetaId - 主键
--- AMetaId - 表AMeta的外键 --- BMetaText

一个

--- AId - 主键
--- AMetaId - 表AMeta的外键 --- AText



--- BId - 主键
--- BMetaId - 表BMeta的外键
--- AId - 表A的外键 --- BText

哪种数据库设计更好?

2 个答案:

答案 0 :(得分:3)

我几乎完全倾向于使用单列主键 - 要么有一个好的自然键可用(很少),要么我在表中添加一个代理INT IDENTITY键。

我的主要原因是:

  • 主键必须是唯一的,始终为非空
  • 默认情况下,主键是SQL Server中的群集键,它会添加稳定(不变),窄(最多4个字节),最好不断增加到标准列表
  • 使用单列主键,我的所有外键也很容易使用单列 - 我不喜欢在3,5或甚至更多列上连接两个表只是为了使连接起作用,这是如果你有一个复合主键,究竟会发生什么?

答案 1 :(得分:2)

第一种方案毫无意义,因为它暗示(并允许)表B中有多个行具有相同的BId值但具有不同的AId值,并且没有与列Bid相关的含义。这是其他地方的FK吗?如果是这样,到底是什么?如果没有,那是什么产生的?这是什么意思?

另一方面,第二种方案在逻辑上是一致的,但暗示表B中的行可以与表AMeta中的两个不同行相关联,

  1. 通过表B使用FK柱 BMetaId并从那里到表 AMeta使用TableB.AMetaId和
  2. 通过表BMeta使用列 BMetaId表BMeta和 那里给AMeta使用BMEta.AMetaId
  3. 这真的是您商业领域模型的准确表示吗?