31 votes

Une table ou plusieurs ?

J'essaie de concevoir une application pour contenir des informations sur les références académiques. Le problème est que chaque type de référence (articles de revues, livres, articles de journaux, etc.) nécessite des informations différentes. Par exemple, une référence à un journal nécessite à la fois un titre de journal et un titre d'article, ainsi qu'un numéro de page, tandis qu'un livre nécessite un éditeur et une date de publication, ce qui n'est pas le cas des articles de journaux.

Par conséquent, dois-je stocker toutes les références dans une seule table de ma base de données et laisser les champs vides lorsqu'ils ne s'appliquent pas, ou dois-je avoir plusieurs tables telles que BookReferences, JournalReferences, NewspaperReferences et placer les références appropriées dans chacune d'elles. Le problème serait alors que cela rendrait la recherche dans toutes les références plus difficile, et que l'édition devrait probablement être faite plus séparément.

(Je prévois d'utiliser Ruby on Rails pour ce projet, mais je doute que cela fasse une différence pour cette question de conception).

Mise à jour :

D'autres avis sur la question ? J'espérais obtenir une réponse simple disant qu'une méthode particulière était définitivement considérée comme "la meilleure" - mais comme d'habitude les choses ne sont pas aussi simples que cela. L'option Single-Table Inheritance semble assez intéressante, mais il n'y a pas beaucoup d'informations à son sujet que je puisse trouver très facilement - je vais peut-être poster une autre question sur ce site à ce sujet.

Je suis partagé entre Réponse d'Olvak y La réponse de Corey . La réponse de Corey donne une bonne raison pour laquelle celle d'Olvak n'est pas la meilleure, mais la réponse d'Olvak donne de bonnes raisons pour lesquelles celle de Corey n'est pas la meilleure ! Je n'avais jamais réalisé que cela pouvait être si difficile...

Tout autre conseil serait le bienvenu !

3voto

Toby Hede Points 22128

Rails supporte l'héritage Single-Table et les types ActiveRecord polymorphes. Je vous suggère d'y jeter un coup d'oeil - ActiveRecord a des opinions sur la façon dont la base de données devrait être structurée.

2voto

HLGEM Points 54641

Une grande partie de ce qui serait le mieux dépend du nombre de champs différents et de la taille des champs, vous avez une restriction sur la taille totale des lignes (cela peut être ignoré dans une certaine mesure sachant que tous les champs ne seront jamais tous remplis, mais une fois que vous arrivez à ce que les pages soient trop larges, le stockage réel dans la base de données finit par diviser l'information, ce qui rend la récupération plus longue. Ainsi, si les informations sont peu nombreuses et (c'est important) peu susceptibles de changer (il serait rare de devoir ajouter un nouveau type d'information non déjà pris en compte), alors la table unique est la meilleure solution. Si la table est trop large ou si elle est sujette à de nombreux changements possibles dans le type de données qui doivent être stockées, alors la table spearate est une meilleure approche, bien qu'elle soit toujours plus difficile à interroger correctement. Si vous voulez souvent interroger plusieurs types de références en même temps, la grande table est une approche plus efficace. Si vous n'avez généralement besoin d'en saisir qu'un seul à la fois, vous ne perdez pas grand-chose en termes d'efficacité en ayant des jointures.

Si vous optez pour une table unique, assurez-vous de mettre en place des déclencheurs sur la table afin d'appliquer les règles d'intégrité des données pour chaque type de données. Vous en aurez besoin car vous ne pouvez pas vous contenter de rendre les champs obligatoires.

L'un des problèmes liés à la séparation des tables est que vous ne savez pas, avant l'exécution, à laquelle des tables vous devez vous joindre. Cela vous place dans le domaine du SQl dynamique dont je ne suis pas un fan (pour des raisons de sécurité, d'efficacité et de maintenance) ou vous oblige à faire des jointures à gauche vers des tables dont vous pouvez avoir besoin ou non, ce qui est inefficace.

Une autre possibilité est de stocker toute la chaîne de référence dans un champ plus grand et d'utiliser l'interface utilisateur pour vérifier que toutes les parties requises sont présentes avant de concaténer l'enregistrement et d'envoyer les informations à la base de données. Cette méthode serait de loin la plus rapide pour la plupart des requêtes qui veulent toutes les informations, mais elle serait pénible si vous n'avez besoin d'extraire qu'une partie des données. Il faut aussi que toutes les données soient insérées par l'interface utilisateur, ce qui n'est pas forcément le cas pour vous. En toute honnêteté, je ne vois pas pourquoi vous auriez besoin que ces informations soient ventilées séparément, et c'est donc l'approche que je choisirais. Mais je ne connais pas vos règles de fonctionnement, alors prenez cela avec un grain de sel.

1voto

nickf Points 185423

Il y a une autre option : pas une que je soutiendrais entièrement, mais c'est quand même une autre option :

Utilisez trois tableaux :

refs (id, title, refType)
-- title of the reference, and what type of reference it is

fieldDef (id, fieldName, refType, dataType)
-- name of the field, which reference types it applies to, and
-- what type of data is stored in these fields (ISDN number, date, etc)

fields (refId, fieldId, value)
-- where you actually add data to the references.

refType peut être le type de référence, et si vous en faites un entier avec des valeurs augmentées par des puissances de deux (1, 2, 4, 8...) alors ils peuvent être additionnés pour faire un masque de bits dans la table fieldDef.

Pour : très simple et extensible. Si vous inventez un autre type de référence, ou un nouveau type de champ pour un type de référence existant, vous pouvez l'ajouter très rapidement. Des formulaires peuvent être générés automatiquement pour chaque type de référence. Toutes les données sont stockées au même endroit, ce qui signifie que vous n'avez pas besoin de suivre plusieurs schémas. (schemata ?) para Opérations CRUD .

Cons C'est de ça qu'est fait le Daily WTF. Les instructions Select peuvent devenir très confuses et compliquées. La base de données ne peut pas effectuer de contrôle de type (par exemple, pour les dates, etc.), et le champ générique "valeur" ne sera pas optimisé pour les données qui y sont stockées.

1voto

peacedog Points 913

Je ne trouve pas la nécessité de joindre des tables particulièrement fastidieuse ; j'adopterais ici une approche plus normalisée.

0voto

Simon Points 14656

Une table et un champ "type" serait ma suggestion.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X