Making the primary key both CountryId
and Name
does not ensure the names are unique. It just ensures that each CountryId
-Name
pair is unique, and obviously CountryId
is already unique, being an "ID". So you could still have, for example, 1-US
and 19-US
, as the pairs are unique.
The only reason to make them both the primary key is if you will be frequently executing queries where both CountryId and Name are used in the Where clause. The primary key by default creates a clustered index, which physically sorts the table, so it makes lookups for rows against those predicates very fast.
Another important point to raise is that in your particular example, you are storing a list of countries which is a) very short and b) doesn't change much. Lookups against this table are going to be extremely fast no matter what you do. Even if SQL Server has to do a full table scan every time, you probably won't even notice. You don't have to worry about page fragmentation. You could just skip the ID column and use the Name
as a primary key.
Or, if you want to keep an ID but also enforce uniqueness of just the country names, you can put a Unique Constraint on the Name column.
It is difficult to cover the issue of primary keys, clustered indexes, and indexes in general, in too much depth in a single answer. Here are a few good resources to get started: