Inden jeg går i gang, vil jeg påpege, at "gas" beskriver enten brændstof eller en slags motor, ikke en slags sedan. Tænk dig godt om, før du fortsætter ad denne vej. (Semantik er vigtigere i databasedesign, end de fleste tror.)
Det, du vil gøre, er ret simpelt, men ikke nødvendigvis nemt. Den vigtige pointe i denne form for supertype/subtype-design (også kendt som en eksklusiv bue) er at gøre det umuligt at have rækker om sedans, der henviser til rækker om semi-lastbiler osv.
MySQL gør koden mere omfattende, fordi den ikke håndhæver CHECK-begrænsninger. Du er heldig; i din applikation kan CHECK-begrænsningerne erstattes af yderligere tabeller og fremmednøgle-begrænsninger. Kommentarer henviser til SQL ovenfor 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 er den slags ting, jeg kan implementere som en CHECK-begrænsning på andre platforme. Det kan du gøre, når betydningen af koderne er indlysende for brugerne. Jeg ville forvente, at brugerne ved eller finder ud af, at 's' er for semifinaler og 'c' er for biler, eller at visninger/applikationskode ville skjule koderne for brugerne.
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 UNIQUE begrænsning lader kolonneparret {veh_id, veh_type_code} være målet for en fremmednøglereference. Det betyder, at en "bil"-række umuligt kan henvise til en "semi"-række, selv ved en fejltagelse.
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)
);
Noget andet, jeg ville implementere som en CHECK-begrænsning på andre platforme. (Se nedenfor.)
insert into veh_type_is_car values ('c');
Kun én række nogensinde.
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ærdien for veh_type_code, sammen med den fremmede nøglereference til veh_type_is_car, garanterer, at denne række i denne tabel kun kan handle om biler og kun referencekøretøjer, der er biler. På andre platforme ville jeg bare erklære kolonnen 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');
Hvis du skal bygge yderligere tabeller, der refererer til sedaner, såsom gas_sedans, diesel_sedans osv., så skal du bygge en-rækkede tabeller svarende til "veh_type_is_car" og angive fremmednøglereferencer til dem.
I produktionen ville jeg tilbagekalde tilladelser på basistabellerne og enten bruge
- opdaterbare visninger til at udføre indsættelser og opdateringer, eller
- lagrede procedurer til at udføre indsættelser og opdateringer.