Comment concevez-vous votre database pour permettre le schéma défini par l'user

Si vous devez créer une application comme – disons une application de blog, la création du schéma de database est relativement simple. Vous devez créer quelques tables, tblPosts, tblAttachments, tblCommets, tblBlaBla … et c'est tout (ok, je sais, c'est un peu simplifié mais vous comprenez ce que je veux dire).

Que faire si vous avez une application dans laquelle vous souhaitez autoriser les users à définir des parties du schéma lors de l'exécution . Supposons que vous souhaitiez créer une application dans laquelle les users peuvent save n'importe quel type de données. Un user veut save ses heures de travail (startTime, endTime, ID de projet, description), le prochain veut collecter des recettes de cuisine, d'autres peut-être des cotations boursières, le poids hebdomadaire de leurs bébés, les dépenses mensuelles pour la nourriture, les résultats de leur équipes de football préférées ou tout ce que vous pouvez penser.

Comment concevez-vous une database pour contenir tout ce type très différent de données? Souhaitez-vous créer un schéma générique pouvant contenir toutes sortes de données, créeriez-vous de nouvelles tables reflétant le schéma de données user ou avez-vous une autre excellente idée pour le faire?

Si c'est important: je dois utiliser SQL Server / Entity Framework

Essayons encore.

Si vous voulez qu'ils soient en mesure de créer leur propre schéma, alors pourquoi ne pas build le schéma en utilisant, oh, je ne sais pas, la déclaration CREATE TABLE. Vous avez un bateau complet, une database complète, fonctionnelle et puissante qui peut faire des choses incroyables comme définir des schémas et stocker des données. Pourquoi ne pas l'utiliser?

Si vous alliez juste faire quelques propriétés ad hoc, alors bien sûr.

Mais si c'est "carte blanche, ils peuvent faire ce qu'ils veulent", alors laissez-les.

Doivent-ils connaître SQL? Umm, non. C'est votre tâche d'interface user. Votre travail en tant qu'outil et concepteur d'applications est de cacher l'implémentation à l'user. Alors présentez des lists de champs, de lignes et de flèches si vous voulez des relations, etc.

Les gens font des «users finaux», des outils de database «simples» depuis des années.

"Et s'ils veulent append une colonne?" Ensuite, ajoutez une colonne, les bases de données font cela, les plus bonnes au less. Sinon, créez la nouvelle table, copyz les anciennes données, déposez l'ancienne.

"Et s'ils veulent supprimer une colonne?" Voir au dessus. Si le vôtre ne peut pas supprimer les colonnes, supprimez-le de la vue logique de l'user afin qu'il semble être supprimé.

"Et s'ils ont cent vingt-douze lignes de données?" Ensuite, ils ont une centaine de zillion de rangées de données et les opérations prennent cent vingt-dix fois plus de time que si elles avaient une rangée de données. S'ils ont des rangées de données de onze millions de zillions, ils ne devraient probablement pas utiliser votre système pour cela.

La fascination de "mettre en place des bases de données sur des bases de données" me échappe.

"J'ai Oracle ici, comment puis-je offrir less de fonctionnalités et faire est plus lent pour l'user?"

Gee, je me request.

Il n'y a aucun moyen de prédire la complexité de leurs besoins en données. Entity-Atsortingbute-Value est une solution typique que de nombreux programmeurs utilisent, mais cela peut être suffisant, par exemple si datatables de l'user sont classiquement modélisées avec plusieurs tables.

Je sérialiserais datatables personnalisées de l'user en format XML ou YAML ou JSON ou un format semi-structuré similaire, et les save dans un BLOB de text.

Vous pouvez même créer des index inversés afin de searchr des valeurs spécifiques parmi les attributes de votre BLOB. Voir http://bret.appspot.com/entry/how-friendfeed-uses-mysql (la technique fonctionne dans n'importe quel SGBDR, pas seulement MySQL).

Envisagez également d'utiliser un magasin de documents tel que Solr ou MongoDB . Ces technologies n'ont pas besoin de se conformer aux conventions de database relationnelles. Vous pouvez append de nouveaux attributes à n'importe quel document lors de l'exécution, sans devoir redéfinir le schéma. Mais c'est un compromis – ne pas avoir de schéma signifie que votre application ne peut pas dépendre des documents / lignes étant similaires dans toute la collection.


Je suis un critique de l'anti-pattern Entity-Atsortingbute-Value.

J'ai écrit sur les problèmes d'EAV dans mon livre, Antipatterns de SQL: Éviter les pièges de la programmation de database .

Voici une réponse SO où je list quelques problèmes avec Entity-Atsortingbute-Value: " Table de produits, de nombreux types de produits, chaque produit a de nombreux parameters ."

Voici un blog que j'ai posté l'autre jour avec plus de discussion sur les problèmes d'EAV: " EAV FAIL ".

Et assurez-vous de lire ce blog " Bad CaRMa " sur la façon dont la tentative de faire une database entièrement flexible a presque détruit une entreprise.

Je choisirais un model entité-valeur-atsortingbut hybride, donc comme la réponse d'Antony, vous avez des tables EAV, mais vous avez aussi des colonnes par défaut (et des propriétés de class) qui existeront toujours.

Voici un excellent article sur ce que vous allez faire 🙂

Comme un commentaire supplémentaire, j'ai frappé un prototype pour cette approche en utilisant Linq2Sql dans quelques jours, et c'était une solution réalisable. Étant donné que vous avez mentionné Entity Framework, je voudrais jeter un oeil à la version 4 et à leur support POCO , car ce serait un bon moyen d'injecter un model EAV hybride sans polluer votre schéma EF.

En surface, une database sans schéma ou orientée document telle que CouchDB ou SimpleDB pour datatables user personnalisées semble idéale. Mais je suppose que cela n'aide pas beaucoup si vous ne pouvez pas utiliser autre chose que SQL et EF.

Je ne suis pas familier avec Entity Framework, mais je pencherais vers le model de database Entity-Atsortingbute-Value ( http://en.wikipedia.org/wiki/Entity-Atsortingbute-Value_model ).

Ainsi, plutôt que de créer des tables et des colonnes à la volée, votre application créerait des attributes (ou des collections d'attributes), puis vos users finaux compléteraient les valeurs.

Mais, comme je l'ai dit, je ne sais pas ce que l'Entity Framework est censé faire pour vous, et il ne vous laissera peut-être pas adopter cette approche.

Ce n'est pas un commentaire critique, mais cela peut vous faire économiser du time pour souligner que c'est l'un de ces problèmes de type Don Quichotte Saint Graal. Il y a une éternelle quête depuis probablement plus de 50 ans pour créer une interface de design de database conviviale.

Les seuls quasi-succès qui ont acquis une traction significative que je peux penser sont 1. Excel (et ses prédécesseurs), 2. Filemaker (l'original, pas sa saveur actuelle), et 3. (probablement, mais douteusement) . Notez que les deux premiers sont limités à une seule table.

Je serais surpris si notre sagesse collective collective va vous aider à franchir la barrière. Mais ce serait merveilleux.

Plutôt que de réimplémenter sqlservers "CREATE TABLE", ce qui a été fait il y a de nombreuses années par une équipe de programmeurs qui étaient probablement meilleurs que vous ou moi, pourquoi ne pas exposer SQLSERVER de façon limitée aux users? leur propre schéma de manière limitée et tirer parti de la puissance de SQLServer pour le faire correctement.

Je voudrais juste leur donner une copy de SQL Server Management Studio, et dire, "allez fou!" Pourquoi réinventer une roue dans une roue?

Consultez ce post, vous pouvez le faire, mais c'est beaucoup de travail 🙂 Si la performance n'est pas une préoccupation, une solution XML pourrait fonctionner aussi bien que c'est aussi beaucoup de travail.