Donc, selon la réponse de Mehrdad à une question connexe , je comprends qu'une colonne de table de base de données "appropriée" ne stocke pas de liste. Au lieu de cela, vous devez créer une autre table qui contient effectivement les éléments de ladite liste, puis créer un lien vers elle directement ou via une table de jonction. Cependant, le type de liste que je souhaite créer sera composé d'éléments uniques (contrairement au fruit de la question liéeexemple). De plus, les éléments de ma liste sont explicitement triés - ce qui signifie que si je stockais les éléments dans une autre table, je devrais les trier chaque fois que j'y accédais. Enfin, la liste est fondamentalement atomique en ce sens que chaque fois que je souhaite accéder à la liste, je veux accéder à la liste entière plutôt qu'à un morceau de celle-ci - il semble donc ridicule de devoir émettre une requête de base de données pour rassembler des éléments de la liste.
La solution d'AKX (lien ci-dessus) est de sérialiser la liste et de la stocker dans une colonne binaire. Mais cela semble également gênant car cela signifie que je dois me soucier de la sérialisation et de la désérialisation.
Y a-t-il une meilleure solution? S'il n'y a pas de solution meilleure, alors pourquoi? Il semble que ce problème devrait survenir de temps en temps.
... juste un peu plus d'informations pour vous dire d'où je viens. Dès que je venais de commencer à comprendre SQL et les bases de données en général, je me suis tourné vers LINQ to SQL, et maintenant je suis un peu gâté car je compte gérer mon modèle d'objet de programmation sans avoir à réfléchir à la façon dont les objets sont interrogés ou stockés dans la base de données.
Merci a tous!
John
MISE À JOUR: Donc, dans la première vague de réponses que j'obtiens, je vois "vous pouvez aller sur la route CSV / XML ... mais NE PAS!". Alors maintenant, je cherche des explications sur pourquoi. Montrez-moi quelques bonnes références.
Aussi, pour vous donner une meilleure idée de ce que je fais: Dans ma base de données, j'ai une table Function qui contiendra une liste de paires (x, y). (Le tableau contiendra également d'autres informations sans conséquence pour notre discussion.) Je n'aurai jamais besoin de voir une partie de la liste des paires (x, y). Je vais plutôt les prendre tous et les tracer à l’écran. Je vais permettre à l'utilisateur de faire glisser les nœuds pour changer les valeurs de temps en temps ou ajouter plus de valeurs au tracé.
Vous pouvez simplement oublier SQL tous ensemble et opter pour une approche "NoSQL". RavenDB , MongoDB et CouchDB viennent à l'esprit en tant que solutions possibles. Avec une approche NoSQL, vous n'utilisez pas le modèle relationnel. Vous n'êtes même pas contraint de schémas.
la source
Voici ce que j'ai vu beaucoup de gens faire (ce n'est peut-être pas la meilleure approche, corrigez-moi si je me trompe):
Le tableau que j'utilise dans l'exemple est donné ci-dessous (le tableau comprend les surnoms que vous avez donnés à vos petites amies spécifiques. Chaque petite amie a un identifiant unique):
Supposons que vous souhaitiez stocker de nombreux surnoms sous un identifiant. C'est pourquoi nous avons inclus un
seq_no
champ.Maintenant, remplissez ces valeurs dans votre table:
Si vous voulez trouver tous les noms que vous avez donnés à votre petite amie id 1, vous pouvez utiliser:
la source
Réponse simple: Si, et seulement si, vous êtes certain que la liste sera toujours utilisée comme une liste, joignez la liste de votre côté avec un caractère (tel que '\ 0') qui ne sera pas utilisé dans le texte jamais, et stockez-le. Ensuite, lorsque vous le récupérez, vous pouvez le diviser par '\ 0'. Il existe bien sûr d'autres façons de procéder, mais celles-ci dépendent de votre fournisseur de base de données spécifique.
À titre d'exemple, vous pouvez stocker JSON dans une base de données Postgres. Si votre liste est du texte et que vous voulez juste la liste sans autre tracas, c'est un compromis raisonnable.
D'autres ont osé des suggestions de sérialisation, mais je ne pense pas vraiment que la sérialisation soit une bonne idée: une partie de la chose intéressante à propos des bases de données est que plusieurs programmes écrits dans des langues différentes peuvent se parler. Et les programmes sérialisés au format Java ne feraient pas très bien si un programme Lisp voulait le charger.
Si vous voulez un bon moyen de faire ce genre de chose, il existe généralement des types de tableaux ou similaires disponibles. Postgres, par exemple, propose un tableau comme type et vous permet de stocker un tableau de texte, si c'est ce que vous voulez , et il existe des astuces similaires pour MySql et MS SQL utilisant JSON, et DB2 d'IBM propose également un type de tableau (dans leur propre documentation utile ). Ce ne serait pas si courant s'il n'y avait pas besoin de cela.
Ce que vous perdez en empruntant cette voie, c'est la notion de liste comme un ensemble de choses en séquence. Au moins nominalement, les bases de données traitent les champs comme des valeurs uniques. Mais si c'est tout ce que vous voulez, alors vous devriez y aller. C'est un jugement de valeur que vous devez faire pour vous-même.
la source
En plus de ce que tout le monde a dit, je vous suggère d'analyser votre approche à plus long terme que maintenant. Il est actuellement le cas que les éléments sont uniques. Il est actuellement le cas que le recours aux éléments nécessiterait une nouvelle liste. Il est presque obligatoire que la liste soit actuellement courte. Même si je n'ai pas les spécificités du domaine, il n'est pas difficile de penser que ces exigences pourraient changer. Si vous sérialisez votre liste, vous cuisez dans une rigidité qui n'est pas nécessaire dans une conception plus normalisée. Btw, cela ne signifie pas nécessairement une relation Many: Many complète. Vous pouvez simplement avoir une seule table enfant avec une clé étrangère vers le parent et une colonne de caractères pour l'élément.
Si vous souhaitez continuer à sérialiser la liste, vous pouvez envisager de stocker la liste au format XML. Certaines bases de données telles que SQL Server ont même un type de données XML. La seule raison pour laquelle je suggère XML est que, presque par définition, cette liste doit être courte. Si la liste est longue, la sérialiser en général est une approche horrible. Si vous utilisez la route CSV, vous devez tenir compte des valeurs contenant le délimiteur, ce qui signifie que vous êtes obligé d'utiliser des identificateurs entre guillemets. En supposant que les listes sont courtes, le fait d'utiliser CSV ou XML ne changera probablement pas grand-chose.
la source
Je le stockerais simplement au format CSV, si ce sont des valeurs simples, cela devrait être tout ce dont vous avez besoin (XML est très verbeux et sérialiser vers / à partir de celui-ci serait probablement excessif, mais ce serait également une option).
Voici une bonne réponse pour savoir comment extraire des CSV avec LINQ.
la source
Si vous devez interroger la liste, stockez-la dans une table.
Si vous voulez toujours la liste, vous pouvez la stocker sous forme de liste délimitée dans une colonne. Même dans ce cas, sauf si vous avez des raisons TRÈS spécifiques de ne pas le faire, stockez-le dans une table de consultation.
la source
Une seule option n'est pas mentionnée dans les réponses. Vous pouvez dé-normaliser votre conception de base de données. Vous avez donc besoin de deux tables. Une table contient la liste appropriée, un élément par ligne, une autre table contient la liste entière dans une colonne (séparée par des virgules, par exemple).
Ici, c'est la conception DB `` traditionnelle '':
Ici, il s'agit d'un tableau dénormalisé:
L'idée ici - vous gérez la table des listes à l'aide de déclencheurs ou de code d'application. Chaque fois que vous modifiez le contenu List_Item, les lignes appropriées dans les listes sont mises à jour automatiquement. Si vous lisez principalement des listes, cela pourrait fonctionner très bien. Avantages - vous pouvez lire les listes en une seule déclaration. Inconvénients - les mises à jour prennent plus de temps et d'efforts.
la source
Si vous voulez vraiment le stocker dans une colonne et le rendre interrogeable, de nombreuses bases de données prennent désormais en charge XML. Sinon, vous pouvez les stocker en tant que valeurs séparées par des virgules et les analyser avec une fonction lorsque vous en avez besoin. Je suis d'accord avec tout le monde cependant si vous cherchez à utiliser une base de données relationnelle, une grande partie de la normalisation est la séparation des données comme ça. Je ne dis pas que toutes les données correspondent à une base de données relationnelle. Vous pouvez toujours consulter d'autres types de bases de données si une grande partie de vos données ne correspond pas au modèle.
la source
Je pense que dans certains cas, vous pouvez créer une FAKE "liste" d'articles dans la base de données, par exemple, la marchandise a quelques images pour montrer ses détails, vous pouvez concaténer tous les identifiants d'images divisés par une virgule et stocker la chaîne dans la base de données, il vous suffit d'analyser la chaîne lorsque vous en avez besoin. Je travaille actuellement sur un site Web et je prévois de l'utiliser de cette façon.
la source
J'étais très réticent à choisir la voie que je décide finalement d'emprunter à cause de nombreuses réponses. Bien qu'ils ajoutent plus de compréhension à ce qu'est SQL et à ses principes, j'ai décidé de devenir un hors-la-loi. J'ai également hésité à publier mes conclusions car pour certains, il est plus important d'exprimer la frustration de quelqu'un qui enfreint les règles plutôt que de comprendre qu'il y a très peu de vérités universelles.
Je l'ai testé de manière approfondie et, dans mon cas spécifique, il était bien plus efficace que d'utiliser le type de tableau (généreusement offert par PostgreSQL) ou d'interroger une autre table.
Voici ma réponse: j'ai implémenté avec succès une liste dans un seul champ dans PostgreSQL, en utilisant la longueur fixe de chaque élément de la liste. Supposons que chaque élément soit une couleur en tant que valeur hexadécimale ARVB, cela signifie 8 caractères. Ainsi, vous pouvez créer votre tableau de 10 éléments maximum en multipliant par la longueur de chaque élément:
Si la longueur des éléments de votre liste diffère, vous pouvez toujours remplir le remplissage avec \ 0
NB: Evidemment ce n'est pas forcément la meilleure approche pour le nombre hexadécimal car une liste d'entiers consommerait moins de stockage mais c'est juste dans le but d'illustrer cette idée de tableau en utilisant une longueur fixe allouée à chaque élément.
La raison pour laquelle: 1 / Très pratique: récupérer l'élément i à la sous-chaîne i * n, (i +1) * n. 2 / Pas de surcharge des requêtes de tables croisées. 3 / Plus efficace et plus économique côté serveur. La liste est comme un mini blob que le client devra fractionner.
Bien que je respecte les gens qui suivent des règles, de nombreuses explications sont très théoriques et omettent souvent de reconnaître que, dans certains cas spécifiques, en particulier lorsque l'on vise un coût optimal avec des solutions à faible latence, certains ajustements mineurs sont plus que bienvenus.
"Dieu nous en préserve qu'il viole un principe sacré sacré de SQL": Adopter une approche plus ouverte d'esprit et pragmatique avant de réciter les règles est toujours la voie à suivre. Sinon, vous pourriez finir comme un fanatique candide récitant les trois lois de la robotique avant d'être effacé par Skynet
Je ne prétends pas que cette solution soit une percée, ni qu'elle soit idéale en termes de lisibilité et de flexibilité de base de données, mais elle peut certainement vous donner un avantage en matière de latence.
la source
De nombreuses bases de données SQL permettent à une table de contenir une sous-table en tant que composant. La méthode habituelle consiste à autoriser le domaine de l'une des colonnes à être une table. Cela s'ajoute à l'utilisation d'une convention telle que CSV pour coder la sous-structure d'une manière inconnue du SGBD.
Lorsque Ed Codd développait le modèle relationnel en 1969-1970, il a spécifiquement défini une forme normale qui interdirait ce type d'imbrication de tables. La forme normale a ensuite été appelée première forme normale. Il a ensuite montré que pour chaque base de données, il existe une base de données dans la première forme normale qui exprime les mêmes informations.
Pourquoi s'embêter avec ça? Eh bien, les bases de données dans la première forme normale permettent un accès par clé à toutes les données. Si vous fournissez un nom de table, une valeur de clé dans cette table et un nom de colonne, la base de données contiendra au plus une cellule contenant un élément de données.
Si vous autorisez une cellule à contenir une liste, un tableau ou toute autre collection, vous ne pouvez plus fournir un accès par clé aux sous-éléments, sans retravailler complètement l'idée d'une clé.
L'accès par clé à toutes les données est fondamental pour le modèle relationnel. Sans ce concept, le modèle n'est pas relationnel. Quant à savoir pourquoi le modèle relationnel est une bonne idée, et quelles pourraient être les limites de cette bonne idée, vous devez examiner les 50 années d'expérience accumulées avec le modèle relationnel.
la source
vous pouvez le stocker sous forme de texte qui ressemble à une liste et créer une fonction qui peut renvoyer ses données sous forme de liste réelle. exemple:
base de données:
Et la fonction de compilation de liste (écrite en python, mais elle devrait être facilement traduisible dans la plupart des autres langages de programmation). TEXT représente le texte chargé à partir de la table sql. renvoie la liste des chaînes de la chaîne contenant la liste. si vous voulez qu'il renvoie des entiers au lieu de chaînes, rendez le mode égal à «int». De même avec 'string', 'bool' ou 'float'.
Voici également une fonction de liste à chaîne au cas où vous en auriez besoin.
la source