Лучший способ создать эти таблицы

0

Часть моей схемы для проекта путешествия имеет следующие таблицы

Cruises
Flights
Hotels
CarParking

Мне нужен контейнер, который обертывает один или несколько из этих продуктов в пакет. Один Cruise/Hotel и т.д. Могут быть частью многих пакетов. Я изначально думал о

Package
- PackageId
- Etc

PackageItem
- PackageItemId
- PackageId (fk)
- ItemId (fk)
- ItemType

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

Моя другая идея была

Package
- ...

PackageItem
- PackageItemId
- PackageId (fk)
- CruiseId (nullable fk)
- FlightId (nullable fk)
- HotelId (nullable fk)
- CarParkingId (nullable fk)
- etc

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

База данных - MySql. Платформа С# MVC ASP.NET

(Я искал и было несколько подобных вопросов, но ничего, что хорошо соответствовало)

Теги:
database-design
foreign-keys

2 ответа

5

Первый вариант является наиболее гибким. И я склонен проявлять гибкость.


Преимущество: общие запросы

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

Используя вторую форму, вам нужно присоединиться и выбрать из разных таблиц.


* Преимущество: рост без изменений схемы

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

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


Стоимость: данные перемещаются в форму, не дружественную для пищеварения человека

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

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


Фальсификация: ограничения не могут быть соблюдены

Ограничение. Каждый компонент упаковки должен быть либо в отеле, упаковке, рейсе или круизе
Метод. Имейте таблицу component_type и FK в эту таблицу.

Ограничение. Только один из каждого типа разрешен для каждой упаковки.
Метод - УНИКАЛЬНОЕ ограничение на (package_id, component_type_id)

Ограничение. Каждый компонент может находиться только в одном пакете. Метод. УНИКАЛЬНОЕ ограничение на (component_id)


Стоимость - отложенная сложность

На мой взгляд, нормализованная таблица для отображения Packages to Components на самом деле проста и элегантна. Следующий шаг - решить, как сохранить связанные детали компонента.


Единая глобальная таблица "компонентов" может содержать все поля, но допускает, чтобы они были обнуляемы. Таким образом, у ГОСТИНИЦА будет NULL Flight_Number. Но у всех компонентов была бы цена.


Или вы можете создать таблицу Entity_Attribute_Value. Это может быть сформировано таким образом, чтобы гостиницы не имели номера рейса...
- component_attributes table = (id, type_id, attribute_id, attribute_value)
- (type_id, attribute_id) могут быть чужой, введенной в допустимые комбинации

Невозможно (afaik) обеспечить соблюдение полей REQUIRED, таких как Price.
Значение часто хранится как VARCHAR.
По этой причине и т.д. Поиск данных по значению становится сложным.


окончательное мнение

Я бы не использовал вариант 2, так как это сильно ограничено и объединяет два соображения вместе. Как хранить данные для разных типов компонентов (отели, полеты и т.д.) И как связать их с родительскими пакетами.

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

  • 0
    Спасибо за комментарии и предложения
3

Вы не упомянули о том, нужно ли вам поддерживать несколько продуктов одного типа внутри одного пакета - то есть, может ли пакет содержать несколько отелей, например.

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

PackageHotelItem
- PackageItemId
- PackageId (fk)
- HotelId (fk)

PackageCruiseItem
- PackageItemId
- PackageId (fk)
- CruiseId (fk)

... etc.

Таким образом, вы сможете иметь ссылочную целостность через обычный механизм FK.

2) Если вам не нужна такая поддержка, вы можете использовать свое второе решение.

  • 1
    Это был бы мой выбор, так как при появлении новых элементов пакета у вас не будет таблицы PackageItem с множеством полей.
  • 0
    Спасибо за предложение. В упаковке должно быть несколько продуктов одного типа. Оба моих варианта учитывают это, так как в обоих случаях у меня будет несколько PackageItems, составляющих пакет.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню