2010-11-21 39 views
9

Je travaille en mode SaaS, où chaque locataire peut avoir plusieurs listes de contacts, chaque liste peut avoir un nombre de les champs personnalisés contacts de cette liste peuvent stocker et n'importe quel nombre de groupes les contancs de la liste peuvent être inclus (les groupes sont utilisés pour segmenter les contacts de la liste). Chaque contact a un champs obligatoire: adresse_mail et un nombre quelconque de champs définis par l'utilisateur qui sont définis pour la liste où il est comme je l'ai mentionné. Nous devons être en mesure de trouver des contacts de la base de listes sur les groupes dans lesquels ils se trouvent et les valeurs des valeurs définies par l'utilisateur. Nous devons fournir jusqu'à 30 champs définis par l'utilisateur. Je vois maintenant trois façons de résoudre ce problème:Comment implémenter les champs définis par l'utilisateur et le regroupement pour l'application multi-tenant: EAV, modèle de table fixe, NoSQL

  1. Utilisation genre de EAV (nous essayons de le faire comme ça), mais il semble assez complexe. Nous avons une liste de tables (listes de locataires), une table connexe custom_fields, un abonné de tables connexes qui a stocké email_addreses des abonnés de la liste, table subscribers_custom_data qui est liée aux abonnées et des tables custom_fields (valeurs stockées des champs personnalisés de les abonnés).

  2. Modèle de tables de champ. Les descriptions de celui-ci est ici http://blog.springsource.com/arjen/archives/2008/01/24/storing-custom-fields-in-the-database/. Dans ce cas, nous utiliserions un champ relatif aux champs personnalisés, qui stockerait dans les colonnes tous les champs personnalisés, par exemple, 30 colonnes pour stocker les valeurs de chaque champ personnalisé et une table contenant le nom et le nom de l'utilisateur. champ défini. Cela a l'air complexe aussi. Nous devons avoir au moins 30 index au moins pour rechercher par les valeurs des champs personnalisés, il y a aussi d'autres problèmes,

  3. Pour utiliser une sorte de base de données NoSQL au moins pour stocker des champs définis par l'utilisateur et peut-être des groupes de la liste. Pensez-vous que ces bases de données peuvent aider ici et si oui comment concevoir pour stocker des champs et des groupes personnalisés. J'essaie de regarder différents types NoSQL, par exemple, orientés document comme MongoDb, mais tout de suite je ne vois pas comment cela peut aider à résoudre ce problème. Nous pouvons stocker des attributs arbitraires ici mais pour rechercher les valeurs des champs personnalisés dont nous avons besoin pour les indexer à l'avance, nous devons donc savoir quels champs personnalisés nous aurons.

Nous vous remercions de votre intérêt à ce sujet.

Répondre

9

Si vous voulez que tous les champs soient indexés en permanence, essayez une technologie comme Apache Solr qui indexe tout. Le but principal de Solr est d'être un moteur de recherche fulltext, mais il s'agit essentiellement d'une base de données orientée document.

Voici les commentaires sur d'autres options:

  1. EAV est pas bon, et je suis contre l'utiliser. Il brise de nombreuses règles de conception de base de données relationnelle, et il ne sera pas à l'échelle. J'ai beaucoup écrit à ce sujet sur Stack Overflow, alors recherchez my answers sous la balise eav.

  2. Vous n'avez pas besoin de seulement 30 index - vous avez besoin d'un maximum de 30 index factoriels pour gérer toute combinaison possible d'index. Gardez à l'esprit que vous pouvez créer des index multi-colonnes et que ces types d'index sont importants pour prendre en charge certaines requêtes. Bien sûr, cela est totalement impossible de créer autant d'index; vous devez créer des index pour correspondre aux requêtes pour lesquelles vous souhaitez optimiser. Si vous ne savez pas quels champs vous aurez et quelles requêtes vous aurez contre eux, vous ne pouvez pas optimiser.

  3. Les bases de données orientées document comme MongoDB/CouchDB ne sont pas magiques, peu importe combien leurs défenseurs essayent de prétendre qu'ils sont. Ils nécessitent que vous indexiez les documents pour les recherches rapides, ce qui signifie que vous devez connaître les champs indexables d'un document.

    La création d'un index lors de l'exécution pose problème, car elle peut prendre beaucoup de temps, en fonction de la quantité de données à indexer. Vous devrez trouver un moyen d'exécuter la création de l'index "hors ligne" (c'est-à-dire ne pas obliger l'utilisateur à l'attendre pendant une seule requête http) et ensuite les avertir quand il sera terminé. Vous devriez lire environ How FriendFeed uses MySQL to store schema-less data Ils utilisent un LOB sérialisé, combinent fondamentalement tous les attributs personnalisés en un blob XML ou JSON. Les utilisateurs peuvent donc créer n'importe quel nombre de champs personnalisés supplémentaires à tout moment. Mais avant qu'un champ personnalisé donné puisse être rendu consultable, vous devez créer une table enfant qui référence les lignes où ce champ contient une valeur donnée. Ainsi, vous obtenez un index qui est seulement aussi grand que le nombre d'instances d'un champ personnalisé défini par l'utilisateur. Et vous n'avez pas besoin de faire chaque consultable sur le terrain.

+0

Avec mon utilisation, je serai capable de connaître les champs indexables (mais seulement à l'exécution). Les locataires sont capables de définir leur propre ensemble de champs (en choisissant parmi un ensemble de prédéfinis et/ou en ajoutant leurs propres descripteurs de champs). Donc, à ce moment-là, ils ajoutent un nouveau champ, je devrais être en mesure de déclencher une création d'index (clairsemée). Donc, pour ce scénario particulier, un magasin orienté document serait-il le mieux adapté? –

+0

Oui, un magasin de documents pourrait fonctionner dans cette situation. Voir ma modification ci-dessus. –

+0

En ce qui concerne l'utilisation de blob, il n'est pas clair comment supprimer/éditer des champs personnalisés. Par exemple, l'utilisateur peut supprimer un champ dans son conteneur et le champ doit être supprimé dans toutes les entités de ce conteneur. Pouvez-vous s'il vous plaît me dire comment supprimer/éditer des champs personnalisés et le refléter dans toutes les entités? En plus de l'exemple, ajouter/supprimer des champs personnalisés par utilisation devrait le rendre disponible en utilisant et en filtrant. Dans le cas où EAV cascade supprimé se produit. La taille d'un champ est limitée et il est difficile de prédire ce qu'il atteindra la limite de taille de blob. Mais il est difficile de dire si nosql peut donner des avantages. – Oleg