Est-ce une mauvaise pratique d'avoir plusieurs relations un à un mutuellement exclusives?

38

Par exemple, une table cara une-à-une relation de tables electric_car, gas_caret hybrid_car. Si a carest electric_car, il ne peut plus apparaître dans gas_carou a hybrid_car, etc.

Y a-t-il un problème avec un tel design? Certains problèmes peuvent survenir plus tard?

Arthur Tarasov
la source

Réponses:

59

Les différents types de voitures illustrent un problème général qui se répète sans cesse dans la modélisation des données. On l'appelle "généralisation / spécialisation" dans la modélisation ER, et "superclasse / sous-classe" dans la modélisation d'objet.

Un modélisateur d'objets utilise les fonctionnalités d'héritage intégrées au modèle d'objet pour résoudre le problème assez facilement. Les sous-classes étendent simplement la super-classe.

Le modeleur relationnel est confronté à un problème. comment concevoir les tables de manière à imiter les avantages que l’on obtiendrait de l’héritage?

La technique la plus simple s'appelle l' héritage d'une table . Les données sur tous les types de voitures sont regroupées dans un seul tableau pour les voitures. Il existe une colonne, type_car, qui regroupe toutes les voitures d'un même type. Aucune voiture ne peut appartenir à plus d'un type. Si une colonne ne concerne pas, par exemple, les voitures électriques, elle sera laissée à NULL dans les lignes relatives aux voitures électriques.

Cette solution simple fonctionne bien pour les cas plus petits et plus simples. La présence d'un grand nombre de valeurs NULL ajoute un tout petit peu à la surcharge de stockage et un peu à la charge de récupération. Le développeur devra peut-être apprendre la logique à trois valeurs SQL si des tests booléens sont effectués sur des colonnes nullables. Cela peut être déconcertant au début, mais on s'y habitue.

Il existe une autre technique, appelée héritage de table de classe . Dans cette conception, il existe des tables séparées pour gas_car, electric_car et hybrid_car, en plus d'une table combinée, voiture, pour chacune d'entre elles. Lorsque vous souhaitez obtenir toutes les données sur un type de voiture spécifique, vous joignez la table des voitures à la table spécialisée appropriée. Il y a moins de valeurs NULL dans cette conception, mais vous en faites davantage. Cette technique fonctionne mieux dans les cas les plus grands et les plus complexes.

Il existe une troisième technique appelée clé primaire partagée. Cette technique est souvent utilisée conjointement avec l'héritage des tables de classes. Les tables spécialisées des sous-classes ont pour clé primaire une copie de la clé primaire de l'entrée correspondante dans la table car. Cette colonne id peut être déclarée comme étant à la fois la clé primaire et une clé étrangère.

Cela implique un peu plus de programmation lorsque de nouvelles voitures doivent être ajoutées, mais cela rend les jointures simples, faciles et rapides.

Les super-classes et les sous-classes se produisent tout le temps dans le monde réel. N'aie pas peur. Mais testez votre conception initiale pour en vérifier les performances. Si votre première tentative est simple et saine, vous pourrez l’ajuster pour l’accélérer.

Walter Mitty
la source
3
Wow merci! C'est ce que j'essayais de comprendre. L'héritage des tables de classes semble être précisément ce dont j'ai besoin. J'ai changé ma réponse acceptée à cela pour les futurs lecteurs car je pense que cela couvre complètement la question, pas seulement mon cas.
Arthur Tarasov
6
Excellente réponse ici. Un conseil: documentez minutieusement ces décisions de conception. Quelle que soit la route choisie, ce ne sera pas évident quand quelqu'un examinera la structure de la base de données. Certaines bases de données telles que Postgres vous permettent de lier un commentaire avec les métadonnées de vos colonnes, tables et autres.
Basil Bourque
Vous ne parlez pas de la restriction visant à empêcher les voitures électriques d'être également des voitures hybrides. Vous avez besoin d'une table séparée pour cela.
Jmoreno
2
Vous avez raison. Si vous ajoutez un champ car_type à la table des voitures, vous pouvez limiter les voitures à un seul type, au détriment de la déviation de la normalisation complète. Un bon SGBD vous permettra de définir une contrainte de vérification qui empêchera une voiture d’être saisie dans plusieurs tables spécialisées. Il y a des frais généraux dans cela, vous allez ajouter de nouvelles voitures.
Walter Mitty
@WalterMitty mais sans car_typechamp, comment sauriez-vous quelle table rechercher dans les détails lors de la récupération des données? Devez-vous lire les trois tableaux pour voir lequel contient des données sur cet carenregistrement spécifique ?
Josh Part
12

Il n'y a rien de mal à avoir dans votre modèle autant de sous-types d'entités qu'il est nécessaire pour refléter la réalité des données que vous essayez de modéliser. La question n'est pas de savoir si les sous-types sont une mauvaise pratique. La question peut être est-ce que c'est un bon modèle ?

Par exemple, dans votre exemple, que faites-vous avec quelque chose comme une Audi A4 eTron - qui est un hybride plug-in? Est-ce une "voiture électrique" ou est-ce une "voiture hybride"?

L'autre question que vous devez vous poser est de savoir pourquoi vous sous-tapez du tout. Combien de prédicats distincts avez-vous dans vos sous-types? Certains de ces prédicats sont-ils partagés entre des sous-types? La situation pourrait se compliquer.

Le sous-typage n'est pas utilisé dans la conception de la base de données pour la classification. Vous pouvez effectuer une classification avec des codes, des clés étrangères dans des tables de codes ou des indicateurs. Le sous-typage est utilisé pour modéliser des ensembles de prédicats distincts pour différents types d'objets d'intérêt. Si vous utilisez des sous-types uniquement à des fins de classification, c'est une mauvaise pratique.

Si vos sous-types modélisent clairement et sans ambiguïté différents ensembles de prédicats pour les éléments qui intéressent votre base de données, il s'agit d'une excellente pratique, quel que soit le nombre de sous-types dont vous avez besoin.

Joel Brown
la source
Merci, j'avais peur de me faire une sorte de piège. Mon problème est que chacun des sous-types aura beaucoup de colonnes. Certains se chevaucheront et je les mettrai dans un cartableau, mais beaucoup ne le seront pas et seront placés dans un tableau de sous-types. Par exemple, ce sera quelque chose comme stocker des pièces élémentaires de types de voiture. Le moteur de voiture électrique peut comporter 100 pièces, le moteur de voiture à essence 75 pièces et une pièce hybride 125 pièces. 50 parties seraient communes et stockées dans cars, tandis que 50, 25 et 75 seront dans electric_car, gas_caret hybrid_cartables
Arthur Tarasov