web-dev-qa-db-fra.com

Comment stocker un tableau ou plusieurs valeurs dans une colonne

Exécution de Postgres 7.4 (oui, nous sommes en train de mettre à jour)

J'ai besoin de stocker de 1 à 100 éléments sélectionnés dans un champ d'une base de données. 98% du temps, il n'y aura qu'un seul élément entré, et 2% du temps (si cela), il y aura plusieurs éléments.

Les éléments ne sont rien de plus qu'une description textuelle, (pour l'instant) rien de plus de 30 caractères. Ce sont des valeurs statiques que l'utilisateur sélectionne.

Je voulais connaître le type de données de colonne optimal utilisé pour stocker les données souhaitées. Je pensais à BLOB mais je ne savais pas si c'était une exagération. Peut-être JSON?

J'ai aussi pensé à ENUM mais pour l'instant je ne peux pas vraiment faire ça puisque nous utilisons Postgres 7.4

Je voulais également être en mesure d'identifier facilement les éléments saisis, donc pas de mappages ou de tables de référence.

29
Phill Pafford

Vous avez quelques questions ici, je vais donc les aborder séparément:

J'ai besoin de stocker un certain nombre d'articles sélectionnés dans un champ dans une base de données

Ma règle générale est: ne le faites pas. C'est quelque chose qui, sauf nécessite une deuxième table (ou une troisième) avec une clé étrangère. Bien sûr, cela peut sembler plus facile maintenant, mais que se passe-t-il si le cas d'utilisation vient où vous devez réellement interroger ces éléments individuellement? Cela signifie également que vous disposez de plus d'options pour l'instanciation paresseuse et que vous bénéficiez d'une expérience plus cohérente dans plusieurs cadres/langages. De plus, vous êtes moins susceptible d'avoir des problèmes de délai d'attente de connexion (30 000 caractères, c'est beaucoup).

Vous avez mentionné que vous envisagiez d'utiliser ENUM. Ces valeurs sont-elles fixes? Les connaissez-vous à l'avance? Si oui, ce serait ma structure:

Table de base (ce que vous avez maintenant):

| id primary_key sequence
| -- other columns here.

Tableau des articles:

| id primary_key sequence
| descript VARCHAR(30) UNIQUE

Table de carte:

| base_id  bigint
| items_id bigint

La table de mappage aurait des clés étrangères, donc base_id mappe sur la table de base et items_id mapperait sur la table des éléments.

Et si vous souhaitez un moyen simple de le récupérer à partir d'une base de données, créez une vue qui fait les jointures. Vous pouvez même créer des règles d'insertion et de mise à jour afin de ne traiter pratiquement qu'une seule table.

Quel format dois-je utiliser pour stocker les données?

Si vous devez faire quelque chose comme ça, pourquoi ne pas simplement utiliser une chaîne délimitée par des caractères? Cela prendra moins de puissance de traitement qu'un CSV, XML ou JSON, et il sera plus court.

Quel type de colonne dois-je utiliser pour stocker les données?

Personnellement, j'utiliserais TEXT. Il ne semble pas que vous gagneriez beaucoup à en faire un BLOB, et TEXT, selon mon expérience, est plus facile à lire si vous utilisez une forme d'IDE.

41
cwallenpoole

Eh bien, il y a un type de tablea dans les versions récentes de Postgres (pas 100% sur PG 7.4). Vous pouvez même les indexer à l'aide d'un index GIN ou Gist. Les syntaxes sont:

create table foo (
  bar  int[] default '{}'
);

select * from foo where bar && array[1] -- equivalent to bar && '{1}'::int[]

create index on foo using gin (bar); -- allows to use an index in the above query

Mais comme le suggère la réponse précédente, il sera préférable de normaliser correctement.

6
Denis de Bernardy