2009-11-29 23 views
14

Kürzlich erkunde ich NoSQL-Datenbanken. Ich brauche einen Rat, wie Daten für ein gegebenes Problem optimal und effizient gespeichert werden können. Ich wende mich jetzt an MongoDB. Bei CouchDB sollte es aber genauso sein.Ich brauche einen Rat über NoSQL/MongoDb und Daten/Modelle Struktur

Sagen wir, wir haben diese drei Modelle:

Story: 
id 
title 

User: 
id 
name 

Vote: 
    id 
    story_id 
    user_id 

Ich möchte die Datenbank diese Fragen stellen können:

  • Wer hat für diese News gestimmt hat?
  • Für was wurde gewählt?

Ich mache einfache Joins während der Arbeit mit einer relationalen DB. Die Frage ist, wie sollte ich die Daten für diese Objekte speichern, um am effizientesten zu sein.

Zum Beispiel, wenn ich die Vote-Objekte als eine Untersammlung von Stories speichern, wird es nicht einfach sein, die Information zu erhalten - "Was ein Benutzer gewählt hat".

Antwort

7

Ich würde vorschlagen, Abstimmungen als Liste der Geschichte _id s in jedem Benutzer speichern. Auf diese Weise können Sie anhand der Liste herausfinden, für welche Artikel ein Nutzer gewählt hat. Um die Benutzer zu erhalten, die für eine Geschichte gestimmt haben Sie so etwas wie tun:

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

wo story_id ist die _id der Geschichte in Frage. Wenn Sie einen Index für das Feld stories erstellen, sind beide Abfragen schnell.

+0

Nun, in der Tat möchte ich mehr Informationen in einem Vote-Modell speichern. Zum Beispiel: created_at, ip, user_agent. Sollte ich die Daten in der Stories-Liste der Benutzer Sammlung speichern? –

+0

Sie könnten die Stimmen als ein Array von Unterdokumenten speichern, jedes wie '{story_id: ..., created_at: ..., ip: ...}' usw. Dann wird die Abfrage zu 'find ({'stories .story_id ': ...}) '. Sie können auch darüber indexieren. – mdirolf

+0

Nun, ich habe eine ziemlich große Datenbank mit ein paar M Datensätzen und werde das obige Szenario testen. –

2

OK, Sie haben ein normalisiertes Datenmodell wie in einem SQL-Setup angegeben.

In meinem Verständnis tun Sie dies nicht in MongoDB. Du kannst Referenzen speichern, aber im allgemeinen Fall nicht aus Leistungsgründen.

Ich bin kein Experte in der NoSQL-Bereich in keiner Weise, aber warum folgen Sie nicht einfach Ihren Bedürfnissen und speichern Sie die Benutzer (ids), die für eine Geschichte in der Stories-Sammlung und der Geschichte (ids) hat ein Benutzer in der Benutzersammlung gewählt?

1

In CouchDB ist das sehr einfach. Ein Blick aussendet:

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

Eine andere Ansicht aussendet:

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

Beide Abfragen sind extrem schnell, da es keine wird kommen. Wenn Sie Benutzerdaten oder Story-Daten benötigen, unterstützt CouchDB das Abrufen mehrerer Dokumente. Auch ziemlich schnell und ist eine Möglichkeit, einen "Join" zu machen.

+0

Ich brauche in diesem Szenario Abfragen, werde ich? Eins zum Abfragen eines Index für Votes-Dokumente und eines zum Abrufen der Dokumente für User/Story. –

+0

@Stanislav. Das ist richtig. Sie müssen zuerst die Stimmen holen und dann Benutzer und/oder Geschichten für diese Stimmen holen. – dnolen

3
  • keine Sorge, wenn Sie Ihre Anfragen effizient sind, bis sie
  • nach unten Zitat zu Materie beginnt, es Sie tun falsch

Die Art, wie ich über die gegangen sind Geist Schalter ist über die Datenbank insgesamt zu vergessen.In der relationalen db Welt müssen Sie immer über Datennormalisierung und Ihre Tabellenstruktur kümmern. Gib alles auf. Layout einfach deine Webseite. Legen Sie sie alle aus. Jetzt schau sie dir an. Deine schon 2/3 da. Wenn Sie die Idee vergessen, dass die Datenbankgröße wichtig ist und Daten nicht dupliziert werden sollten, als Ihre 3/4 dort, und Sie nicht sogar haben, schreiben Sie jeden möglichen Code! Lassen Sie Ihre Ansichten Ihre Modelle diktieren. Sie müssen Ihre Objekte nicht nehmen und sie 2 dimensionale mehr als in der relationalen Welt machen. Sie können jetzt Objekte mit Form speichern.

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

0

Ich habe in letzter Zeit viel in MongoDB und CouchDB suchen, aber meine Einsicht ist begrenzt. Wenn Sie darüber nachdenken, die Stimmen im Story-Dokument zu speichern, müssen Sie sich möglicherweise Gedanken darüber machen, ob Sie das 4-MB-Limit für Dokumente einhalten können. Selbst wenn Sie dies nicht tun, erhöhen Sie möglicherweise die Größe des Dokuments ständig genug, um es zu verschieben und damit Ihre Schreibvorgänge zu verlangsamen (siehe Größe der Dokumente in MongoDB).

Wie bei CouchDB sind diese Dinge ziemlich einfach, elegant und ziemlich schnell, sobald die Ansicht Indizes berechnet werden. Persönlich habe ich jedoch gezögert, ein ähnliches Projekt in CouchDB zu machen, weil es Benchmarks gibt, die zeigen, dass es sich progressiv verlangsamt, wenn die Datenbank wächst (und die View-Indizes wachsen). Ich würde gerne einige neuere Benchmarks sehen, die die Leistung von CouchDB zeigen, wenn die Datenbankgröße zunimmt. Ich möchte versuchen MongoDB oder CouchDB, aber SQL scheint immer noch so effizient und logisch, so werde ich bleiben, bis das Projekt die Versuchung genau richtig passt.