查找表上的SQL主键或唯一约束?
我想创建一个查找表'orderstatus'。即在下面,为了说明这一点,将在数据仓库中使用。如果需要的话,我需要通过OrderStatus来获取INT(如果我创建一个)以用于其他地方。例如,在事实表中,我会将int存储在事实表中以链接到查找表。查找表上的SQL主键或唯一约束?
+------------------------+------------------+
| OrderStatus | ConnectionStatus |
+------------------------+------------------+
| CLOSED | APPROVE |
+------------------------+------------------+
| COMPLETED | APPROVE |
+------------------------+------------------+
| FULFILLED | APPROVE |
+------------------------+------------------+
| CANCELLED | CLOSED |
+------------------------+------------------+
| DECLINED | CLOSED |
+------------------------+------------------+
| AVS_CHECK_SYSTEM_ERROR | CLOSED |
+------------------------+------------------+
关于主键/唯一键的最佳实践是什么?我应该创建一个OrderStatusKey INT作为PrimaryKey与身份?或者在订单状态(唯一)上创建唯一约束?谢谢。
为此,我建议您创建一个标识列,并使该集群主键。
表被认为是表具有某种主键的最佳实践,但对于这样的表具有聚集索引是允许在多表查询中使用此表的最快方式(带连接) 。
下面是一个简单的如何添加:
ALTER TABLE dbo.orderstatus
ADD CONSTRAINT PK_orderstatus_OrderStatusID PRIMARY KEY CLUSTERED (OrderStatusID);
GO
文章更多的细节MSDN
,这里是用来说明一个主键Primary Key Primer
如果OrderStatus
是独一无二的另一种资源和主标识符AND,您将直接在相关表格中重新使用此状态代码(而不是指向此状态代码的数字指针),然后按原样保留这些列,并使OrderStatus
主聚集索引。
稍加说明:
主键在表中是唯一的;聚集索引将所有记录数据连接回该索引。并不总是需要将主键也作为表上的聚集索引,但通常情况就是这样。
如果你要使用比状态代码以外的东西,然后创建int
类型的另一列作为IDENTITY
,使该主聚集键被链接到订单状态。还要添加一个独特的非聚集索引OrderStatus
以确保不会添加重复项。
无论哪种方式,你去每个表应该有一个主键,以及一个聚集索引(再次,通常它们是相同的指数)。
这里有一些事情要考虑:
-
PRIMARY KEY
确保有在表 -
UNIQUE KEY
没有空值或重复可以包含NULL
和(由ANSI标准)的任何数量的NULL
秒。 (这种行为取决于SQL Server设置和可能的索引过滤器r非null约束) -
CLUSTERED INDEX
包含与树叶上一行有关的所有数据。- 当
CLUSTERED INDEX
不是唯一的(并且不为空),在SQL Server将增加一个隐藏GUID
到每一行。 - SQL Server的一个隐藏的GUID列添加到键列列表时,键列不是唯一的区分单个记录)
- 当
- 所有的索引使用聚集索引或关键列的任意值堆表的rowid。
- 查询优化器使用的索引统计信息,找出执行查询
- 对于较小的表的最佳方法,该指标忽视平时,因为这样做索引扫描,然后对每个值的查找比做得更贵全表扫描(当您有非常小的表格时,它将读取一页或两页)
- 状态查找表通常非常小,可以存储在一个页面上。
引用表将在其结构中存储PK值(或唯一值)(这也是您将用于执行连接的值)。如果您有一个整数键用作参考(又名SQL Server中的IDENTITY),则可以获得轻微的性能优势。
如果您通常不想列出ConnectionStatus
,那么使用实际显示值(OrderStatus
)可能会有好处,因为您不必加入查找表。
您可以将两个值都存储在引用表中,但维护这两列有一些开销和更多空间用于出错。
群集/非群集问题取决于此表的使用情况。如果您通常使用OrderStatus
进行过滤(使用文本格式),OrderStatu
上的NON CLUSTERED IDENTITY PK
和CLUESTERED UNIQUE
可能是有益的。然而(正如你可以在上面看到的那样),在小表中,效果/性能增益通常可以忽略不计。
如果您不熟悉上面的东西,你觉得它更安全,然后创建一个身份聚集PK(OrderKey
或OrderID
),并在OrderStatus
一个独特的非聚集键。
在外键中使用PK作为引用/引用列。
还有一件事:如果该列仅由一个表引用,则可能需要考虑创建一个包含表数据的索引视图。
此外,我会建议添加一个虚拟值,如果没有设置状态(并将其用作所有引用列的默认值),您可以使用该值。因为没有设置仍然是一个地位,不是吗?
如果'OrderStatus'列将在许多表中引用,那么我将使用带有主键的'Identity'列并将其引用到其他表中。检查这个问题以及http://stackoverflow.com/questions/3162202/sql-primary-key-integer-vs-varchar –
你应该给这个读。 http://www.agiledata.org/essays/keys.html。 – JamieSee