2010-06-12 60 views
0

我最近遇到了一个相当复杂的问题,并经过四处寻找,我无法找到解决方案。我在stackoverflow.com上找到了很多次我的问题的答案,所以我决定在这里发帖。带两个外键的2列表。性能/设计问题

因此,我正在为基于Web的项目制作用户/组管理系统,并将所有相关数据存储到PostgreSQL数据库中。此系统依靠三个表:

  1. USERS(包含主键 “USER_ID”)
  2. 基(包含主键 “GROUP_ID”)
  3. GROUP_USERS

两个第一表只需定义站点上的所有用户和所有组,并且最后一个表GROUP_USERS存储每个用户所属的组。它只有两列:

  1. USER_ID
  2. GROUP_ID

由于每个用户都可以是多个组的成员,我决定做一个单独的表用于此目的,而不是存储逗号在USERS表中分隔列。

现在,这两列都是外键,我也想让它们成为一个组合主键,因为USER_ID和GROUP_ID的每个组合都必须是唯一的。但是现在我被困在似乎只有很多索引和关系的很小的表中,其中只包含数字。最后,我希望这个表尽可能快,即使包含数万行。磁盘上的大小不应该是一个问题,因为它只是所有的数字,但它感觉非常愚蠢的全尺寸索引引用一个较小的表。

我应该坚持我目前的解决方案,存储逗号分隔值列在用户表或有任何其他的解决办法,我应该知道的。我在寻找的是最好的表现。此表可能(但不太可能或通常)在单个页面加载时被查询数百次。

我不想使用数组列,即使它们被postgreSQL支持。我希望尽可能通用,以便稍后可以切换数据库(如有必要)。

编辑:换句话说,将使用复合主键,并且在一个表中的两个外键仅具有两个列已而不是相反对性能有负面影响,由于所生成的索引的大小?

编辑2:澄清。

谢谢!

回答

1

我相信你在正确的道路是正确的了,但不明白你真正定义的索引。

我的建议是你应该在用户可以通过USER_ID你的主键索引,成群的GROUP_ID你的主键索引,并在GROUP_USERS两个指标。 GROUP_USERS中的其中一个索引应由夫妇(USER_ID,GROUP_ID)或夫妻(GROUP_ID,USER_ID)提供。第二个索引应该是在最后定义的索引中排在第二位的字段。

现在,当定义了GROUP_USERS主键为什么我提到的两个选项?这是因为主键索引与任何其他重复索引之间的性能差异较小。对该表最常见的查询很可能是查明用户是否在某个组中,并且该查询将以任何方式执行。你必须考虑的是以下两个查询中的哪一个更常见。

  1. 查询哪些组特定用户是英寸
  2. 查询哪些用户是在一定的基团。

如果1更可能超过2,那么您的主键应该是(USER_ID,GROUP_ID),否则(GROUP_ID,USER_ID)。

+0

我已按照您的建议设置了表格。我相信我很可能会检查用户是否在某个特定组中,而不是相反。 您的回复让我感到更加自信,我现在正以正确的方式进行,所以我正在考虑回答这个问题。 再次谢谢你。 – Emanuel 2010-06-12 22:25:45

0

如果我正确地理解你的问题,你可能会丢失的是主键(对于这个问题,外键以及)可能是所谓复合,这意味着它们包含多个列。这就是你想要的。在两个用户ID和的GroupId,并在每一个indivudyally外键的复合主键,每个指向(参考文献)中的各父表中的PK。

+0

嗯,是的。我不完全确定如何将我的问题转化为文字,也许我只是感到困惑。 ;) 我的问题是,如果你刚才提到的这个解决方案会对性能产生负面影响,而不是相反。 我会编辑主要的帖子,以便更清楚。 谢谢你的快速答案! – Emanuel 2010-06-12 16:27:06

+0

每个索引对插入,更新和删除性能都有一定的负面影响,因为数据中的每个更改都需要额外的写入IO才能更新每个索引,但无论添加多少个索引都只能对Read产生积极影响操作,因为如果有索引可用于帮助查找所需的记录,这将显着减少访问数据所需的读取IO数量。 – 2010-06-13 14:21:53