J'essaie de décider de la conception de la base de données, avec le moins d'hypothèses (concernant l'évolution réelle de l'application Web) à ce stade.
Dans un premier temps, sachant que les JOINS sont chers, je considère un petit nombre de tables monolithiques par opposition à un grand nombre de tables plus petites normalisées. Comme deuxième point, je suis confus entre l'utilisation de hstore par rapport aux tables régulières par rapport à JSONB (avec indexation GiST).
AFAIK (n'hésitez pas à corriger):
Généralement, dans Postgres, hstore est connu pour être plus performant que les autres types de données. Cette présentation de FOSDEM PGDAY a des statistiques intéressantes (dans la seconde moitié des diapositives). https://wiki.postgresql.org/images/b/b4/Pg-as-nosql-pgday-fosdem-2013.pdf
Un avantage avec hstore est l'indexation rapide (GiN ou GiST). Cependant, avec JSONB, l'indexation GiN et GiST peut également être appliquée aux données JSON.
Ce blog d'un professionnel du 2nd Quadrant dit "À ce stade, il vaut probablement la peine de remplacer l'utilisation de hstore par jsonb dans toutes les nouvelles applications" (faites défiler jusqu'à la fin): http://blog.2ndquadrant.com/postgresql-anti-patterns-unnecessary -jsonhstore-dynamic-columns /
Je voudrais donc décider de ce qui suit:
- Pour la partie principale (structurée) des données: doit-elle aller dans quelques tables relationnelles (relativement grandes avec de nombreuses colonnes), ou doit-elle être un certain nombre de magasins de valeurs-clés utilisant hstore?
- Pour les données ad hoc (contribuées par l'utilisateur / non structurées), doivent-elles se trouver dans JSON ou dans des magasins de valeurs de clés ad hoc dans hstore (avec les clés stockées dans l'une des principales tables relationnelles)?
la source
JSON(B)
ethstore
(et EAV) conviennent aux données de structure inconnue.Réponses:
Les bases de données relationnelles sont conçues autour des jointures et optimisées pour bien les faire.
Sauf si vous avez une bonne raison de ne pas utiliser un design normalisé, utilisez un design normalisé.
jsonb
et des choses commehstore
sont bonnes lorsque vous ne pouvez pas utiliser un modèle de données normalisé, comme lorsque le modèle de données change rapidement et est défini par l'utilisateur.Si vous pouvez le modéliser de manière relationnelle, modélisez-le de manière relationnelle. Si vous ne le pouvez pas, pensez à json, etc. Si vous choisissez entre json / jsonb / hstore, choisissez généralement jsonb, sauf si vous avez une raison de ne pas le faire.
C'est ce que j'ai dit dans mon article de blog , qui ne traite que de ce sujet. Veuillez lire l'intégralité du message . Le paragraphe que vous avez cité souligne que si vous choisissez une structure dynamique, vous devez choisir jsonb plutôt que hstore, mais le reste de l'article de blog explique pourquoi vous devriez généralement préférer modéliser de manière relationnelle si vous le pouvez.
Alors. Modélisez la partie structurée principale de manière relationnelle. Si les tables sont vraiment larges avec beaucoup de colonnes, cela pourrait être un signe qu'une normalisation supplémentaire est nécessaire. N'ayez pas peur des jointures. Apprenez à aimer les jointures. Rejoindre de nombreuses petites tables sera souvent plus rapide que d'interroger et de gérer de grandes tables dénormalisées. Ne dénormalisez que si vous en avez besoin pour des cas spécifiques, et de préférence via des vues matérialisées ... mais ne le faites pas avant de savoir que vous en avez besoin et que vous avez un problème concret à résoudre.
Pour les données fournies par les utilisateurs de forme libre et non structurées, utilisez jsonb. Il devrait fonctionner aussi bien que hstore, mais il est plus flexible et plus facile à utiliser.
Une chose pertinente à comprendre: les index GiST et GIN comme ceux utilisés sur jsonb sont généralement beaucoup moins efficaces qu'un index b-tree simple. Ils sont plus flexibles, mais un index b-tree sur une colonne normale sera presque toujours beaucoup, beaucoup plus rapide.
la source
hstore
est obsolète. Utilisezjsonb
.