É possível que o mesmo Mongo ObjectId exato seja gerado para um documento em duas coleções diferentes? Percebo que é definitivamente muito improvável, mas é possível?
Sem ser muito específico, o motivo pelo qual pergunto é que, com um aplicativo em que estou trabalhando, mostramos perfis públicos de funcionários eleitos que esperamos converter em usuários de pleno direito do nosso site. Temos coleções separadas para usuários e funcionários eleitos que atualmente não são membros do nosso site. Existem vários outros documentos que contêm vários dados sobre os funcionários eleitos que são mapeados de volta para a pessoa usando seu ObjectId oficial eleito.
Após criar a conta, ainda destacamos os dados associados ao funcionário eleito, mas agora eles também fazem parte da coleção de usuários com um ObjectId de usuários correspondente para mapear seu perfil para interações com nosso aplicativo.
Começamos a converter nosso aplicativo do MySql para o Mongo há alguns meses e, enquanto estamos em transição, armazenamos o ID do MySql herdado para esses dois tipos de dados e também começamos a armazenar o Mongo ObjectId oficial eleito nos usuários documento para mapear de volta aos dados oficiais eleitos.
Eu estava pensando em especificar o novo usuário ObjectId como o ObjectId oficial eleito anterior para tornar as coisas mais simples, mas queria ter certeza de que não era possível ter uma colisão com qualquer usuário existente ObjectId.
Obrigado pela sua compreensão.
Edit: Logo após postar esta pergunta, percebi que minha solução proposta não era uma idéia muito boa. Seria melhor manter o esquema atual que possuímos e apenas vincular ao funcionário eleito '_id' no documento do usuário.
Respostas:
Resposta curta
Apenas para adicionar uma resposta direta à sua pergunta inicial: SIM, se você usar a geração de BSON Object ID, para a maioria dos drivers, os IDs certamente serão únicos nas coleções. Veja abaixo o que "quase certamente" significa.
Resposta longa
É altamente provável que os IDs de objeto BSON gerados pelos drivers Mongo DB sejam únicos nas coleções. Isso ocorre principalmente pelos últimos 3 bytes do ID, que para a maioria dos drivers são gerados por meio de um contador estático de incremento. Esse contador é independente da coleção; é global. O driver Java, por exemplo, usa um AtomicInteger estático, inicializado aleatoriamente.
Então, por que, nos documentos do Mongo, eles dizem que os IDs têm "alta probabilidade" de serem únicos, em vez de dizerem claramente que eles serão únicos? Podem ocorrer três possibilidades em que você não obterá um ID exclusivo (entre em contato se houver mais):
Antes desta discussão, lembre-se de que o ID do objeto BSON consiste em:
[4 bytes segundos desde a época, hash da máquina de 3 bytes, ID do processo de 2 bytes, contador de 3 bytes]
Aqui estão as três possibilidades, para que você julgue por si mesmo qual a probabilidade de ser burro:
1) Estouro do contador: existem 3 bytes no contador. Se você inserir mais de 16.777.216 (2 ^ 24) documentos em um único segundo, na mesma máquina, no mesmo processo, poderá exceder os bytes de contador incrementais e acabar com dois IDs de Objeto que compartilham o mesmo tempo, máquina , processo e valores de contador.
2) Contador sem incremento: alguns drivers Mongo usam números aleatórios em vez de incrementar números para os bytes do contador. Nesses casos, existe uma chance de 1 / 16.777.216 de gerar um ID não exclusivo, mas apenas se esses dois IDs forem gerados no mesmo segundo (ou seja, antes da seção de tempo do ID ser atualizada para o próximo segundo), no mesmo máquina, no mesmo processo.
3) Hash da máquina e do processo com os mesmos valores. Os valores de ID de máquina e de processo podem, em algum cenário altamente improvável, mapear para os mesmos valores para duas máquinas diferentes. Se isso ocorrer e, ao mesmo tempo, os dois contadores nas duas máquinas diferentes, durante o mesmo segundo, gerarem o mesmo valor, você terá um ID duplicado.
Esses são os três cenários a serem observados. Os cenários 1 e 3 parecem altamente improváveis e o cenário 2 é totalmente evitável se você estiver usando o driver correto. Você terá que verificar a fonte do driver para ter certeza.
fonte
ObjectId
que você tinha antes, enquanto o hash máquina, ID do processo, e contra todos o mesmo resultadoOs ObjectIds são gerados no lado do cliente de maneira semelhante ao UUID, mas com algumas propriedades mais agradáveis para armazenamento em um banco de dados, como aumentar aproximadamente a ordem e codificar seu tempo de criação gratuitamente. O principal para o seu caso de uso é que eles são projetados para garantir exclusividade a uma alta probabilidade, mesmo que sejam gerados em máquinas diferentes.
Agora, se você estava se referindo ao campo _id em geral, não exigimos exclusividade entre as coleções, portanto é seguro reutilizar o antigo _id. Como um exemplo concreto, se você tiver duas coleções
colors
efruits
, ambas podem ter simultaneamente um objeto como{_id: 'orange'}
.Caso você queira saber mais sobre como os ObjectIds são criados, aqui está a especificação: http://www.mongodb.org/display/DOCS/Object+IDs#ObjectIDs-BSONObjectIDSpecification
fonte
Caso alguém esteja tendo problemas com os ObjectIDs do Mongo duplicados, você deve saber que, apesar da improvabilidade de dups acontecendo no próprio Mongo, é possível ter _id's duplicados gerados com PHP no Mongo.
O caso de uso em que isso aconteceu com regularidade para mim é quando estou percorrendo um conjunto de dados e tentando injetar os dados em uma coleção.
A matriz que contém os dados da injeção deve ser redefinida explicitamente a cada iteração - mesmo se você não estiver especificando o valor _id. Por alguma razão, o processo INSERT adiciona o Mongo _id à matriz como se fosse uma variável global (mesmo que a matriz não tenha escopo global). Isso pode afetá-lo mesmo se você estiver chamando a inserção em uma chamada de função separada, na qual normalmente espera que os valores da matriz não persistam de volta à função de chamada.
Existem três soluções para isso:
unset()
o campo _id da matrizarray()
cada vez que percorrer seu conjunto de dadosMeu palpite é que isso é um bug na interface do PHP, e não um problema com o Mongo, mas se você encontrar esse problema, desative o _id e você ficará bem.
fonte
Não há garantia alguma sobre a exclusividade do ObjectId entre as coleções. Mesmo que seja probabilisticamente muito improvável, seria um design de aplicativo muito ruim que dependesse da exclusividade _id entre as coleções.
Pode-se facilmente testar isso no shell mongo:
Portanto, não confie absolutamente em _id sendo único nas coleções e, como você não controla a função de geração do ObjectId, não confie nela.
É possível criar algo mais parecido com um uuid e, se você fizer isso manualmente, poderá ter uma garantia melhor de exclusividade.
Lembre-se de que você pode colocar objetos de "tipos" diferentes na mesma coleção. Por que não colocar apenas suas duas "tabelas" na mesma coleção? Eles compartilhariam o mesmo espaço _id e, portanto, teriam garantia única. Mudar de "prospectivo" para "registrado" seria um simples movimento de um campo ...
fonte