结构:
Actor <=== ActorMovie ===> Movie
ActorMovie: ActorID (fk), MovieId (fk)... ===> pk: (ActorID, MovieID)
我应该为这样的
ActorMovie
表创建一个代理键吗?
ActorMovie: ActorMovieID (pk), ActorID (fk), MovieId (fk)...
如果有帮助的话,约定就是好的
“SQL 反模式”,第 4 章,“需要 ID”
主键的含义
主键 - 您可以使用它在表中的唯一地址来识别您的行。这意味着,不仅某些代理列可以是主键。事实上,主键应该是:
化合物与替代物
在某些情况下,代理键有好处。最常见的问题 - 如果您有包含人名的表。
first_name
+ last_name
+ taxpayer_id
的组合可以是唯一的吗?在大多数情况下 - 是的。但理论上,可能会出现重复的情况。因此,在这种情况下,代理键在任何情况下都将提供行的唯一标识。
但是,如果我们谈论表之间的多对多链接,很明显,链接表将始终包含每对一次。事实上,您甚至需要在操作该表之前检查是否不存在重复项(否则 - 它是冗余行,因为它不包含任何附加信息,除非您的设计有特殊意图来存储该信息)。因此,您的
ActorID
+ MovieID
组合满足主键的所有条件,并且 不需要 创建代理键。您可以这样做,但这没有什么意义(如果没有的话),因为它比对行进行编号没有任何意义。另一方面,使用复合键,您将拥有:
作为结论 - 是的,在某些情况下,应该(甚至必须)应用代理键,但在您的特定情况下,它肯定会是反模式 - 使用复合键。
参考资料:
我总是使用复合键。我的推理:
除非您实际在自己的表之外使用代理键,否则我会使用复合键。
让我提一下其他发帖者似乎忽略的一个细节:InnoDB 表是集群的。
如果你只有一个主键,你的整个表将由一个单独的 B 树表示,这是非常高效的。添加代理只会创建另一个 B 树(并且由于集群的工作原理,比预期启动时“更胖”),而没有任何好处来抵消增加的开销。
代理有其位置,但联结表通常不是。
如果您想将其他数据元素与连接表关联起来,例如所扮演的角色的名称(可能是子表),那么我当然会这样做。如果你确定你从来不想那么我会认为它是可选的。
在这个主题上,我的观点非常简单:代理主键始终有效,而复合键可能并不总是有效这些天,这有多种原因。
所以当你开始问自己“复合是否比代孕更好”时,你就已经进入了浪费时间的过程。去找代孕妈妈吧它总是有效的。并切换到下一步。
如果您有 n 个中间表,没有任何其他附加字段,请使用复合键。
如果“中间”表有附加字段,则不是一个简单的中间表。然后,拥有代理键会更好,因为对其他字段进行索引和查询会更加高效。