sql中每条记录有多个外键?

时间:2011-06-06 00:42:01

标签: mysql sql foreign-keys

我正在创建一个应用程序(使用PHP / Codeigniter / MYSQL)来跟踪活动中的志愿者。我希望多名志愿者能够登录每个活动。我计划使用一个名为signup的表来执行此操作,如下所示:

TABLE SIGNUP
============

VolunteerId         EventId
-----------         -------
    12                223
    13                223
    15                223
    12                235
    13                235
    19                235

两列都是外键(分别对应volunteer表和event表的主键。)

有更好的方法吗? 我应该使用复合键作为主键吗?

4 个答案:

答案 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(以及我正在解释)引入一个人工的,代理的,非易失性密钥通常是一个好主意,但由于它通常难以确定波动性,因此没有正式的方法可以知道何时真正需要它。

只要这张表是......就说了。

  • 跟踪志愿者已报名参加活动
  • 没有任何其他属性对R具有功能或连接依赖性(VolunteerId,EventID)

...然后用Yogi Berra的不朽话语“当你来到路上的叉子时,把它拿出来”意思是所有三个选择都是有效的,选择可能不会影响你的系统是这样或那样的。

我个人通常这样做。

SIGNUP
-------
SignUpID (PK)
VolunteerId (AK1) (Not Null)
EventId (AK1) (Not Null)