Mysql
 sql >> Base de données >  >> RDS >> Mysql

Contrainte de table croisée MySQL

Vous pouvez utiliser une table "type":

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

avec exactement 2 lignes (autant que de tables de sous-types différentes dont vous avez besoin :

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

La table de supertypes (qui inclut une colonne faisant référence à "Type") :

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

Les tables de sous-types (qui font maintenant référence à la combinaison de la clé primaire et du type_code de A :

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

Ce qui précède fonctionnerait bien, si seulement MySQL avait implémenté CHECK contraintes. Mais ce n'est pas le cas. Donc, pour être absolument sûr que toutes vos spécifications sont appliquées, et non 'B' les données de type sont insérées dans C table, vous devrez ajouter 2 tables de "type" supplémentaires (et supprimer l'inutile dans MySQL CHECK contraintes):

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

avec exactement 1 lignes chacune :

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

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

et les FK supplémentaires :

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

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

Avec ces contraintes, chaque ligne de la table A sera de type B ou C et sera dans la table respective (B ou C) et jamais dans les deux.

Si vous voulez également vous assurer qu'ils seront dans exactement une table (et jamais dans ni B ni C), cela doit être pris en compte lors de l'insertion dans A (toutes les insertions doivent être effectuées avec une transaction qui applique cette exigence).