我正在为Postgres的停车场设计一个数据库。我需要定义一个约束(或类似)来验证表Id_Lot
中Ticket中的"Lot"
是否为空。
我怎么做?
相关表格是:
票:
"Id_Ticket" serial PRIMARY KEY,
"Date_Entrance" date NOT NULL,
"Time_Entrance" time without time zone NOT NULL,
"License_plate" varchar(6) NOT NULL references "Vehicle"("L_Plate"),
"Id_Lot" varchar(4) NOT NULL references "Lot"("Code")
批号:
"Code" varchar(4) NOT NULL PRIMARY KEY,
"Type" varchar(5) NOT NULL,
"Empty" boolean NOT NULL
答案 0 :(得分:1)
假设你想强制执行:
"Id_Lot"
实际存在于"Lot"."Code"
中。 - > FK约束"Lot"."Empty"
该地点为TRUE
。你可以使用NOT VALID
CHECK
约束使用假IMMUTABLE
函数来检查另一个表。详细说明:
但是您的数据模型在很多方面都很不稳定。我建议采用更清洁的方法。
不要存储当前批次是否与该批次冗余。这非常容易出错并容易出现并发问题。强制每批只能使用 exclusion constraint 进行一次。为此,请另外在ticket
中保存退出时间。
CREATE TABLE lot (
lot_id varchar(4) NOT NULL PRIMARY KEY -- I would use integer if possible
, lot_type text NOT NULL
);
lot
表中没有冗余当前状态。
要使排除约束起作用,您需要额外的模块btree_gist。详细说明:
CREATE TABLE ticket (
ticket_id serial PRIMARY KEY
, during tsrange NOT NULL
, license_plate text NOT NULL REFERENCES "Vehicle"("L_Plate"),
, lot_id int NOT NULL REFERENCES lot
, CONSTRAINT lot_uni_ticket EXCLUDE USING gist (lot_id WITH =, during WITH &&)
, CONSTRAINT during_lower_bound_not_null CHECK (NOT lower_inf(during))
, CONSTRAINT during_bounds CHECK (lower_inc(during) AND NOT upper_inc(during))
);
使用时间戳范围数据类型tsrange
表示停车时间during
。
当汽车进入时,以上限NULL输入。当汽车退出时以上限更新。
除此之外,这也使得汽车可以停放多天。
在CHECK
上执行基本规则的一些额外during
限制:
相关: