web-dev-qa-db-ja.com

階層データ構造の代理キーと複合キー

現在、階層データ構造のスキーマを評価しています。私の主な問題は、一貫性のないデータ(別の階層の外部キーの参照)を防ぐためにスキーマをどのように設計するかです。私が発見した2つのバリアントは、複合キーまたは代理キーを使用することです。

要件

  • 階層ごとの厳密な整合性チェック(例:階層Aのパーツは、階層Bのタイプに外部キーを持つことはできません(下のスキーマ例を参照)。
  • データベースはさまざまなアプリケーションから使用されるため、アプリケーションコードではなくデータベースで制約を確認する必要があります。
  • パフォーマンスのためにスケーラブルで、より多くの階層レベルで拡張可能です。

バリエーション1:複合キー

この例では、外部キーは複合主キーの一部です。これにより、複合主キーの一部であるため、パーツのタイプが同じアイテム(同じ階層)に割り当てられていることが自動的にチェックされます。

モデルを拡張するのは簡単ではないので、このアプローチは私にとって厄介なようです。たとえば、単一のPartのメタデータを保持するPartMetadataテーブルを作成する場合、全体を含める必要がありますメタデータが階層に接続されていない場合でも、複合キー。

Item
  ItemId (PK)
  Name

Type
  TypeId (PK)
  ItemId (PK, FK)
  Name

SubItem
  SubItemId (PK)
  ItemId (PK, FK)
  Name

Part
  PartId (PK)
  ItemId (PK, FK)
  SubItemId (PK, FK)
  TypeId (PK, FK)
  Name

バリエーション2:サロゲートキー

この場合、別のアイテムに属するタイプのパーツを挿入できないようにするために、追加の制約またはトリガーを定義する必要があります。

Item
  ItemId (PK)
  Name

Type
  TypeId (PK)
  ItemId (FK)
  Name

SubItem
  SubItemId (PK)
  ItemId (FK)
  Name

Part
  PartId (PK)
  SubItemId (FK)
  TypeId (FK)
  Name

ご質問

  • 代理ソリューションを常に優先する必要がありますか?複合キーソリューションを使用するとどのような場合に役立ちますか?
  • 特に階層が大きくなる場合、長期的に維持できるソリューションはどれですか。
  • パフォーマンスを向上させるソリューションはどれですか(レポート、CRUD)?チェック制約またはトリガーのため、代理ソリューションは大きな影響を及ぼしますか?
  • 他のオプションはありますか(私の意見では、私の両方のバリエーションは非理想的なソリューションのように見えます)?
  • 誰かが両方の亜種を経験し、彼の知恵を共有できますか?
4
Dave

1番目の設計では、Partが同じSubItemに(TypeおよびItemを介して)関連付けられるように強制できます。 2番目の方法ではできません(DDLのみを使用して、前述のトリガーを適用するか、すべてのCRUD操作が制限を処理するストアドプロシージャを介して実行されるようにするためにトリガーが必要です)。そうでない場合、Partに関連するSubItemと、異なるTypeを参照するItemsが存在する場合があります。

(1番目の)デザインに関する注意事項:

  • 正しいFOREIGN KEY制約。 Partの3つの単純なFKで要件を強制することはできませんが、2つの複合FKが必要です。

    Part
      PartId    (PK)
      ItemId    (PK, FK1, FK2)
      SubItemId (PK, FK1)
      TypeId    (PK,      FK2)
      Name
    
  • PKにPartIdがなくてもかまいません。同じSubItemと同じTypeに属する2つ以上のパーツを持つことはできますか?そうでない場合、一意(または主キー)制約は(ItemId, SubItemId, TypeId)。はいの場合、それは(ItemId, SubItemId, TypeId, PartId)、ご存知の通り。

PartMetadataまたはPartテーブルを参照できるその他のテーブルに関しては、Partの複合キー全体を含める必要はありません。いつでも、新しいサロゲートUNIQUEキーをPartに追加して、代わりに使用できます。これは、エンティティの複雑で高い階層で私が考える一般的な方法です。ある程度までは、複合PKとFKを使用できます。それらが広すぎる場合(4〜6列)、いくつかの重要なテーブルに代理一意キーを追加し、モデルの下位のテーブルからの参照にそれらを使用できます。

3
ypercubeᵀᴹ