UUIDv7 в качестве идентификаторов сущностей (v0.0.0)

UUIDv7 в качестве идентификаторов сущностей (v0.0.0)

Что использовать в качестве идентификаторов сущностей - целочисленные значения или UUID-ы - достаточно давний спор.

У целочисленных значений следующие преимущества:

  1. Лучшая производительность вставки данных в БД относительно UUIDv4 - они монотонно возрастают соответственно B-дерево для индекса первичного ключа не надо постоянно перестраивать;

    1. Но UUIDv7 нивелировал это преимущество;

  2. Лучшая производительность генерации новых идентификаторов - добавить единицу к целому числу намного быстрее, чем сгенерировать случайное число;

  3. Меньший размер как в памяти и на диске (8 байт против 16), так и при передачи по сети (<19 байт против 36);

  4. Большая эргономичность - человеку проще работать со значением 23435, чем с f3f2e850-b5d4-11ef-ac7e-96584d5248b2. Плюс в большинстве приложений двойной клик по целочисленному идентификатору позволяет выбрать сразу весь идентификатор, в то время как клик по части UUID выбирает только её.

У UUID-ов же универсальные преимущества такие:

  1. Основное - они могут генерироваться на стороне клиента или хотя бы приложения, соответственно намного лучше горизонтально масштабируются, чем целочисленные идентификаторы, которые могут генерироваться только на стороне СУБД для того чтобы гарантировать уникальность;

  2. UUID-ы намного сложнее подобрать, чем целочисленное значение и в целом они дают меньше информации (например - по UUID невозможно оценить количество экземпляров идентифицируемого типа сущностей, а по целочисленным значениям - можно).

Кроме того, в контексте Эргономичного подхода у UUID-ов есть ещё два преимущества:

  1. Они позволяют при подготовке фикстуры теста разделить сборку графа сущностей фикстуры и сохранение этого графа в БД, что существенно упрощает код;

  2. При пакетной вставке они позволяют не полагаться на то, что СУБД вернёт сгенерированные идентификаторы в том же порядке, в каком были переданы INSERT-ы, что (в случае Postgres-а, по крайней мере) на деле соответствует действительности на данный момент, но не гарантируется СУБД и может измениться, породив очень неприятные баги.

Исходя из этого - используйте UUIDv7 в качестве идентификаторов сущностей.

В PostgreSQL поддержка UUIDv7 ожидается в 18 версии, пока что можно использовать третьестороннее расширение (на C) или скопировать одну из реализаций на pgsql.

В Kotlin поддержка UUIDv7 ожидается в версии 2.2, пока что можно скопировать одну из третьесторонних реализаций.