「タイプ」テーブルを使用できます。
CREATE TABLE Type
( type_code CHAR(1) NOT NULL
, PRIMARY KEY (type_code)
) ;
正確に 2 行 (必要な異なるサブタイプ テーブルと同じ数:
INSERT INTO Type (type_code)
VALUES ('B'), ('C') ;
スーパータイプ テーブル (「タイプ」を参照する列を含む):
CREATE TABLE A
( a_id INT NOT NULL AUTO_INCREMENT
, type_code CHAR(1) NOT NULL
, PRIMARY KEY (a_id)
, UNIQUE KEY (type_code, a_id)
, FOREIGN KEY (type_code)
REFERENCES Type (type_code)
) ;
サブタイプ テーブル (現在、A のプライマリ キーと type_code の組み合わせを参照しています。
CREATE TABLE B
( a_id INT NOT NULL
, type_code CHAR(1) NOT NULL DEFAULT 'B'
, PRIMARY KEY (type_code, a_id)
, FOREIGN KEY (type_code, a_id)
REFERENCES A (type_code, a_id)
, CHECK (type_code = 'B')
) ;
CREATE TABLE C
( a_id INT NOT NULL
, type_code CHAR(1) NOT NULL DEFAULT 'C'
, PRIMARY KEY (type_code, a_id)
, FOREIGN KEY (type_code, a_id)
REFERENCES A (type_code, a_id)
, CHECK (type_code = 'C')
) ;
CHECK
上記は、MySQL のみが制約を実装していれば問題なく機能します。しかし、そうではありません。したがって、すべての仕様が適用され、'B'
型データがC
テーブルに挿入されないことを確実にするには、さらに 2 つの「型」テーブルを追加する必要があります (そして、MySQLCHECK
制約で役に立たないものを削除します)。
CREATE TABLE TypeB
( type_code CHAR(1) NOT NULL
, PRIMARY KEY (type_code)
) ;
CREATE TABLE TypeC
( type_code CHAR(1) NOT NULL
, PRIMARY KEY (type_code)
) ;
それぞれ正確に1行:
INSERT INTO TypeB (type_code)
VALUES ('B') ;
INSERT INTO TypeC (type_code)
VALUES ('C') ;
および追加の FK:
ALTER TABLE B
ADD FOREIGN KEY (type_code)
REFERENCES TypeB (type_code) ;
ALTER TABLE C
ADD FOREIGN KEY (type_code)
REFERENCES TypeC (type_code) ;
これらの制約により、テーブル A のすべての行はタイプ B または C のいずれかになり、それぞれのテーブル (B または C) に含まれ、両方には決して含まれません。
また、それらが正確に 1 つのテーブルにあることを確認したい (B にも C にもない) 場合は、A に挿入するときに注意する必要があります (すべての挿入は、その要件を強制するトランザクションで行う必要があります)。