PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Recherche d'une bonne structure EAV basée sur jsonb

Objectif :Vous souhaitez stocker un attribut lié à une entité donnée.

Je ne recommande pas une table séparée pour les valeurs d'attribut comme nous aurions pu le faire dans le passé. Mettez un jsonb champ droit sur la table appropriée et appelez-le Attributes . Ajouter un GIN indexez-le afin que vous puissiez interroger les valeurs rapidement. Ou utilisez les autres techniques décrites dans.

Lisez ceci :https://dba.stackexchange.com/a/174421/7762

La plus grande question ici est de savoir si vous avez l'intention de prédéfinir des valeurs d'attribut. Si vous le faites, il existe un moyen extrêmement efficace de les stocker. Sinon, je recommande un objet JSON standard.

Si vous pouvez prédéfinir les noms ET les valeurs de vos attributs :

Cela vous donne le plus de contrôle, de vitesse et offre toujours de la flexibilité.

Créer une table Attribute qui a ces champs :

  • AttributeID int4 unsigned not null primary key
  • ParentAttributeID int4 unsigned null
  • Name varchar(64) not null
  • Deleted bool non nul par défaut faux
  • Ajouter un index sur ParentAttributeID
  • Ajouter un déclencheur pour empêcher AttributeID de changer
  • Ajoutez une règle sur la suppression, définissez à la place Deleted=True

Ensuite, dans n'importe quelle table que vous souhaitez attribuer, ajoutez ce champ :

Qu'est-ce que cela a accompli ?

Vous avez créé une arborescence d'attributs. Cela pourrait ressembler à ceci :

ID   Parent  Name
----------------------------
100  NULL    Color
101  100       Blue
102  100       Red
103  100       Green
110  NULL    Size
111  110       Large
112  110       Medium 
113  110       Small

Supposons que vous ayez une table appelée Items et dessus vous avez ajouté AttributeSet :

      ItemID: 1234
        Name: Tee Shirt
AttributeSet: [100, 103, 110, 112]

Une fois traduit, cela signifie qu'il a le Color=Green et l'attribut Size=Medium attribut. 103 et 112 étaient suffisants pour stocker cela, mais parfois c'est bien de pouvoir dire "Montre-moi tous les articles qui ont une taille définie", c'est pourquoi 110 a été inclus.

Vous pouvez rendre cela rapide comme l'éclair et ultra flexible.

SELECT
  "ItemID", "Name"
FROM
  "Items"
WHERE "AttributeMap" @> ARRAY[103,112]

Renverra tous les articles qui ont Size=Medium et Color=Green

Ou vous pouvez utiliser les autres opérateurs sur https://www.postgresql .org/docs/10/static/functions-array.html pour trouver des requêtes géniales.

Lorsque vous ne connaissez pas les valeurs des attributs, mais qu'il s'agit d'un petit ensemble :

Cela vous donne le plus de vitesse, de contrôle et est encore plus flexible. Vous pouvez marquer de nouveaux attributs pour examen si nécessaire.

Vous pouvez utiliser la technique ci-dessus et simplement ajouter dynamiquement des valeurs à l'Attribute table s'ils n'existent pas.

Lorsque vous ne connaissez pas les valeurs des attributs et que les valeurs sont diverses

Cela vous donne le plus de flexibilité, mais au détriment du contrôle.

Dans ce cas, ajoutez simplement ceci à n'importe quel tableau :

  • AttributeMap jsonb not null default '{}'::jsonb
  • Ajouter un index GIN à ce champ

Écrivez du code pour valider les valeurs par rapport à votre Attribute table. Ayez un indicateur s'il s'agit d'une valeur unique ou multiple...

Stockez comme ceci dans le AttributeMap champ :

{
    "Color": "Green", 
    "Size": "Medium", 
    "Categories": ["Sports", "Leisure"]
}

Notez que Catégories est un multi-attribut. Dans votre Attribute table, vous devriez avoir un champ qui est IsMulti bool not null qui vous permettra de savoir comment l'interroger.