如何确保数据库中的 startDate 和 endDate 列不重叠?

Posted

技术标签:

【中文标题】如何确保数据库中的 startDate 和 endDate 列不重叠?【英文标题】:How to ensure non overlapping startDate and endDate columns in database? 【发布时间】:2021-12-21 05:34:58 【问题描述】:

下表存储了不同日期范围内的产品价格

id
productID
startDate
endDate
price

如何在数据库级别确保给定日期没有多个条目。 (MongoDB / mysql)

正确设置

startDate     endDate
2020-01-01    2020-01-05
2020-01-07    2020-01-07
2020-01-08    2020-01-20

不正确的设置

日期 2020-01-04 有两个条目(第一个和第二个)

startDate     endDate
2020-01-01    2020-01-05
2020-01-04    2020-01-07
2020-01-08    2020-01-20

【问题讨论】:

我猜你需要一个触发器。 您是否希望 (1) 确保当前数据没有重叠 (2) 以防止与现有行重叠的行插入? 如果 2 个范围重叠,则下一个表达式为真:start1 < end2 AND start2 < end1 @SalmanA 什么样的触发器? @Akina 我想在插入时确保。此表中的每个新插入都会导致更新/插入/删除操作的组合。例如,在正确的 SET 中,如果我想添加第 5 到 25 的条目,则需要更新第 1 条目,删除第 2 和第 3 条目并为 21 到 25 日创建新条目。我想确保这个表永远不会得到重叠的条目。如果我在每次操作后都执行验证查询,那么这将导致过多的开销,因为在此表中每小时会发生数百次插入。 【参考方案1】:
CREATE TRIGGER check_for_overlapping
BEFORE INSERT
ON prices
FOR EACH ROW
BEGIN
    IF EXISTS ( SELECT NULL
                FROM prices
                WHERE prices.productID = NEW.productID
                  AND prices.startDate <= NEW.EndDate
                  AND NEW.startDate <= prices.EndDate ) THEN
        SIGNAL SQLSTATE '45000' 
            SET MESSAGE_TEXT = 'Entered data overlaps with existing data';
    END IF;
END;

DEMO

【讨论】:

【参考方案2】:

更改架构。

说真的。你有多余的信息。并且缺少信息(参见“2020-01-6”)。

不要有开始和结束,只有开始。 (等效地,您只能有一个“结束”日期。)

一个条目的“结束”由下一行的“开始”给出。 (见下例)

因为你似乎有未分配的日子;在那段时间(例如,2020-01-06)“产品”是否不可用?如果这是有效的业务逻辑,请添加一行以某种方式表明这种情况。

对于 IP 地址范围,我执行了上述操作。 (并且间隙是有效的——它们指的是“未分配的”IP。)参见http://mysql.rjweb.org/doc.php/ipranges。它包括许多需要从“ip-address”调整为“date”的操作(插入、查找、修改等)的代码。

正如 Akina 指出的,责任在于插入代码,以确保数据符合业务逻辑规则。

在您的示例中,2020-01-07 2020-01-07 的意思是“所有 7 个”吗?如果是这样,那么它在逻辑上是&gt;= '2020-01-07' AND &lt; '2020-01-08'。这适用于我的 IP 类比等。

请注意,我选择为所有操作存储例程。这避免了“每次操作后执行验证查询”的需要

【讨论】:

以上是关于如何确保数据库中的 startDate 和 endDate 列不重叠?的主要内容,如果未能解决你的问题,请参考以下文章

Python中的字典分组和聚合列表

如何连续提取每一年[重复]

如何根据 startdate 和 enddate 参数隐藏 s-s-rs 报告生成器中的列?

sql如何截取日期字段中的年和月

fullcalendar events加载数据失败

js判断两个时间相隔多少天