Как генерировать уникальные идентификаторы только 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. Необязательно, установите начальное значение на что-то высокое.