DatabaseStatusSyntax FamilyMin Version
PostgreSQL full sql-standard 15
MySQL partial - -
MariaDB partial - -
Oracle partial - -
SQL Server partial - -
SQLite partial - -
Redshift partial - -
DB2 partial - -
Snowflake partial - -
BigQuery none - -

Compare Databases

Database Details

PostgreSQL full
-- Default: multiple NULLs are allowed (NULLS DISTINCT)
CREATE TABLE users (
  id    INT PRIMARY KEY,
  email TEXT UNIQUE
);

-- PostgreSQL 15+: allow only one NULL
CREATE TABLE users (
  id    INT PRIMARY KEY,
  email TEXT UNIQUE NULLS NOT DISTINCT
);

-- Also works on a named constraint or index
CREATE UNIQUE INDEX idx_users_email
  ON users (email) NULLS NOT DISTINCT;
  • Pre-15: multiple NULLs always allowed.
  • 15+: NULLS NOT DISTINCT caps the column at one NULL. Also works on CREATE UNIQUE INDEX.
MySQL partial
-- Multiple NULLs are always permitted in a UNIQUE index
CREATE TABLE users (
  id    INT PRIMARY KEY,
  email VARCHAR(255) UNIQUE
);
INSERT INTO users (id, email) VALUES (1, NULL);
INSERT INTO users (id, email) VALUES (2, NULL); -- succeeds
  • Multiple NULLs always allowed; no knob to change it.
MariaDB partial
-- Same as MySQL: multiple NULLs always allowed
CREATE TABLE users (
  id    INT PRIMARY KEY,
  email VARCHAR(255) UNIQUE
);
  • Same as MySQL: multiple NULLs always allowed, no knob.
Oracle partial
-- Multiple NULLs are always allowed
CREATE TABLE users (
  id    NUMBER PRIMARY KEY,
  email VARCHAR2(255) UNIQUE
);

-- Workaround: unique function-based index that treats NULLs as a sentinel
CREATE UNIQUE INDEX idx_users_email_nn
  ON users (CASE WHEN email IS NOT NULL THEN email END);
  • Multiple NULLs always allowed. To emulate NULLS NOT DISTINCT, build a function-based index that maps NULL to a sentinel, e.g. CASE WHEN col IS NULL THEN 0 ELSE 1 END.
SQL Server partial
-- SQL Server UNIQUE allows at most one NULL per column
CREATE TABLE users (
  id    INT PRIMARY KEY,
  email NVARCHAR(255) UNIQUE
);

-- Workaround: filtered unique index allows many NULLs while enforcing uniqueness on non-NULL values
CREATE UNIQUE INDEX idx_users_email
  ON users (email)
  WHERE email IS NOT NULL;
  • Default is one NULL allowed per column — the opposite of SQL:2003.
  • CREATE UNIQUE INDEX ... WHERE col IS NOT NULL gives many NULLs plus unique non-NULLs.
SQLite partial
-- Multiple NULLs are always allowed
CREATE TABLE users (
  id    INTEGER PRIMARY KEY,
  email TEXT UNIQUE
);
  • Multiple NULLs always allowed. Use CREATE UNIQUE INDEX ... WHERE col IS NOT NULL for NULLS NOT DISTINCT-style behavior.
Redshift partial
  • UNIQUE isn't enforced; NULL handling is moot.
DB2 partial
-- Multiple NULLs allowed; Db2 treats NULL as distinct in UNIQUE indexes
CREATE TABLE users (
  id    INTEGER NOT NULL PRIMARY KEY,
  email VARCHAR(255) UNIQUE
);
  • Multiple NULLs always allowed. For strict single-value uniqueness, make the column NOT NULL.
Snowflake partial
  • UNIQUE isn't enforced; NULL handling is moot.
BigQuery none
  • No UNIQUE syntax at all.