Я категорически не согласен с автором выбранного ответа, что Нет идентификатора автоинкремента в MongoDB, и для этого есть веские причины . Мы не знаем причин, по которым 10gen не поощрял использование автоматически увеличивающихся идентификаторов. Это предположение. Я думаю, что 10gen сделал этот выбор, потому что проще обеспечить уникальность 12-байтовых идентификаторов в кластерной среде. Это стандартное решение, которое подходит большинству новичков, поэтому повышает популярность продукции, что хорошо для бизнеса 10gen.
Теперь позвольте мне рассказать всем о моем опыте использования ObjectIds в коммерческой среде.
Я строю социальную сеть. У нас около 6 миллионов пользователей, и у каждого пользователя около 20 друзей.
Теперь представьте, что у нас есть коллекция, в которой хранятся отношения между пользователями (которые следят за кем). Похоже, это
_id : ObjectId
user_id : ObjectId
followee_id : ObjectId
по которому мы имеем уникальный составной индекс {user_id, followee_id}
. Мы можем оценить размер этого индекса как 12 * 2 * 6M * 20 = 2 ГБ. Теперь это показатель быстрого поиска людей, за которыми я следую. Для быстрого поиска людей, которые следуют за мной, мне нужен обратный индекс. Это еще 2 ГБ.
И это только начало. Я должен носить эти идентификаторы везде. У нас есть кластер деятельности, где мы храним вашу ленту новостей. Это каждое событие, которое вы или ваши друзья делаете. Представьте себе, сколько места занимает.
И, наконец, один из наших инженеров принял бессознательное решение и решил сохранить ссылки в виде строк, представляющих ObjectId, который удваивает его размер.
Что происходит, если индекс не помещается в ОЗУ? Ничего хорошего, говорит 10ген:
Когда индекс слишком велик, чтобы поместиться в ОЗУ, MongoDB должен прочитать его с диска, что намного медленнее, чем чтение из ОЗУ. Имейте в виду, что индекс помещается в ОЗУ, когда на сервере имеется ОЗУ, доступное для индекса, в сочетании с остальной частью рабочего набора.
Это означает, что чтение происходит медленно. Конфликт блокировки возрастает. Пишет становится медленнее. Я не вижу шока, когда вижу, что конфликт на 80% -ном уровне.
Прежде чем вы это знаете, у вас получился кластер 460 ГБ, который нужно разделить на осколки и которым довольно трудно манипулировать.
Facebook использует 64-битную длину в качестве идентификатора пользователя :) Для этого есть причина. Вы можете генерировать последовательные идентификаторы
- по совету 10gen .
- использование mysql в качестве хранилища счетчиков (если вас беспокоит скорость, взгляните на handlersocket )
- используя созданный вами сервис генерации идентификаторов или используя что-то вроде Snowflake от Twitter.
Так вот мой общий совет всем. Пожалуйста, сделайте ваши данные как можно меньше. Когда ты вырастешь, это спасет тебя от многих бессонных ночей.