始める前に、「ガス」はセダンの種類ではなく、燃料またはエンジンの種類を表すことを指摘しておきます。この道を進み続ける前によく考えてください。(セマンティクスは、ほとんどの人が考えるよりもデータベース設計において重要です。)
やりたいことはかなり単純ですが、必ずしも簡単ではありません。この種のスーパータイプ/サブタイプの設計 (排他的アークとも呼ばれます) の重要な点は、セミトラックなどに関する行を参照するセダンに関する行を持たないようにすることです.
MySQL は CHECK 制約を強制しないため、コードをより冗長にします。幸運ですね; アプリケーションでは、CHECK 制約を追加のテーブルと外部キー制約に置き換えることができます。コメントは、その上の SQL を参照します。
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');
これは、他のプラットフォームで CHECK 制約として実装する可能性のあるものです。コードの意味がユーザーにとって明らかな場合は、これを行うことができます。ユーザーは、「s」がセミ用で「c」が車用であること、またはビュー/アプリケーションコードがコードをユーザーから隠していることを知っているか理解することを期待しています.
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)
);
UNIQUE 制約により、列のペア {veh_id, veh_type_code} を外部キー参照のターゲットにすることができます。つまり、「car」行が「semi」行を誤って参照することはあり得ないということです。
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)
);
他のプラットフォームで CHECK 制約として実装したいものがあります。(下記参照。)
insert into veh_type_is_car values ('c');
今まで一行だけ。
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)
);
veh_type_code のデフォルト値は、veh_type_is_car への外部キー参照とともに、このテーブルのこの行が車に関するもののみであり、車である車両のみを参照できることを保証します。他のプラットフォームでは、列 veh_type_code を として宣言するだけ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');
Gas_sedans、diel_sedans などのセダンを参照する追加のテーブルを作成する必要がある場合は、「veh_type_is_car」のような 1 行のテーブルを作成し、それらへの外部キー参照を設定する必要があります。
本番環境では、ベース テーブルに対するアクセス許可を取り消し、どちらかを使用します。
- 挿入と更新を行うための更新可能なビュー、または
- 挿入と更新を行うためのストアド プロシージャ。