Mysql
 sql >> Baza danych >  >> RDS >> Mysql

MySQL — projektowanie nadtypów/podtypów

Zanim zacznę, chciałbym zaznaczyć, że „gaz” oznacza albo paliwo, albo rodzaj silnika, a nie rodzaj sedana. Pomyśl mocno, zanim pójdziesz dalej tą ścieżką. (Semantyka jest ważniejsza w projektowaniu baz danych, niż większość ludzi myśli.)

To, co chcesz zrobić, jest dość proste, ale niekoniecznie łatwe. Ważnym punktem tego rodzaju projektu nadtypu/podtypu (znanego również jako ekskluzywny łuk) jest uniemożliwienie umieszczania wierszy o sedanach odwołujących się do wierszy o naczepach itp.

MySQL sprawia, że ​​kod jest bardziej szczegółowy, ponieważ nie wymusza ograniczeń CHECK. Jesteś szczęściarzem; w aplikacji ograniczenia CHECK można zastąpić dodatkowymi tabelami i ograniczeniami klucza obcego. Komentarze odnoszą się do SQL powyżej ich.

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

To jest rodzaj rzeczy, które mogę zaimplementować jako ograniczenie CHECK na innych platformach. Możesz to zrobić, gdy znaczenie kodów jest oczywiste dla użytkowników. Spodziewam się, że użytkownicy będą wiedzieć lub zorientować się, że „s” oznacza naczepy, a „c” oznacza samochody, lub że widoki/kod aplikacji ukryje kody przed użytkownikami.

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

Ograniczenie UNIQUE umożliwia parze kolumn {veh_id, veh_type_code} miejsce docelowe odwołania do klucza obcego. Oznacza to, że wiersz „samochód” nie może odwoływać się do wiersza „pół”, nawet przez pomyłkę.

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

Coś innego zaimplementowałbym jako ograniczenie CHECK na innych platformach. (Patrz poniżej.)

insert into veh_type_is_car values ('c');

Tylko jeden rząd kiedykolwiek.

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

Domyślna wartość veh_type_code wraz z odniesieniem klucza obcego do veh_type_is_car gwarantuje, że te wiersze w tej tabeli mogą dotyczyć tylko samochodów i mogą tylko pojazdy referencyjne, którymi są samochody. Na innych platformach po prostu zadeklarowałbym kolumnę veh_type_code jako 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');

Jeśli musisz zbudować dodatkowe tabele odwołujące się do sedanów, takie jak gas_sedans, diesel_sedans itp., musisz zbudować jednowierszowe tabele podobne do „veh_type_is_car” i ustawić do nich odniesienia do kluczy obcych.

W środowisku produkcyjnym cofnąłbym uprawnienia do tabel podstawowych i albo używałbym

  • widoki, które można aktualizować w celu wykonania wstawek i aktualizacji, lub
  • przechowywane procedury wykonywania wstawek i aktualizacji.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Data i godzina za godzinę po wstawieniu. Czas letni

  2. Zapytanie SQL zatrzymane w stanie statystyk

  3. MySQL - Znajdź MIN, ale nie zero

  4. Jak łatwo określić wiek od urodzin? (php)

  5. Przekazywanie nazwy tabeli jako parametru przygotowanego zestawienia