As answered in this question: Cardinality in PostgreSQL, cardinality is enfforced using constraints.
Cardinality rules define the allowable counts of the relationships – one-to-many, many-to-many, etc. Many-to-many is achieved using join-tables and one-to-many using FOREIGN KEY.
But how can one implement one-to-one_or_many (one-to-1+) relationship. Which is same as to ask: How can I enforce minimum cardinality in PostgreSQL?
A practical situation would be where one needs to store say address (or telephone number) which MUST be provided (but can be more that one) by the person (say user or customer).
Edit:
The above mentioned situation is a special case (with cardinality one) of a general problem. The general problem being: How to enforce cardinality of arbitrary number?
As answered by jug a non-null FOREIGN KEY reference can be used as a work-around, if minimum-cardinality is one. It will also provide an additional feature to select default among many.
But consider another situation of relationship between team of Cricket and its players. Every team MUST have a MINIMUM of 11 players to qualify as a team. Here the minimum cardinality is eleven (11).
Similary, a relation between a course and a student in a school, where every student MUST enroll in AT-LEAST 5 courses and every course MUST have a MINIMUM of 10 students.
Minimum cardinality: minimum number of entity instances that must participate in a relationship.
A relationship with cardinality specified as 1:1 to 1:n is commonly referred to as 1 to n when focusing on the maximum cardinalities. A minimum cardinality of 0 indicates that the relationship is optional.
reltuples : Number of live rows in the table. This is only an estimate used by the planner. It is updated by VACUUM , ANALYZE , and a few DDL commands such as CREATE INDEX .
If you set the minimum cardinality to 0, selecting items is optional. If you set the minimum cardinality to greater than 0, the user must select that number of items from the relationship. Maximum Cardinality. Sets the maximum number of items that the user can select from a relationship.
There's no way to specify this using a CHECK constraint, so I think the best approach is a trigger:
http://www.postgresql.org/docs/9.1/static/sql-createtrigger.html
http://www.postgresql.org/docs/9.1/static/plpgsql-trigger.html
You'd end up with something like (I haven't tested it or anything):
CREATE TRIGGER at_least_one before INSERT, UPDATE, DELETE ON the_one_table FOR EACH ROW EXECUTE PROCEDURE check_at_least_one();
CREATE OR REPLACE FUNCTION check_at_least_one() RETURNS trigger AS $$
BEGIN
nmany := select count(*) from the_many_table where the_many_table.the_one_id=NEW.id;
IF nmany > 0 THEN
RETURN NEW;
END IF;
RETURN NULL;
END;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With