SQL: Null in Unique Constraints
Welcome to the Null in Unique Constraints lesson!
This lesson is shown as static text below. However, it's designed to be used interactively. Click the button below to start!
What happens if there are
NULLs in a column with aUNIQUEconstraint? At first glance, here's what you might expect: oneNULLis allowed, but multipleNULLs will violate theUNIQUEconstraint. But that would make some things very difficult in practice. Here's an example:Suppose that we have a
userstable with anemailcolumn, which has aUNIQUEconstraint. Some users will register with a third-party authentication system like Google's, Twitter's, or GitHub's. Those users will have aNULLemail address column.If a
UNIQUEconstraint only allowed oneNULL, then only one user would be allowed to register with those third-party authentication systems. After that, all further registration attempts would violate theUNIQUEconstraint.For exactly this reason,
UNIQUEhas special behavior forNULL.NULLvalues are effectively ignored by aUNIQUEconstraint.(In the following examples, you can answer with
errorif a query will result in an error. Queries likeINSERTandCREATEthat return no rows will have a return value of[].)>
exec(`CREATE TABLE users (email TEXT NULL UNIQUE)`);exec(`INSERT INTO users (email) VALUES ('amir@example.com')`);exec(`INSERT INTO users (email) VALUES ('betty@example.com')`);Result:
[]
>
exec(`CREATE TABLE users (email TEXT NULL UNIQUE)`);exec(`INSERT INTO users (email) VALUES (NULL)`);exec(`SELECT * FROM users`);Result:
[{email: null}]>
exec(`CREATE TABLE users (email TEXT NULL UNIQUE)`);exec(`INSERT INTO users (email) VALUES ('amir@example.com')`);exec(`INSERT INTO users (email) VALUES ('amir@example.com')`);Result:
Error: UNIQUE constraint failed: users.email
>
exec(`CREATE TABLE users (email TEXT NULL UNIQUE)`);exec(`INSERT INTO users (email) VALUES (NULL)`);exec(`INSERT INTO users (email) VALUES (NULL)`);exec(`SELECT * FROM users`);Result:
[{email: null}, {email: null}]Sometimes, language quirks are mistakes: a language designer might not anticipate problems with the language they've designed. This
NULL/UNIQUEbehavior is a quirk, but it's not a language design mistake. It's an intentional choice that allows us to build databases like the one above.