sql >> Databasteknik >  >> RDS >> Mysql

MySQL - Supertyp/Subtypdesign

Innan jag sätter igång vill jag påpeka att "gas" beskriver antingen bränsle eller en sorts motor, inte en sorts sedan. Tänk efter innan du fortsätter på den här vägen. (Semantik är viktigare i databasdesign än de flesta tror.)

Vad du vill göra är ganska enkelt, men inte nödvändigtvis lätt. Den viktiga punkten i denna typ av supertyp/subtypdesign (även känd som en exklusiv båge) är att göra det omöjligt att ha rader om sedaner som hänvisar till rader om semi-lastbilar osv.

MySQL gör koden mer utförlig, eftersom den inte upprätthåller CHECK-begränsningar. Du har tur; i din applikation kan CHECK-begränsningarna ersättas av ytterligare tabeller och främmande nyckelbegränsningar. Kommentarer hänvisar till SQL ovan dem.

create table vehicle_types (
  veh_type_code char(1) not null,
  veh_type_name varchar(10) not null,
  primary key (veh_type_code),
  unique (veh_type_name)
);

insert into vehicle_types values
('s', 'Semi-truck'), ('c', 'Car');

Det här är sånt jag kan implementera som en CHECK-begränsning på andra plattformar. Det kan du göra när innebörden av koderna är uppenbar för användarna. Jag förväntar mig att användare ska veta eller komma på att "s" är för semi och "c" är för bilar, eller att visningar/applikationskod skulle dölja koderna för användarna.

create table vehicles (
  veh_id integer not null,
  veh_type_code char(1) not null,
  other_columns char(1) default 'x',
  primary key (veh_id),
  unique (veh_id, veh_type_code),
  foreign key (veh_type_code) references vehicle_types (veh_type_code)
);

Den UNIKA begränsningen låter kolumnparet {veh_id, veh_type_code} vara målet för en främmande nyckelreferens. Det betyder att en "bil"-rad omöjligen kan referera till en "halv"-rad, inte ens av misstag.

insert into vehicles (veh_id, veh_type_code) values
(1, 's'), (2, 'c'), (3, 'c'), (4, 'c'), (5, 'c'), 
(6, 'c'), (7, 'c');

create table car_types (
  car_type char(3) not null,
  primary key (car_type)
);

insert into car_types values
('Van'), ('SUV'), ('Sed');

create table veh_type_is_car (
  veh_type_car char(1) not null,
  primary key (veh_type_car)
);

Något annat jag skulle implementera som en CHECK-begränsning på andra plattformar. (Se nedan.)

insert into veh_type_is_car values ('c');

Endast en rad någonsin.

create table cars (
  veh_id integer not null,
  veh_type_code char(1) not null default 'c',
  car_type char(3) not null,
  other_columns char(1) not null default 'x',
  primary key (veh_id ),
  unique (veh_id, veh_type_code, car_type),
  foreign key (veh_id, veh_type_code) references vehicles (veh_id, veh_type_code),
  foreign key (car_type) references car_types (car_type),
  foreign key (veh_type_code) references veh_type_is_car (veh_type_car)
);

Standardvärdet för veh_type_code, tillsammans med den främmande nyckelreferensen till veh_type_is_car, garanterar att dessa rader i den här tabellen endast kan handla om bilar och endast referensfordon som är bilar. På andra plattformar skulle jag bara deklarera kolumnen veh_type_code som veh_type_code char(1) not null default 'c' check (veh_type_code = 'c') .

insert into cars (veh_id, veh_type_code, car_type) values
(2, 'c', 'Van'), (3, 'c', 'SUV'), (4, 'c', 'Sed'),
(5, 'c', 'Sed'), (6, 'c', 'Sed'), (7, 'c', 'Sed');

create table sedan_types (
  sedan_type_code char(1) not null,
  primary key (sedan_type_code)
);

insert into sedan_types values
('g'), ('d'), ('h'), ('e');

create table sedans (
  veh_id integer not null,
  veh_type_code char(1) not null,
  car_type char(3) not null,
  sedan_type char(1) not null,
  other_columns char(1) not null default 'x',
  primary key (veh_id),
  foreign key (sedan_type) references sedan_types (sedan_type_code),
  foreign key (veh_id, veh_type_code, car_type) references cars (veh_id, veh_type_code, car_type)
);

insert into sedans (veh_id, veh_type_code, car_type, sedan_type) values 
(4, 'c', 'Sed', 'g'), (5, 'c', 'Sed', 'd'), (6, 'c', 'Sed', 'h'),
(7, 'c', 'Sed', 'e');

Om du måste bygga ytterligare tabeller som refererar till sedaner, såsom gas_sedans, diesel_sedans, etc., måste du bygga enradstabeller som liknar "veh_type_is_car" och ställa in främmande nyckelreferenser till dem.

I produktionen skulle jag återkalla behörigheter för bastabellerna och antingen använda

  • uppdaterbara vyer för att infoga och uppdatera, eller
  • lagrade procedurer för att infoga och uppdatera.


  1. Vilken är den bästa MySQL-samlingen för tyska språket

  2. Hur man slumpmässigt ställer in text till knappar från SQLite utan upprepning?

  3. Analys med MariaDB AX - tThe Open Source Columnar Datastore

  4. Hur man hämtar poster som innehåller alfanumeriska tecken + blanksteg