Какой тип столбца UUID наиболее эффективен?

15

Для хранения 128-битного UUID есть несколько вариантов хранения:

  1. байт [16] столбец
  2. два столбца bigint / long (64 бит)
  3. столбец CHAR (36) - 32 шестнадцатеричных числа + 4 тире.
  4. специфичный для базы данных столбец UUID, если db поддерживает его

С точки зрения индексации, какие из них наиболее эффективны? Если БД не поддерживает выделенный тип uuid, какие из 1, 2, 3 являются лучшими кандидатами?

Влад Михалча
источник
1
Это слишком «зависит» - много особенностей реализации.
Крейг Рингер,
2
Я бы никогда не выбрал 3: никогда не храню что-либо в 36 байтах, когда это можно сделать в 16. Я использую raw(16)в Oracle и uuidв PostgreSQL.
Colin 't Hart,
1
чем проще, тем лучше.
Акузминский
uuid>> bytea>> textс CHECKограничением> varchar(36)>> char(36). См. Dba.stackexchange.com/a/89433/3684 и dba.stackexchange.com/a/115316/3684 .
Эрвин Брандштеттер

Ответы:

15

Выделенный uuidтип - ваш лучший выбор для PostgreSQL. Трудно сказать с другими БД - для кого-то не исключено, что кто-то может реализовать uuidтип, который хранится менее эффективно, чем простой тип байта.

Опять же, в PostgreSQL, byteaбудет разумным способом хранить UUID, если у вас нет этого uuidтипа. Для других БД это зависит от того, как они хранят двоичные данные.

Там, где это возможно, я бы сильно избегал использования шестнадцатеричных черточек. Это гораздо менее эффективно сравнивать, сортировать и хранить.

Так что на самом деле, «не (2) или (3)». Когда-либо. Используйте (4), где поддерживается, (1) в противном случае.

Крейг Рингер
источник
Следует отметить, что тип UUID PostgreSQL не поддерживается изначально в массивах или это исправлено? postgresql.org/message-id/…
Кристоф Русси
@ChristopheRoussy Это с 2013 года. Это был незначительный недосмотр. SELECT ARRAY['ef1e0638-072e-4caa-88b3-97bfa5b2e8c3']::uuid[]
Крейг Рингер
3

В порядке предпочтения: 4,1,2,3 Не используйте UUID в качестве ключа кластеризации, если используется сервер SQL, поскольку он не только плохо фрагментируется, ключ кластеризации используется во всех некластеризованных индексах, и вы добавляете эти байты в каждая строка индекса. Фрагментация может быть уменьшена с помощью NEWSEQUENTIALID, но обычно предпочитает идентификацию bingint для вашего ключа кластеризации над GUID для предотвращения раздувания в других индексах.

Разница между выбором 1 вместо 2 будет зависеть от того, насколько более эффективно база данных обрабатывает два столбца базовых типов в одном столбце фиксированного массива. Это должно быть достаточно легко проверить с помощью фиктивных данных. Посмотрите на скорость ваших запросов, а также размер индексов и данных. Маленький + быстрый лучший!

GilesDMiddleton
источник
1

Можно было бы предположить, что любой тип данных с внутренней поддержкой будет лучше оптимизирован в продукте, чем что-либо, что может быть объединено в качестве клиента этого продукта. После этого все, что имеет наименьшее количество байтов, позволяет получить максимальное количество строк на странице.

Майкл Грин
источник
Верно, но имеет ли значение только размер байта? Разве тип не влияет на алгоритм индексации?
Влад Михалча,
@ Влад я использую SQL Server. AFAIK все типы данных обрабатываются одинаково при построении B-дерева (или хеш-индекса для 2104 в памяти). Есть веские причины, чтобы сделать это как можно более узким.
Майкл Грин