2

Я пытаюсь правильно использовать внешние ключи для обеспечения целостности данных. Я на самом деле не парень базы данных, поэтому мне интересно, есть ли какой-то общий принцип дизайна, о котором я не знаю. Вот пример того, что я пытаюсь сделать:Дизайн базы данных с внешними ключами Вопрос

Скажите, что вы хотите создать базу данных транспортных средств с типом (автомобиль, грузовик и т. Д.), Марка и модель. Пользователь должен ввести, по крайней мере, тип, но Make и Model являются необязательными (если модель задана, тогда требуется Make). Моя первая идея состоит в том, чтобы создать базу данных как таковой:

Type: 
-id (PK) 
-description 

Make: 
-id (PK) 
-type_id (FK references Type:id) 
-description 

Model: 
-id (PK) 
-make_id (FK references Make:id) 
-description 

Vechicle: 
-id (PK) 
-type_id (FK references Type:id) 
-make_id (FK references Make:id) 
-model_id (FK references Model:id) 

Как бы вы установили, что ФКС для автомобиля, чтобы убедиться, что тип, марка, модель и все совпасть? Например, как бы вы предотвратили наличие транспортного средства (Тип: Motorcyle, Make: Ford, Model: Civic)? Каждый из них будет действительным FK, но они не поддерживают отношения, показанные через FK других таблиц.

Кроме того, поскольку модель не требуется, я не могу просто сохранить model_id FK и работать с ней обратно.

Я вообще не привязан к дизайну базы данных, поэтому я открыт для возможности изменить способ настройки таблиц. Есть идеи?

P.S. - Я использую mysql, если кому-то это интересно, но это скорее общий вопрос о базах данных.

Edit (Разъяснения):

-type_id и make_id необходимы в таблице транспортного средства, если нет какой-то способ, чтобы понять те, в том случае, model_id равно нулю;

- необходимо поддерживать связи между типами, make_id и model_id.

+0

Вам не нужны столбцы make_id и type_id в таблице вашего автомобиля. – Wacek

ответ

2

Что вы ищете - это ограничение CHECK. К сожалению, MySQL в настоящее время не поддерживает это. Вы могли бы эмулировать такие функции с помощью триггеров, но вам нужно было бы создать как INSERT, так и триггер UPDATE для его работы.

Однако, как указывали другие ответы, все, что вы действительно должны хранить, - это модель транспортного средства. В вашем приложении вы должны сверлить тип, если он доступен.

+0

Я мог бы в основном подражать этому с помощью триггера нет? – blazeprogrammer

+0

Да, я пересмотрел свой ответ. –

0

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

Если вы хотите сохранить тип автомобиля/целостность модели/модели в базе данных, вы можете добавить контрольное ограничение на таблицу вашего транспортного средства, которая удостоверяет, что идентификатор типа транспортного средства равен идентификатору предоставленного типа. И если идентификатор модели не равен NULL, убедитесь, что он делает id таким же, как и идентификатор make.

+0

Спасибо. Это в основном то, что у меня есть (приложение делает проверку). Я хотел бы переместить это в базу данных, если это возможно, поэтому я рассмотрю это. – blazeprogrammer

+0

В настоящее время MySQL не применяет ограничения CHECK. –

2

Как это:

Тип:

  • ид (PK)
  • описание

Make:

  • ид (PK)
  • type_id (ссылки FK Тип: идентификатор, а не нулевой)
  • описание

Модель:

  • ID (PK)
  • make_id (ссылки FK Марка: идентификатор, а не нулевой)
  • описание

Vechicle:

  • идентификатор (ПК)
  • model_id (FK код модели: идентификатор)

В основном не двойной опорный марку и тип из транспортного средства, а также. Если вы это сделаете, у вас возникнут проблемы. Вы можете получить марку и тип от модели транспортного средства (если определено). Модель должна была сделать. Make должен иметь тип.

Подумайте об этом в течение секунды: если автомобиль имеет данную модель, но транспортное средство и модель имеют марку, эти значения могут быть разными. Такая несогласованность может развиваться из-за избыточности информации. Вы хотите избежать этого вообще.

Если вам нужно выяснить марку и тип транспортного средства SQL, начинает выглядеть следующим образом:

SELECT v.id, v.model_id, m.make_id, k.type_id 
FROM vehicle v 
LEFT JOIN model m ON v.model_id = m.id 
JOIN make k ON m.make_id = k.id 
JOIN type t ON k.type_id = t.id 

И так далее.

+0

Спасибо, но, к сожалению, это решает только часть проблемы (хотя это основная проблема). Если модель не указана, нет способа вернуться к типу или марке автомобиля. Я согласен с тем, что ссылка на марку и тип автомобиля кажется потенциальным источником проблем. Я думал (надеясь), что я просто что-то упустил. – blazeprogrammer

+0

Ваш SQL, похоже, не решает проблему, когда make равен NULL. Мне это не хватает? – blazeprogrammer

+0

Вам нужно четко понимать, что вы моделируете. У моделей есть Make? Или у транспортных средств есть Make? Я мог бы быть одновременно, но у вас будут проблемы с этим (как указано выше). Кроме того, Make в силе применяется в модели выше. – cletus

1

Вот один подход:

- Один сделать (Ford, GM, Honda) может иметь много модели, один модели принадлежит только одна марка.
- Модель имеет номер тип (автомобиль, грузовик).
- Транспортное средство имеет номер модель. Один автомобиль может быть только одного модель; может быть много автомобилей модели.

Таблица моделей содержит столбцы, общие для всех моделей; в то время как автомобиль, грузовик и мотоцикл имеют столбцы, характерные для каждого из них.

При моделировании БД рассмотрите данные, сущности и отношения; не начинайте с пользовательского интерфейса - между ними есть деловой слой, чтобы разобраться. Хорошо использовать MySQL, вы можете применять ограничения проверки и внешнего ключа на своем прикладном уровне.

vehicle_model_01

-1

Я вижу, вы уже приняли ответ, но альтернативный подход, который обрабатывает фактическую структурную проблему и не использовать триггеры или проверочные ограничения, было бы создание фиктивных записей в марке и модели столов с описанием «n/a» или таковым, по одному для каждой записи в Type и Make соответственно, а затем избавиться от избыточных столбцов в Vehicle.

Таким образом, если все, что вам известно, является типом транспортного средства, вы найдете фиктивную запись в Make, которая ссылается на соответствующий тип, а затем найдите фиктивную запись в Model, которая ссылается на Make, затем ссылается на эту модель из новый ряд в автомобиле.

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