Nous implémentons une relation un-à-plusieurs en ajoutant le PK d'une table, comme FK à l'autre table. Nous implémentons une relation plusieurs à plusieurs en ajoutant 2 PK de table à une troisième table.
Comment implémenter une relation IS-A?
Les Entités sont TECHNICIENNE et ADMINISTRATIVE qui sont toutes deux EMPLOYÉES. Je pourrais simplement utiliser un champ supplémentaire dans la table EMPLOYÉ (id, nom, prénom, rôle, ... AdminFields ..., ... TechFields ...)
mais je voudrais explorer l'option IS-A.
EDIT: J'ai fait comme Donnie l'a suggéré, mais sans le champ de rôle.
J'ai fait comme Donnie l'a suggéré, mais sans le champ role, car cela complique les choses. Ceci est la mise en œuvre finale:
DDL:
CREATE TABLE Employee (
ast VARCHAR(20) not null,
firstname VARCHAR(200) not null,
surname VARCHAR(200) not null,
...
PRIMARY KEY(ast)
);
CREATE TABLE Administrative (
employee_ast VARCHAR(20) not null REFERENCES Employee(ast),
PRIMARY KEY(employee_ast)
);
CREATE TABLE Technical (
employee_ast VARCHAR(20) not null REFERENCES Employee(ast),
...
PRIMARY KEY(employee_ast)
);
Diagramme ER:
Dans ce modèle, il n'y a pas d'employés de type générique. Ici, un employé ne peut être que administratif ou technique.
J'ai toujours fait cela avec un champ role
, puis des relations facultatives.
C'est-à-dire, table EMPLOYEE (id, ...generic fields... , role)
Et puis, pour chaque rôle:
table ROLE1 (employeeid, ...specific fields...)
Cela vous permet d'obtenir des informations générales sur les employés avec une seule requête et nécessite des jointures pour accéder aux informations spécifiques au rôle. Le seul inconvénient (gros) est que si vous avez besoin d'un super-rapport avec toutes les informations sur le rôle, vous êtes coincé avec un tas de jointures externes.
La relation IS-A est également connue sous le nom de modèle de conception gen-spec. Gen-spec est l'abréviation de "généralisation spécialisation".
La modélisation relationnelle de gen-spec est différente de la modélisation d'objet de gen-spec car le modèle relationnel n'a pas d'héritage intégré.
Voici un bon article qui montre comment implémenter gen-spec comme une collection de tables.
http://www.javaguicodexample.com/erdrelationalmodelnotes1.html
Portez une attention particulière à la façon dont les clés primaires sont configurées dans les tables spécialisées. C'est ce qui rend l'utilisation de ces tableaux si simple.
Vous pouvez trouver beaucoup d'autres articles par googlin "modélisation relationnelle de spécialisation de généralisation".
Si vous avez une application OO dont vous avez besoin pour vous connecter à une base de données back-end relationnelle, je vous recommande d'obtenir Martin Fowler Patterns of Enterprise Application Architecture .
Il a également quelques notes et diagrammes pertinents sur son site Web. Plus précisément, les modèles héritage de table unique , héritage de table de classe et héritage de table concret décrivent trois tactiques pour mapper IS-A dans les tableaux de données.
Si vous utilisez Hibernate ou JPA, ils prennent en charge les mappages pour tous ces éléments, bien qu'ils aient des noms différents pour eux.
Dans ce cas précis, je n'utiliserais pas du tout IS-A.
Des choses comme les rôles des employés sont mieux modélisées comme HAS-A, comme
Cet article décrit certaines stratégies de mappage des généralisations dans la conception de schéma.
http://www.sztaki.hu/conferences/ADBIS/3-Eder.pdf
Une copie du résumé:
Les modèles de données plus riches des bases de données relationnelles objet ouvrent de nombreuses autres options pour la conception logique d'un schéma de base de données, ce qui augmente considérablement la complexité de la conception de la base de données logique. En nous concentrant sur les constructions de généralisation des modèles conceptuels, nous explorons les implications de performance des différentes alternatives de conception pour mapper les généralisations dans le schéma d'un système de base de données relationnelle objet.
Pourquoi ne pas implémenter cela comme une relation de table un à zéro/un? Supposons que vous ayez une table représentant une classe de base appelée Vehicle, avec une clé primaire de VehicleID. Ensuite, vous pouvez avoir n'importe quel nombre de tables satellites représentant toutes les sous-classes de Vehicle, et ces tables ont également VehicleID comme clé primaire, ayant une relation 1-> 0/1 de Vehicle-> Subclass.
Ou, si vous voulez le simplifier et que vous savez avec certitude que vous n'aurez que quelques sous-classes et qu'il n'y a pas beaucoup de chances que cela change, vous pouvez simplement représenter toute la structure dans une seule table avec un champ de type discriminateur .
Cela dépend si vous construisez une mono-hiérarchie ou une poly-hiérarchie. Il s'agit d'une conception codée en dur, ce qui, je crois, est ce que vous vouliez.
Pour mono (la table enfant a une table parent), où le parent IS-A enfant, le FK et le PK sont les mêmes dans la table enfant, et cette clé est également le PK dans la table parent.
Pour poly (la table enfant a plusieurs tables parent), où l'enfant IS-A parent-1 et l'enfant IS-A parent-2, vous aurez une clé composite (ce qui signifie plusieurs clés primaires pour rendre l'enregistrement de table unique), où la règle est identique à une mono-hiérarchie pour chaque clé.
La plupart des ORM mettent en œuvre la relation IS-A à l'aide d'un discriminateur à colonne unique, en choisissant la sous-classe à instancier en fonction de la valeur dans une colonne particulière. En ce qui concerne votre exemple, vous ne voulez probablement pas vraiment dire role, car généralement une personne peut remplir de nombreux types de rôles différents. Les rôles sont généralement modélisés comme une relation a-a . Si vous essayez de l'implémenter en utilisant des relations is-a (ou sous-classement), vous finirez inévitablement par devoir faire quelque chose de plus compliqué pour gérer les cas où vous avez une personne occupant un poste hybride - c'est-à-dire une secrétaire qui fonctionne également comme la personne informatique locale, ayant besoin d'autorisations ou d'attributs des deux.