PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Come posso definire questo vincolo?

Soluzione per quello che chiedi

Supponendo che tu voglia farlo rispettare:

  1. "Id_Lot" esiste effettivamente in "Lot"."Code" . -> Vincolo FK
  2. "Lot"."Empty" per lo spot è TRUE solo al momento del controllo.

Potresti fallo con un NOT VALID CHECK vincolo usando un falso IMMUTABLE funzione per controllare sull'altra tabella. Dettagli:

Ma il tuo modello di dati è traballante sotto diversi aspetti. Suggerirei un approccio molto più pulito.

Design più pulito con vincolo di esclusione

Non memorizzare se un lotto è attualmente vuoto in modo ridondante con il lotto. Questo è molto soggetto a errori e suscettibile di problemi di concorrenza. Assicurati che ogni lotto possa essere preso solo una volta alla volta con un vincolo di esclusione . Affinché funzioni, salva il tempo di uscita in ticket , in aggiunta.

CREATE TABLE lot (
  lot_id   varchar(4) NOT NULL PRIMARY KEY  -- I would use integer if possible
, lot_type text NOT NULL
);

Nessuno stato corrente ridondante nel lot tabella.

Affinché il vincolo di esclusione funzioni, è necessario il modulo aggiuntivo btree_gist . Istruzioni dettagliate:

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))
);
  • Utilizzo di un tipo di dati di intervallo timestamp tsrange per la durata del parcheggio during .Inserire con il limite superiore NULL, quando l'auto entra. Aggiorna con il limite superiore all'uscita dell'auto. Tra le altre cose, questo consente anche di parcheggiare le auto per più giorni.

  • Qualche ulteriore CHECK vincoli per applicare le regole di base su during :

Correlati: