Email address unique or primary key?

Let's first distinguish between keys and indexes, key is part of the logical model and is often implemented with an unique index. You can however create a unique index without creating a key, but that can not be referenced by a foreign key.

A candidate key is something that uniquely identifies a row in a table, in SQL one of the candidate keys are normally used as a primary key (I never really understood why one of the c.k. is concidered "better" than the others, but that's another story), and the remaining c.k becomes unique constraints.

A unique constraint can be used the same way as a primary key can. Consider:

create table A ( x ... not null
               , y ... not null
               , z ... not null
               ,     unique (x)
               ,     primary key (y,z) );

create table B ( x ...
               ,   ...
               ,     foreign key (x) references A (x) );

create table C ( y ...
               , z ...
               ,   ...
               ,     foreign key (y, z) references A (y, z) );  

B references the unique constraint and C references the primary key constraint.

NOT NULL is yet another kind of constraint. In your case you can enforce this for email without declaring it unique.

The next aspect of your post concerns the stability of a key, a key should be stable (but that doesn't mean it can never change, it does not have to be immutable). Some DBMS implements ON UPDATE CASCADE that can be of help for such operation, still if the key is distributed around your model it will be a pain updating it.

In your case I would probably choose another candidate key as the primary key, and declare email to be NOT NULL and UNIQUE.


Yes having a unique index on the EmailAddress column should be ok. The only problem would be if someone gave up the email address after signing up for your service but didn't tell you, then whoever the owner of the email address tries to sign up. But that's a pretty rare edge case.

As to if a Unique Index allows null values that'll depend on your database platform. Oracle does, SQL Server allows a single NULL value. You can solve this by making the column not allow NULL values, then building the unique index on it.


Having the unique index on EmailAddress is fine.

As you have already stated that there is validation in your application for having Email Address as required field, I would say as the other validation would be from database is not accept a user with out an Email address and prevent duplicate entry as well and these validation will be imposed with this Unique Index.

As stated in other answer for SQL Server you need to make a column not allow null value before building unique indexes.