用于保存日期范围的数据库

时间:2014-07-02 07:04:38

标签: mysql database algorithm postgresql

我对数据库设计有一个大问题。

我需要为不同日期的不同酒店存储不同房型的价格。日期可以是间隔,也可以是该时间间隔内的特定工作日,间隔是完全随机的。

所以我尝试评估两种解决方案:

  1. 每天的商店价格。问题是我们有超过3,000家不同的酒店,所以最终价格表将包含超过1000万行。

  2. 将整年的日期存储为字节数组,每个位代表1天。因此价格的每一行都包括价格有效的整个时间间隔。问题是如何索引日期字节数组,以及搜索的速度有多快;以及您输入的转移价格处理方式正确。

  3. 我应该选择哪种解决方案?我没有尝试任何东西,也不知道不同的数据库如何处理不同的场景以及字节数组(字符串)的索引如何用于按位运算比较等等。欢迎任何其他建议。

2 个答案:

答案 0 :(得分:2)

由于您还使用PostgreSQL对此进行了标记,因此9.2中引入的新间隔数据类型似乎是一个很好的(且有效的)适合:

简化示例如下所示:

create table room_price
(
   room_id       integer       not null,
   hotel_id      integer       not null,
   price         numeric(16,4) not null,
   valid_during  daterange not null
);

然后你可以插入这样的东西:

insert into room_price 
  (room_id, hotel_id, price, valid_during)
values 
  (1, 1, 100.0, '[2014-07-01,2014-07-01]'),
  (1, 1,  90.0, '[2014-07-02,2014-07-12]');

[...]表示法定义了一个包含两个日期的区间([..)将定义排除左边缘的区间)。

您可以非常轻松地查询上表以获取特定日期特定房间的价格:

select *
from room_price
where room_id = 1
  and valid_during @> date '2014-07-04;

将以90.0

返回价格

您甚至可以定义一个阻止重叠日期的约束:

alter table room_price
  add constraint check_price_range 
  exclude using gist (room_id with =, valid_during with &&)

通过上述约束,Postgres将拒绝以下插入:

insert into room_price
  (room_id, hotel_id, price, valid_during)
values 
  (1,  90.0, '[2014-07-03,2014-07-04]');

约束隐式地在表上创建一个索引,用于查找数据,从而使查询非常有效。

答案 1 :(得分:1)

PostgreSQL有一对专门为此类设计的功能:范围类型和排除约束。

将有效期的价格存储为范围或范围集。然后定义排除约束,以确保两个价格在给定地点/时间有效时不会重叠。

不幸的是,范围可能不稀疏(有漏洞),所以这对你有用还取决于数据模式。

了解更多信息: