Как генерировать уникальные идентификаторы только Integer, такие как Facebook Twitter
После поиска SO и других сайтов мне не удалось найти убедительных доказательств того, как Facebook, Twitter и Pinterest генерируют свои идентификаторы. Причина, по которой это необходимо, - избегать коллизий URL. Переход на совершенно другой идентификатор предотвратит это, потому что не будет квадриллионов записей.
- Facebook.com/username/posts/362095193814294
- Pinterest.com/pin/62487513549577588
- Twitter.com/#!/Имя пользователя/статус/17994686627061761
Если вы посмотрите на Pinterest в качестве примера, первые несколько цифр относятся к идентификатору пользователя, а последние 6 или около того цифры представляют собой идентификатор сохранения, который может быть автоматическим приращением.
Чтобы создать похожий идентификатор, но не уникальный, я смог использовать: base_convert(user_id.save_id, 16, 10)
. Проблема здесь в том, что она не уникальна, например: base_convert(15.211, 16, 10)
vs. base_convert(152.11, 16, 10)
. Эти два одинаковы. Просто просто слияние двух уникальных наборов чисел будет по-прежнему давать повторяющиеся результаты. Бросание uniqid()
в микс будет по существу исправлять дубликаты, но это не кажется большой практикой.
Обновление: Twitter, похоже, использует это: https://github.com/twitter/snowflake
Любые предложения по созданию уникального идентификатора, подобного приведенным выше примерам?
Ответы
Ответ 1
Комментарий Flickr выше был очень полезен. Мы также используем осколки. У нас есть поле локатора bigint (int64). Он генерируется путем объединения идентификатора базы данных int (int32) и поля идентификации int (int32).
Если вы знаете, что у вас будет максимальное число макс INT16 (вполне вероятно), вы можете объединить идентификатор базы данных int16 (smallint) и идентификатор пользователя int32 (int) и идентификатор действия int16 (smallint). Я не знаю разумных чисел для вашего приложения. Но зарезервируйте часть для идентификатора базы данных, даже если это просто tinyint, так что вы знаете, что в будущем вы будете безопасны, если вы добавите больше баз данных.
Ответ 2
Предположим, что ваши идентификаторы являются числовыми. Отделите их символом A
(так как он, конечно, не отображается в исходных идентификаторах) и выполните базовое преобразование с base-11 на base-10.
В приведенном примере мы получили разные результаты:
echo base_convert("15A211", 11, 10); //247820
echo base_convert("152A11", 11, 10); //238140
Ответ 3
Собственно, если вы посмотрите (например) идентификаторы пользователей в своих друзьях (на Facebook), вы заметите, что они являются последовательными среди всех пользователей, точно так же, как поле базы данных AUTO_INCREMENT. Тем не менее, они, вероятно, не начинаются с 1. Список моих друзей, например, имеет несколько цифр в миллионах, а затем внезапно перескочит на 1 триллион и что-то в этом роде, поэтому я предполагаю, что значение auto_increment было натолкнуто - это может быть сделано "скрыть", сколько именно пользователей существует.
В любом случае, чтобы генерировать уникальные идентификаторы, просто создайте их последовательно с этим полем AUTO_INCREMENT. Необязательно, установите начальное значение на что-то высокое.