Możesz użyć tabeli typu:
CREATE TABLE Type
( type_code CHAR(1) NOT NULL
, PRIMARY KEY (type_code)
) ;
z dokładnie 2 wierszami (tyle ile różnych tabel podtypów potrzebujesz:
INSERT INTO Type (type_code)
VALUES ('B'), ('C') ;
Tabela nadtypów (zawierająca kolumnę odwołującą się do „Typu”):
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)
) ;
Tabele podtypów (które teraz odwołują się do kombinacji klucza podstawowego A i 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')
) ;
Powyższe działałoby dobrze, gdyby tylko MySQL zaimplementował CHECK
ograniczenia. Ale tak się nie stało. Tak więc, aby mieć absolutną pewność, że wszystkie Twoje specyfikacje są egzekwowane, a nie 'B'
dane typu są wstawiane w C
tabeli, będziesz musiał dodać 2 kolejne tabele typu (i usunąć niepotrzebne w MySQL CHECK
ograniczenia):
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)
) ;
z dokładnie 1 rzędem w każdym:
INSERT INTO TypeB (type_code)
VALUES ('B') ;
INSERT INTO TypeC (type_code)
VALUES ('C') ;
i dodatkowe 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) ;
Dzięki tym ograniczeniom każdy wiersz tabeli A będzie typu B lub C i będzie znajdował się w odpowiedniej tabeli (B lub C), a nigdy w obu.
Jeśli chcesz również upewnić się, że będą one znajdować się dokładnie w jednej tabeli (i nigdy w B ani C), należy to zachować podczas wstawiania w A (wszystkie wstawienia powinny być wykonane z transakcją, która wymusza to wymaganie).