我正在创建一个应用程序(使用PHP / Codeigniter / MYSQL)来跟踪活动中的志愿者。我希望多名志愿者能够登录每个活动。我计划使用一个名为signup
的表来执行此操作,如下所示:
TABLE SIGNUP
============
VolunteerId EventId
----------- -------
12 223
13 223
15 223
12 235
13 235
19 235
两列都是外键(分别对应volunteer
表和event
表的主键。)
有更好的方法吗? 我应该使用复合键作为主键吗?
答案 0 :(得分:2)
复合UNIQUE键的一个用途是防止同一志愿者/事件对在表格中出现两次。这不需要主键。
答案 1 :(得分:2)
老实说,我没有看到你设置它的方式有问题。像这样的表通常用于建立不同对象之间的一对多关系。我在表格中做了类似的事情,引用了某个州的县和城市。 (有些城市跨越多个县。)
数据库设计最佳实践声明您应该声明表的主键。你不必这样做;您可以在技术上声明没有主键的表。但是,请注意,如果您没有专门声明密钥,许多数据库引擎只会在幕后为您创建主键;然而,对于每种情况(通常都不是),这可能并不理想。指定您选择的主键有利于数据库优化和组织。
由于这个原因,我想你也可以使用复合键作为多对多表的主键,而不是创建一个单独的索引列。在这种情况下,这将满足表的要求(因为db引擎将为你创建一个主键),它将防止同一对的多次出现,这对多对多的任何好处都不会有好处。参考表。
简短回答:使用复合主键 - primary key(VolunteerID, EventID)
。你不应该出错。
答案 2 :(得分:1)
应该避免为什么要使用复合主键的好讨论:What are the down sides of using a composite/compound primary key?
答案 3 :(得分:1)
鉴于您所描述的表格,您有三个选择
1 - lunchmeat317
SIGNUP
-------
VolunteerId (PK)
EventId (PK)
2 - Ted Hopp
SIGNUP
-------
VolunteerId (AK1)
EventId (AK1)
3 - ic3b3rg
SIGNUP
-------
SignUpID (PK)
VolunteerId (AK1)
EventId (AK1)
正如Thomas所指出的那样,1和2之间的主要区别在于Unique不会阻止以下内容。
VolunteerId EventId
----------- -------
null null
null null
但是,如果这些字段不允许空值开头(并且不应该),则它们完全相同。
您还可以添加,因为ic3b3rg建议使用代理键(SignUpID)。但是,因为CJ Date notes(以及我正在解释)引入一个人工的,代理的,非易失性密钥通常是一个好主意,但由于它通常难以确定波动性,因此没有正式的方法可以知道何时真正需要它。
只要这张表是......就说了。
...然后用Yogi Berra的不朽话语“当你来到路上的叉子时,把它拿出来”意思是所有三个选择都是有效的,选择可能不会影响你的系统是这样或那样的。
我个人通常这样做。
SIGNUP
-------
SignUpID (PK)
VolunteerId (AK1) (Not Null)
EventId (AK1) (Not Null)