Is it possible to use UUID values as a primary key in SQLite? I'm finding extremely limited information on the topic, so I'm not sure if SQLite even supports a UUID data type. Should I be storing a UUID as a string?
5 Answers
CL's answer is correct but kind of skirts the issue at hand. As mentioned, a column (or multiple columns) of any type can be used as a primary key. So you could store the UUID as a formatted, human-readable string and make that your table's key. And since a UUID is just a 128-bit integer, you could also store the integer's bytes as a BLOB, which saves space and might be slightly faster.
But to more directly answer what I believe is the question at hand, no, SQLite does not have any features that directly support UUID's. When SQLite creates a table, it uses a column's declared type to determine which of the five underlying storage classes (integer, real, text, blob or null) it will use. After the table is created, a column's type isn't used and the column's behavior is determined entirely by its storage class. There are no UUID-specific column types or storage classes. There also don't seem to be any functions available for converting to and from a formatted UUID string. To get your UUID's bytes, you'll want to see what methods are provided by the language your application is written in. For example, Java's UUID class, Apple's NSUUID, or Swift's UUID.

- 8,931
- 5
- 60
- 66

- 6,524
- 7
- 52
- 65
SQLite allows to use any data type as primary key.
UUIDs can be stored either as strings (which are human-readable) or as 16-byte BLOBs (which might be faster if the records are so small that the difference matters).

- 173,858
- 17
- 217
- 259
-
Are either of those data types more efficient than the other for storing UUIDs? – Mike Baxter Jun 24 '13 at 14:48
-
5For other readers… the human-readable 36-character hex string looks like this: `988097c8-3f9c-4ecf-9d1d-64701bb9764c` – Basil Bourque Feb 25 '14 at 00:36
-
7UUID BLOB vs TEXT matters the file size, however, the speed of insert and query is about the same, see http://stackoverflow.com/a/11337522/254109 – xmedeko Mar 23 '16 at 15:18
There is now an extension for sqlite that creates valid uuids as per https://sqlite.org/src/file/ext/misc/uuid.c

- 411
- 3
- 7
-
1
-
4a bit fiddly.. see here for details https://www.sqlite.org/loadext.html#:~:text=An%20SQLite%20extension%20is%20a,using%20the%20sqlite3_load_extension()%20API. – DrGo Dec 07 '21 at 17:00
-
1After downloading the file, `gcc -g -fPIC -dynamiclib uuid.c -o uuid.c.dylib` You can then in sqlite3 `SELECT load_extension('uuid.c');` – zvxr Jan 07 '23 at 17:58
I needed an implementation for UUID in sqlite, since it's not a native feature, so here is a trick that I came across in the internet.
SQLite doesn't support UUID, so the idea is to create a function that would generate a UUID using the randomblob()
function
select lower(hex( randomblob(4)) || '-' || hex( randomblob(2))
|| '-' || '4' || substr( hex( randomblob(2)), 2) || '-'
|| substr('AB89', 1 + (abs(random()) % 4) , 1) ||
substr(hex(randomblob(2)), 2) || '-' || hex(randomblob(6)))
This will ensure that you will have a UUID that can be stored in your table as varchar
, so now to implement it. SQLite doesn't store functions, so you can use a trigger that can be called once a new record is inserted in your table
CREATE TABLE UUID_TABLE(
id varchar(500),
name varchar(500) NOT NULL,
CONSTRAINT name_unique UNIQUE (name),
CONSTRAINT rid_pkey PRIMARY KEY (id)
);
and the trigger
CREATE TRIGGER AutoGenerateGUID_RELATION_3
AFTER INSERT ON UUID_TABLE
FOR EACH ROW
WHEN (NEW.relation_id IS NULL)
BEGIN
UPDATE UUID_TABLE SET relation_id = (select lower(hex( randomblob(4)) || '-' || hex( randomblob(2))
|| '-' || '4' || substr( hex( randomblob(2)), 2) || '-'
|| substr('AB89', 1 + (abs(random()) % 4) , 1) ||
substr(hex(randomblob(2)), 2) || '-' || hex(randomblob(6))) ) WHERE rowid = NEW.rowid;
END;
So whenever a new row is inserted, by default a NULL value will be affected to the id, and after that the trigger will modify it to a new UUID value stored as varchar.
Solution inspired from: solution source

- 880
- 1
- 9
- 22
-
5what I meant is that UUID is not defined as a data type in sqlite , check this https://www.sqlite.org/datatype3.html The accepted answer suggest that UUID can be stored as a string in sqlite. Unlike postgresql that support UUID as a datatype, thing that can help you to generate UUID automatically – Idhem Apr 02 '20 at 20:47
-
1@NicoHaase that accepted answer literally says: UUIDs can be stored as strings or as blobs. I.e.: there is no first-class support of UUIDs in sqlite. There are many ways to inerpret what kaygi22 said, but you can reasonably interpret it as being sensible. – hraban Jan 15 '21 at 21:05
-
For large volumes of small records, storing UUIDs as strings will take up a disproportionate amount of storage - it probably isn't optimal for indices either. I expect you could do better by storing 128-bit (16-byte) blobs, using a similar technique, but with bitwise operators to create valid UUID v4 bits - and then convert to/from formatted strings in your client layer. – mindplay.dk Jan 11 '22 at 16:25
Not sure about using it as default field, but if someone needs to generate unique value in sqlite query following approach suggested here can be used:
The randomblob(N) function return an N-byte blob containing pseudo-random bytes. If N is less than 1 then a 1-byte random blob is returned. Hint: applications can generate globally unique identifiers using this function together with hex() and/or lower() like this:
hex(randomblob(16))
or
lower(hex(randomblob(16)))

- 1,341
- 22
- 29
-
15UUID is not a `randomblob(16)`, see http://stackoverflow.com/a/22725697/254109 If you do not need exact UUID, then `randomblob` is sufficient. – xmedeko Mar 23 '16 at 15:20
-
12