Database Reference
In-Depth Information
Example 6-5. Building foreign key constraints and covering indexes
set search_path = census , public ;
ALTER TABLE facts ADD CONSTRAINT fk_facts_1 FOREIGN KEY ( fact_type_id )
REFERENCES lu_fact_types ( fact_type_id )
ON UPDATE CASCADE ON DELETE RESTRICT ;
CREATE INDEX fki_facts_1 ON facts ( fact_type_id );
We define a foreign key relationship between our facts and fact_types tables.
This prevents us from introducing fact types into facts unless they are already
present in the fact types lookup table.
We add a cascade rule that automatically updates the fact_type_id in our facts
table should we renumber our fact types. We restrict deletes from our lookup
table so fact types in use cannot be removed. RESTRICT is the default behavior,
but we suggest stating it for clarity.
Unlike for primary key and unique constraints, PostgreSQL doesn't
automatically create an index for foreign key constraints; you should add this
yourself to speed up queries.
Unique Constraints
Each table can have no more than a single primary key. If you need to enforce uniqueness
on other columns, you must resort to unique constraints or unique indexes. Adding a
unique constraint automatically creates an associated unique index. Similar to primary
keys, unique key constraints can participate in REFERENCES part of foreign key con‐
straints and cannot have NULL values. A unique index without a unique key constraint
does allow NULL values. The following example shows how to add a unique index:
ALTER TABLE logs_2011 ADD CONSTRAINT uq UNIQUE ( user_name , log_ts );
Often you'll find yourself needing to ensure uniqueness for only a subset of your rows.
PostgreSQL does not offer conditional unique constraints, but you can achieve the same
effect by using a partial uniqueness index. See “Partial Indexes” on page 116 .
Check Constraints
Check constraints are conditions that must be met for a field or a set of fields for each
row. The query planner can also take advantage of check constraints and abandon
queries that don't meet the check constraint outright. We saw an example of a check
constraint in Example 6-2 . That particular example prevents the planner from having
to scan rows failing to satisfy the date range specified in a query. You can exercise some
creativity in your check constraints, because you can use functions and Boolean ex‐
pressions to build complicated matching conditions. For example, the following con‐
straint requires all user names in the logs tables to be lowercase:
ALTER TABLE logs ADD CONSTRAINT chk CHECK ( user_name = lower ( user_name ));
Search WWH ::




Custom Search