web-dev-qa-db-ja.com

1つの列で複数のテーブルのIDを使用する

同僚の1人が次のようなスキーマを作成しました。これは、この質問に対処するために必要な部分のみを含む簡略化されたスキーマです。

システムルールは次のとおりです。

  1. 部門は0から多くの部門を持つことができます。
  2. 部門は1つの部門のみに属している必要があります。
  3. 記事は、部署またはその部署のいずれかに割り当てることができます。

スキーマは次のとおりです。

Department
---------- 
DepartmentID (PK) int NOT NULL
DepartmentName varchar(50) NOT NULL

Division
--------
DivisionID (PK) int NOT NULL
DepartmentID (FK) int NOT NULL
DivisonName varchar(50) NOT NULL

Article
-------
ArticleID (PK) int NOT NULL
UniqueID int NOT NULL
ArticleName varchar(50) NOT NULL

彼は架空のルール(より良い用語がないため)を使用してスキーマを定義しました。すべてのDepartmentIDは1から100の間であり、すべてのDivisionIDは101から200の間です。Articleテーブルにクエリを実行すると、 UniqueIDは、該当する範囲に基づいて、DepartmentテーブルまたはDivisionテーブルから取得されます。

これは貧弱な設計だと思い、次の代替スキーマを提案しました:

Department
----------
DepartmentID (PK) int NOT NULL
ParentDepartmentID (FK) int NULL /* Self-referencing foreign key.  Divisions have parent departments. */
DepartmentName varchar(50) NOT NULL

Article
-------
ArticleID (PK) int NOT NULL
DepartmentID (FK) int NOT NULL
ArticleName varchar(50) NOT NULL

これは適切に正規化されたスキーマであり、関係とデータの整合性を適切に実施すると同時に、上で概説したビジネスルールを守っていると思います。

私の具体的な質問はこれです:

1つの列を使用して2つのドメインの値を含めるのは設計が良くないことを知っており、Articleテーブルの外部キーの利点を主張できます。しかし、誰かが私が自分の立場をバックアップするために使用できる特定のデータベース設計記事/論文への参照を提供できますか?私が具体的なことを指摘できれば、それはずっと簡単になります。

6
DCNYAM

自己参照により、部門内に部門の階層が導入される可能性があります。部門でこれを許可しないようにするには、コード(通常はトリガー)が必要です。

エンコーディングを使用する元のスキーマも壊れています。強制可能なFKがありません

個人的には、行ごとにDepartmentIDとDivisionIDのいずれか1つのみが入力されるようにするために、チェック制約を使用してこれを検討します。

Article
-------
ArticleID (PK) int NOT NULL
DepartmentID (FK) int NULL
DivisionID (FK) int NULL
ArticleName varchar(50) NOT NULL

どうして?

  • コードは不要
  • ネストされた分割はありません
  • 親テーブルへのFKを介した完全なDRI
  • 「複数の親、一度に1つだけ」を適用

計算された列を使用して、「department」または「division」を示す列を追加することもできます

別の方法:各部門に少なくとも1つの部門があることを義務付けます...

5
gbn