Sebelum saya mulai, saya ingin menunjukkan bahwa "gas" menggambarkan bahan bakar atau sejenis mesin, bukan sejenis sedan. Berpikir keras sebelum Anda terus menyusuri jalan ini. (Semantik lebih penting dalam desain database daripada yang dipikirkan kebanyakan orang.)
Apa yang ingin Anda lakukan cukup sederhana, tetapi tidak selalu mudah. Poin penting dalam desain supertipe/subtipe semacam ini (juga dikenal sebagai busur eksklusif) adalah untuk membuat baris tentang sedan yang merujuk pada baris tentang semi-truk, dll.
MySQL membuat kode lebih bertele-tele, karena tidak menerapkan batasan CHECK. Anda beruntung; dalam aplikasi Anda, batasan CHECK dapat diganti dengan tabel tambahan dan batasan kunci asing. Komentar mengacu pada SQL di atas mereka.
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');
Ini adalah hal yang mungkin saya terapkan sebagai batasan CHECK pada platform lain. Anda dapat melakukannya ketika arti kode jelas bagi pengguna. Saya berharap pengguna mengetahui atau mengetahui bahwa 's' untuk semifinal dan 'c' untuk mobil, atau bahwa tampilan/kode aplikasi akan menyembunyikan kode dari pengguna.
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)
);
Batasan UNIQUE memungkinkan pasangan kolom {veh_id, veh_type_code} menjadi target referensi kunci asing. Itu berarti baris "mobil" tidak mungkin merujuk pada baris "semi", bahkan karena kesalahan.
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)
);
Hal lain yang akan saya terapkan sebagai batasan CHECK pada platform lain. (Lihat di bawah.)
insert into veh_type_is_car values ('c');
Hanya satu baris yang pernah ada.
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)
);
Nilai default untuk veh_type_code, bersama dengan referensi kunci asing ke veh_type_is_car, menjamin bahwa baris dalam tabel ini hanya dapat berisi tentang mobil, dan dapat hanya kendaraan referensi yang mobil. Pada platform lain, saya baru saja mendeklarasikan kolom veh_type_code sebagai 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');
Jika Anda harus membuat tabel tambahan yang mereferensikan sedan, seperti bensin_sedan, diesel_sedan, dll., maka Anda perlu membuat tabel satu baris yang mirip dengan "veh_type_is_car" dan menyetel referensi kunci asing ke tabel tersebut.
Dalam produksi, saya akan mencabut izin pada tabel dasar, dan menggunakan
- tampilan yang dapat diperbarui untuk melakukan penyisipan dan pembaruan, atau
- prosedur tersimpan untuk melakukan penyisipan dan pembaruan.