sql >> Databáze >  >> RDS >> Mysql

Omezení křížové tabulky MySQL

Můžete použít tabulku typu:

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

s přesně 2 řádky (tolik, kolik potřebujete různých tabulek podtypů:

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

Tabulka nadtypů (která obsahuje sloupec, který odkazuje na "Typ"):

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

Tabulky podtypů (které nyní odkazují na kombinaci primárního klíče A 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')
  ) ;

Výše uvedené by fungovalo dobře, kdyby pouze MySQL implementovalo CHECK omezení. Ale není. Abyste si byli naprosto jisti, že jsou vynuceny všechny vaše specifikace, a nikoli 'B' typová data jsou vložena do C tabulky, budete muset přidat další 2 "typové" tabulky (a odstranit nepotřebné v MySQL CHECK omezení):

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

každý s přesně 1 řádky:

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

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

a další 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) ;

S těmito omezeními bude každý řádek tabulky A buď typu B nebo C a bude v příslušné tabulce (B nebo C) a nikdy v obou.

Pokud chcete také zajistit, že budou přesně v jedné tabulce (a nikdy ani v B ani C), měli byste na to dávat pozor při vkládání do A (všechna vkládání by měla být provedena s transakcí, která tento požadavek vynucuje).




  1. spuštění souboru .sql v příkazovém řádku

  2. Rozdělte daný řetězec a připravte případové prohlášení

  3. PostgreSQL omezení - pouze jeden řádek může mít nastaven příznak

  4. Kdy mám použít CROSS APPLY přes INNER JOIN?