2010-04-14 27 views
1

J'ai un modèle, disons, Item. Je veux stocker un nombre arbitraire d'attributs, comme title, description, release_date. Et je veux qu'ils ne soient pas seulement des chaînes mais ont un type python, donc string, booléen, datetime, etc.Données typées arbitraires dans le modèle django

Quelles sont mes options ici? Le modèle EAV avec une table de nom-valeur séparée ne fonctionnera pas en raison du même type de base de données pour toutes les valeurs. JSONField peut probablement aider, mais il ne connaît pas datetime, par exemple. De plus, je regardais PickeField, ça correspond parfaitement, mais je suis un peu préoccupé par la performance.

Répondre

4

Vous avez quelques options et aucune d'elles n'est géniale. Certains d'entre eux ont été discutés before sur Stack Overflow. Tout d'abord, comme vous l'avez suggéré, vous avez le modèle de conception entité-attribut-valeur.

  • Vous pouvez ajouter une vérification de type de base de données en disposant d'une table pour VARCHAR, une autre pour les INT et une autre pour les BOOLEAN, et ainsi de suite. EAV rend les sélections très douloureuses. Vous devez interroger un certain nombre de tables pour obtenir réellement un objet et si vous devez utiliser des valeurs de la table EAV dans la recherche, vous rencontrerez des problèmes de performances à mesure que la taille augmente.
  • En général, cependant, EAV ne doit être utilisé que pour des données très rares, où une autre option ne fonctionne tout simplement pas.
  • Il y a un paquet Django pour cela sur PyPI, mais je ne l'ai pas utilisé.
  • J'ai vu quelques produits commerciaux à grande échelle assez grande qui utilisent cette approche quand beaucoup de flexibilité est absolument nécessaire

Une approche légèrement mieux est d'avoir une table dont les changements de schéma et une table de métadonnées qui décrit ce tableau . Pour les données denses où la plupart des éléments ont la plupart des attributs, cela a beaucoup d'avantages sur EAV. Cette approche est parfois appelée tables dynamiques ou lignes dynamiques.

  • INSERT, UPDATE et DELETE sont beaucoup plus rapides puisque tout est dans 1-2 tables
  • vérification de type et potentiellement contraintes peuvent être ajoutées
  • Cependant, cette approche laisse une base de données très complexe qui peut être plus difficile à travailler avec
  • Je ne sais pas comment Django utiliserait son ORM avec ce type de base de données puisque vos modèles changeraient à la volée.
  • Vous modifiez votre base de données avec ALTER TABLE à la volée. Mieux vaut être très prudent avec vos transactions

Une bonne approche si vous n'avez pas besoin d'effectuer de recherches basées sur ces attributs dynamiques est de stocker des données dynamiques dans un JSONField ou mieux encore un XMLField validé par un schéma. Cependant, les recherches seront pénibles si vous devez rechercher en fonction d'un attribut dynamique qui fait partie de votre JSON ou XML. La meilleure approche dépend de la rareté de vos données et de la façon dont vous allez rechercher ces données. Aussi, une très bonne question à poser est de savoir si vous avez absolument besoin de cette flexibilité. J'ai travaillé sur certains projets où nous avons décidé que nous avions besoin d'EAV mais depuis que le projet est entré dans la production, les attributs sont rarement ajoutés et rarement enlevés, donc nous avons tous les inconvénients et aucun des avantages.

Questions connexes