索引 - 唯一标识符外键或中间映射表?

Cra*_*igA 6 schema index sql-server uniqueidentifier

寻找对这些人的一些专家意见 - 我不是一名 DBA,因此希望得到任何建议。不需要对架构的其余部分进行评论,因为它纯粹是为了说明我的问题而捏造的。

基本上,我正在为现有系统开发新功能,但无法更改现有架构。因此,假设当前有一个Users表,它具有一个类型为uniqueidentifier的主键UserID。我想创建一个名为Alerts的新表- 以一对多关系与 Users 表相关(一个用户可以有多个警报)。警报将通过此外键定期查询。我希望索引该字段以提高性能。

我的问题是 - 根据我对索引策略的理解,对 uniqueidentifier 列进行索引(巧妙地放置)不是一个好主意 - 所以有一个中间表来将这些 un​​iqueidentifier 键映射到更好的索引候选像一个更好的主意吗?整数?

用户

  • 用户 ID唯一标识符{PK}
  • 用户名varchar(50)

警报

  • AlertID int {PK}
  • 用户 ID唯一标识符{FK}
  • 消息varchar(250)
  • 时间戳日期时间

或者

用户

  • 用户 ID唯一标识符{PK}
  • 用户名varchar(50)

用户地图

  • UserKey int identity(1,1) {PK}
  • 用户 ID唯一标识符{FK}

警报

  • AlertID int identity(1,1) {PK}
  • UserKey int {FK}
  • 消息varchar(250)
  • 时间戳日期时间

Mat*_*t M 6

好的,我对这个答案做了很多假设(INT 而不是 VARCHAR(50) 是其中之一),所以如果需要,请随时纠正我。选项 B 的问题在于它引入了一个新的连接来将用户与警报联系起来,而没有任何真正的额外好处。如果在 UserID 上加入,最好为 UserID 建立索引,这样您就可以利用搜索进行加入。

对于选项 A,UserID 将是 Users 表上的聚簇键(聚簇索引的索引键)。UserID 将是 Alerts 表上的非聚集索引键。这将花费每个警报 16 个字节。

对于选项 B,UserID 将是 Users 表上的集群键。UserId 也可能是 UserMap 中的聚类键,以提高加入效率。UserKey(假设这是一个 INT)然后将是 Alerts 表上的非聚集索引键。这将花费每个警报 4 个字节。每个 UserMap 20 个字节。

纵观全局,对于选项 A,一种关系需要 16 字节的存储空间,并且涉及 1 次连接操作。而对于选项 B,一种关系需要 24 字节的存储空间,并涉及 2 个连接操作。

此外,可能有 340,282,366,920,938,000,000,000,000,000,000,000,000 个唯一标识符,而只有 4,294,967,296 个 INT。当您开始重用 INT 时,为此类关系实现到 INT 映射的唯一标识符可能会导致意外结果。

创建这种类型的映射表的唯一原因是,如果您计划在用户和警报之间创建多对多关系。

考虑到所有这些,我会推荐选项 A。

我希望这有帮助,

马特

  • +1 表示“唯一的原因……是如果您打算创建多对多……” (2认同)