我有一个活动,我必须为一年中的每一天设置小时间隔,在其中播放或不播放。
例如:
将在一年中的每一天播放,除了星期一和星期二它不会从 7 点到 9.30 播放。
如何有效地将结构存储在 SQL 数据库中?我有 365 天和 48 个半小时的间隔。我不想对不同的表使用外键,因为它效率低下。
谢谢你。
我有一个活动,我必须为一年中的每一天设置小时间隔,在其中播放或不播放。
例如:
将在一年中的每一天播放,除了星期一和星期二它不会从 7 点到 9.30 播放。
如何有效地将结构存储在 SQL 数据库中?我有 365 天和 48 个半小时的间隔。我不想对不同的表使用外键,因为它效率低下。
谢谢你。
最简单的表看起来像这样。它可能不是最好的结构,因为半小时时间段的结尾没有明确存储。尽管如此 。. .
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 的索引。我还添加了一个播放索引,以防 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 无论如何都不会强制执行它们。)