-- Uniques and indexes to enforce data integrity and performance -- Unique, case-insensitive names CREATE UNIQUE INDEX IF NOT EXISTS ux_make_name ON vehicles.make (lower(name)); CREATE UNIQUE INDEX IF NOT EXISTS ux_model_make_name ON vehicles.model (make_id, lower(name)); -- Model/Year availability ALTER TABLE vehicles.model_year ADD CONSTRAINT ux_model_year UNIQUE (model_id, year); CREATE INDEX IF NOT EXISTS ix_model_year_year_model ON vehicles.model_year (year, model_id); -- Trims are unique per model_year by name (case-insensitive) CREATE UNIQUE INDEX IF NOT EXISTS ux_trim_modelyear_name ON vehicles.trim (model_year_id, lower(name)); CREATE INDEX IF NOT EXISTS ix_trim_modelyear_name ON vehicles.trim (model_year_id, name); -- Engine uniqueness (prefer code when present) CREATE UNIQUE INDEX IF NOT EXISTS ux_engine_code_not_null ON vehicles.engine (code) WHERE code IS NOT NULL; CREATE UNIQUE INDEX IF NOT EXISTS ux_engine_name ON vehicles.engine (lower(name)); -- Bridge indexes CREATE INDEX IF NOT EXISTS ix_trim_engine_trim ON vehicles.trim_engine (trim_id); CREATE INDEX IF NOT EXISTS ix_trim_engine_engine ON vehicles.trim_engine (engine_id);