Факт подлога можно определить тем, что, у вас, допустим, пейзаж или репортажный снимок с фокусировкой на бесконечность. А в данных снимка будет (условно) фокусировка 2 метра (ну или с какого расстояния вы фотографировали готовое изображение с монитора или принта).
Как-то оно всё неочевидно и выглядит не очень надёжным. Кто его знает - треды кончатся у приложения и джобы перестанут отрабатывать, а мы об этом даже не узнаем (только из логов разве что, т.е. по их отсутствию).
Для MVP-приложения сойдёт, но для прода, пожалуй, продолжу делать на Quartz. Как-то понадёжнее ИМХО.
Ваша таблица говорит о том, что указанные два сегмента должны быть одинаковыми для всех UUID, сгенерированных в пределах одной миллисекунды.
Вернее, это значение инкрементируется при каждой генерации в рамках миллисекунды, но оно явно не должно быть каждый раз рандомным, как у господина@wildraidв его коде выше.
То есть, метод генерации должен иметь state в виде последнего инкрементированного значения, если я правильно понимаю.
А про 9 бит я ошибся спросонья. Я имел в виду указанные 11 + 12 бит. Но, возможно, я крепко запутался, заранее извините.
Я, возможно, ошибаюсь, но ваш код не учитывает, что все UUID'ы, сгенерированные в пределах одной миллисекунды, должны иметь одинаковые случайные 9 бит.
Но как хранить в Postgres 128 + 64 бита? В тип uuid влезает только 128. Нужно приписать справа (как? через дефис?) кастомные биты, сконвертировать в строку и хранить в varchar или как? Выглядит как-то странно и без примеров вообще видимо никто не понял, что авторы имеют в виду.
Я совсем не понял насчёт кастомного сегмента. Сложил количество бит в таблице из статьи, получил ровно 128. Куда писать дополнительные данные? "Справа от UUID", это как? :)
Я понимаю, о чём вы, но забавно читать про генерацию средствами PostgreSQL, в то время как основная фича UUID'ов - это всё-таки генерация вне БД, ну или до обращения к ней.
Вот, кстати, что мешает базам данных иметь опцию о формате отображения UUID'ов? Ну или клиентам к БД, типа DBeaver. Хочешь - будет отображаться как e027e693-4525-45bb-9fad-319e7373b839, хочешь - в base32 01H7K17QKJ5ND32CQS0NB03FXW .
Т.е. ИМХО если ID не генерируется извне системы, то лучше использовать что-то своё, типа рандомной строки с префиксом. Если же ID генерируется (условно) на фронтенде - то да, UUID лучше т.к. оно лучше стандартизировано и условный фронтендерский фреймворк лучше и быстрее сгенерирует то что нужно.
Вот кстати да, если уж реально надо внешний ID, можно сделать отдельную колонку external_id для него и пихать туда что лучше подходит - рандомную строку, UUID, да что угодно. Можно даже генерить на лету и по запросу, если данные нужны относительно редко. И если доступ надо убрать - можно этот внешний ИД обнулить.
А почему прокси решает создать новый инстанс класса при каждом вызове метода? Это довольно контринтуитивно.
Большое спасибо за ваши комментарии. Не скажу, что теперь стало понятно с логикой спринга (скорее, всё стало сложнее), но буду впредь осторожнее с бинами, чтобы не попасть как автор статьи.
Факт подлога можно определить тем, что, у вас, допустим, пейзаж или репортажный снимок с фокусировкой на бесконечность. А в данных снимка будет (условно) фокусировка 2 метра (ну или с какого расстояния вы фотографировали готовое изображение с монитора или принта).
Как-то оно всё неочевидно и выглядит не очень надёжным. Кто его знает - треды кончатся у приложения и джобы перестанут отрабатывать, а мы об этом даже не узнаем (только из логов разве что, т.е. по их отсутствию).
Для MVP-приложения сойдёт, но для прода, пожалуй, продолжу делать на Quartz. Как-то понадёжнее ИМХО.
А как Postgres хранит дату/время в jsonb?
Если в jsonb мы передадим строку '
2012-04-23T18:25:43.511Z
', то он "поймёт", что это не совсем простая строка? Будет ли её как-то особенно хранить?Я не знаю, с чего вдруг active record начали антипаттерном.
В Quarkus он вполне себе неплохо себя чувствует и для простейших CRUD'ов удобен: https://quarkus.io/guides/hibernate-orm-panache
Говорят, в Grails он вообще крутой. Сам не пробовал, только доку читал: https://gorm.grails.org/latest/hibernate/manual/index.html
del
А в чём может быть практическая необходимость определять версию UUID'а?
Ваша таблица говорит о том, что указанные два сегмента должны быть одинаковыми для всех UUID, сгенерированных в пределах одной миллисекунды.
Вернее, это значение инкрементируется при каждой генерации в рамках миллисекунды, но оно явно не должно быть каждый раз рандомным, как у господина@wildraidв его коде выше.
То есть, метод генерации должен иметь state в виде последнего инкрементированного значения, если я правильно понимаю.
А про 9 бит я ошибся спросонья. Я имел в виду указанные 11 + 12 бит. Но, возможно, я крепко запутался, заранее извините.
Я из вашей статьи взял. Есть 2 (11 и 12 бит) сегмента с таким описанием:
И ещё сегмент (50 бит):
Т.е. для первых двух сегментов инициализируем каждую миллисекунду, для третьего генерим для каждого UUID.
Да, там ещё для первых двух происходит инкремент, насколько я понял, но этого в коде выше тоже нет.
Я, возможно, ошибаюсь, но ваш код не учитывает, что все UUID'ы, сгенерированные в пределах одной миллисекунды, должны иметь одинаковые случайные 9 бит.
Но как хранить в Postgres 128 + 64 бита? В тип uuid влезает только 128. Нужно приписать справа (как? через дефис?) кастомные биты, сконвертировать в строку и хранить в varchar или как? Выглядит как-то странно и без примеров вообще видимо никто не понял, что авторы имеют в виду.
А что произойдёт, если логика "откат создания пользователя" не отработает?
Я совсем не понял насчёт кастомного сегмента. Сложил количество бит в таблице из статьи, получил ровно 128. Куда писать дополнительные данные? "Справа от UUID", это как? :)
Я понимаю, о чём вы, но забавно читать про генерацию средствами PostgreSQL, в то время как основная фича UUID'ов - это всё-таки генерация вне БД, ну или до обращения к ней.
Вот, кстати, что мешает базам данных иметь опцию о формате отображения UUID'ов? Ну или клиентам к БД, типа DBeaver. Хочешь - будет отображаться как
e027e693-4525-45bb-9fad-319e7373b839
, хочешь - в base3201H7K17QKJ5ND32CQS0NB03FXW
.А реально были случаи с коллизией СНИЛС'ов? Аналитики хватаются за сердце. :)
Спасибо за статью. Пара вопросов:
Что означает поле
source
? Это ID самой первой версии записи? И все последующие версии хранят внутри себя ссылку на неё?Как достать самую актуальную (текущую) версию? Смотреть на
datetime_before is null
?Можно в отдельную колонку положить "внешний ID" и генерировать его в виде рандомной строки, пример. Вот здесь варианты привёл: https://habr.com/ru/articles/760272/comments/#comment_25975708
Т.е. ИМХО если ID не генерируется извне системы, то лучше использовать что-то своё, типа рандомной строки с префиксом. Если же ID генерируется (условно) на фронтенде - то да, UUID лучше т.к. оно лучше стандартизировано и условный фронтендерский фреймворк лучше и быстрее сгенерирует то что нужно.
Очень напоминает Snowflake ID алгоритм: https://en.wikipedia.org/wiki/Snowflake_ID
Вот кстати да, если уж реально надо внешний ID, можно сделать отдельную колонку external_id для него и пихать туда что лучше подходит - рандомную строку, UUID, да что угодно. Можно даже генерить на лету и по запросу, если данные нужны относительно редко. И если доступ надо убрать - можно этот внешний ИД обнулить.
А почему прокси решает создать новый инстанс класса при каждом вызове метода? Это довольно контринтуитивно.
Большое спасибо за ваши комментарии. Не скажу, что теперь стало понятно с логикой спринга (скорее, всё стало сложнее), но буду впредь осторожнее с бинами, чтобы не попасть как автор статьи.