Re: id integer vs uuid
От: BlackEric http://black-eric.lj.ru
Дата: 19.08.22 14:35
Оценка: 12 (1) +3
Здравствуйте, vsb, Вы писали:

vsb>Наверное набивший оскомину вопрос, извините.


vsb>У каждой таблицы с данными должен быть синтетический ключ id. Ссылки на эту таблицу должны быть по этому ключу.


UUID, т.к. int при репликации и генерации на клиенте создает много проблем.
https://github.com/BlackEric001
Re: id integer vs uuid
От: wildwind Россия  
Дата: 19.08.22 16:41
Оценка: 3 (1) +1
Здравствуйте, vsb, Вы писали:

vsb>Разница в производительности на больших объёмах вставок тоже объективно будет. Вариант 2.2 собственно только ради этого и придумывался.


Не только на вставках, но и на последующих выборках.

vsb>3. Запросы order by id. Понятно, что обычно есть что-то вроде created_at, но всё равно удобно иметь возможность упорядочить строки в порядке создания, переиспользуя уже существующий индекс.


vsb>4. Читабельность. Ну тут целые числа однозначно приятней глазу, чем UUID.


Если нужен читабельный пользователями ID, лучше завести отдельный ключ, отличный от PK. Даже если PK это такой же int.

vsb>5. Безопасность.

vsb>Однако с вариантом 2.3 с безопасностью есть нюансы — утекает timestamp так или иначе.

И 2.2 и 2.3 можно перебирать/подбирать. Чуть сложнее, чем 1, но вполне успешно. Если нужно защититься от подбора, опять же заводим отдельный ключ, видимый "извне".

vsb>Также есть проблема с реализацией вариантов 2.2 и 2.3, это не слишком часто используемые подходы и возможно придется использовать редкие библиотеки или писать самому. Это не великая проблема, но всё же.


Не вижу проблемы. Библиотек полно, и все современные ОС предоставляют подобный сервис.

vsb>Я сейчас работаю над best practices, которыми будем руководствоваться в будущем для создания сервисов. И нужно этот вопрос решить. Плюсы и минусы там и там есть. Скорей склоняюсь к UUID 2.3, т.к. считаю, что проблемы с производительностью будут малозаметны, а удобство читаемых id не перевешивает плюсов UUID.


Главное помнить, что best practices это не догмы, а рекомендации. Подходы вполне можно совмещать, даже в рамках одной БД.
Таблицы-справочники, меняющиеся раз в год, и таблицы-перечисления, на которые ссылается полбазы, вполне могут жить с целочисленными ключами. Особенно если ключи укладываются, скажем, в байт. Проблемы генерации ключа на клиенте (раз в год) их не касаются.
Re: id integer vs uuid
От: Anton Batenev Россия https://github.com/abbat
Дата: 20.08.22 08:28
Оценка: 8 (1)
Здравствуйте, vsb, Вы писали:

vsb> Наверное набивший оскомину вопрос, извините.


Если сервис будет работать больше чем на localhost, то глобально монотонно возрастающий UUID (нечастые промахи в хвосте последовательности допустимы). Других вариантов нет.
Re: id integer vs uuid
От: Alex.Che  
Дата: 19.08.22 15:15
Оценка: :)
реферат на тему?
Re: id integer vs uuid
От: Pzz Россия https://github.com/alexpevzner
Дата: 22.08.22 18:33
Оценка: +1
Здравствуйте, vsb, Вы писали:

vsb>Я сейчас работаю над best practices, которыми будем руководствоваться в будущем для создания сервисов. И нужно этот вопрос решить. Плюсы и минусы там и там есть. Скорей склоняюсь к UUID 2.3, т.к. считаю, что проблемы с производительностью будут малозаметны, а удобство читаемых id не перевешивает плюсов UUID. Заранее спасибо за конструктивные отзывы.


У тебя в разделе про UUID есть пункты 2.1, еще раз 2.1 и 2.2, а ты ссылаешься на 2.3.

UUID прекрасен тем, что его можно генерировать случайно, и вероятность коллизий очень мала. Если тебе кажется, что 128 бит недостаточно, с легкостью можно подняться до 160-и или 256-и (что, правда, не увеличит читабельности).

В некоторых случаях бывает полезен еще такой вариант, вычислять ID как криптохеш от содержимого записи. Конечно, должен существовать способ однозначным образом представить это содержимое в виде последовательности байт, от которых, собственно, и вычисляется хеш, чтобы разные записи не совпадали а одинаковые не давали разных ID.
id integer vs uuid
От: vsb Казахстан  
Дата: 19.08.22 14:27
Оценка:
Наверное набивший оскомину вопрос, извините.

У каждой таблицы с данными должен быть синтетический ключ id. Ссылки на эту таблицу должны быть по этому ключу.

Два основных подхода:

1. Использовать целочисленный ключ (обычно 1, 2, 4, 8 байтов в зависимости от предполагаемого числа строк), который генерируется в виде глобально возрастающего значения.

2. Использовать 128-битный UUID.

2.1. Генерировать UUID случайным образом.

2.2. Генерировать UUID в виде локально возрастающей последовательности (она возрастает, но может в какой-то момент "переполняться").

2.3. Генерировать UUID в виде глобально возрастающей последовательности (для простоты можно считать, что левые 64 бита это timestamp, правые 64 бита случайны).

На что это влияет:

1. Чем меньше байтов, тем быстрей оно работает. Ну это, наверное, очевидно. И читать меньше и памяти меньше занимает и кешей меньше требует и индексы меньше, и промахов меньше. Разница между типичным 4-байтовым целым и 16-байтовым UUID в 4 раза. Понятно, что упереться в производительность в этом месте — надо постараться, с другой стороны вопрос про то, что будет в каждой таблице, так что какая-то доля процента производительности тут объективно будет.

2. Возрастающие значения в индекс ложатся гораздо быстрей, чем случайные. Возрастающие просто в конец узла B-дерева добавляются, изредка его немного перестраивая. Дерево компактное. Случайные значения летят в случайные узлы, дерево будет более "разбитое". Разница в производительности на больших объёмах вставок тоже объективно будет. Вариант 2.2 собственно только ради этого и придумывался.

3. Запросы order by id. Понятно, что обычно есть что-то вроде created_at, но всё равно удобно иметь возможность упорядочить строки в порядке создания, переиспользуя уже существующий индекс.

4. Читабельность. Ну тут целые числа однозначно приятней глазу, чем UUID.

5. Безопасность. В некоторых сценариях UUID хорош тем, что его нельзя перебирать. Обычно для таких сценариев делают отдельный столбец с UUID, если в базе id целочисленный, но иметь этот столбец уже готовым удобней. Также, когда внешние идентфикаторы всегда UUID, это в целом безопасней, т.к. про безопасность отдельных эндпоинтов не всегда люди думают, тут оно "нахаляву". Однако с вариантом 2.3 с безопасностью есть нюансы — утекает timestamp так или иначе.

6. Генерация ID на стороне клиента. Порой это бывает удобно. Я бы сказал, это вообще всегда удобно. Генерация ID на стороне сервера накладывает достаточно ощутимые ограничения на используемые протоколы и во многих случаях усложняет код.

7. Распределённая БД. К примеру у нас есть древовидная структура БД, когда в каждом филиале стоит отдельная БД (для возможности автономной работы) и данные уходят в центральную БД. В случае UUID всё выглядит гораздо проще. В случае id нужно думать чуть больше.

8. Совпадения id для разных сущностей. К примеру можно сделать join по неправильному полю. Если id не совпадают, запрос ничего не вернёт, что вероятно насторожит и не даст багу идти дальше. В противном случае может вернуться бессмысленный, но ненулевой результат.

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

Я сейчас работаю над best practices, которыми будем руководствоваться в будущем для создания сервисов. И нужно этот вопрос решить. Плюсы и минусы там и там есть. Скорей склоняюсь к UUID 2.3, т.к. считаю, что проблемы с производительностью будут малозаметны, а удобство читаемых id не перевешивает плюсов UUID. Заранее спасибо за конструктивные отзывы.
Отредактировано 22.08.2022 20:01 vsb . Предыдущая версия . Еще …
Отредактировано 19.08.2022 14:33 vsb . Предыдущая версия .
Отредактировано 19.08.2022 14:31 vsb . Предыдущая версия .
Отредактировано 19.08.2022 14:30 vsb . Предыдущая версия .
Re: id integer vs uuid
От: Sharov Россия  
Дата: 19.08.22 15:07
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Наверное набивший оскомину вопрос, извините.


Еще бы -- http://rsdn.org/forum/flame.comp/7911173.1
Автор: Ватакуси
Дата: 23.12.20
Кодом людям нужно помогать!
Re[2]: id integer vs uuid
От: vsb Казахстан  
Дата: 19.08.22 17:08
Оценка:
Здравствуйте, wildwind, Вы писали:

vsb>>4. Читабельность. Ну тут целые числа однозначно приятней глазу, чем UUID.


W>Если нужен читабельный пользователями ID, лучше завести отдельный ключ, отличный от PK. Даже если PK это такой же int.


Речь про читабельность для программиста/админа. Например я могу сделать select, увидеть там id=12762 и без копипаста напечатать его же в следующем запросе. С UUID это невозможно.

W>И 2.2 и 2.3 можно перебирать/подбирать. Чуть сложнее, чем 1, но вполне успешно.


Сомневаюсь. Даже 32 бита ты не переберёшь, тебя задолго до этого забанит чего-нибудь. В общем это не то, что обычно понимают под перебором.

vsb>>Также есть проблема с реализацией вариантов 2.2 и 2.3, это не слишком часто используемые подходы и возможно придется использовать редкие библиотеки или писать самому. Это не великая проблема, но всё же.


W>Не вижу проблемы. Библиотек полно, и все современные ОС предоставляют подобный сервис.


Ну приведи пример для postgres. Что за современные ОС, у меня alpine linux, что за сервис ты имеешь в виду?

W>Главное помнить, что best practices это не догмы, а рекомендации. Подходы вполне можно совмещать, даже в рамках одной БД.

W>Таблицы-справочники, меняющиеся раз в год, и таблицы-перечисления, на которые ссылается полбазы, вполне могут жить с целочисленными ключами. Особенно если ключи укладываются, скажем, в байт. Проблемы генерации ключа на клиенте (раз в год) их не касаются.

В моём понимании смысл best practices в том, чтобы не отходить от них без существенных причин. Поэтому таблицы справочники точно будут с UUID в такой модели, по крайней мере я не вижу ни одной причины исключать их. А использовать там однобайтовые идентификаторы это каноничный premature optimization, который с очень ощутимой вероятностью выстрелит лет через 5, когда придётся делать миграцию половины таблиц на более широкий тип. Но в целом, конечно, согласен, если очень надо — без проблем, это не догма.
Отредактировано 19.08.2022 17:11 vsb . Предыдущая версия .
Re[3]: id integer vs uuid
От: BlackEric http://black-eric.lj.ru
Дата: 19.08.22 17:17
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Здравствуйте, wildwind, Вы писали:


vsb>>>4. Читабельность. Ну тут целые числа однозначно приятней глазу, чем UUID.


W>>Если нужен читабельный пользователями ID, лучше завести отдельный ключ, отличный от PK. Даже если PK это такой же int.


vsb>Речь про читабельность для программиста/админа. Например я могу сделать select, увидеть там id=12762 и без копипаста напечатать его же в следующем запросе. С UUID это невозможно.


Это вообще не аргумент. Профессионалы могут и скопировать или же просто дописать запрос.
https://github.com/BlackEric001
Re[4]: id integer vs uuid
От: vsb Казахстан  
Дата: 19.08.22 17:20
Оценка:
Здравствуйте, BlackEric, Вы писали:

BE>Это вообще не аргумент. Профессионалы могут и скопировать или же просто дописать запрос.


Для меня аргумент. Ещё вариант — саппорт скинул фотографию с телефона интерфейса, на котором видно ID в URL-е, который мне нужно. Да много такого. Соглашусь, что не самый веский аргумент.
Re[3]: id integer vs uuid
От: wildwind Россия  
Дата: 19.08.22 18:01
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Сомневаюсь. Даже 32 бита ты не переберёшь, тебя задолго до этого забанит чего-нибудь. В общем это не то, что обычно понимают под перебором.


Опытным путем определяется алгоритм генерации, его входные данные. Если повезет, даже конкретная библиотека. Дальше дело техники.


vsb>Ну приведи пример для postgres. Что за современные ОС, у меня alpine linux, что за сервис ты имеешь в виду?


С первой страницы поиска:

https://github.com/tvondra/sequential-uuids
https://pkgs.alpinelinux.org/package/edge/main/x86/libuuid
Re[4]: id integer vs uuid
От: vsb Казахстан  
Дата: 19.08.22 18:31
Оценка:
Здравствуйте, wildwind, Вы писали:

vsb>>Сомневаюсь. Даже 32 бита ты не переберёшь, тебя задолго до этого забанит чего-нибудь. В общем это не то, что обычно понимают под перебором.


W>Опытным путем определяется алгоритм генерации, его входные данные. Если повезет, даже конкретная библиотека. Дальше дело техники.


Ну определил ты, что 48 битов заполняются текущим временем, 80 битов заполняется случайными значениями, чего дальше? 80 битов будешь подбирать?

vsb>>Ну приведи пример для postgres. Что за современные ОС, у меня alpine linux, что за сервис ты имеешь в виду?


W>С первой страницы поиска:


W>https://github.com/tvondra/sequential-uuids


Плохая библиотека, нужна функция без параметров и не перекручивающаяся. Звёзд мало, проблем мало, релизов мало.

W>https://pkgs.alpinelinux.org/package/edge/main/x86/libuuid


https://linux.die.net/man/3/libuuid ? Тут ничего нет про возрастающие значения, это обычный uuid.

Да ладно, уж как-нибудь сгенерировать 128 битов я смогу без библиотек, я не из того поколения, которым нужен left-pad, чтобы пробелы почистить. Это так, к слову больше было.
Отредактировано 19.08.2022 18:37 vsb . Предыдущая версия .
Re: id integer vs uuid
От: Нomunculus Россия  
Дата: 20.08.22 09:44
Оценка:
Здравствуйте, vsb, Вы писали:

Вообще не обязательно такой длинный как UUID, там вроде 38 символов или типа того.
Я обычно генерю UUID и беру первые 7-9 символов. Для уникальности хватает за глаза. И вполне читаемо
Re[2]: id integer vs uuid
От: Sharov Россия  
Дата: 22.08.22 16:26
Оценка:
Здравствуйте, wildwind, Вы писали:

W>Если нужен читабельный пользователями ID, лучше завести отдельный ключ, отличный от PK. Даже если PK это такой же int.


А в чем смысл? Чем один int лучше другого?
Кодом людям нужно помогать!
Re[3]: id integer vs uuid
От: fmiracle  
Дата: 22.08.22 20:15
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>В моём понимании смысл best practices в том, чтобы не отходить от них без существенных причин. Поэтому таблицы справочники точно будут с UUID в такой модели, по крайней мере я не вижу ни одной причины исключать их.


А мне понравилась идея.

Причины тут те же самые, что ты описал выше, только только для справочников у них веса другие
Т.е. выборка типа
select * from orders where statusId = 2 and cityId=678
(где "2" — это "открыт" а город 678 это Питер и аналитик/саппорт это прекрасно помнит уже)

такая может быть куда чаще требоваться в анализе данных, чем выборка по id собственно заказа и полезно что она может быть записана наглядно и быстро. Т.е. "плохая читабельность" для справочников более большая проблема, чем для таблиц данных, а польза от удобной распределенной генерации для них совершенно несущественна.

При этом проблемы расхода места и памяти для них вполне актуальны, т.к. поля со значением из справочника в таблице очень даже часто индексируются, а более компактный индекс лучше чем менее компактный.
Отредактировано 22.08.2022 20:17 fmiracle . Предыдущая версия .
Re[2]: id integer vs uuid
От: GarryIV  
Дата: 22.08.22 20:19
Оценка:
Здравствуйте, Нomunculus, Вы писали:

Н>Вообще не обязательно такой длинный как UUID, там вроде 38 символов или типа того.

Н>Я обычно генерю UUID и беру первые 7-9 символов. Для уникальности хватает за глаза. И вполне читаемо

A UUID (Universal Unique Identifier) is a 128-bit value

WBR, Igor Evgrafov
Re[2]: id integer vs uuid
От: fmiracle  
Дата: 22.08.22 20:35
Оценка:
Здравствуйте, Нomunculus, Вы писали:

Н>Вообще не обязательно такой длинный как UUID, там вроде 38 символов или типа того.

Н>Я обычно генерю UUID и беру первые 7-9 символов. Для уникальности хватает за глаза. И вполне читаемо

Ерунда какая-то. UUID это число. Обычно его пишут в символьной форме в шестнадцатеричной системе, но исходно это число, и нормальные БД умеют с ним работать как с числом.

Беря из него "первые 9 символов" ты одновременно теряешь все гарантии уникальности uuid (он хорошо размазан в целом, но если выкусывать из него только часть, то в ней коллизии могут быть и весьма частые ведь)
И одновременно, если ты хранишь его в строковом виде (а как ты еще берешь первые символы?), ты теряешь больше места на их хранении и больше вычислительных ресурсов на сравнение чем чельный uuid.

Ты можешь просто брать псевдослучайное число в диапазоне миллиард — и то будет лучше, наверное.
Re[3]: id integer vs uuid
От: Нomunculus Россия  
Дата: 23.08.22 06:26
Оценка:
Здравствуйте, GarryIV, Вы писали:

Очевидно же что имелась ввиду GUID строка вместе с "-", но как отказать себе в удовольствии поумничать, так ведь?
Re[3]: id integer vs uuid
От: Нomunculus Россия  
Дата: 23.08.22 06:27
Оценка:
Здравствуйте, fmiracle, Вы писали:

Разумеется от задачи зависит. Что какие нудные. Для многих задач уникальности первый 9 символов за глаза, даже с большей веротностью повторяемости.
Re[4]: id integer vs uuid
От: fmiracle  
Дата: 23.08.22 07:37
Оценка:
Здравствуйте, Нomunculus, Вы писали:

Н>Разумеется от задачи зависит. Что какие нудные. Для многих задач уникальности первый 9 символов за глаза, даже с большей веротностью повторяемости.


А почему не использовать просто случайные числа тогда?
Re: id integer vs uuid
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 24.08.22 12:39
Оценка:
Здравствуйте, vsb, Вы писали:


vsb>Я сейчас работаю над best practices, которыми будем руководствоваться в будущем для создания сервисов. И нужно этот вопрос решить. Плюсы и минусы там и там есть. Скорей склоняюсь к UUID 2.3, т.к. считаю, что проблемы с производительностью будут малозаметны, а удобство читаемых id не перевешивает плюсов UUID. Заранее спасибо за конструктивные отзывы.


Если бы существовали best practices на этот счет, то их бы уже давно придумали. Если еще не придумали, значит есть tradeoffs, которые в разных ситуациях перевешивают в пользу разных решений.
Вариантов на самом деле больше представленных четырех, так как никто не мешает иметь несколько ключей в таблице: первичный (кластерный) ключ в виде автоинкрементного ID, GUID для для распределённых систем, и естественный ключ для пользователя. И все это в любом сочетании в зависимости от сценария.

Я бы выдал один bestpractice на этот счет: если ты точно не знаешь что тебе нужен GUID, то возьми автоинкрементный числовой ключ.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.