При добавлении новых элементов в базу данных с внешними ключами следует ли использовать триггеры SQL для создания связанных строк в других таблицах? - PullRequest
2 голосов
/ 11 декабря 2008

Я реализую проект базы данных, в которой есть таблица транспортных средств, двигатель двигателя и таблица передач автомобиля с использованием SQL 2005.

У каждой таблицы есть идентификатор, который является идентификационным номером SQL, а каждый двигатель и передача связаны с идентификатором транспортного средства. Поэтому, прежде чем создавать автомобиль, я должен создать двигатель и передачу.

Как узнать идентификационный номер автомобиля при создании двигателя и коробки передач? Ряд транспортных средств еще не создан из-за ограничения внешнего ключа для таблиц двигателя и коробки передач?

Должен ли я реализовать автоматический триггер, который при создании транспортного средства создает пустую строку для двигателя и передачи, связанной с транспортным средством? Но опять же, как я мог узнать идентификатор транспортного средства?

Ответы [ 10 ]

4 голосов
/ 11 декабря 2008

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

Мне кажется, я понимаю дизайн. Каждое транспортное средство может иметь один двигатель и одну коробку передач. Но вы можете записать трансмиссию или двигатель до того, как найдете автомобиль.

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

Еще один более интересный вопрос - можете ли вы в конечном итоге получить трансмиссию с двигателем, но без транспортного средства. Часто можно увидеть двигатель и механизм сцепления, скрепленные болтами, и ни одного автомобиля не видно. И они часто будут продаваться вместе.

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

Триггеры здесь не играют роли. Если они вообще используются, триггеры должны быть ограничены детальными правилами ссылочной целостности структуры схемы, а не бизнес-правилами, подобными этим. Не существует обязательных ограничений - каждый внешний ключ является необязательным (обнуляемым). И есть несколько различных способов настроить поля FK.

1 голос
/ 11 декабря 2008

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

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

Кроме того, вы можете создать свою запись Транспортного средства, а затем присвоить ей записи о двигателе и передаче по мере их создания.

1 голос
/ 11 декабря 2008

Вы уверены, что правильно разработали стол? Я не очень понимаю, какие у вас отношения между вами. Например: вы пытаетесь создать отношения один ко многим или много к одному между транспортным средством и двигателем?

Один из вариантов может быть (если он соответствует вашим потребностям):

Автомобиль: (ID, EngineID, GearID, ...)

Двигатель (ID, другие данные двигателя)

Шестерня (ID, другие данные шестерни)

0 голосов
/ 11 декабря 2008

Спасибо за все ответы.

На самом деле я имел в виду: Транспортное средство: (удостоверение личности, другие данные транспортного средства, ...) Двигатель (ID, VehicleID, другие данные двигателя) Снаряжение (ID, VehicleID, другие данные о передаче)

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

Я не знал об обязательном ограничении внешнего ключа, которое по умолчанию установлено в YES в SQL 2005.

Так что установите его на NO и знайте, что он работает просто отлично.

Еще раз спасибо,

Омри.

0 голосов
/ 11 декабря 2008

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

Триггерное решение, которое во много раз проще реализовать, будет труднее всего поддерживать, поскольку оно «прячет» за важными бизнес-правилами.

Ну ... в любом случае, вам действительно следует взглянуть на определение проблемы, поскольку вопросы такого рода обычно возникают из-за неправильного определения бизнес-области.

Итог: каждый ваш триггер будет головной болью для следующей итерации проекта.

0 голосов
/ 11 декабря 2008

Но опять же, как я мог узнать автомобиль ID

Существует таблица с именем INSERTED , которая доступна в триггерах вставки. Вы найдете там идентификатор автомобиля.

0 голосов
/ 11 декабря 2008

Подобные вещи решаются с помощью любых постоянных рамок. В типичном сценарии сопоставления O / R вы просто создаете требуемые объекты (например, косвенно), и преобразователь O / R сохраняет их в правильном порядке и автоматически синхронизирует поля FK / PK.

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

(отказ от ответственности: я ведущий разработчик структуры o / r mapper)

0 голосов
/ 11 декабря 2008

Я должен сказать, что лично я считаю, что этот сценарий не имеет смысла, на самом деле.

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

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

0 голосов
/ 11 декабря 2008

Если у вас должно быть две отдельные таблицы, вы можете объединить их в представлении, а затем обновить / вставить в представление ...

CREATE VIEW VehicleComplete AS SELECT * FROM Vehicle INNER JOIN VehicleEngine USING(VehicleID)

UPDATE VehicleComplete SET Rego = 'ABC 123', EngineModel = '380' WHERE VehicleID = 1
0 голосов
/ 11 декабря 2008

Будет ли у вас только один двигатель и одна передача для каждого транспортного средства? Если это так, то почему они в разных таблицах?

Если они необходимы в двух таблицах, вы можете создать триггер INSTEAD OF INSERT, как описано здесь: http://msdn.microsoft.com/en-us/library/ms175089.aspx

...