3

我有你期望的标准表,如'房间','预订'等。一切都在关系数据库中。酒店预订系统:如何存储每晚预订的单独价格?

“预约”表存储诸如room_id,入住日期和结帐日期等项目。

现在,简单地说,当进行预约时,系统检查房间价格表并获取每晚保留的费用(取决于日期,入住等) - 费用可能不同每晚取决于当前的价格。
很显然,预订时,每晚的价格是固定的。因此,即使房价在事后更新,该预订仍然保持约定价格,因为它是在价格变化之前完成的。

我的问题是:如何在预订时为每晚存储这些单独的商定价格?

我正在考虑使用另一个表格'PriceForNight'来存储每晚预订的预订ID,价格和日期。

我看到的唯一可能的问题是可伸缩性。如果平均预订时间为5晚,这意味着'PriceForNight'表格将比'Reservation'表快5倍左右。

将'PriceForNight'数据更好地存储在NoSQL数据库或类似的东西?

正在考虑的另一个选项是将每晚的价格作为以逗号分隔的字符串存储在“预订”表格行中的单个列中,例如:“150.00,175.00,175.00,200.00,150.00” 5晚预订。

我可能会过度思考这个问题,因为一个真正的问题可能只存在,如果它增长了1000倍,但我喜欢做正确的事情,所以我想我会接触到社区。

任何输入,非常感谢。

+0

由于无论如何您都要在该表中输入每个晚上的记录,为什么不将这些数据存储在保留表中?您可以添加两列,即机架速率和实际速率。 – 2012-01-28 15:29:50

+0

@MarkKram'Reservation'表中的每个预订只有一个条目,无论有多少晚上。 – Alex 2012-01-28 23:11:47

+0

Aaah,好我现在明白了 – 2012-01-29 01:54:06

回答

3

纯粹的关系型方法应该是有一个ReservationNight表,它存储了有关预订每晚的详细信息,包括价格。是的,这张桌子会快速增长,但无论您如何储存价格,数据都会迅速增长。

+0

谢谢您的意见。因此,我的'PriceForNight'表与您的建议相同?'reservation_id','价格'和'日期'? – Alex 2012-01-27 20:08:02

+0

是的,虽然我认为它可能不仅仅是存储的价格。重点在于,您需要每晚预订时需要存储的信息,因此请列出ReservationNight表。如果它只有一个有趣的列(价格),那就这样吧,这不应该放在表格的名字中。 – 2012-01-27 20:15:36

+0

我完全理解。感谢您的时间。 – Alex 2012-01-27 20:25:44

1

通常,逗号分隔的列表不属于SQL数据库。我会说你最好的选择是一个交界点。

StackOverflower Bill Karwin这里回答得好:Is storing a comma separated list in a database column really that bad?

除了因为存储在一个单一的列值的 重复组的违反First Normal Form,逗号分隔 列表有很多其他更实际的问题:

  • 不能保证每个值是正确的数据类型:没办法,防止1,2,3,香蕉,5
  • 无法使用外键约束将值链接到查找表;没有办法强制参照完整性。
  • 不能强制唯一性:没有办法阻止1,2,3,3,3,5
  • 没有获取整个列表不能从列表中删除一个值。
  • 很难搜索列表中给定值的所有实体;您必须使用低效的表扫描。
  • 很难统计列表中的元素,或执行其他聚合查询。
  • 很难将这些值加入到它们引用的查找表中。
  • 很难按排序顺序获取列表。

为了解决这些问题,你必须写吨的应用程序代码, 重塑功能的RDBMS 已经提供了更有效的

逗号分隔的列表是错误的,因此我在本书中创建了第一个 章节:SQL Antipatterns: Avoiding the Pitfalls of Database Programming

有些时候你需要使用非规范化,但是正如@OMG 小马提到的,这些都是异常情况。任何非关系型 “优化”都会以牺牲数据的其他用途 为代价获得一种查询类型,因此请确保您知道您的哪些查询需要特别处理,以致它们应该得到非规范化。

+0

我以前没有见过这个答案,谢谢。逗号分隔的想法绝对没有。 – Alex 2012-01-27 20:24:25

0

您可以使用日期范围而不是固定日期。

所以,如果我预约:

Night 27 01 2012: 20 $ 
Night 28 01 2012: 20 $ 
Night 29 01 2012: 30 $ 

在DB:

reservationId from  to  price 
5457848  20120127 20120128 20 
5457848  20120129 20120129 30 

如果它是很常见的,每天有一个羞怯的价格,这将不会减少行的数量。但这很罕见,那么它最多会减少到1排。

+0

我们之前也考虑过这一点,但认为每次需要显示价格时都会产生大量的处理开销,因而无法解构数据。另外,如果我们希望生成财务报告或进行分析,单独的夜晚大多可能是最容易的。 – Alex 2012-01-27 20:23:00

+0

然后,你应该确实与新表。它是最好的做法,它会创造更多的行。也许你可以在主要的预订中加入一个标志,如果你选择了所有夜晚的费用是相同的,并且你在这一行中花费了费用。如果不是,则参考其他表格。 – Jeff 2012-01-27 21:12:29

+0

也是一个很好的建议。我们会考虑这一点。感谢您的时间。 – Alex 2012-01-27 22:52:32

0

一张储存每晚费用的表格,每晚一行似乎是合理的。

每个房间一年可以租用不超过365晚。 (在现实世界中,这是差不多是真的,汽车旅馆的业务实际上比它看起来更复杂。)

如果你有200个房间,你每年大概看200 * 365行,或73,000行。 (我得到的算术是否正确?)以这样的速度,如果技术没有完全改进,那么您不必考虑至少100年来担心SQL dbms的性能。

您可能还会发现this answer有用。它遵循同样的思路。

+0

感谢您的回复。单独的表格方法对我们来说是最容易实现的,所以听到这种说法让人放心。 – Alex 2012-01-27 20:13:48

+0

@Alex:[This SO answer](http://stackoverflow.com/a/8009992/562459)遵循同样的思路。 – 2012-01-28 14:57:56