首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Server主键/聚集索引设计决策

Server主键/聚集索引设计决策
EN

Database Administration用户
提问于 2012-02-22 10:38:49
回答 3查看 4.4K关注 0票数 6

为了寻求一些关于表/索引设计决策的建议,我必须对一些表进行修改,这些表必须从现有的基于4GL的数据库移植到SQL服务器。

我有一个产品历史表,该表被频繁地插入(从未更新),并且该表具有这样的结构

  1. ProductNo字符串(20)
  2. CreatedDateTime DateTime
  3. 描述字符串(100)

目前,主键是由ProductNo和CreatedDateTime组合而成的,目的是定义唯一的索引键。我们每个产品都有很多记录。

我将创建大约1到1个相关的表,并且不希望将productno和createddatetime字段都带到相关表中,以充当foriegn键。我还认为,为了保证独特性,这种组合有点脆弱。

因此,我计划在表'ProductHistoryPK‘中添加一个新字段,作为一个递增的Int或SequentialGuid,作为相关表的主键和外键。

就索引而言,我正在考虑创建

  1. 新ProductHistoryPK字段上的非群集主键。
  2. ProductNo字段上的聚集索引,因为这是经常被搜索的字段。

对此有什么想法或建议吗?

谢谢..。

EN

回答 3

Database Administration用户

发布于 2012-02-22 10:47:23

将“聚集索引”与“主键”分开是正确的:

  • 聚集索引是如果的话,磁盘上数据的组织更好
    • 数字
    • 增加(严格单调)

  • 主键标识行。

注意:GUID会产生错误的聚类密钥。

在这种情况下,使用代理项列,表中有两个候选键:

  • ProductHistoryID
  • ProductNo + CreatedDateTime

假定的约定是ProductHistoryID变成PK,但是您可以将PK放在(ProductNo,CreatedDateTime)上:它只是非集群的。这导致索引:

  • 聚集索引应该在ProductHistoryID上
  • 唯一的非聚集索引(ProductNo,CreatedDateTime)

示例

代码语言:javascript
复制
CREATE TABLE Product (
    ProductHistoryID int NOT NULL IDENTITY (1,1) NOT NULL,
    ProductNo ...
    CreatedDateTime ...

那你就可以选择

代码语言:javascript
复制
    CONSTRAINT PK_Product PRIMARY KEY CLUSTERED (ProductHistoryID)
    CONSTRAINT UQ_Product UNIQUE NONCLUSTERED (ProductHistoryID)

代码语言:javascript
复制
    CONSTRAINT PK_Product PRIMARY KEY NONCLUSTERED (ProductNo, CreatedDateTime)
    CONSTRAINT PK_Product UNIQUE CLUSTERED (ProductHistoryID)

另外,您所拥有的模式是“类型2 缓慢变化维数”。

票数 9
EN

Database Administration用户

发布于 2012-02-22 12:15:28

我只想强调一件事:请仔细挑选你的聚集索引!

它是SQL Server数据库中复制最多的数据结构(假设它是您正在讨论的Server )。聚类键也是表中每个非聚集索引的一部分--当然在叶级,也可能在索引导航结构中。

在选择群集密钥时,您应该非常小心--应该是:

  • 窄(4字节理想)
  • unique (毕竟它是“行指针”--如果您不使其惟一,SQL Server -对您来说-在后台-每个条目要花费几个字节-乘以您拥有的行数和非聚集索引的数量-代价很高!)
  • 静态的(永远不要改变--如果可能的话)
  • 理想的情况是不断增加,这样您就不会以糟糕的索引碎片告终( GUID与一个好的集群键完全相反--因为这个特殊原因)
  • 它应该是不可空的,而且理想的情况下,它还可以用-a varchar(250)来修复,这样做的聚类键会非常糟糕。

任何其他的东西都应该是这些要点背后的第二和第三重要层次.

看看金伯利·特里普(“索引女王”)关于这个主题的博客文章--她在博客上写的任何东西都是无价的--阅读它,消化它--靠它生活!

  • GUID作为主键和/或群集密钥
  • 聚集指数辩论还在继续。
  • 不断增加的聚类键-聚集索引辩论.再次!
票数 5
EN

Database Administration用户

发布于 2012-02-22 10:47:43

这是一个有趣的问题。在实践中,是的,我们更喜欢主键是一个简单的、唯一的、数字的字段,但是,通常,这对建立良好的业务密钥没有什么意义。因此,您可能通过将新的密钥强加到它们上来为自己提供dis服务。

除非有重大的数据重新设计计划,我个人建议继续工作,只要它确实工作。

您可以对这两列设置一个主键,如下所示:

代码语言:javascript
复制
CREATE TABLE HISTORY
(
    ProductNo NVARCHAR(20) NOT NULL,
    CreatedDateTime DateTime NOT NULL,
    Description NVARCHAR(100),
    CONSTRAINT PK_HISTORY PRIMARY KEY (ProductNo, CreatedDateTime)
);

您还可以设置一个外键约束,强制使用这两列。

票数 2
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/13778

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档