MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

relacionamento muitos para muitos com nosql (mongodb e mangusto)


Pelo contrário, as soluções 1 e 2 são sua melhor aposta. A solução 3 pode ser considerada quando a frequência de atualização/criação é muito menor em comparação com a frequência de leitura de projetos e usuários, pois mesmo que para atualizar/criar sejam necessárias duas consultas, a facilidade de leitura será compensada.

Para escolher entre as soluções 1 e 2, você precisa considerar as frequências de leitura. Você vai precisar de projetos de um usuário ou usos de um projeto com mais frequência e escolher de acordo com isso. Se você sentir que ambos têm relativamente a mesma frequência, é melhor manter o objeto de usuário o menos agrupado possível. Qualquer que seja a opção escolhida, considere manter um index na matriz que armazena o _id s (de projetos ou usuários).

Por ex.
userSchema = new Schema(
            {//otherstuff
               project_ids: [{type: Schema.Types.ObjectId, ref: 'Project'}})
              ...
            }) 
userSchema.index({'project_ids':1})

ou
projectSchema = new Schema(
            {//otherstuff
               user_ids: [{type: Schema.Types.ObjectId, ref: 'User'}})
              ...
            }) 
projectSchema.index({'user_ids':1})

Mantendo um índice no array de _id melhorará muito a velocidade de suas consultas no lado em que você teme que haja uma sobrecarga significativa.

Mas mantenha o index somente se essa relação for uma relação importante com muitas consultas em andamento. Se este é apenas um recurso secundário do seu projeto, você pode fazer without um índice também.

Se o usuário puder fazer muitas coisas e tiver muitas relações, você precisará desse objeto de usuário constantemente em todo o aplicativo, portanto, se seu aplicativo não for específico do projeto, seria melhor não colocar os IDs do projeto no esquema do usuário . Mas como estamos apenas colocando os ids, não é uma sobrecarga de qualquer maneira. Não precisa se preocupar com isso.

Índice Reg em ambas as matrizes:Sim, você pode, claro. Mas quando você for para a solução 3, não precisará de um índice, pois não fará uma consulta para obter a lista de projetos de um usuário ou a lista de usuários em um projeto. A solução 3 torna a leitura muito fácil, mas a escrita um pouco complicada. Mas como você mencionou que seu caso de uso envolve reading>>writing , vá com a solução 3, mas sempre há o perigo de inconsistência de dados que você precisa cuidar.

A indexação apenas torna as coisas mais rápidas. Vá até os documentos e faça um pouco de googling. Nada chique. Consultar arrays indexados é mais eficiente do que arrays normais. Por ex. Vamos supor que você use a solução 2. Armazene os IDs do projeto no campo project_ids.

Você pode obter os projetos de um usuário facilmente. Isso é direto.

Mas para obter usuários de project1. Você precisa de uma consulta como esta.
User.find({project_ids:project._id},function(err,docs){
     //here docs will be the list of the users of project1
})
//The above query might be slow if the user base is large. 
//But it can be improved vastly by indexing the project_ids field in the User schema.

Similarmente para a solução 1. Cada projeto possui o campo user_ids. Vamos supor que temos um user1. Para obter os projetos do usuário fazemos a seguinte consulta
Project.find({user_ids:user1._id},function(err,docs){
      //here docs will be the projects of user1
      //But it can be improved vastly by indexing the user_ids field in the Project schema.

Se você está ponderando sobre a solução 1 versus a solução 2, a solução 1 é melhor, eu acho. Pode haver casos em que você precise do usuário sem seus projetos, mas as chances de exigir o projeto sem os usuários são muito baixas. Mas isso depende do seu caso de uso exato.