2010-11-21 13 views
9

Ich arbeite an einem SaaS, wo jeder Mieter mehrere Listen von Kontakten haben können, kann jede Liste eine beliebige Anzahl von Benutzerdefinierte Felder Kontakte dieser Liste können speichern und eine beliebige Anzahl von Gruppen die Contacts der Liste enthalten können (Gruppen werden für die Segmentierung Kontakte der Liste verwendet). Jeder Kontakt hat eine Pflichtfelder: email_address und eine beliebige Anzahl von benutzerdefinierten Feldern, die für die Liste definiert sind, wo es ist, wie ich erwähnt habe. Wir müssen Kontakte der Listen basierend auf den Gruppen, in denen sie sich befinden, und den Werten der benutzerdefinierten Werte finden können. Wir müssen bis zu 30 benutzerdefinierte Felder bereitstellen. Ich sehe jetzt drei Möglichkeiten, dieses Problem zu lösen:Wie benutzerdefinierte Felder und Gruppierung für die Multi-Tenant-Anwendung implementieren: EAV, feste Tabellen Muster, NoSQL

  1. Mit Art von EAV (wir versuchen, es so zu tun), aber es sieht ziemlich komplex. Wir haben eine Tabelle Listen (Listen der Mieter), eine verwandte Tabellen custom_fields, eine verknüpfte Tabellen Abonnenten, die email_addreses von Abonnenten der Liste, Tabelle subscribers_custom_data gespeichert, die mit Abonnenten und custom_fields Tabellen (gespeicherten Werte der benutzerdefinierten Felder von verwandt die Abonnenten).

  2. Feld Tabellen Muster. Die Beschreibung davon ist hier http://blog.springsource.com/arjen/archives/2008/01/24/storing-custom-fields-in-the-database/. In diesem Fall würden wir ein Feld für benutzerdefinierte Felder verwenden, die alle benutzerdefinierten Felder in Spalten speichern würden, z. B. 30 Spalten zum Speichern von Werten für alle möglichen benutzerdefinierten Felder und eine Tabelle zum Speichern der Zuordnung von Spaltenname und Name des Benutzers definiertes Feld Es sieht auch komplex aus. Wir müssten mindestens 30 Indizes haben, um nach den Werten von benutzerdefinierten Feldern zu suchen, dort auch andere Probleme,

  3. Um eine Art von NoSQL-Datenbank zumindest für das Speichern von benutzerdefinierten Feldern und vielleicht Gruppen von Die Liste. Denken Sie, dass solche Datenbanken hier helfen können und wenn ja, wie Sie benutzerdefinierte Felder und Gruppen speichern. Ich versuche, verschiedene Arten von NoSQL zu betrachten, zum Beispiel dokumentorientiert wie MongoDb, aber sofort kann ich nicht sehen, wie es helfen kann, dieses Problem zu lösen. Wir können hier beliebige Attribute speichern, aber um nach den Werten der benutzerdefinierten Felder zu suchen, müssen wir sie im Voraus indizieren, damit wir wissen, welche benutzerdefinierten Felder wir haben.

Vielen Dank für weitere Informationen.

Antwort

9

Wenn Sie alle Felder wollen die ganze Zeit indiziert werden, versuchen, eine Technologie wie Apache Solr die Indizes alles. Der Hauptzweck von Solr ist es, eine Volltextsuchmaschine zu sein, aber es ist im Grunde eine dokumentenorientierte Datenbank.

Hier sind Kommentare über andere Optionen:

  1. EAV ist nicht gut, und ich bin gegen die Verwendung es. Es bricht viele Regeln des relationalen Datenbankentwurfs, und es wird nicht skalieren. Ich habe viel über Stack Overflow geschrieben, also suche nach my answers unter dem eav Tag.

  2. Sie brauchen nicht nur 30 Indizes - Sie müssen bis zu 30-faktoriellen Indizes jede mögliche Kombination von Indizes zu handhaben. Beachten Sie, dass Sie mehrspaltige Indizes erstellen können, und diese Arten von Indizes sind wichtig, um bestimmte Abfragen zu unterstützen. Natürlich ist es völlig unpraktisch, so viele Indizes zu erstellen; Sie müssen Indizes erstellen, die den Abfragen entsprechen, für die Sie optimieren möchten. Wenn Sie nicht wissen, welche Felder Sie haben und welche Abfragen Sie haben werden, können Sie nicht optimieren.

  3. Dokument-orientierte Datenbanken wie MongoDB/CouchDB sind keine Zauberei, egal wie sehr ihre Befürworter versuchen zu behaupten, dass sie es sind. Sie müssen Dokumente für schnelle Suchvorgänge indizieren, was bedeutet, dass Sie die indizierbaren Felder eines Dokuments kennen müssen.

    Das Erstellen eines Index zur Laufzeit ist ein Problem, da es je nach Datenmenge, die indexiert werden muss, sehr lange dauern kann. Sie müssen einen Weg finden, die Indexerstellung "offline" auszuführen (d. H. Den Benutzer nicht während einer einzelnen HTTP-Anforderung darauf warten zu lassen) und sie dann zu benachrichtigen, wenn sie abgeschlossen ist.

  4. Sie sollten über How FriendFeed uses MySQL to store schema-less data lesen. Sie verwenden ein serialisiertes LOB, kombinieren grundsätzlich alle benutzerdefinierten Attribute zu einem XML- oder JSON-Blob. So können Benutzer jederzeit beliebig viele zusätzliche benutzerdefinierte Felder erstellen. Bevor jedoch ein benutzerdefiniertes Feld durchsucht werden kann, erstellen Sie eine untergeordnete Tabelle, die auf Zeilen verweist, in denen dieses Feld einen bestimmten Wert enthält. Somit erhalten Sie einen Index, der nur so groß ist wie die Anzahl der Instanzen eines benutzerdefinierten benutzerdefinierten Feldes. Und Sie müssen nicht alle Feld durchsuchbar machen.

+0

Mit meinem Anwendungsfall kann ich die indexierbaren Felder kennen (aber nur zur Laufzeit). Die Mieter sind in der Lage, ihren eigenen Feldsatz zu definieren (indem sie aus einem Satz von vordefinierten auswählen und/oder ihre eigenen Felddeskriptoren hinzufügen). Wenn sie zu diesem Zeitpunkt ein neues Feld hinzufügen, sollte ich eine (spärliche) Indexerstellung auslösen können. Würde also für dieses spezielle Szenario ein dokumentenorientierter Laden am besten passen? –

+0

Ja, ein Dokumentenspeicher könnte in dieser Situation funktionieren. Siehe meine Bearbeitung oben. –

+0

Wie zur Verwendung von Blob ist es nicht klar, wie benutzerdefinierte Felder gelöscht/bearbeitet werden. Zum Beispiel kann der Benutzer ein Feld in seinem Container löschen und das Feld sollte in allen Entitäten dieses Containers gelöscht werden. Können Sie mir bitte sagen, wie Sie benutzerdefinierte Felder löschen/bearbeiten und in allen Entitäten widerspiegeln? Neben dem Hinzufügen/Löschen von benutzerdefinierten Feldern zum Beispiel sollte es verfügbar machen und filtern. Falls EAV Kaskade gelöscht wird passiert. Die Größe eines Feldes ist begrenzt und es ist schwer vorherzusagen, wie groß die Blobgröße sein wird. Aber es ist schwer zu sagen, ob Nosql irgendwelche Vorteile geben kann. – Oleg