3

我经常发现自己在创建“链接表”。例如,下表将用户记录映射到事件记录。

CREATE TABLE [dbo].[EventLog](
    [EventId] [int] NOT NULL,
    [UserId] [int] NOT NULL,
    [Time] [datetime] NOT NULL,
    [Timestamp] [timestamp] NOT NULL
)

出于此问题的目的,请假设 EventId 加上 UserId 的组合是唯一的,并且所讨论的数据库是 MS SQL Server 2008 安装。

我遇到的问题是我永远不确定这些表应该如何被索引。例如,我可能想要列出特定事件的所有用户,或者我可能想要列出特定用户的所有事件,或者检索特定的 EventId/UserId 记录。我考虑过的索引选项包括:

  1. 在 EventId 和 UserId 上创建复合主键(但我知道在通过 UserId 自行访问时索引将无用)。
  2. 在 EventId 和 UserId 上创建复合主键,并在 UserId 上添加补充索引。
  3. 在 EventId 上创建主键,在 UserId 上创建补充索引。

任何意见,将不胜感激。

4

2 回答 2

1

您的问题的答案取决于几个方面。

  1. 这取决于您要使用的 DBMS。有些人更喜欢单列索引(如 Postgresql),有些人可以更多地利用多列索引(如 Oracle)。有些可以完全从覆盖索引(如 sqlite)回答查询,有些则不能并且最终必须读取实际表的页面(再次,如 postgres)。

  2. 这取决于您要回答的问题。例如,您是否在两个方向上导航,即您是否加入了您的两个 Id 列?

  3. 这也取决于您对数据修改的空间和处理时间要求。请记住,索引通常比它们索引的实际表大,并且更新索引通常比仅更新基础表更昂贵。

编辑:

当您的概念模型在两个实体 E1 和 E2 之间具有多对多关系 R 时,即 R 的逻辑语义是“相关”或“不相关”时,我总是会声明 R 的组合主键. 那将创建一个唯一索引。然而,主要动机是数据一致性,而不是查询优化,即:

CREATE TABLE [dbo].[EventLog](
    [EventId] [int] NOT NULL,
    [UserId] [int] NOT NULL,
    [Time] [datetime] NOT NULL,
    [Timestamp] [timestamp] NOT NULL,
    PRIMARY KEY([EventId],[UserId])

)

于 2013-10-23T12:13:02.687 回答
1

索引旨在解决性能问题。如果你还没有遇到这样的问题并且不能确切地知道你会在哪里遇到麻烦,那么你不应该创建索引。指数相当昂贵。因为它不仅会占用磁盘空间,还会造成写入或修改数据的开销。所以你必须清楚地了解你通过创建索引来决定的具体性能问题。因此,您可以理解创建它的必要性。

于 2013-10-23T12:12:42.890 回答