我想创建一个查找表'orderstatus'。即下面,只是为了澄清这将用于数据仓库。如果需要,我将需要通过OrderStatus加入以检索INT(如果我创建一个)以在其他地方使用。例如,在事实表中,我会将int存储在事实表中以链接到查找表。
+------------------------+------------------+
| OrderStatus | ConnectionStatus |
+------------------------+------------------+
| CLOSED | APPROVE |
+------------------------+------------------+
| COMPLETED | APPROVE |
+------------------------+------------------+
| FULFILLED | APPROVE |
+------------------------+------------------+
| CANCELLED | CLOSED |
+------------------------+------------------+
| DECLINED | CLOSED |
+------------------------+------------------+
| AVS_CHECK_SYSTEM_ERROR | CLOSED |
+------------------------+------------------+
主键/唯一键的最佳做法是什么?我应该创建一个OrderStatusKey INT作为具有身份的PrimaryKey吗?或者在订单状态(唯一)上创建唯一约束?感谢。
答案 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
确保表UNIQUE KEY
可以包含NULL
和(按ANSI标准)任意数量的NULL
s。 (此行为取决于SQL Server设置和可能的索引过滤器r非空约束)CLUSTERED INDEX
包含与树叶上一行相关的所有数据。
CLUSTERED INDEX
不唯一(且不为空)时,SQL Server将向每行添加隐藏的GUID
。引用表将PK值(或唯一)存储在其结构中(这也是您用来进行连接的内容)。如果您有一个整数键作为参考(在SQL Server中称为IDENTITY),则可以获得轻微的性能优势。
如果您通常不想列出ConnectionStatus
,那么使用实际显示值(OrderStatus
)可能会有所帮助,因为您不必加入查询表
您可以将这两个值存储在引用表中,但是维护这两个列会产生一些开销和更多错误空间。
群集/非群集问题取决于此表的用例。如果您经常使用OrderStatus
进行过滤(使用文字表单),则NON CLUSTERED IDENTITY PK
上的CLUESTERED UNIQUE
和OrderStatu
可能会有所帮助。但是(如上所述),在小表格中,效果/性能增益通常可以忽略不计。
如果您不熟悉上述内容并且感觉更安全,那么在OrderKey
上创建一个身份集群PK(OrderID
或OrderStatus
)和一个唯一的非群集密钥
在外键中使用PK作为引用/引用列。
还有一件事:如果此列仅由一个表引用,您可能需要考虑创建一个包含表格数据的索引视图。
另外,我建议添加一个虚拟值,如果没有设置状态,可以使用它(并将其用作所有引用列的默认值)。因为未设置仍然是状态,不是吗?