在 SQL 中保存一系列日期的最佳实践
Best practice for saving a series of dates in SQL
我正在修改一些旧程序,其中一个我需要在数据库中保存一系列重复的日期。用户在 PHP-Form 中选择 1-31 之间的日期和 1-12 之间的月份。多项选择是可能的。必须至少提供一个。
然后我将使用每天计划的任务来检查是否给出了值(日和月),如果是 - 做一些事情。
在旧系统中我是这样保存的:
| Days | Months |
|1,2,5,13,15 | 1,2,3,4,5,6,7,8,9,10,11,12|
然后我分解了由计划任务触发的 PHP-File 中的每一行并遍历数组。如果其中一个日期有效 - 做点什么。
此用例的最佳实践是什么?我考虑了一些解决方案,例如 "saving all possible Outcomes of days and months as single rows in an mapping-table",但我认为这不是一个优雅的解决方案......而且它在实施后也需要可编辑。
有什么建议吗?
我想你正在看三个 tables。
Table 一个记录组,给它一个连续的组 ID 以及您需要记录的关于整个日期组的任何其他属性(请求用户 ID)。
第二个 table 只是来自 table 的组 ID 和行中选择的日期,因此每个组有多个行。
第三个 table 与第二个相同,但持续数月。
当您需要最终结果时,将第二个和第三个 table 加入组 ID 上的第一个。你会自动得到两者之间的交叉连接,给出你需要的组合。
如果您期望大量数据 and\or 大量重复相同的组,那么您可能需要考虑重新使用日期和月份组的可能性。这将是一个类似的 table 设计,但 tables 2 和 3 将有自己的组 ID,并且 table 将有两个额外的列,一个用于日组,一个用于月组。
看来,您可以使用类似维度的方案并将日-月对附加到不同的实体。假设,实体被称为 "task".
| tasks | | days | | months |
| ------- | | -------- | | -------- |
| id_task | | id_day | | id_month |
| ... | >---M:1--- | id_month | >---M:1--- | month |
| id_day | | day |
不要忘记为 day
(1-31) 和 month
(1-12) 列添加检查约束。
我认为你应该扩展数据库中的数据。显然,您需要一个 table groups
(或类似的东西),每组一行:
create table groups (
group_id int identity(1, 1) primary key,
. . . -- additional columns
);
然后,展开每个组的日程安排的日期:
create table groups_schedule (
group_schedule_id int identity(1, 1) primary key,
group_id int references groups(group_id),
month int,
day int
);
这需要将数据库中的数据相乘。但是,我认为这是更准确的表示。此外,它将在未来为您提供更大的灵活性,因此您不会特别受限于 months/days 的列表。例如,您可能在大多数月份都有“25”日,但在 12 月却没有。
我正在修改一些旧程序,其中一个我需要在数据库中保存一系列重复的日期。用户在 PHP-Form 中选择 1-31 之间的日期和 1-12 之间的月份。多项选择是可能的。必须至少提供一个。
然后我将使用每天计划的任务来检查是否给出了值(日和月),如果是 - 做一些事情。
在旧系统中我是这样保存的:
| Days | Months |
|1,2,5,13,15 | 1,2,3,4,5,6,7,8,9,10,11,12|
然后我分解了由计划任务触发的 PHP-File 中的每一行并遍历数组。如果其中一个日期有效 - 做点什么。
此用例的最佳实践是什么?我考虑了一些解决方案,例如 "saving all possible Outcomes of days and months as single rows in an mapping-table",但我认为这不是一个优雅的解决方案......而且它在实施后也需要可编辑。
有什么建议吗?
我想你正在看三个 tables。
Table 一个记录组,给它一个连续的组 ID 以及您需要记录的关于整个日期组的任何其他属性(请求用户 ID)。
第二个 table 只是来自 table 的组 ID 和行中选择的日期,因此每个组有多个行。
第三个 table 与第二个相同,但持续数月。
当您需要最终结果时,将第二个和第三个 table 加入组 ID 上的第一个。你会自动得到两者之间的交叉连接,给出你需要的组合。
如果您期望大量数据 and\or 大量重复相同的组,那么您可能需要考虑重新使用日期和月份组的可能性。这将是一个类似的 table 设计,但 tables 2 和 3 将有自己的组 ID,并且 table 将有两个额外的列,一个用于日组,一个用于月组。
看来,您可以使用类似维度的方案并将日-月对附加到不同的实体。假设,实体被称为 "task".
| tasks | | days | | months |
| ------- | | -------- | | -------- |
| id_task | | id_day | | id_month |
| ... | >---M:1--- | id_month | >---M:1--- | month |
| id_day | | day |
不要忘记为 day
(1-31) 和 month
(1-12) 列添加检查约束。
我认为你应该扩展数据库中的数据。显然,您需要一个 table groups
(或类似的东西),每组一行:
create table groups (
group_id int identity(1, 1) primary key,
. . . -- additional columns
);
然后,展开每个组的日程安排的日期:
create table groups_schedule (
group_schedule_id int identity(1, 1) primary key,
group_id int references groups(group_id),
month int,
day int
);
这需要将数据库中的数据相乘。但是,我认为这是更准确的表示。此外,它将在未来为您提供更大的灵活性,因此您不会特别受限于 months/days 的列表。例如,您可能在大多数月份都有“25”日,但在 12 月却没有。