查找表或唯一约束的SQL主键?

时间:2016-11-30 16:19:03

标签: sql sql-server sql-server-2012

我想创建一个查找表'orderstatus'。即下面,只是为了澄清这将用于数据仓库。如果需要,我将需要通过OrderStatus加入以检索INT(如果我创建一个)以在其他地方使用。例如,在事实表中,我会将int存储在事实表中以链接到查找表。

+------------------------+------------------+
| OrderStatus            | ConnectionStatus |
+------------------------+------------------+
| CLOSED                 | APPROVE          |
+------------------------+------------------+
| COMPLETED              | APPROVE          |
+------------------------+------------------+
| FULFILLED              | APPROVE          |
+------------------------+------------------+
| CANCELLED              | CLOSED           |
+------------------------+------------------+
| DECLINED               | CLOSED           |
+------------------------+------------------+
| AVS_CHECK_SYSTEM_ERROR | CLOSED           |
+------------------------+------------------+

主键/唯一键的最佳做法是什么?我应该创建一个OrderStatusKey INT作为具有身份的PrimaryKey吗?或者在订单状态(唯一)上创建唯一约束?感谢。

3 个答案:

答案 0 :(得分:1)

为此,我建议您创建一个Identity列,并将其作为群集主键。

表被认为是具有某种主键的最佳实践,但是为这样的表创建聚簇索引是允许在多表查询(带连接)中使用此表的最快方法。

以下是如何添加它的示例:

ALTER TABLE dbo.orderstatus 
ADD CONSTRAINT PK_orderstatus_OrderStatusID PRIMARY KEY CLUSTERED (OrderStatusID);
GO

包含更多详情的文章MSDN

这是解释主键Primary Key Primer

的另一种资源

答案 1 :(得分:1)

如果OrderStatus是唯一的并且主要标识符AND您将直接在相关表中重复使用此状态代码(而不是指向此状态代码的数字指针),则保持列不变并生成{{1}主聚集索引。

一点解释:

主键在表格中是唯一的;聚簇索引将所有记录数据绑定回该索引。并不总是必须让主键也是表上的聚簇索引,但通常情况就是如此。

如果您要使用状态代码以外的其他内容链接到订单状态,请创建另一个类型为OrderStatus的列int,并将其作为主群集密钥。还要为IDENTITY添加唯一的非聚集索引,以确保不会添加重复项。

无论哪种方式,每个表都应该有一个主键和一个聚簇索引(再次,通常它们是相同的索引)。

答案 2 :(得分:1)

以下是需要考虑的事项:

  • PRIMARY KEY确保表
  • 中没有NULL值或重复项
  • UNIQUE KEY可以包含NULL和(按ANSI标准)任意数量的NULL s。 (此行为取决于SQL Server设置和可能的索引过滤器r非空约束)
  • CLUSTERED INDEX包含与树叶上一行相关的所有数据。
    • CLUSTERED INDEX不唯一(且不为空)时,SQL Server将向每行添加隐藏的GUID
    • 当关键列不唯一以区分各个记录时,SQL Server将一个隐藏的GUID列添加到键列列表中。
  • 所有索引都使用聚簇索引的键列值或堆表的rowid值。
  • 查询优化器使用索引统计信息来找出执行查询的最佳方式
  • 对于小型表,通常会忽略索引,因为执行索引扫描,然后查找每个值比执行全表扫描(当您有非常小的表时将读取一页或两页)更昂贵< / LI>
  • 状态查找表通常非常小,可以存储在一个页面上。

引用表将PK值(或唯一)存储在其结构中(这也是您用来进行连接的内容)。如果您有一个整数键作为参考(在SQL Server中称为IDENTITY),则可以获得轻微的性能优势。

如果您通常不想列出ConnectionStatus,那么使用实际显示值(OrderStatus)可能会有所帮助,因为您不必加入查询表

您可以将这两个值存储在引用表中,但是维护这两个列会产生一些开销和更多错误空间。

群集/非群集问题取决于此表的用例。如果您经常使用OrderStatus进行过滤(使用文字表单),则NON CLUSTERED IDENTITY PK上的CLUESTERED UNIQUEOrderStatu可能会有所帮助。但是(如上所述),在小表格中,效果/性能增益通常可以忽略不计。

如果您不熟悉上述内容并且感觉更安全,那么在OrderKey上创建一个身份集群PK(OrderIDOrderStatus)和一个唯一的非群集密钥

在外键中使用PK作为引用/引用列。

还有一件事:如果此列仅由一个表引用,您可能需要考虑创建一个包含表格数据的索引视图。

另外,我建议添加一个虚拟值,如果没有设置状态,可以使用它(并将其用作所有引用列的默认值)。因为未设置仍然是状态,不是吗?