Способ ссылки на различные таблицы в одном столбце? [Дубликат]

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

7
задан Cristian 1 July 2013 в 18:06
поделиться

2 ответа

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

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

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

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

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

  • обновляемые представления для вставки и обновления или
  • хранимые процедуры для вставки и обновления.
7
ответ дан Mike Sherrill 'Cat Recall' 21 August 2018 в 04:30
поделиться
  • 1
    Большое спасибо за этот ответ. Это именно то, что мне нужно! Одна вещь, которую я не совсем понимаю, это «veh_type_is_car». который будет иметь тот же код "c" как & quot; veh_type_code & quot; из "автомобилей" Таблица. Это только для того, чтобы помочь в улучшении кодирования или запросов? Связь между транспортными средствами и автомобилями включает в себя код "c" также. Почему я должен добавить эту таблицу? – Cristian 1 July 2013 в 18:04
  • 2
    @Cristian: В «автомобилях» есть внешний ключ. который ссылается на эту таблицу. Это гарантирует, что только 'c' может появиться в этом столбце, если строка о машине. То есть, он предотвращает серию полуавтомобилей в «транспортных средствах». от привязки к ряду автомобилей в «автомобилях». – Mike Sherrill 'Cat Recall' 1 July 2013 в 18:52
  • 3
    Хорошо понял. Я полагаю, что роль гарантирования того, что только "с" превратить его в "автомобили" таблица также может быть реализована с помощью кода. Было бы слишком много, чтобы иметь его как в mysql, так и в коде? Overkill? – Cristian 1 July 2013 в 20:24
  • 4
    Зависит от того, что вы подразумеваете под «реализованным кодом». Если вы можете использовать интерфейс командной строки MySQL, чтобы сделать что-то помимо того, что гарантируют эти декларативные ограничения, то нет, они не могут быть реализованы с помощью кода. (Поведение и гарантии, предоставляемые dbms, отличаются от поведения и гарантий, предоставляемых кодом приложения.) Но нет ничего необычного в том, что код приложения проверяет правильные значения и предоставляет полезные, дружественные рекомендации по их исправлению перед отправкой этих значений в dbms , – Mike Sherrill 'Cat Recall' 1 July 2013 в 21:01
  • 5
    ", реализованный посредством кода" = код приложения. Спасибо. Я также сделаю много проверки кода приложения, а также ваши предложения по проверке db! – Cristian 1 July 2013 в 22:58

Я ссылаюсь на вкладку «Информация» в следующих трех тегах:

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

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

3
ответ дан Walter Mitty 21 August 2018 в 04:30
поделиться
  • 1
    Благодаря! Огромные ресурсы для чтения. – Cristian 1 July 2013 в 18:26
Другие вопросы по тегам:

Похожие вопросы: