2013-07-01 6 views
7

Мне нужно создать следующую базу данных:MySQL - Supertype/Подтип дизайн

enter image description here

для полуавтоматических машин мне не нужны дополнительные подтипы, в то время как для автомобиля мне нужно иметь только те 3 подтип и также для Седана мне нужны четыре подтипа. Для SELECT я буду использовать JOINs (нормализованная база данных), но мне нужно найти простой способ сделать INSERT.

  • таблица Vehicle хранит общие информационные
  • Semi-грузовик хранит конкретную информацию для полуфабрикатов
  • таблицы автомобилей имеет специальные поля для автомобилей и поле car_type, который связан с тремя подтипов
  • Ван, сув и Седан (и другие типы, если он мне понадобится) должен быть в одной таблице CAR_TYPE
  • Однако для типа Sedan мне нужно иметь дополнительные подтипы, которые, возможно, должны содержаться в другой таблице. Эти подтипы не нужны для Suvs и Vans (в реальной жизни SUV, фургоны могут иметь те же подтипы, что и седаны, но не в моем случае).

Мне нужна эта база данных, которая будет создана точно так, как на диаграмме.

До сих пор мой первый подход заключается в следующие таблицы:

  • Автомобиль: veh_id, veh_type (Semi, автомобиль), ..., other_fields
  • Vehicle_semis: veh_id, ..., other_semis_fields
  • Vehicle_car: veh_id, car_type (Ван, Сув, Седан), other_car_specific_fields
  • car_type: car_type_id, тип
  • Sedan_type: sedan_type_id, тип

Моя проблема в том, что я не уверен, что это был бы правильный подход, и я не знаю точно, как создавать отношения между таблицами.

Любые идеи?

Спасибо!

UPDATE:

Следующая диаграмма основана на ответ @ Mike «s: enter image description here

+0

Первый шаг - определить, какая будет первичная (наиболее используемая) операция для этого db: читать, писать (вставлять, обновлять, удалять), потому что дизайн будет очень различным для каждого случая, а также какой объем данных у вас будет , будет ли он расти в будущем? если да, то сколько? сколько клиентов будет допрашивать db? как часто ? это всего лишь несколько вопросов, которые вам нужно знать о – Stephan

+0

@Stephan - данные будут расти в будущем, возможно, 100 тыс. Моя основная операция - ЧТЕНИЕ.Что касается клиентов, их было бы довольно много работать с db! – Cristian

+0

в схеме, которую вы указали, проблема может быть прочитана, поскольку данные «очень» нормализованы ... представьте, если вам нужно получить седаны для ex, вам понадобится 4 соединения или более, что не очень эффективно, но с учетом низких данных том, это не должно быть проблемой даже для многих пользователей. Я рекомендую использовать движок InnoDB, потому что у него есть 2 ключевых функции для приложения ur: поддержка транзакций и блокировка уровня строк. – Stephan

ответ

7

Перед тем, как приступить к работе, я хочу отметить, что„газ“описывает либо топлива или своего рода двигателя, а не своего рода седана. Подумайте, прежде чем продолжать идти по этому пути. (Семантика важнее в дизайне базы данных, чем большинство людей думает.)

Что вы хотите сделать, это довольно просто, но не всегда легко. Важным моментом в этом виде супертипа/подтипа (также известный как эксклюзивная дуга) является невозможность иметь ряды о седанах, ссылающихся на ряды о полуавтоматах и ​​т. Д.

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 на других платформах. Вы можете это сделать, когда смысл кода для пользователей очевиден. Я ожидаю, что пользователи узнают или выяснят, что «для» - это для semis, а «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) 
); 

ограничение уникальности позволяет пару столбцов {veh_id, veh_type_code} быть объектом внешнего ключа ссылки. Это означает, что строка «автомобиль» не может ссылаться на «полу», даже по ошибке.

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 как .

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, diesel_sedans и т.д., то вам нужно построить однорядные таблицы, аналогичные «veh_type_is_car» и установить внешний ключ ссылки на них.

В производстве, я бы отменить разрешения на базовые таблицы, а также использовать

  • обновляемые видом делать вставки и обновления, или
  • хранимые процедуры, чтобы сделать вставки и обновления.
+0

Большое спасибо за этот ответ. Это именно то, что мне нужно! Одна вещь, которую я не совсем понимаю, это «veh_type_is_car», которая будет иметь тот же код «c», что и «veh_type_code» из таблицы «cars». Это только для того, чтобы помочь в улучшении кодирования или запросов? Взаимосвязь между автомобилями и автомобилями включает в себя код «c». Почему я должен добавить эту таблицу? – Cristian

+0

@Cristian: В «автомобилях» есть внешний ключ, который ссылается на этот стол. Это гарантирует, что * только * 'c' может появиться в этом столбце, если строка о машине. То есть, это препятствует тому, чтобы серию полуавтомобилей в «транспортных средствах» связывали с автомобильным рядом в «автомобилях». –

+0

Хорошо, понял. Я полагаю, что роль гарантии того, что только «c» попадает в таблицу «cars», также может быть реализована кодом. Было бы слишком много, чтобы иметь его как в mysql, так и в коде? Overkill? – Cristian

3

Я отсылаю вас к вкладке «Info» в следующих трех тегов:

Первые два описания двух основных шаблонов проектирования для решения класса/подкласса (так называемый тип/подтип) при создании реляционной базы данных. Третий описывает метод использования одного первичного ключа, который присваивается в таблице суперкласса и распространяется на таблицы подкласса.

Они не полностью отвечают на вопросы, которые вы поднимаете, но они проливают свет на всю тему. Эта тема, имитирующая наследование в SQL, появляется снова и снова как в SO, так и в области DBA.

+0

Спасибо! Огромные ресурсы для чтения. – Cristian

Смежные вопросы