Meilleur moyen de stocker une valeur pouvant être de plusieurs types

10

Je voudrais poser une question de manière plus directe et générale:

Comment créez-vous une table pour stocker des valeurs qui pourraient être de plusieurs types différents?

Dans mon cas, les valeurs fournissent des diagnostics sur un événement. Ex: l'événement s'est produit -> Stocker les lectures de plusieurs automates qui contiennent des informations pertinentes sur l'événement. Les automates peuvent surveiller tout type de données.

Quelques exemples auxquels je peux penser:

  • Créez une colonne pour chaque type possible et créez une autre colonne pour indiquer la colonne à utiliser
    • Ex: Cols: IntVal, StrVal, BoolVal, Type. Vals: null, null, True, "BOOL"
  • Stockez les valeurs n'importe quoi en tant que varchar
Plage de Jared
la source

Réponses:

9

Il semblerait que l'on vous ait déjà dit que vous vous dirigiez vers le modèle EAV . Jetez un œil à l' image ici pour savoir pourquoi le modèle EAV devrait être évité à pratiquement tous les coûts.

Bill Karwin, l'auteur responsable de l'image ci-dessus, a écrit un livre "SQL Antipatterns: éviter les pièges de la programmation de base de données" et il consacre le premier chapitre à l'anti-modèle EAV. Il est également un grand frappeur sur ce groupe et énorme sur StackOverflow (pour les problèmes de base de données).

Mon conseil serait d'avoir un tableau pour chaque type de résultat puis d'utiliser les VIEWs pour les combiner si nécessaire.

Par exemple, vous pourriez avoir

CREATE TABLE char_result
(
  question_id INT,
  user_id INT,
  cresult CHAR,
  result_correct BOOLEAN (or equivalent in your RDBMS)
  ..
  <other stuff>
  ..
);

Faites de même pour num_result, sauf remplacez nresult INT (FLOAT ... que ce soit) pour cresult - même idée pour VARCHAR & c.

Créez ensuite des VIEWs sur vos différents tableaux de résultats pour result_correct(et d'autres champs - number_of_attempts... & c. - quels que soient vos autres champs). Dans ce cas, vous comparez le même avec le même et ne faites pas de calculs équivalents à l'ajout de population à l'altitude selon l'image hilarante référencée ci-dessus!

Vérace
la source
Pour contrer Bill, j'ai écrit en faveur de l'EAV ici: sqlblog.com/blogs/aaron_bertrand/archive/2009/11/19/…
Aaron Bertrand
Je ne pense pas que le fait d'avoir plusieurs types possibles pour la même colonne logique constitue un EAV. Je pense qu'il cherche un type "variant / objet". C'est beaucoup plus facile à faire avec quelques colonnes qu'une table par type. Cela semble très gênant. Et une fois la vue créée, c'est vraiment la même chose que de créer les types dans la même table en premier lieu.
usr
@usr Je serais intéressé de voir votre solution.
Jared Beach
2
Une seule colonne par type me semble correcte. Je l'ai fait comme ça dans le passé. C'est la moins mauvaise solution. Voici un autre argument: et s'il y avait deux colonnes de type variable. La solution de cette réponse nécessite un nombre quadratique de tables. On pourrait le diviser en une table de base plus N * M plus de tables ... Cela ne semble pas correct.
usr
@usr n'est pas un problème avec votre solution qu'aucune de ces colonnes ne peut l'être NOT NULL? Personnellement, je suis un grand NOT NULLpartisan de la constance autant que possible .
Vérace
2

Je pense que s'il était absolument nécessaire de stocker une valeur de cette façon dans une base de données relationnelle, j'utiliserais une solution comme les colonnes JSON de Microsoft SQL Server .

Plage de Jared
la source