设计这些表的最佳方法

时间:2011-12-06 09:57:02

标签: mysql sql database-design foreign-keys

我的旅行项目架构的一部分有以下表格

Cruises
Flights
Hotels
CarParking

我需要一个容器,将一个或多个这些产品包装到一个包中。一个游轮/酒店等可能是许多套餐的一部分。我最初想到的是

Package
- PackageId
- Etc

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

其中ItemType表示它是否是Cruise,Flight,Hotel等。我想我可以使用触发器来强制执行参照完整性。

我的另一个想法是

Package
- ...

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

我认为每个人都有利有弊,但我无法决定。你觉得哪个更好,如果你必须实现这样的话,你会选择哪个?

数据库是MySql。平台是C#MVC ASP.NET

(我做了搜索,但有一些类似的问题,但没有任何相应的问题)

2 个答案:

答案 0 :(得分:5)

第一种选择是最灵活的。而且我倾向于灵活性。


优势:常见查询

如果您想要有关巡航的报告,则查询与酒店的查询相同,但使用不同的WHERE子句。

使用第二种形式,您需要加入并从不同的表中选择。


* 优势:没有架构变更的增长

如果您需要向模型中添加Excursions(当然有许多与单个包相关联的东西),您只需创建一个新的Excursions类型。

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


成本:数据转移到不适合人类消化的形式

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

此外,虽然这是一个成本,但它的好处是可以强迫你进入一个不太可能的中间位置,因此做出简单的假设并犯下草率的错误。这是我喜欢的费用。


Falacy:无法强制执行约束

约束 - 每个包裹组件必须是酒店,包装,飞行或巡航
方法 - 拥有component_type表,并将FK添加到该表

约束 - 每个包只允许每种类型中的一种
方法 - 对(package_id,component_type_id)

的UNIQUE约束

约束 - 每个组件只能在一个包中 方法 - 对(component_id)

的UNIQUE约束


费用 - 延迟复杂性

在我看来,将Packages映射到Components的规范化表实际上是简单而优雅的。下一步是决定如何存储组件的相关细节。


单个全局“组件”表可以包含所有字段,但允许它们可以为空。因此,HOTEL将具有NULL Flight_Number。但是所有组件都有价格。


或者您可以创建Entity_Attribute_Value表。这可以以防止酒店有航班号的方式形成......
- component_attributes table =(id,type_id,attribute_id,attribute_value)
- (type_id,attribute_id)可以外键修改为允许的组合

执行必需的字段是不可能的(afaik),例如Price Value通常存储为VARCHAR 出于这个原因,和其他人一样,通过Value搜索数据变得困难。


最终意见

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

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

答案 1 :(得分:3)

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

1)如果需要支持每个包装的多个相同类型的产品,那么您应该采用第一种方式,但可能将每种产品类型的关系拆分为单独的表格,即

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

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

... etc.

通过这种方式,您可以通过普通的FK机制获得参照完整性。

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