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

MySQL Cross Table Constraint

Du kan bruge en "type"-tabel:

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

med præcis 2 rækker (så mange som de forskellige undertypetabeller du har brug for:

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

Supertypetabellen (der inkluderer en kolonne, der refererer til "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)
  ) ;

Undertypetabellerne (der nu refererer til kombinationen af ​​A's primære nøgle og 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')
  ) ;

Ovenstående ville fungere fint, hvis kun MySQL havde implementeret CHECK begrænsninger. Men det har den ikke. Så for at være helt sikker på, at alle dine specifikationer håndhæves, og ikke 'B' typedata indsættes i C tabel, bliver du nødt til at tilføje 2 flere "type"-tabeller (og fjerne de ubrugelige i MySQL CHECK begrænsninger):

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

med nøjagtig 1 række hver:

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

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

og de yderligere FK'er:

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

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

Med disse begrænsninger vil hver række i tabel A være enten af ​​type B eller C, og den vil være i den respektive tabel (B eller C) og aldrig i begge.

Hvis du også vil sikre dig, at de vil være i nøjagtig én tabel (og aldrig i hverken B eller C), skal du være opmærksom på det, når du indsætter i A (alle indsættelser skal ske med en transaktion, der håndhæver dette krav).




  1. Tabel specificeret to gange i Procedure, hvordan rettes?

  2. SQL-forespørgsel - Opdater, hvis den findes, indsæt ellers

  3. Hjælp mig med at forstå forskellen mellem CLOB'er og BLOB'er i Oracle

  4. Indsættelse fra MS SQL Server til MySQL-database