特定のテーブルが多数の異なる親テーブルの1つにFKできるデータベースの状況に頻繁に出くわします。この問題に対する2つの解決策を見てきましたが、どちらも個人的に満足できるものではありません。私はあなたがそこに見た他のどのようなパターンに興味がありますか?それを行うためのより良い方法はありますか?
不自然な例
システムが持っているとしましょうAlerts
。アラートは、顧客、ニュース、製品などのさまざまなオブジェクトに対して受信できます。特定のアラートは、1つだけのアイテムに対応できます。何らかの理由で、顧客、記事、製品は動きが速い(ローカライズされている)ため、アラートの作成時に必要なテキスト/データをアラートに取り込むことはできません。このセットアップを考えると、2つのソリューションを見てきました。
注:以下のDDLはSQL Server用ですが、私の質問はどのDBMSにも当てはまります。
解決策1-複数のNullable FKey
このソリューションでは、1対多のテーブルにリンクするテーブルに複数のFK列があります(簡潔にするため、以下のDDLにはFKの作成は示されていません)。 良い -このソリューションでは、外部キーを持っていると便利です。FKのヌル最適性により、この便利で正確なデータを比較的簡単に追加できます。BADクエリは、関連付けられたデータを取得するためにN LEFT JOINSまたはN UNIONステートメントを必要とするため、優れていません。SQL Serverでは、特にLEFT JOINSにより、インデックス付きビューの作成ができなくなります。
CREATE TABLE Product (
ProductID int identity(1,1) not null,
CreateUTC datetime2(7) not null,
Name varchar(100) not null
CONSTRAINT PK_Product Primary Key CLUSTERED (ProductID)
)
CREATE TABLE Customer (
CustomerID int identity(1,1) not null,
CreateUTC datetime2(7) not null,
Name varchar(100) not null
CONSTRAINT PK_Customer Primary Key CLUSTERED (CustomerID)
)
CREATE TABLE News (
NewsID int identity(1,1) not null,
CreateUTC datetime2(7) not null,
Name varchar(100) not null
CONSTRAINT PK_News Primary Key CLUSTERED (NewsID)
)
CREATE TABLE Alert (
AlertID int identity(1,1) not null,
CreateUTC datetime2(7) not null,
ProductID int null,
NewsID int null,
CustomerID int null,
CONSTRAINT PK_Alert Primary Key CLUSTERED (AlertID)
)
ALTER TABLE Alert WITH CHECK ADD CONSTRAINT CK_OnlyOneFKAllowed
CHECK (
(ProductID is not null AND NewsID is null and CustomerID is null) OR
(ProductID is null AND NewsID is not null and CustomerID is null) OR
(ProductID is null AND NewsID is null and CustomerID is not null)
)
ソリューション2-各親テーブルに1つのFK
このソリューションでは、各「親」テーブルにアラートテーブルへのFKがあります。親に関連付けられたアラートを簡単に取得できます。マイナス面として、アラートから参照者への実際のチェーンはありません。さらに、データモデルは孤立したアラートを許可します。アラートは、製品、ニュース、または顧客に関連付けられていません。繰り返しますが、複数のLEFT JOINを使用して関連付けを見つけます。
CREATE TABLE Product (
ProductID int identity(1,1) not null,
CreateUTC datetime2(7) not null,
Name varchar(100) not null
AlertID int null,
CONSTRAINT PK_Product Primary Key CLUSTERED (ProductID)
)
CREATE TABLE Customer (
CustomerID int identity(1,1) not null,
CreateUTC datetime2(7) not null,
Name varchar(100) not null
AlertID int null,
CONSTRAINT PK_Customer Primary Key CLUSTERED (CustomerID)
)
CREATE TABLE News (
NewsID int identity(1,1) not null,
CreateUTC datetime2(7) not null,
Name varchar(100) not null
AlertID int null,
CONSTRAINT PK_News Primary Key CLUSTERED (NewsID)
)
CREATE TABLE Alert (
AlertID int identity(1,1) not null,
CreateUTC datetime2(7) not null,
CONSTRAINT PK_Alert Primary Key CLUSTERED (AlertID)
)
これは関係データベースの単なる寿命ですか?より満足できる代替ソリューションはありますか?
Alertable
。それは理にかなっていますか?