我对数据库非常陌生,而且我是来自Java的数据抽象新手。为了自学,我正在开发一个在线应用程序,除其他外,它将允许用户成为多个组的一部分。
勾勒出数据库,似乎我必须拥有类似于"会员资格"表:
UserID|GroupID
------|-------
1 | 1
1 | 2
2 | 1
2 | 3
2 | 5
我对此有点担心,因为它只有两个外键,只能用于链接两个对象。这种关系的标准做法是什么?如果没有,首选方法是什么?
同样,我对数据库非常陌生。我的书没有提到这种情况,所以如果有一些反映这个功能的关键词我忽略了......
谢谢。
答案 0 :(得分:7)
这是表示多对多关系的标准方式,被称为“联结表”(或“链接表”)。
您已经注意到UserID和GroupID都是引用其他表的外键。但是当涉及到键(而不是外来键)时,您有几个选择:
{UserID, GroupID}
上创建复合(主)键。除了确保同一用户不能多次连接到同一组之外,它还有助于有效搜索给定用户的组。由于UserID位于索引的前沿(DBMS在密钥下自动创建),因此与同一UserID关联的所有GroupID值都在索引B-tree内的连续范围内,因此,DBMS可以通过简单的索引范围扫描来完成给定用户的组。{GroupID, UserID}
上创建复合(主)键。相同的字段,相反的顺序。这有助于快速获得给定组的用户(即,与(1)相比,在相反的“方向”查询)。{UserID, GroupID}
上的{GroupID, UserID}
和(唯一)索引上设置密钥(反之亦然)。如果您需要在两个方向进行查询,这非常有用:分别获取给定用户的组和获取给定组的用户。{UserGroupID}
)。如果您具有引用联结表的“子”表,并且希望简化通过外键迁移到它们的键的大小,则这可能很有用。如果您的ORM工具不能很好地使用复合键,那么它也可能很有用。如果您决定选项(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