Mysql 设计这些表格的最佳方法

Mysql 设计这些表格的最佳方法,mysql,sql,database-design,foreign-keys,Mysql,Sql,Database Design,Foreign Keys,我的旅游项目模式的一部分包含以下表格 Cruises Flights Hotels CarParking 我需要一个容器,将一个或多个此类产品包装成一个包装。一个邮轮/酒店等可能是许多套餐的一部分。我最初想到的是 Package - PackageId - Etc PackageItem - PackageItemId - PackageId (fk) - ItemId (fk) - ItemType 其中ItemType将指示它是否是邮轮、航班、酒店等。我想我可以使用触发器来强制引用完整

我的旅游项目模式的一部分包含以下表格

Cruises
Flights
Hotels
CarParking
我需要一个容器,将一个或多个此类产品包装成一个包装。一个邮轮/酒店等可能是许多套餐的一部分。我最初想到的是

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。平台是C MVC ASP.NET


我做了搜索,有一些类似的问题,但没有一个与之完全对应的问题

您在问题中没有提到是否需要在一个包中支持多个相同类型的产品,例如,包是否可以包含多个酒店

1如果每个包需要支持多个相同类型的产品,那么您应该首先选择,但可以将关系拆分为每个产品类型的单独表,即

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

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

... etc.
这样,您将能够通过正常的FK机制获得引用完整性


2如果您不需要此类支持,则可以使用第二种解决方案。

第一种方案是最灵活的。我倾向于灵活性

优点:常见查询

如果您想要邮轮的报告,查询与酒店的查询相同,但带有不同的WHERE子句

使用第二个表单,您需要连接到不同的表并从中进行选择

*优点:增长而不改变模式

如果您需要向模型中添加一些与单个包相关联的短途旅行,您只需创建一个新的短途旅行类型

使用第二个表单,您需要向表中添加新字段,创建新表以保存数据,并更新查询和逻辑以使用这些新表和字段

成本:数据移动到不利于人类消化的形式

许多人可以合理地说,这根本不重要。我说这很重要,因为你必须考虑到它。。。 -这会使调试变得更加困难,因此您需要更加严格和有条理 -这意味着您的GUI必须更智能地转换数据以供显示

此外,尽管这是一项成本,但它的好处是迫使你进入一个中等偏上的环境,在那里你不太可能做出简单的假设,犯草率的错误。这是我喜欢的成本

谬误:约束无法强制执行

约束-每个包裹组件必须是酒店、包装、航班或邮轮 方法-有一个组件类型表,并将FK添加到该表

约束-每个包只允许一种类型 方法-包id、组件类型id上的唯一约束

约束-每个组件只能在一个包中 方法-组件id上的唯一约束

成本递延复杂性

在我看来,将包映射到组件的标准化表实际上是简单而优雅的。下一步是决定如何存储组件的关联详细信息

单个全局组件表可以容纳所有字段,但允许它们为空。因此,酒店的航班号为空。但所有组件都有价格

或者您可以创建一个实体属性值表。这可以形成这样一种方式,以防止酒店有一个航班号。。。 -组件属性表=id,类型id,属性id,属性值 -类型\ id、属性\ id可以外键设定为允许的组合

afaik不可能强制执行必填字段,例如价格。 该值通常存储为VARCHAR。 由于这个原因和其他原因,按值搜索数据变得很困难

最后意见

我不会使用选项2,因为这是高度受限的,并且将两个考虑因素合并在一起——如何保存不同组件类型(酒店、航班等)的数据,以及如何将它们与其父包关联


我建议你考虑多种方法来保存组件数据,并根据你的需要做出决定。然后使用1:many标准化映射表将这些组件与包关联起来。您的选项1。

这将是我的选择,因为当出现新的包项目时,您不会在PackageItem表中出现大量字段。谢谢您的建议。一个包中确实需要有多个相同类型的产品。我的两个选项都考虑到了这一点,因为在这两种情况下,我将有几个PackageItem组成一个包。您的第一个选项很有趣,但可以说比我的第二个选项更复杂。要得到一个完整的包,您必须查询每个包项目联接表,因此添加一个新的产品类型将是非常痛苦的。是的,查询可能更复杂。但是你会得到清晰的数据库结构
如果您决定在某个点添加(比如)铁路车站,也可以轻松地进行扩展。每件事都有它自己的优点和缺点,包括我的解决方案。谢谢你的评论和建议