Paul Sturrock wrote:Even better is not to use a composite id at all, since these tend to just be extra complications of indeterminate value. Use a surrogate key and a unique index, this way your primary key has all the assurances a primary key should have (unchanging, unique, not null) and your SQL is less complex.
Surrogates have their drawbacks too. For example, with composite foreign key some joins might be avoided if the query can be answered with data from the child table only.
In some databases surrogates might prevent some optimizations from happening. In Oracle better partition pruning can be achieved if the parent and child table are partitioned on the primary/foreign key in the same way. Oracle is also able to eliminate some tables from complex queries altogether without your intervention, if it can answer the question from the rest of the tables. Using surrogates everywhere reduces the possibilities of such optimizations (intermediate table that might be otherwise eliminated is needed to resolve the surrogates). These optimizations are completely transparent to the application. Of course, in other databases things might be different.
Moreover, if you ever have to inspect data in the table manually, seeing the real values instead of surrogates is much better. True, this can be easily avoided using views that do the join and show real values instead of surrogates, but then you have to maintain these views.
The complexities of the SQL with composite keys generally boil down to having to specify multiple columns in the join clauses. I'm personally well with two- or three-column composite keys. I'd hesitate creating composite key from four or more columns, because the data model would look suspicious to me. In short, there are usually pros and cons everywhere, including surrogates.
Of course, if there is a possibility that the key might be mutable, then surrogate should definitely be used. However this is true regardless of whether the key is composite or not.