我有以下DDL
create table repeat_group(
id int,
start_date date.
end_date date,
createby int,
createdon timestamp not null default current_timestamp,
updatedby int,
updatedon timestamp,
primary key(id)
);
该表表示一组在start_date和end_date之间的工作日重复的类。我想将一组重复的日子存储在此表的一列中。
我想出了三种解决方案:
每个工作日有7列,并存储一个标记为recurring_day
的标志。这将创建很多NULL。
制作一个单独的表并将其与一对多关系相关。
将日期存储在某些代码中(例如:字节码),如下所示:
列名称:recussing_days char(7)
。这将存储7个字符串,如0000010
。此代码意味着该课程将在start_date
和end_date
之间的每个星期六重复。
考虑到第三种解决方案需要计算,我想问哪种解决方案最有效。另外,是否还有其他有效的解决方案。
谢谢。
答案 0 :(得分:0)
这取决于您所说的“高效”的含义以及数据的使用方式。
如果您要提高可读性,那么每周的每一天都会有一列。试图确定课程是否在星期一开课的开发人员只需查看“星期一”列;所有查询都将具有描述性且易于理解。但是,您的日列将具有稀疏的数据,并且基数较低,这意味着它们将不适合索引。如果您要存储数百万行,则 可能是个问题。
如果您的目标是绝对速度,那么我将使用整数来存储日期,并使用按位运算;大多数RDBMS引擎确实擅长此操作,并且整数字段可能更“索引友好”,因为您可能会分散大量的值。但是,查询的可读性较差,您可能会遇到一些愚蠢的错误(一周从星期日还是星期一开始?)。
这非常快,因为日期的每种组合都等于一个不同的唯一整数,这反过来又使该列可以得到有效索引。初始计算(将“星期一和星期二而不是星期三和(星期四或星期五)转换为整数”)仅发生一次,并且非常快。但是,将该整数与您的“类”表中的数百万条记录(我从您的注释中获得“数百万条,但似乎很大……”)进行比较比较耗时。
我当然不会将您的位标志存储在字符串中-这样您将失去内置按位逻辑的好处。
单独的表可能很容易阅读,但可能导致尴尬的查询-查找在星期一和星期二运行的所有课程,但在星期三不是,这需要几个join / in子句。这可能更难粘到前端(尤其是在使用ORM的情况下)。