sql >> Base de Datos >  >> RDS >> PostgreSQL

¿Cómo puedo definir esta restricción?

Solución para lo que pides

Suponiendo que desea hacer cumplir eso:

  1. "Id_Lot" realmente existe en "Lot"."Code" . -> Restricción FK
  2. "Lot"."Empty" para el lugar es TRUE solo en el momento del cheque.

podrías haz esto con un NOT VALID CHECK restricción usando un falso IMMUTABLE Función para verificar en la otra tabla. Detalles:

Pero su modelo de datos es inestable en varios aspectos. Sugeriría un enfoque mucho más limpio.

Diseño más limpio con restricción de exclusión

No almacene si un lote está actualmente vacío de forma redundante con el lote. Eso es muy propenso a errores y susceptible a problemas de concurrencia. Haga cumplir que cada lote solo se puede tomar una vez a la vez con un restricción de exclusión . Para que eso funcione, guarda la hora de salida en ticket , adicionalmente.

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

No hay estado actual redundante en el lot mesa.

Para que funcione la restricción de exclusión, necesita el módulo adicional btree_gist . Instrucciones detalladas:

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))
);
  • Usando un tipo de datos de rango de marca de tiempo tsrange para la duración del estacionamiento during .Ingrese con límite superior NULL, cuando ingrese el automóvil. Actualice con el límite superior cuando el automóvil salga. Entre otras cosas, esto también hace posible que los automóviles se estacionen varios días.

  • Algunos CHECK adicionales restricciones para hacer cumplir las reglas básicas en during :

Relacionado: