Mysql
 sql >> Datenbank >  >> RDS >> Mysql

MySQL-Kreuztabellenbeschränkung

Sie können eine "Typ"-Tabelle verwenden:

CREATE TABLE Type
  ( type_code CHAR(1) NOT NULL
  , PRIMARY KEY (type_code)
  ) ;

mit genau 2 Zeilen (so viele wie die verschiedenen Subtyp-Tabellen, die Sie benötigen:

INSERT INTO Type (type_code)
VALUES ('B'), ('C') ;

Die Supertype-Tabelle (die eine Spalte enthält, die auf "Type" verweist):

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)
  ) ;

Die Untertyptabellen (die jetzt auf die Kombination aus dem Primärschlüssel von A und type_code verweisen:

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')
  ) ;

Das Obige würde gut funktionieren, wenn MySQL nur CHECK implementiert hätte Einschränkungen. Aber das hat es nicht. Um also absolut sicher zu sein, dass alle Ihre Angaben durchgesetzt werden und nicht 'B' Typdaten werden in C eingefügt Tabelle müssen Sie 2 weitere "Typ"-Tabellen hinzufügen (und die unbrauchbaren in MySQL CHECK entfernen Beschränkungen):

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)
  ) ;

mit jeweils genau 1 Zeile:

INSERT INTO TypeB (type_code)
VALUES ('B') ;

INSERT INTO TypeC (type_code)
VALUES ('C') ;

und die zusätzlichen FKs:

ALTER TABLE B
  ADD FOREIGN KEY (type_code)
    REFERENCES TypeB (type_code) ;

ALTER TABLE C
  ADD FOREIGN KEY (type_code)
    REFERENCES TypeC (type_code) ;

Mit diesen Einschränkungen ist jede Zeile der Tabelle A entweder vom Typ B oder C und sie befindet sich in der entsprechenden Tabelle (B oder C) und niemals in beiden.

Wenn Sie auch sicherstellen möchten, dass sie sich in genau einer Tabelle befinden (und niemals in B oder C), sollte dies beim Einfügen in A beachtet werden (alle Einfügungen sollten mit einer Transaktion erfolgen, die diese Anforderung erzwingt).