Question

Are composite keys guaranteed to be unique as long as the individual values of the columns it consists of are unique (as in the column values are separately evaluated), or is it the resulting value (as in a concatenation of the column values) that makes up the key and has to be unique?

Would, for example, the following two rows result in the same key, or would they both be considered unique and therefore allowed:

PRIMARY KEY (user_id, friend_id)

|-----------|-------------|
|  user_id  |  friend_id  |
|-----------|-------------|
|    10     |     283     |
|   1028    |      3      |
|-----------|-------------|

Now, I'm obviously no database expert, it's actually the first time I'm thinking about using composite keys (never had reason to before), so it might be something that "everyone" knows about or is just really easy to find in the documentation, but I've been unable to find an answer to it.

You expect the example above to work (logically, why shouldn't it? The separate values are certainly unique), but I just really want to be sure before I proceed with my project.

Was it helpful?

Solution

A PRIMARY KEY constraint is implemented by UNIQUE index on the involved columns plus NOT NULL constraints on all involved columns.

"Unique" means that the combination of all columns is unique. What you are worrying about is the concatenation of the textual representation of two values ('10' || '283') = ('1028' || '3') but that's not how composite types operate at all. All fields are considered separately and as values of the defined data types, not as text representations.

NULL values are never considered to be equal, but those are not allowed in pk columns.

The order of columns is relevant for performance. The accompanying composite index preferences the leading columns. More details in this closely related answer:
PostgreSQL composite primary key

OTHER TIPS

each unique constraint (including primary key constraints) demands that each row in the relation has a functional dependency on the projection to the attributes named in the constraint.

What that means is that, in your example,

user_id | friend_id
======= | =========
1       | 1
1       | 2
2       | 1
4       | 5

are all allowed; since no pair of <user_id, friend_id> occurs more than once. given the above, you could not have another <1, 1> because it would conflict with the first row.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top