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

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!


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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.