Простые требования легче реализовывать
Всем привет, работаю java разработчиком 10 лет. Хотел бы на примере пояснить, почему важно внимательно вникать в требования, и не допускать их избыточного утяжеления.
Представим, что нам нужно сделать систему, проводящую платежные поручения, и у каждого поручения должен быть свой уникальный идентификатор. Поддержку уникальности осуществляет реляционная база данных, идентификатор используется как primary key. Какой тип и правило задать для генерации идентификатора?
integer, числовая последовательность: 0001, 0002, ...
UUID.random() : 8c061868-5bbd-4ea7-824f-d8640fb4f6e3, ...
UUID может совпасть при двух генерациях, но с крайне малой вероятностью - можно сказать что он уникален. Значения в последовательности тоже уникальны. То есть уникальность поддерживается там и там.
Так как эти уникальные значения можно сравнивать, то можно привести их к полному порядку - отсортировать и расположить в виде структуры с эффективным доступом (например, дерево со сложностью logN).
Числовая последовательность обеспечивает не какой-то порядок - он еще и совпадает с порядком добавления записей в таблицу. Если в конце месяца мы захотим подарить подарок 1000-му пользователю сервиса, то это можно сделать если исходный порядок сохранен.
В большинстве реляционных баз реализована поддержка реплик - узлов в резерве, на случай падения основного узла, осуществляющего запись. Реплики копируют данные с основного узла с небольшим отставанием, например последний платеж может в какой-то момент времени еще не дойти до реплики:
main: (0001, 0002, 0003)
replica: (0001, 0002)
Если основной узел выйдет из строя, то дальше все операции по записям возьмет на себя реплика. В указанном случае она будет выдавать идентификаторы далее: 0003, 0004, ... . Получается, у разных узлов будет разное представление об операции с id = 0003 - это создаст конфликт, если первый узел вернется к жизни.
Можно было бы вместо этого выбирать тысячную запись не по id, а по времени создания. В этом случае можно использовать UUID как идентификатор, и добавлять время создания записи, чтобы позже по нему выявить 1000-го пользователя. В случае падения основного узла конфликта с id не будет, но на разных узлах может не совпадать время - а это бывает при проблемах с ntp сервисами. Например, во время выхода из строя основного узла время на нем было 15:20, а на реплике 15:12, и у новых пользователей время будет меньше чем у существующих.
Еще можно было бы согласовывать следующее число в последовательности общим решением всех узлов, но такой подход более затратен и имеет свои проблемы.
На этом примере видно, что разработчику стоит строго фильтровать требования от бизнеса - пользуясь глубоким пониманием используемых решений давать справедливую оценку сложности доработок. Всем удачных проектов и профессионального роста!