同僚の1人が次のようなスキーマを作成しました。これは、この質問に対処するために必要な部分のみを含む簡略化されたスキーマです。
システムルールは次のとおりです。
スキーマは次のとおりです。
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テーブルの外部キーの利点を主張できます。しかし、誰かが私が自分の立場をバックアップするために使用できる特定のデータベース設計記事/論文への参照を提供できますか?私が具体的なことを指摘できれば、それはずっと簡単になります。
自己参照により、部門内に部門の階層が導入される可能性があります。部門でこれを許可しないようにするには、コード(通常はトリガー)が必要です。
エンコーディングを使用する元のスキーマも壊れています。強制可能なFKがありません
個人的には、行ごとにDepartmentIDとDivisionIDのいずれか1つのみが入力されるようにするために、チェック制約を使用してこれを検討します。
Article
-------
ArticleID (PK) int NOT NULL
DepartmentID (FK) int NULL
DivisionID (FK) int NULL
ArticleName varchar(50) NOT NULL
どうして?
計算された列を使用して、「department」または「division」を示す列を追加することもできます
別の方法:各部門に少なくとも1つの部門があることを義務付けます...