And*_*rus 2 sql postgresql database-design schedule postgresql-9.2
PostgreSql 9.2 保留表定义为
CREATE EXTENSION btree_gist;
CREATE TABLE schedule (
id serial primary key,
during tsrange not null,
EXCLUDE USING gist (during WITH &&)
);
Run Code Online (Sandbox Code Playgroud)
假期见表
CREATE TABLE holiday ( day primary key );
Run Code Online (Sandbox Code Playgroud)
工作日工作时间为 8:00 至 18:00,且只能以 30 分钟为间隔进行预订。如何向 while 值添加约束,以便仅允许在工作时间进行预订:
将这些或其中一些约束添加到该表中是否合理?如果有,如何添加?如果有帮助的话,可以更改计划表结构。
您可以使用简单的CHECK约束解决除第 3 项之外的所有问题:
使用专用范围函数 lower(anysrange)并upper(anyrange)访问范围的下限/上限。
1.) tsrange 中的开始日期和结束日期始终相同。
CONSTRAINT schedule_same_day
CHECK (lower(during)::date = upper(during)::date)
Run Code Online (Sandbox Code Playgroud)
2.) 开始和结束日期不能是周六和周日
使用isodow, 不是dow为了更简单的表达。
CONSTRAINT schedule_no weekend
CHECK (EXTRACT(ISODOW FROM lower(during)) < 6) -- upper is on same day
Run Code Online (Sandbox Code Playgroud)
3.) 开始和结束日期不能出现在公共假期表中
为此,您需要一个触发器,例如:
CONSTRAINT schedule_same_day
CHECK (lower(during)::date = upper(during)::date)
Run Code Online (Sandbox Code Playgroud)
4.) 开始时间只能为 8:00、8:30、9:00、9:30、...、16:00、16:30、17:00 或 17:30(含)。
5.) 结束时间只能是 8:30、9:00、9:30、...、16:00、16:30、17:00、17:30 或 18:00(不含)。
CONSTRAINT schedule_no weekend
CHECK (EXTRACT(ISODOW FROM lower(during)) < 6) -- upper is on same day
Run Code Online (Sandbox Code Playgroud)
更新:在Postgres 14或更高版本中使用date_bin():
CREATE OR REPLACE FUNCTION trg_during_no_holy()
RETURNS trigger
LANGUAGE plpgsql AS
$func$
BEGIN
IF EXISTS (SELECT FROM holiday WHERE day = lower(NEW.during)) THEN
RAISE EXCEPTION 'Day too holy: %', lower(NEW.during);
END IF;
RETURN NEW;
END
$func$;
CREATE TRIGGER insupbef_holycheck
BEFORE INSERT OR UPDATE
ON schedule
FOR EACH ROW
EXECUTE PROCEDURE trg_during_no_holy();
Run Code Online (Sandbox Code Playgroud)
这也强制执行您的附加要求“限制秒和小数秒”。
看: