如何在关系数据库中有效存储一年中每一天的小时间隔?

时间:2013-03-28 08:43:34

标签: mysql sql relational-database

我有一个广告系列,为此我必须设置一年中每天的小时间隔,在该广告系列中播放或不播放。

例如:

除了星期一和星期二之外每年每天都会播放一次,从7点到9点30分不会播放。

如何在SQL数据库中有效地存储结构?我有365天和48个半小时的间隔。我不想将外键用于不同的表,因为它效率低下。

谢谢。

1 个答案:

答案 0 :(得分:1)

最简单的表格看起来像这样。 可能不是最佳结构,因为未明确存储半小时时间段的结尾。不过。 。

create table campaign_times (
  campaign_name varchar(35) not null,
  time_segment timestamp not null,
  play boolean not null default true,
  primary key (campaign_name, time_segment)
);

我生成了一堆随机广告系列名称(大约175个),并以全年半小时间隔交叉加入这些名称:3,083,520行。我知道我需要time_segment的索引。我还添加了一个play的索引,以防PostgreSQL可以使用它。 (PostgreSQL过去曾多次对低选择性色谱柱的智能处理感到惊讶。)

create index on campaign_times (time_segment);
create index on campaign_times (play);

确保统计信息是最新的。

analyze campaign_times;

现在让我们看看这种情况到底有多糟糕。

explain analyze
select *
from campaign_times 
where current_timestamp between time_segment and time_segment + interval '30 minutes'
  and play = true;

"Index Scan using campaign_times_time_segment_idx on campaign_times  
[snip]
"Total runtime: 498.713 ms"

从300万行的表格中获取当前播放列表不到半秒钟。并且不考虑优化,例如删除旧行,尝试更周到的索引,存储更少的行(比如今天的日期提前一个月)等等。

我可以忍受。


在制作中,我想要外键和检查约束。这些不会影响PostgreSQL中SELECT语句的速度,我不会认为它们会影响MySQL中的SELECT速度。 (好吧,检查约束肯定不会,因为MySQL无论如何都不强制执行它们。)