表格纯粹由外键组成?

时间:2014-05-05 15:48:39

标签: sql database database-design foreign-keys foreign-key-relationship

我对数据库非常陌生,而且我是来自Java的数据抽象新手。为了自学,我正在开发一个在线应用程序,除其他外,它将允许用户成为多个组的一部分。

勾勒出数据库,似乎我必须拥有类似于"会员资格"表:

UserID|GroupID
------|-------
  1   |   1
  1   |   2
  2   |   1
  2   |   3
  2   |   5

我对此有点担心,因为它只有两个外键,只能用于链接两个对象。这种关系的标准做法是什么?如果没有,首选方法是什么?

同样,我对数据库非常陌生。我的书没有提到这种情况,所以如果有一些反映这个功能的关键词我忽略了......

谢谢。

2 个答案:

答案 0 :(得分:7)

这是表示多对多关系的标准方式,被称为“联结表”(或“链接表”)。

您已经注意到UserID和GroupID都是引用其他表的外键。但是当涉及到键(而不是外来键)时,您有几个选择:

  1. {UserID, GroupID}上创建复合(主)键。除了确保同一用户不能多次连接到同一组之外,它还有助于有效搜索给定用户的组。由于UserID位于索引的前沿(DBMS在密钥下自动创建),因此与同一UserID关联的所有GroupID值都在索引B-tree内的连续范围内,因此,DBMS可以通过简单的索引范围扫描来完成给定用户的组。
  2. {GroupID, UserID}上创建复合(主)键。相同的字段,相反的顺序。这有助于快速获得给定组的用户(即,与(1)相比,在相反的“方向”查询)。
  3. {UserID, GroupID}上的{GroupID, UserID} (唯一)索引上设置密钥(反之亦然)。如果您需要在两个方向进行查询,这非常有用:分别获取给定用户的组和获取给定组的用户。
  4. 上面的(1)或(2)或(3),但制作代理键(例如{UserGroupID})。如果您具有引用联结表的“子”表,并且希望简化通过外键迁移到它们的键的大小,则这可能很有用。如果您的ORM工具不能很好地使用复合键,那么它也可能很有用。
  5. 如果您决定选项(1)或(2),cluster表(如果您的DBMS支持它)。由于您只进行索引范围扫描,因此根本不需要存在表堆。您甚至应该考虑(3)的聚类,因为两个索引都是covering所以不存在双重查找的危险。

答案 1 :(得分:0)

这种设置非常普遍,完美无缺。

我也会在自动增量列上添加主键索引,并确保在userid和groupid上有索引。

如果您知道应用程序将如何使用数据,并且您可以利用复合(AKA复合AKA多列AKA ...)索引,请在userid和groupid上执行该操作而不是单列索引。

您可以在此处详细了解多列索引:http://www.mysqlperformanceblog.com/2009/09/19/multi-column-indexes-vs-index-merge/

http://dev.mysql.com/doc/refman/5.0/en/multiple-column-indexes.html