web-dev-qa-db-ja.com

一部のSQLサーバーテーブルに主キーがありません

WorldWideImportersデータベースを標準のdb(SQL ServerのMicrosoftサンプルデータベース)としてダウンロードしました。このデータベースでは、一部のテーブルに主キーがありませんが、クラスター化インデックスが表示されます。一部のテーブルがPKなしで機能している理由を誰かに教えてもらえますか?理由は何ですか?

コメントをいただければ幸いです!

6
Commander

次のクエリを実行して、主キーのないテーブルを表示できます。

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');

これは次を返します

+-------------+------------------------------+--------------------+
|   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      |
+-------------+------------------------------+--------------------+

これらの100%がテンポラルテーブルペアの履歴テーブルコンポーネントであることがわかります。

したがって、説明は ドキュメントごと のように非常に簡単です。

履歴テーブルに制約(主キー、外部キー、テーブルまたは列の制約)を含めることはできません。

3
Martin Smith

主キーがないテーブルを確認するには、次のスクリプトを実行します。

SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES 
EXCEPT 
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS 
WHERE  CONSTRAINT_TYPE = 'PRIMARY KEY'

次のリストが表示されます。

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

アーカイブテーブルに主キーがないことは明らかです。設計上の選択だったと思います。主キーのないテーブルはリレーションではなく、もちろんすべての行を識別できるという保証はありません。しかし、データの唯一のソースはPKを持つ非アーカイブテーブルからのものであるため、リスクが少ないと誰かがどのように考えているかがわかります。私見は間違っていますが、珍しいことではありません。

プロジェクトは GitHub にあるため、スキーマにPKを提供できます。

HTH

UPDATE:マーティンは、これらは実際には時間履歴テーブルであり、システムで管理されているため、PKまたはその他の制約を持つことができないと正しくコメントしました。

5
SQLRaptor

Microsoftデータベースは、ドキュメント内で広く使用されています。したがって、一部の設計は、データベース設計のベストプラクティスを教えるのではなく、優れた例を提供して製品を紹介するためにあります。 (証明はできませんが)この選択は教育的またはマーケティング上の理由で行われたと思います。

2
Michael Green