Mysql
 sql >> Database >  >> RDS >> Mysql

Vincolo della tabella incrociata MySQL

Puoi usare una tabella "tipo":

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

con esattamente 2 righe (tante quante sono le diverse tabelle di sottotipo di cui hai bisogno:

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

La tabella dei supertipi (che include una colonna che fa riferimento a "Tipo"):

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

Le tabelle dei sottotipi (che ora fanno riferimento alla combinazione di chiave primaria di A e 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')
  ) ;

Quanto sopra funzionerebbe bene, se solo MySQL avesse implementato CHECK vincoli. Ma non è così. Quindi, per essere assolutamente sicuro che tutte le tue specifiche vengano applicate e non 'B' i dati di tipo sono inseriti in C tabella, dovrai aggiungere altre 2 tabelle di "tipo" (e rimuovere l'inutile in MySQL CHECK vincoli):

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

con esattamente 1 riga ciascuno:

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

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

e gli FK aggiuntivi:

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

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

Con questi vincoli, ogni riga della tabella A sarà di tipo B o C e sarà nella rispettiva tabella (B o C) e mai in entrambe.

Se vuoi anche assicurarti che si trovino esattamente in una tabella (e mai né in B né in C), dovresti fare attenzione quando inserisci in A (tutti gli inserimenti dovrebbero essere eseguiti con una transazione che imponga tale requisito).