Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Ograniczenie tabel krzyżowych MySQL

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




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. utwórz URL rest api, aby połączyć się z bazą danych mysql

  2. Jakie są odpowiedniki w SQLlite INTERVAL i UTC_TIMESTAMP w MySQL?

  3. utwórz sformatowany arkusz kalkulacyjny Excel z danymi MySQL i PHP przy użyciu tabel

  4. Błąd pobierania tabeli nie istnieje, ale tabela istnieje (ActiveRecord::StatementInvalid Mysql2::Error:Tabela nie istnieje)

  5. Indeksy wielokrotne i pojedyncze