我如何定义这个约束?

时间:2014-12-06 23:09:38

标签: database postgresql database-design constraints

我正在为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

1 个答案:

答案 0 :(得分:1)

您要求的解决方案

假设你想强制执行:

  1. "Id_Lot"实际存在于"Lot"."Code"中。 - > FK约束
  2. 仅在检查时,
  3. "Lot"."Empty"该地点为TRUE
  4. 可以使用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))
    );
    

    相关: