Database guide

Generate UUIDs in SQL Server, PostgreSQL and MySQL

Use UUIDs in SQL databases with practical notes for PostgreSQL, SQL Server, MySQL and indexing.

Use NEWID() in SQL Server, gen_random_uuid() in PostgreSQL, or UUID() in MySQL to generate an identifier in SQL. These functions are not interchangeable: check the generated version, column type and engine’s index ordering before choosing a default.

Key takeaways

  • Use native UUID types when your database supports them.
  • Think about insert order before choosing UUID v4 for huge tables.
  • Keep public identifiers and internal storage choices separate when needed.

For implementation context, continue with Database Guide, UUID v7, and UUID vs GUID. These pages cover the closest generator, comparison, validation or storage decisions without repeating this guide.

Generate UUIDs in PostgreSQL with a column default

Use the native uuid type and let a column default generate the ID when an INSERT omits it. gen_random_uuid() is built in from PostgreSQL 13 and produces UUID v4; older installations need an appropriate extension.

CREATE TABLE accounts (
  id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  email text NOT NULL UNIQUE,
  created_at timestamptz NOT NULL DEFAULT now()
);

INSERT INTO accounts (email) VALUES ('developer@example.com')
RETURNING id;

Generate a UUID in SQL Server with NEWID()

SQL Server calls UUID values GUIDs and stores them in uniqueidentifier columns. SELECT NEWID() returns a new value. A DEFAULT NEWID() constraint generates the ID for an INSERT that omits the column.

This example makes the random GUID primary key nonclustered. Choose a clustering strategy separately for your workload; a random clustered key can distribute inserts across many index pages.

SELECT NEWID() AS GeneratedGuid;

CREATE TABLE dbo.Events (
  Id uniqueidentifier NOT NULL
    CONSTRAINT DF_Events_Id DEFAULT NEWID(),
  Name nvarchar(200) NOT NULL,
  CreatedAt datetime2 NOT NULL
    CONSTRAINT DF_Events_CreatedAt DEFAULT SYSUTCDATETIME(),
  CONSTRAINT PK_Events PRIMARY KEY NONCLUSTERED (Id)
);

INSERT INTO dbo.Events (Name)
OUTPUT inserted.Id
VALUES (N'Example event');

NEWID() vs NEWSEQUENTIALID() in SQL Server

NEWSEQUENTIALID() is an alternative for a uniqueidentifier column default when local insertion order is useful. It cannot be called as SELECT NEWSEQUENTIALID(). Its ordering can change after restarts or moves between hosts, and it is not the UUID v7 algorithm.

Sequential GUIDs can expose ordering information. Compare them with a separate numeric clustering key and a random public UUID before choosing an index design.

CREATE TABLE dbo.SequentialEvents (
  Id uniqueidentifier NOT NULL DEFAULT NEWSEQUENTIALID()
    PRIMARY KEY CLUSTERED,
  Name nvarchar(200) NOT NULL
);

INSERT INTO dbo.SequentialEvents (Name)
OUTPUT inserted.Id
VALUES (N'Example event');

Store a UUID in MySQL as BINARY(16)

In MySQL 8, UUID_TO_BIN() and BIN_TO_UUID() convert between display text and a 16-byte value. MySQL UUID() creates a version 1 UUID; generate v4 or v7 in your application if you need those layouts.

This example imports a sample v4 value with no byte swapping. The optional swap flag is intended for the time fields in v1; do not apply that convention automatically to v4 or v7. Always use the same conversion convention on write and read.

CREATE TABLE fixtures (
  id BINARY(16) PRIMARY KEY,
  label VARCHAR(100) NOT NULL
);

INSERT INTO fixtures (id, label) VALUES (
  UUID_TO_BIN('4f8b1a9a-7c2d-4a59-9b9f-1c2d2f7e5a01'), 'Sample'
);

SELECT BIN_TO_UUID(id) AS uuid, label FROM fixtures;

Generate UUID v7 in PostgreSQL 18 and later

PostgreSQL 18 adds a built-in uuidv7() function. In older releases, generate v7 in the application or use an extension verified for your database version. The uuid column type can store both v4 and v7.

-- PostgreSQL 18+
SELECT uuidv7();

UUID v4 vs UUID v7 for indexes

UUID v4 values arrive in random order. UUID v7’s timestamp prefix can improve locality when the database compares values in that order. SQL Server uniqueidentifier ordering differs from ordinary UUID byte order, so do not assume a v7 GUID gives the same index behavior in every engine.

That does not mean every table needs UUID v7. Small tables, low-write systems and public identifiers with sensitive timing concerns may still be fine with UUID v4.

FAQ

Generate UUIDs in SQL Server, PostgreSQL and MySQL questions

How do I generate a UUID in SQL Server?

Run SELECT NEWID(). For automatic row IDs, add DEFAULT NEWID() to a uniqueidentifier column and omit that column in the INSERT. Use OUTPUT inserted.Id to retrieve the generated GUID.

Can I use NEWSEQUENTIALID() in a SELECT?

No. SQL Server permits NEWSEQUENTIALID() in a DEFAULT constraint on a uniqueidentifier column. Insert a row using that default and retrieve its identifier with OUTPUT.

Should a UUID primary key be text?

Use a native UUID type when available. Use text only when the database or toolchain does not support a better UUID representation.

Are UUIDs bad for database performance?

Not automatically. Random UUID v4 values can be harder on some indexes at scale, while ordered choices such as UUID v7 can reduce that pain.

Can SQL Server store UUIDs?

Yes. SQL Server stores GUID values with the uniqueidentifier type.

Primary references

Standards and technical sources

The implementation and guidance on this page are checked against these standards and platform documentation sources.

Generate UUID in SQL - SQL Server, PostgreSQL and MySQL