2009-11-29 8 views
14

Recientemente estoy explorando bases de datos NoSQL. Necesito un consejo sobre cómo almacenar datos de la manera más óptima y eficiente para un problema determinado. Me estoy dirigiendo a MongoDB, ahora. Sin embargo, debería ser lo mismo con CouchDB.Necesito un consejo acerca de NoSQL/MongoDb y la estructura de datos/modelos

Digamos que tenemos estos 3 modelos:

Story: 
id 
title 

User: 
id 
name 

Vote: 
    id 
    story_id 
    user_id 

Quiero ser capaz de pedir a la base de datos de estas preguntas:

  • que ha votado por esta noticia?
  • ¿Para qué ha votado este usuario?

Estoy haciendo uniones simples mientras trabajo con una base de datos relacional. La pregunta es, ¿cómo debo almacenar los datos de esos objetos para ser más eficiente?

Por ejemplo, si almaceno los objetos Vote como una subcolección de Historias, no será fácil obtener la información - "Por lo que un usuario ha votado".

Respuesta

7

Yo sugeriría que se guarden los votos como una lista de la historia _id s en cada usuario. De esta forma, puede averiguar para qué historias ha votado un usuario simplemente mirando la lista. Para obtener los usuarios que han votado por una historia que puede hacer algo como:

db.users.find({stories: story_id})

donde story_id es el _id de la historia en cuestión. Si crea un índice en el campo stories, ambas consultas serán rápidas.

+0

Bueno, de hecho, quiero almacenar más información en un modelo de Voto. Por ejemplo: created_at, ip, user_agent. ¿Debo almacenar los datos en la lista de historias de la colección de usuarios? –

+0

Puede almacenar los votos como una matriz de sub documentos, cada uno como '{story_id: ..., created_at: ..., ip: ...}', etc. Luego la consulta se convierte en 'find ({'stories .story_id ': ...}) '. Puedes indexar sobre eso, también. – mdirolf

+0

Bueno, tengo una base de datos bastante grande con unos pocos registros M y probaré el escenario anterior. –

2

Ok, no has dado un modelo de datos normalizado como lo harías en una configuración de SQL.

Según tengo entendido, esto no se hace en MongoDB. Puede almacenar referencias, pero no por razones de rendimiento en el caso general.

No soy un experto en el área NoSQL de ninguna manera, pero ¿por qué no simplemente sigue sus necesidades y almacena el usuario (ids) que ha votado por una historia en la colección de historias y la historia (ids) un usuario ha votado en la colección de usuarios?

1

En CouchDB esto es muy simple. Un punto de vista emite:

function(doc) { 
if(doc.type == "vote") { 
    emit(doc.story_id, doc.user_id); 
} 
} 

Otra vista emite:

function(doc) { 
if(doc.type == "vote") { 
    emit(doc.user_id, doc.story_id); 
} 
} 

Ambos son consultas extremadamente rápido ya que no se unen. Si necesita datos de usuario o datos de historias, CouchDB admite búsquedas de documentos múltiples. También bastante rápido y es una forma de hacer un "join".

+0

Necesitaré consultas en este escenario, ¿o sí? Uno para consultar un índice de documentos de Votos y otro para obtener los documentos de Usuario/Historia. –

+0

@Stanislav. Eso es correcto. Primero deberá obtener los votos y luego buscar usuarios y/o historias para esos votos. – dnolen

3
  • no se preocupe si sus preguntas son eficientes hasta que comienza a adquirir importancia
  • de acuerdo a continuación cita, lo estás haciendo mal

La forma en que he estado yendo sobre la interruptor de la mente es olvidarse de la base de datos alltogether.En el mundo db relacional , siempre debe preocuparse por la normalización de datos y la estructura de la tabla . Deshazte de todo. Simplemente diseñe su página web. Ponlos todo. Ahora míralo. Su ya 2/3 allí. Si olvida la noción de que el tamaño de la base de datos es importante y los datos de no se deben duplicar allí que 3/4 y ni siquiera tiene que escribir ningún código. Deje que sus puntos de vista dicten sus Modelos. No tiene que tomar sus objetos y hacerlos 2 dimensional como en el mundo relacional . Puede almacenar objetos con forma ahora.

how-to-think-in-data-stores-instead-of-databases

0

He estado buscando en MongoDB y CouchDB mucho últimamente, pero mi visión es limitada. Aún así, al pensar en almacenar los votos dentro del documento de la historia, es posible que deba preocuparse por alcanzar el límite de tamaño de documento de 4MB. Incluso si no lo hace, puede estar aumentando constantemente el tamaño del documento lo suficiente como para hacer que se mueva y, por lo tanto, ralentice sus escrituras (vea cómo se dimensionan los documentos en MongoDB).

En cuanto a CouchDB, este tipo de cosas son bastante simples, elegantes y bastante rápidas una vez que se calculan los índices de vista. Personalmente, sin embargo, he dudado en hacer un proyecto similar en CouchDB debido a los puntos de referencia que lo muestran cada vez más lento a medida que la base de datos crece (y los índices de vista crecen). Me encantaría ver algunos benchmarks más recientes que muestren el rendimiento de CouchDB a medida que aumenta el tamaño de la base de datos. QUIERO probar MongoDB o CouchDB, pero SQL todavía parece tan eficiente y lógico, así que me quedaré con él hasta que el proyecto se ajuste a la tentación correcta.

Cuestiones relacionadas