Com*_*der 6 database-design sql-server primary-key sql-server-2016
我已将 WorldWideImporters 数据库下载为标准数据库(SQL Server 的 Microsoft 示例数据库)。在这个数据库中,一些表没有主键,但可以看到聚集索引。谁能告诉我为什么有些表在没有 PK 的情况下工作?是什么原因?
任何意见将不胜感激!
要查看哪些表没有主键,请运行以下脚本:
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
EXCEPT
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE CONSTRAINT_TYPE = 'PRIMARY KEY'
Run Code Online (Sandbox Code Playgroud)
您将获得以下列表:
TABLE_NAME
----------
BuyingGroups_Archive
Cities_Archive
ColdRoomTemperatures_Archive
Colors_Archive
Countries_Archive
CustomerCategories_Archive
Customers_Archive
DeliveryMethods_Archive
PackageTypes_Archive
PaymentMethods_Archive
People_Archive
StateProvinces_Archive
StockGroups_Archive
StockItems_Archive
SupplierCategories_Archive
Suppliers_Archive
TransactionTypes_Archive
Run Code Online (Sandbox Code Playgroud)
现在很明显 Archive 表没有主键。我猜这是一个设计选择,您可以争辩说没有主键的表不是关系,当然不能保证能够识别每一行。但是,我可以看到有人会怎么想,因为唯一的数据源来自具有 PK 的非存档表,因此风险较小。恕我直言,这是错误的,但并不少见。
由于该项目位于GitHub 上,您可以向架构贡献 PK。
HTH
更新: Martin 正确地评论说,这些实际上是时间历史表,因此不能有 PK 或其他约束,因为它们是系统管理的。
您可以运行以下查询来查看没有主键的表。
SELECT [schema] = SCHEMA_NAME(schema_id),
name,
temporal_type_desc
FROM sys.tables
WHERE object_id NOT IN (SELECT parent_object_id
FROM sys.key_constraints
WHERE type = 'PK');
Run Code Online (Sandbox Code Playgroud)
这将返回以下内容
+-------------+------------------------------+--------------------+
| schema | name | temporal_type_desc |
+-------------+------------------------------+--------------------+
| Warehouse | ColdRoomTemperatures_Archive | HISTORY_TABLE |
| Warehouse | Colors_Archive | HISTORY_TABLE |
| Warehouse | PackageTypes_Archive | HISTORY_TABLE |
| Warehouse | StockGroups_Archive | HISTORY_TABLE |
| Warehouse | StockItems_Archive | HISTORY_TABLE |
| Application | Cities_Archive | HISTORY_TABLE |
| Application | Countries_Archive | HISTORY_TABLE |
| Application | DeliveryMethods_Archive | HISTORY_TABLE |
| Application | PaymentMethods_Archive | HISTORY_TABLE |
| Application | People_Archive | HISTORY_TABLE |
| Application | StateProvinces_Archive | HISTORY_TABLE |
| Application | TransactionTypes_Archive | HISTORY_TABLE |
| Purchasing | SupplierCategories_Archive | HISTORY_TABLE |
| Purchasing | Suppliers_Archive | HISTORY_TABLE |
| Sales | BuyingGroups_Archive | HISTORY_TABLE |
| Sales | CustomerCategories_Archive | HISTORY_TABLE |
| Sales | Customers_Archive | HISTORY_TABLE |
+-------------+------------------------------+--------------------+
Run Code Online (Sandbox Code Playgroud)
您将看到其中 100% 是时态表对的历史表组件。
所以根据文档,解释非常简单。
历史表不能有约束(主键、外键、表或列约束)。