Pull to refresh

Comments 9

Есть нюанс: использование кэша повышает производительность, но ценой потери строгой последовательности. При сбое или перезагрузке БД все кэшированные, но не использованные значения теряются, образуя «дырки» в нумерации. Также каждый SEQUENCE требует места в системном каталоге. Следовательно, если требуется гарантированная непрерывность последовательности ключей — что критично для аудита, борьбы с мошенничеством или соблюдения таких норм, как законы о кассовых аппаратах, — кэшированное решение не подходит.

Sequence не гарантирует непрерывности. Если не ошибаюсь то гарантировать непрерывность практически невозможно. Либо возможно но гарантировано угробит производительность.

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

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

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

Хотелось бы передать многообразие ключей и причины их появления, поэтому про интеграцию систем и эффективность потоков данных, как раз следующий DWH уровень.

Вот эти мифы, не имеющие ничего общего с действительностью:

  • Больший размер UUIDv7 (16 байт) якобы "снижает эффективность хранения". Загадочный параметр. Если имеется в виду скорость CRUD операций, то в PostgreSQL для UUIDv7 она такая же, как у автоинкремента (подтверждается бенчмарками, а не сомнительным теоретизированием). Если имеется в виду объем БД, то при использовании UUIDv7 устраняется необходимость в поле таймстемпа created_at, а также устраняется необходимость в замене ключей и, соответственно, в промежуточных таблицах при интеграции данных из нескольких источников. То есть, с использованием UUIDv7 объем БД может даже уменьшиться по сравнению с автоинкрементом

  • Якобы при использовании UUIDv7 имеется "повышенная сложность реализации, требующая поддержки со стороны библиотек и фреймворков". Это совершенно устаревшие сведения. Все ведущие СУБД и языки программирования уже реализовали встроенные функции генерации UUIDv7 (PostgreSQL и даже SQL Server, правда, без толковой документации), или имеют их в стандартных библиотеках (Python) или в самых популярных библиотеках (Golang, Rust). Для Java тоже есть, но я особо не интересовался

  • Упорядоченность на основе времени якобы раскрывает информацию о моменте создания объекта. Если неумело пользоваться, то раскрывает. Но в PostgreSQL и в Percona Server for MySQL значение таймстемпа в UUIDv7 можно сдвинуть хоть на несколько тысячелетий вперед (и до 1970 года назад)

  • Упорядоченность на основе времени якобы требует синхронизации системных часов между инстансами для сохранения корректной последовательности. Разные инстансы синхронизируется не между собой, а с мировым временем (по протоколу NTP и др.). Если инстансы находятся очень далеко друг от друга, то задержку сигнала можно компенсировать сдвигом значения таймстемпа. Если все же последовательность незначительно нарушается, то это никак не влияет на эффективность индексов и скорость работы БД

  • Якобы структура UUIDv7 менее случайна по сравнению с UUID v4, что может быть недостатком в сценариях, где критична полная непредсказуемость идентификаторов. Хакер, предсказавший значение UUIDv7 для строго по RFC 9562 реализованной функции генерации UUIDv7 (в PostgreSQL, Python, Rust и др.), получит нобелевку и золотой бюст на родине героя. Такое предсказание просто невозможно. И, кстати, таймстемп заметно уменьшает и без того нулевые шансы правильного предсказания. А использование UUIDv7, как и UUIDv4 для контроля доступа и других криптоцелей запрещено стандартом RFC 9562

  • Ключевым преимуществом UUID якобы стала независимо и гарантировано уникальная генерация идентификаторов в любой точке системы без централизованной координации. Часто можно столкнуться с ошибочными мнениями, что UUIDv7 нужны для распределенных систем, а для одного сервера лучше автоинкремент. Но генерировать UUIDv7 можно и на одном сервере, и UUIDv7 первоначально планировались именно для этого, а не для распределенных систем и генерации на клиенте (это лишь дополнительный бонус). UUIDv4 использовались для объединения данных из нескольких таблиц без необходимости замены ключей, но сильно замедляли работу БД. UUIDv7 разрабатывались с той же целью, но должны были и обеспечили скорость обработки данных как у автоинкремента

Этот пример это и показывает. Помимо того, что любой SEQUENCE не гарантирует непрерывность числового ряда. Например, при откате транзакции полученное значение теряется безвозвратно. Но даже в "идеальном мире" — без единого отката — использование CASHE - основная причина разрывов.

И кстати ваш пример с user-name, payments, date в приципе не правильный.

Даже если предположить что user-name строго уникальный, payments сам по себе не может быть уникальным.

Если вы 5 раз заплатили по 1 рублю, то все платежи «одинаковые» вам все равно вернут вам деньги с первого платежи или с последнего.

Поэтом здесь не может быть первичного ключа. Даже если вы впихнете поле id Integer Primary Key, это будет “row id” а не первичный ключ в смысле реляционной теории и бизнес-логики.

Я вообще не знаю как тут можно прикрутить первичный ключ и зачем он тут нужен.

С учетом того, что бизнес-процесс был изначально устроен так, что по одному клиенту мог проводиться только один платеж в день выбор ключа PRIMARY KEY (client_name, payment_date) очевиден. И при возврате вернется именно тот платеж, который был совершен в эту дату этим клиентом.

Бизнес процессы имеют тенденцию меняться. И понятно что не может вот требования один платеж от одного клиента в реальной жизни. Задача изначально была типа сферического коня в вакууме. Если нужна задача для иллюстрации: берите классику: студенты, преподаватели, курсы и оценки. Тогда не придётся придумывать несуществующие ограничения там где их нет

Мне кажется лучше даже не начинать проек с sql базой. За кажущейся легкостью в начале потом настает час расплаты и много боли. Лучше юзать самую простую бд типа ключ значение и хорошо думать как все индексировать на лету. UUID - dense id связи, roaring bitmap и т.д. "Отшардировать" потом будет тоже проще

Sign up to leave a comment.

Articles