Skip to main content
Last updated on

UUID Data Type

Description

UUID stores a 128-bit universally unique identifier in 16 bytes. Use it for identifiers that need compact storage, equality filtering, joins, or sorting. Text output always uses lowercase canonical form: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.

Syntax and input format

UUID
PropertyBehavior
StorageFixed 16-byte value; canonical text has 36 characters
Canonical input32 hexadecimal digits with hyphens in the 8-4-4-4-12 positions
Compact input32 hexadecimal digits without hyphens
Letter caseUppercase and lowercase hexadecimal digits are accepted; output is lowercase
Value range00000000-0000-0000-0000-000000000000 through ffffffff-ffff-ffff-ffff-ffffffffffff
ValidationChecks text format, without requiring a particular UUID version or variant
NULLSupported for nullable columns; the all-zero UUID is a valid value distinct from NULL
OrderingUnsigned 128-bit order in canonical byte order, equivalent to lexicographic order of normalized canonical text

Basic usage

CREATE DATABASE IF NOT EXISTS uuid_demo;
USE uuid_demo;

CREATE TABLE uuid_events (
id INT NOT NULL,
event_id UUID NULL,
generated_id UUID NOT NULL DEFAULT UUID_V7()
)
DUPLICATE KEY(id)
DISTRIBUTED BY HASH(id) BUCKETS 1
PROPERTIES ('replication_num' = '1');

INSERT INTO uuid_events (id, event_id) VALUES
(1, '550E8400E29B41D4A716446655440000'),
(2, '00000000-0000-0000-0000-000000000000'),
(3, NULL);

SELECT id, event_id, UUID_VERSION(generated_id) AS generated_version
FROM uuid_events ORDER BY id;
+----+--------------------------------------+-------------------+
| id | event_id | generated_version |
+----+--------------------------------------+-------------------+
| 1 | 550e8400-e29b-41d4-a716-446655440000 | 7 |
| 2 | 00000000-0000-0000-0000-000000000000 | 7 |
| 3 | NULL | 7 |
+----+--------------------------------------+-------------------+

Each omitted generated_id receives a generated value. Its exact text varies between executions.

SELECT id FROM uuid_events
WHERE event_id = CAST('550e8400-e29b-41d4-a716-446655440000' AS UUID);
+----+
| id |
+----+
| 1 |
+----+

Functions and conversion

FunctionResult and purpose
UUID_V4Native random UUID v4; aliases GENERATE_UUID_V4() and GENERATEUUIDV4()
UUID_V7Native UUID v7 containing a millisecond timestamp; aliases GENERATE_UUID_V7() and GENERATEUUIDV7()
UUID_VERSIONTINYINT version field (0–15), without validating the variant
TO_UUID_OR_NULLParse text; invalid text and NULL return NULL
TO_UUID_OR_ZEROParse text; invalid text returns the all-zero UUID, while NULL stays NULL
TO_UUID_OR_DEFAULTParse text; invalid text or NULL uses the supplied UUID fallback, defaulting to the all-zero UUID
UUID_V7_TO_DATETIMEExtract the timestamp as DATETIME(3) in a selected time zone
DATETIME_TO_UUID_V7Generate a UUID v7 from a date and time interpreted in the session time zone
UUIDExisting function returning VARCHAR, rather than the native UUID type

Use CAST(text AS UUID) to parse text and CAST(uuid AS STRING) for canonical output. With enable_strict_cast = true, invalid text raises an error; with it disabled, invalid text returns NULL. TRY_CAST(text AS UUID) returns NULL for invalid text in either mode. UUID and integer, floating-point, date/time, or IP types cannot be directly cast to each other. See UUID conversion for implicit conversion, VARIANT, and migration rules.

The existing IS_UUID() accepts some text, such as canonical UUIDs enclosed in braces, that the native parser rejects. Use TO_UUID_OR_NULL() or TRY_CAST to validate text for a UUID column.

Table design and restrictions

  • UUID columns can be keys in Duplicate, Unique, and Aggregate tables, hash distribution columns, and manual RANGE or LIST partition columns. Specify partition boundaries as quoted UUID text. Numeric-step batch range creation does not apply to UUID.
  • UUID values support comparison, IN, sorting, grouping, joins, MIN, MAX, and COUNT(DISTINCT ...). UUID is not a numeric type: arithmetic and numeric aggregates such as SUM and AVG are not supported.
  • Aggregate-table UUID value columns support MIN, MAX, REPLACE, and REPLACE_IF_NOT_NULL.
  • UUID can be an ARRAY element, a MAP key or value, or a STRUCT field. The existing constraints on the outer complex type still apply.
  • UUID supports prefix, ZoneMap, BloomFilter, and inverted indexes. For an inverted index, use equality/range lookup without a text parser. UUID does not support NGRAM_BF or vector indexes.
  • UUID cannot be an AUTO_INCREMENT column or a Sequence column.
  • At table creation, UUID columns support literal defaults and dynamic defaults UUID_V4() / UUID_V7(), including their aliases. Dynamic UUID defaults are only valid for UUID columns.
  • ALTER TABLE ADD COLUMN accepts a UUID literal default, but rejects UUID generator defaults because existing rows cannot be backfilled with independent persistent generated values. Directly changing another column type to UUID, or UUID to another type, is not supported by schema change. Create a new column/table and convert during insertion instead.

Loading, export, and clients

For CSV input, provide UUID text as a field; for JSON input, provide it as a JSON string or null. Both canonical and compact text are accepted. To choose a fallback explicitly, load the source as text and use one of the TO_UUID_OR_* functions in the column mapping.

Structured interfaces carry the 16-byte value rather than its text form: Arrow IPC and Arrow Flight SQL use the standard arrow.uuid extension over fixed_size_binary(16), and Parquet and ORC exports write the binary value together with type metadata. STRING columns are unaffected: a string that happens to contain UUID text is still transferred and exported as text.

Interface or formatUUID representation
MySQL protocolCanonical text; a client may report a string type even when the Doris column is UUID
Arrow Flight SQLNative UUID as the standard arrow.uuid extension over a 16-byte big-endian fixed_size_binary(16) value, including UUID elements nested in ARRAY, MAP, or STRUCT. With the Arrow Flight SQL JDBC driver, the column type is Types.OTHER, getObject() returns java.util.UUID, getString() returns canonical text, and getBytes() returns the 16 bytes
CSV, JSON, and Hive Text outputCanonical text; JSON represents UUID values as strings
OUTFILE / EXPORT to ParquetFIXED_LEN_BYTE_ARRAY(16) with the Parquet UUID logical annotation, in canonical big-endian byte order, including nested UUID elements. The file keeps the native type, but TVF schema inference still exposes UUID leaves as STRING/VARBINARY
OUTFILE / EXPORT to ORCBINARY with the Doris-specific doris.logical_type=uuid attribute, including nested UUID elements. ORC has no standard UUID type, so other tools see plain binary
Native Parquet UUID inputSupports the UUID logical annotation on FIXED_LEN_BYTE_ARRAY(16), in canonical big-endian byte order. TVF schema inference retains the existing STRING / VARBINARY mapping controlled by enable_mapping_varbinary; convert canonical STRING with CAST(value AS UUID), or raw VARBINARY with CAST(HEX(value) AS UUID)
ORC inputA BINARY column that carries the doris.logical_type=uuid attribute is read back as native UUID, including nested elements and in both ORC readers; the TVF reports uuid, array<uuid>, and struct<k:uuid> for such columns. Other ORC BINARY and STRING columns keep the existing STRING mapping
IcebergCatalog UUID mapping remains STRING / VARBINARY according to enable.mapping.varbinary. Both mappings preserve the 16 raw bytes; use CAST(HEX(value) AS UUID) to convert to native UUID. Writes to Iceberg UUID fields preserve the UUID logical annotation in Parquet
ClickHouse JDBC CatalogClickHouse UUID maps to native Doris UUID; earlier documented releases map it to STRING
Python UDFSQL UUID maps to uuid.UUID, and NULL maps to None, in scalar, vectorized (list and pandas.Series), aggregate, and table functions, including UUID elements nested in ARRAY, MAP, or STRUCT. A function that returns UUID must return a uuid.UUID object or None
Java UDFSQL UUID maps to java.util.UUID, including within supported complex types

Best practices

Use the native type when identifiers are UUIDs and 16-byte storage or UUID comparisons are useful. Normalize and validate existing string data before migration; keep text storage if original spelling or non-UUID identifiers must be preserved. Use UUID_V4() for random identifiers and UUID_V7() for identifiers with approximate time locality. Keep a separate date/time column for event-time filtering: distributed UUID v7 generation does not provide a global sequence or an exact event timestamp.