Bonjour,
Voici un problème qui se pose à moi assez souvent et avec lequel je
suis mal à l'aise. Il s'agit se situation ou un "objet" est soit un
truc soit un machin. Par exemple un compte en banque appartient soit à
un particulier (avec nom, prénom, civilité...) soit à une entreprise
(nom, raison sociale, type...).
Il me semble que la solution "orthodoxe" est de faire une table
contenant ce qu'il y a de commun, puis une table pour chaque cas
particulier.
Bonjour,
Voici un problème qui se pose à moi assez souvent et avec lequel je
suis mal à l'aise. Il s'agit se situation ou un "objet" est soit un
truc soit un machin. Par exemple un compte en banque appartient soit à
un particulier (avec nom, prénom, civilité...) soit à une entreprise
(nom, raison sociale, type...).
Il me semble que la solution "orthodoxe" est de faire une table
contenant ce qu'il y a de commun, puis une table pour chaque cas
particulier.
Bonjour,
Voici un problème qui se pose à moi assez souvent et avec lequel je
suis mal à l'aise. Il s'agit se situation ou un "objet" est soit un
truc soit un machin. Par exemple un compte en banque appartient soit à
un particulier (avec nom, prénom, civilité...) soit à une entreprise
(nom, raison sociale, type...).
Il me semble que la solution "orthodoxe" est de faire une table
contenant ce qu'il y a de commun, puis une table pour chaque cas
particulier.
la problématique que tu soulève est aisée à programmer avec un
langage objet
la problématique que tu soulève est aisée à programmer avec un
langage objet
la problématique que tu soulève est aisée à programmer avec un
langage objet
Voici un problème qui se pose à moi assez souvent et avec lequel je
suis mal à l'aise. Il s'agit se situation ou un "objet" est soit un truc
soit un machin. Par exemple un compte en banque appartient soit à un
particulier (avec nom, prénom, civilité...) soit à une entreprise (nom,
raison sociale, type...).
Il me semble que la solution "orthodoxe" est de faire une table
contenant ce qu'il y a de commun, puis une table pour chaque cas
particulier.
Exemple concret et vécu. Dans un jeu de simulation économique, un
investisseur est soit un joueur, soit une société créée par un joueur.
CREATE TABLE Investisseurs (
id SERIAL PRIMARY KEY,
nom TEXT NOT NULL UNIQUE,
type CHAR(1) DEFAULT 'U' NOT NULL,
solde NUMERIC(14,2) DEFAULT 0 NOT NULL, ...
)
CREATE TABLE Joueurs (
est INTEGER PRIMARY KEY REFERENCES Investisseurs(id) ON DELETE
CASCADE, passwd CHAR(13) NOT NULL,
...
)
CREATE TABLE Societes (
est INTEGER PRIMARY KEY REFERENCES Investisseurs(id) ON DELETE
CASCADE, description VARCHAR(4000),
cours NUMERIC(14,2) DEFAULT 100 NOT NULL CHECK(cours > 0), ...
)
Le soucis est que pour conserver les contraintes d'intégrité, il me
faut
tout un arsenal :
- index unique sur les clef étrangère (qui deviennent des clefs
primaires) ; - triggers sur l'insertion dans Joueurs et Societes pour
vérifier que le type
correspond à ce qu'on inserre ;
- REVOKE UPDATE (type) ON TABLE Investisseurs.
Et même comme ça, il peut exister un investisseur qui n'est référencé
ni dans Joueurs, ni dans Societes.
Une autre solution est d'inverser la référence :
CREATE TABLE Investisseurs (
id SERIAL PRIMARY KEY,
nom TEXT NOT NULL UNIQUE,
joueur INTEGER UNIQUE REFERENCES Joueurs(id), societe INTEGER UNIQUE
REFERENCES Societes(id), CHECK ((joueur IS NULL AND societe IS NOT
NULL) OR
(societe IS NULL AND joueur IS NOT NULL)),
solde NUMERIC(14,2) DEFAULT 0 NOT NULL, ...
)
CREATE TABLE Joueurs (
id SERIAL PRIMARY KEY,
passwd CHAR(13) NOT NULL,
...
)
CREATE TABLE Societes (
id SERIAL PRIMARY KEY,
description VARCHAR(4000),
cours NUMERIC(14,2) DEFAULT 100 NOT NULL CHECK(cours > 0), ...
)
Et là le soucis est inverse, c'est à dire qu'on peut avoir une société
ou un joueurs qui n'est pas un investisseur.
D'autre part ça me
parait plus difficile à "étendre", si par exemple on veut ajouter une
troisième alternative.
Voici un problème qui se pose à moi assez souvent et avec lequel je
suis mal à l'aise. Il s'agit se situation ou un "objet" est soit un truc
soit un machin. Par exemple un compte en banque appartient soit à un
particulier (avec nom, prénom, civilité...) soit à une entreprise (nom,
raison sociale, type...).
Il me semble que la solution "orthodoxe" est de faire une table
contenant ce qu'il y a de commun, puis une table pour chaque cas
particulier.
Exemple concret et vécu. Dans un jeu de simulation économique, un
investisseur est soit un joueur, soit une société créée par un joueur.
CREATE TABLE Investisseurs (
id SERIAL PRIMARY KEY,
nom TEXT NOT NULL UNIQUE,
type CHAR(1) DEFAULT 'U' NOT NULL,
solde NUMERIC(14,2) DEFAULT 0 NOT NULL, ...
)
CREATE TABLE Joueurs (
est INTEGER PRIMARY KEY REFERENCES Investisseurs(id) ON DELETE
CASCADE, passwd CHAR(13) NOT NULL,
...
)
CREATE TABLE Societes (
est INTEGER PRIMARY KEY REFERENCES Investisseurs(id) ON DELETE
CASCADE, description VARCHAR(4000),
cours NUMERIC(14,2) DEFAULT 100 NOT NULL CHECK(cours > 0), ...
)
Le soucis est que pour conserver les contraintes d'intégrité, il me
faut
tout un arsenal :
- index unique sur les clef étrangère (qui deviennent des clefs
primaires) ; - triggers sur l'insertion dans Joueurs et Societes pour
vérifier que le type
correspond à ce qu'on inserre ;
- REVOKE UPDATE (type) ON TABLE Investisseurs.
Et même comme ça, il peut exister un investisseur qui n'est référencé
ni dans Joueurs, ni dans Societes.
Une autre solution est d'inverser la référence :
CREATE TABLE Investisseurs (
id SERIAL PRIMARY KEY,
nom TEXT NOT NULL UNIQUE,
joueur INTEGER UNIQUE REFERENCES Joueurs(id), societe INTEGER UNIQUE
REFERENCES Societes(id), CHECK ((joueur IS NULL AND societe IS NOT
NULL) OR
(societe IS NULL AND joueur IS NOT NULL)),
solde NUMERIC(14,2) DEFAULT 0 NOT NULL, ...
)
CREATE TABLE Joueurs (
id SERIAL PRIMARY KEY,
passwd CHAR(13) NOT NULL,
...
)
CREATE TABLE Societes (
id SERIAL PRIMARY KEY,
description VARCHAR(4000),
cours NUMERIC(14,2) DEFAULT 100 NOT NULL CHECK(cours > 0), ...
)
Et là le soucis est inverse, c'est à dire qu'on peut avoir une société
ou un joueurs qui n'est pas un investisseur.
D'autre part ça me
parait plus difficile à "étendre", si par exemple on veut ajouter une
troisième alternative.
Voici un problème qui se pose à moi assez souvent et avec lequel je
suis mal à l'aise. Il s'agit se situation ou un "objet" est soit un truc
soit un machin. Par exemple un compte en banque appartient soit à un
particulier (avec nom, prénom, civilité...) soit à une entreprise (nom,
raison sociale, type...).
Il me semble que la solution "orthodoxe" est de faire une table
contenant ce qu'il y a de commun, puis une table pour chaque cas
particulier.
Exemple concret et vécu. Dans un jeu de simulation économique, un
investisseur est soit un joueur, soit une société créée par un joueur.
CREATE TABLE Investisseurs (
id SERIAL PRIMARY KEY,
nom TEXT NOT NULL UNIQUE,
type CHAR(1) DEFAULT 'U' NOT NULL,
solde NUMERIC(14,2) DEFAULT 0 NOT NULL, ...
)
CREATE TABLE Joueurs (
est INTEGER PRIMARY KEY REFERENCES Investisseurs(id) ON DELETE
CASCADE, passwd CHAR(13) NOT NULL,
...
)
CREATE TABLE Societes (
est INTEGER PRIMARY KEY REFERENCES Investisseurs(id) ON DELETE
CASCADE, description VARCHAR(4000),
cours NUMERIC(14,2) DEFAULT 100 NOT NULL CHECK(cours > 0), ...
)
Le soucis est que pour conserver les contraintes d'intégrité, il me
faut
tout un arsenal :
- index unique sur les clef étrangère (qui deviennent des clefs
primaires) ; - triggers sur l'insertion dans Joueurs et Societes pour
vérifier que le type
correspond à ce qu'on inserre ;
- REVOKE UPDATE (type) ON TABLE Investisseurs.
Et même comme ça, il peut exister un investisseur qui n'est référencé
ni dans Joueurs, ni dans Societes.
Une autre solution est d'inverser la référence :
CREATE TABLE Investisseurs (
id SERIAL PRIMARY KEY,
nom TEXT NOT NULL UNIQUE,
joueur INTEGER UNIQUE REFERENCES Joueurs(id), societe INTEGER UNIQUE
REFERENCES Societes(id), CHECK ((joueur IS NULL AND societe IS NOT
NULL) OR
(societe IS NULL AND joueur IS NOT NULL)),
solde NUMERIC(14,2) DEFAULT 0 NOT NULL, ...
)
CREATE TABLE Joueurs (
id SERIAL PRIMARY KEY,
passwd CHAR(13) NOT NULL,
...
)
CREATE TABLE Societes (
id SERIAL PRIMARY KEY,
description VARCHAR(4000),
cours NUMERIC(14,2) DEFAULT 100 NOT NULL CHECK(cours > 0), ...
)
Et là le soucis est inverse, c'est à dire qu'on peut avoir une société
ou un joueurs qui n'est pas un investisseur.
D'autre part ça me
parait plus difficile à "étendre", si par exemple on veut ajouter une
troisième alternative.
Bonjour,
Voici un problème qui se pose à moi assez souvent et avec lequel je
suis mal à l'aise. Il s'agit se situation ou un "objet" est soit un
truc soit un machin. Par exemple un compte en banque appartient soit à
un particulier (avec nom, prénom, civilité...) soit à une entreprise
(nom, raison sociale, type...).
Il me semble que la solution "orthodoxe" est de faire une table
contenant ce qu'il y a de commun, puis une table pour chaque cas
particulier.
Exemple concret et vécu. Dans un jeu de simulation économique, un
investisseur est soit un joueur, soit une société créée par un joueur.
CREATE TABLE Investisseurs (
id SERIAL PRIMARY KEY,
nom TEXT NOT NULL UNIQUE,
type CHAR(1) DEFAULT 'U' NOT NULL,
solde NUMERIC(14,2) DEFAULT 0 NOT NULL,
...
)
CREATE TABLE Joueurs (
est INTEGER PRIMARY KEY REFERENCES Investisseurs(id) ON DELETE
passwd CHAR(13) NOT NULL,
...
)
CREATE TABLE Societes (
est INTEGER PRIMARY KEY REFERENCES Investisseurs(id) ON DELETE CASCADE,
description VARCHAR(4000),
cours NUMERIC(14,2) DEFAULT 100 NOT NULL CHECK(cours> 0),
...
)
Le soucis est que pour conserver les contraintes d'intégrité, il me faut
tout un arsenal :
- index unique sur les clef étrangère (qui deviennent des clefs primaires) ;
- triggers sur l'insertion dans Joueurs et Societes pour vérifier que le type
correspond à ce qu'on inserre ;
- REVOKE UPDATE (type) ON TABLE Investisseurs.
Et même comme ça, il peut exister un investisseur qui n'est référencé ni
dans Joueurs, ni dans Societes.
Une autre solution est d'inverser la référence :
CREATE TABLE Investisseurs (
id SERIAL PRIMARY KEY,
nom TEXT NOT NULL UNIQUE,
joueur INTEGER UNIQUE REFERENCES Joueurs(id),
societe INTEGER UNIQUE REFERENCES Societes(id),
CHECK ((joueur IS NULL AND societe IS NOT NULL) OR
(societe IS NULL AND joueur IS NOT NULL)),
solde NUMERIC(14,2) DEFAULT 0 NOT NULL,
...
)
CREATE TABLE Joueurs (
id SERIAL PRIMARY KEY,
passwd CHAR(13) NOT NULL,
...
)
CREATE TABLE Societes (
id SERIAL PRIMARY KEY,
description VARCHAR(4000),
cours NUMERIC(14,2) DEFAULT 100 NOT NULL CHECK(cours> 0),
...
)
Et là le soucis est inverse, c'est à dire qu'on peut avoir une société ou un
joueurs qui n'est pas un investisseur. D'autre part ça me parait plus
difficile à "étendre", si par exemple on veut ajouter une troisième
alternative.
Bref, quelle est la "bonne" façon de modéliser ce genre de situation ?
J'utilise Pg-8.4, mais j'aimerais surtout avoir une réponse "théorique".
Merci de m'avoir lu jusqu'ici,
Bonjour,
Voici un problème qui se pose à moi assez souvent et avec lequel je
suis mal à l'aise. Il s'agit se situation ou un "objet" est soit un
truc soit un machin. Par exemple un compte en banque appartient soit à
un particulier (avec nom, prénom, civilité...) soit à une entreprise
(nom, raison sociale, type...).
Il me semble que la solution "orthodoxe" est de faire une table
contenant ce qu'il y a de commun, puis une table pour chaque cas
particulier.
Exemple concret et vécu. Dans un jeu de simulation économique, un
investisseur est soit un joueur, soit une société créée par un joueur.
CREATE TABLE Investisseurs (
id SERIAL PRIMARY KEY,
nom TEXT NOT NULL UNIQUE,
type CHAR(1) DEFAULT 'U' NOT NULL,
solde NUMERIC(14,2) DEFAULT 0 NOT NULL,
...
)
CREATE TABLE Joueurs (
est INTEGER PRIMARY KEY REFERENCES Investisseurs(id) ON DELETE
passwd CHAR(13) NOT NULL,
...
)
CREATE TABLE Societes (
est INTEGER PRIMARY KEY REFERENCES Investisseurs(id) ON DELETE CASCADE,
description VARCHAR(4000),
cours NUMERIC(14,2) DEFAULT 100 NOT NULL CHECK(cours> 0),
...
)
Le soucis est que pour conserver les contraintes d'intégrité, il me faut
tout un arsenal :
- index unique sur les clef étrangère (qui deviennent des clefs primaires) ;
- triggers sur l'insertion dans Joueurs et Societes pour vérifier que le type
correspond à ce qu'on inserre ;
- REVOKE UPDATE (type) ON TABLE Investisseurs.
Et même comme ça, il peut exister un investisseur qui n'est référencé ni
dans Joueurs, ni dans Societes.
Une autre solution est d'inverser la référence :
CREATE TABLE Investisseurs (
id SERIAL PRIMARY KEY,
nom TEXT NOT NULL UNIQUE,
joueur INTEGER UNIQUE REFERENCES Joueurs(id),
societe INTEGER UNIQUE REFERENCES Societes(id),
CHECK ((joueur IS NULL AND societe IS NOT NULL) OR
(societe IS NULL AND joueur IS NOT NULL)),
solde NUMERIC(14,2) DEFAULT 0 NOT NULL,
...
)
CREATE TABLE Joueurs (
id SERIAL PRIMARY KEY,
passwd CHAR(13) NOT NULL,
...
)
CREATE TABLE Societes (
id SERIAL PRIMARY KEY,
description VARCHAR(4000),
cours NUMERIC(14,2) DEFAULT 100 NOT NULL CHECK(cours> 0),
...
)
Et là le soucis est inverse, c'est à dire qu'on peut avoir une société ou un
joueurs qui n'est pas un investisseur. D'autre part ça me parait plus
difficile à "étendre", si par exemple on veut ajouter une troisième
alternative.
Bref, quelle est la "bonne" façon de modéliser ce genre de situation ?
J'utilise Pg-8.4, mais j'aimerais surtout avoir une réponse "théorique".
Merci de m'avoir lu jusqu'ici,
Bonjour,
Voici un problème qui se pose à moi assez souvent et avec lequel je
suis mal à l'aise. Il s'agit se situation ou un "objet" est soit un
truc soit un machin. Par exemple un compte en banque appartient soit à
un particulier (avec nom, prénom, civilité...) soit à une entreprise
(nom, raison sociale, type...).
Il me semble que la solution "orthodoxe" est de faire une table
contenant ce qu'il y a de commun, puis une table pour chaque cas
particulier.
Exemple concret et vécu. Dans un jeu de simulation économique, un
investisseur est soit un joueur, soit une société créée par un joueur.
CREATE TABLE Investisseurs (
id SERIAL PRIMARY KEY,
nom TEXT NOT NULL UNIQUE,
type CHAR(1) DEFAULT 'U' NOT NULL,
solde NUMERIC(14,2) DEFAULT 0 NOT NULL,
...
)
CREATE TABLE Joueurs (
est INTEGER PRIMARY KEY REFERENCES Investisseurs(id) ON DELETE
passwd CHAR(13) NOT NULL,
...
)
CREATE TABLE Societes (
est INTEGER PRIMARY KEY REFERENCES Investisseurs(id) ON DELETE CASCADE,
description VARCHAR(4000),
cours NUMERIC(14,2) DEFAULT 100 NOT NULL CHECK(cours> 0),
...
)
Le soucis est que pour conserver les contraintes d'intégrité, il me faut
tout un arsenal :
- index unique sur les clef étrangère (qui deviennent des clefs primaires) ;
- triggers sur l'insertion dans Joueurs et Societes pour vérifier que le type
correspond à ce qu'on inserre ;
- REVOKE UPDATE (type) ON TABLE Investisseurs.
Et même comme ça, il peut exister un investisseur qui n'est référencé ni
dans Joueurs, ni dans Societes.
Une autre solution est d'inverser la référence :
CREATE TABLE Investisseurs (
id SERIAL PRIMARY KEY,
nom TEXT NOT NULL UNIQUE,
joueur INTEGER UNIQUE REFERENCES Joueurs(id),
societe INTEGER UNIQUE REFERENCES Societes(id),
CHECK ((joueur IS NULL AND societe IS NOT NULL) OR
(societe IS NULL AND joueur IS NOT NULL)),
solde NUMERIC(14,2) DEFAULT 0 NOT NULL,
...
)
CREATE TABLE Joueurs (
id SERIAL PRIMARY KEY,
passwd CHAR(13) NOT NULL,
...
)
CREATE TABLE Societes (
id SERIAL PRIMARY KEY,
description VARCHAR(4000),
cours NUMERIC(14,2) DEFAULT 100 NOT NULL CHECK(cours> 0),
...
)
Et là le soucis est inverse, c'est à dire qu'on peut avoir une société ou un
joueurs qui n'est pas un investisseur. D'autre part ça me parait plus
difficile à "étendre", si par exemple on veut ajouter une troisième
alternative.
Bref, quelle est la "bonne" façon de modéliser ce genre de situation ?
J'utilise Pg-8.4, mais j'aimerais surtout avoir une réponse "théorique".
Merci de m'avoir lu jusqu'ici,
Dans joueurs/societes , un index unique devrait suffire non, plutôt
que des clefs primaires ?
Avec deux tables, le type n'est pas indispensable, vu que vous pouvez
vous en sortir avec 2 LEFT OUTER JOIN. Ce qui résout le problème du
REVOKE et du trigger sur l'insertion.
Et même comme ça, il peut exister un investisseur qui n'est
référencé ni dans Joueurs, ni dans Societes.
Un trigger peut vérifier cela.
Une autre solution est d'inverser la référence :
Ce qui, sur votre exemple bien précis, me paraît plus collé au besoin.
Et là le soucis est inverse, c'est à dire qu'on peut avoir une
société ou un joueurs qui n'est pas un investisseur.
Ce qui peut arriver, non, dans la modélisation ?
Autre piste, comme variation de votre dernier exemple et qui résout
les problèmes d'extensions futures:
* table investisseurs sans attribut joueur ni societe
* table supplémentaire investisseurs_type définie avec:
- investisseur_id en référence sur investisseurs.id
- type (éventuellement), codant la table fille concernée
- type_id contenant l'id dans la table joueurs/societes
mais alors on perd l'intégrité référentielle, en tout cas sans trigger
Ou alors
investisseur_id
joueur_id
societe_id
en ayant les références et en vérifiant que l'un vaut NULL.
Les séquences d'id sont ainsi décorrélées.
Ce ne sont que quelques pistes, en espérant que ca vous donne des
idées.
Dans joueurs/societes , un index unique devrait suffire non, plutôt
que des clefs primaires ?
Avec deux tables, le type n'est pas indispensable, vu que vous pouvez
vous en sortir avec 2 LEFT OUTER JOIN. Ce qui résout le problème du
REVOKE et du trigger sur l'insertion.
Et même comme ça, il peut exister un investisseur qui n'est
référencé ni dans Joueurs, ni dans Societes.
Un trigger peut vérifier cela.
Une autre solution est d'inverser la référence :
Ce qui, sur votre exemple bien précis, me paraît plus collé au besoin.
Et là le soucis est inverse, c'est à dire qu'on peut avoir une
société ou un joueurs qui n'est pas un investisseur.
Ce qui peut arriver, non, dans la modélisation ?
Autre piste, comme variation de votre dernier exemple et qui résout
les problèmes d'extensions futures:
* table investisseurs sans attribut joueur ni societe
* table supplémentaire investisseurs_type définie avec:
- investisseur_id en référence sur investisseurs.id
- type (éventuellement), codant la table fille concernée
- type_id contenant l'id dans la table joueurs/societes
mais alors on perd l'intégrité référentielle, en tout cas sans trigger
Ou alors
investisseur_id
joueur_id
societe_id
en ayant les références et en vérifiant que l'un vaut NULL.
Les séquences d'id sont ainsi décorrélées.
Ce ne sont que quelques pistes, en espérant que ca vous donne des
idées.
Dans joueurs/societes , un index unique devrait suffire non, plutôt
que des clefs primaires ?
Avec deux tables, le type n'est pas indispensable, vu que vous pouvez
vous en sortir avec 2 LEFT OUTER JOIN. Ce qui résout le problème du
REVOKE et du trigger sur l'insertion.
Et même comme ça, il peut exister un investisseur qui n'est
référencé ni dans Joueurs, ni dans Societes.
Un trigger peut vérifier cela.
Une autre solution est d'inverser la référence :
Ce qui, sur votre exemple bien précis, me paraît plus collé au besoin.
Et là le soucis est inverse, c'est à dire qu'on peut avoir une
société ou un joueurs qui n'est pas un investisseur.
Ce qui peut arriver, non, dans la modélisation ?
Autre piste, comme variation de votre dernier exemple et qui résout
les problèmes d'extensions futures:
* table investisseurs sans attribut joueur ni societe
* table supplémentaire investisseurs_type définie avec:
- investisseur_id en référence sur investisseurs.id
- type (éventuellement), codant la table fille concernée
- type_id contenant l'id dans la table joueurs/societes
mais alors on perd l'intégrité référentielle, en tout cas sans trigger
Ou alors
investisseur_id
joueur_id
societe_id
en ayant les références et en vérifiant que l'un vaut NULL.
Les séquences d'id sont ainsi décorrélées.
Ce ne sont que quelques pistes, en espérant que ca vous donne des
idées.
Il me semble que la solution "orthodoxe" est de faire une table
contenant ce qu'il y a de commun, puis une table pour chaque cas
particulier.
lisez l'article que j'ai écrit à ce sujet :
http://sqlpro.developpez.com/cours/modelisation/heritage/
Si vous conceviez vos bases à partir d'un MCD (modèle conceptuel de
données), ce mécanisme serait automatisé par l'outil de modélisation;
Par exemple Power AMC, sait faire cela très bien...
CREATE TABLE Investisseurs (
id SERIAL PRIMARY KEY,
nom TEXT NOT NULL UNIQUE,
type CHAR(1) DEFAULT 'U' NOT NULL,
solde NUMERIC(14,2) DEFAULT 0 NOT NULL,
...
)
La colonne type est inutile si elle sert à départager entre joueur et
société et même dangereuse car il y a redondance de l'information !
En effet, vous savez si un Investisseur est un joueur ou une société
pas la jointure.
Au passage nommer une colonne "Type" n'est pas une bonne idée car
comme c'est un mot clef de SQL, vous allez au devant de problèmes de
génération d'erreur de syntaxe...
Au passage les colonnes "est" devrait être "id".
En effet dans un modèle de données, la même information doit avoir
partout le même nom, ce qui est le cas des clef étrangères qui
doivent avoir le même nom que la clef primaire de référence (sauf
impossibilité).
- index unique sur les clef étrangère (qui deviennent des clefs
primaires) ;
inutile, car les clef primaire sont indexées
- triggers sur l'insertion dans Joueurs et Societes pour vérifier
que le type correspond à ce qu'on inserre ;
inutile car la vue s'en occupe !
Une autre solution est d'inverser la référence :
[snip]
Ce qu'en revanche vous avez oublié c'est de gérer l'exclusion
mutuelle entre joueurs et investisseur qui se règle à coup de
déclencheurs.
Voici dans la papier cité des exemples de triggers de gestion de
l'exclusion mutuelle :
http://sqlpro.developpez.com/cours/modelisation/heritage/#L5
Il me semble que la solution "orthodoxe" est de faire une table
contenant ce qu'il y a de commun, puis une table pour chaque cas
particulier.
lisez l'article que j'ai écrit à ce sujet :
http://sqlpro.developpez.com/cours/modelisation/heritage/
Si vous conceviez vos bases à partir d'un MCD (modèle conceptuel de
données), ce mécanisme serait automatisé par l'outil de modélisation;
Par exemple Power AMC, sait faire cela très bien...
CREATE TABLE Investisseurs (
id SERIAL PRIMARY KEY,
nom TEXT NOT NULL UNIQUE,
type CHAR(1) DEFAULT 'U' NOT NULL,
solde NUMERIC(14,2) DEFAULT 0 NOT NULL,
...
)
La colonne type est inutile si elle sert à départager entre joueur et
société et même dangereuse car il y a redondance de l'information !
En effet, vous savez si un Investisseur est un joueur ou une société
pas la jointure.
Au passage nommer une colonne "Type" n'est pas une bonne idée car
comme c'est un mot clef de SQL, vous allez au devant de problèmes de
génération d'erreur de syntaxe...
Au passage les colonnes "est" devrait être "id".
En effet dans un modèle de données, la même information doit avoir
partout le même nom, ce qui est le cas des clef étrangères qui
doivent avoir le même nom que la clef primaire de référence (sauf
impossibilité).
- index unique sur les clef étrangère (qui deviennent des clefs
primaires) ;
inutile, car les clef primaire sont indexées
- triggers sur l'insertion dans Joueurs et Societes pour vérifier
que le type correspond à ce qu'on inserre ;
inutile car la vue s'en occupe !
Une autre solution est d'inverser la référence :
[snip]
Ce qu'en revanche vous avez oublié c'est de gérer l'exclusion
mutuelle entre joueurs et investisseur qui se règle à coup de
déclencheurs.
Voici dans la papier cité des exemples de triggers de gestion de
l'exclusion mutuelle :
http://sqlpro.developpez.com/cours/modelisation/heritage/#L5
Il me semble que la solution "orthodoxe" est de faire une table
contenant ce qu'il y a de commun, puis une table pour chaque cas
particulier.
lisez l'article que j'ai écrit à ce sujet :
http://sqlpro.developpez.com/cours/modelisation/heritage/
Si vous conceviez vos bases à partir d'un MCD (modèle conceptuel de
données), ce mécanisme serait automatisé par l'outil de modélisation;
Par exemple Power AMC, sait faire cela très bien...
CREATE TABLE Investisseurs (
id SERIAL PRIMARY KEY,
nom TEXT NOT NULL UNIQUE,
type CHAR(1) DEFAULT 'U' NOT NULL,
solde NUMERIC(14,2) DEFAULT 0 NOT NULL,
...
)
La colonne type est inutile si elle sert à départager entre joueur et
société et même dangereuse car il y a redondance de l'information !
En effet, vous savez si un Investisseur est un joueur ou une société
pas la jointure.
Au passage nommer une colonne "Type" n'est pas une bonne idée car
comme c'est un mot clef de SQL, vous allez au devant de problèmes de
génération d'erreur de syntaxe...
Au passage les colonnes "est" devrait être "id".
En effet dans un modèle de données, la même information doit avoir
partout le même nom, ce qui est le cas des clef étrangères qui
doivent avoir le même nom que la clef primaire de référence (sauf
impossibilité).
- index unique sur les clef étrangère (qui deviennent des clefs
primaires) ;
inutile, car les clef primaire sont indexées
- triggers sur l'insertion dans Joueurs et Societes pour vérifier
que le type correspond à ce qu'on inserre ;
inutile car la vue s'en occupe !
Une autre solution est d'inverser la référence :
[snip]
Ce qu'en revanche vous avez oublié c'est de gérer l'exclusion
mutuelle entre joueurs et investisseur qui se règle à coup de
déclencheurs.
Voici dans la papier cité des exemples de triggers de gestion de
l'exclusion mutuelle :
http://sqlpro.developpez.com/cours/modelisation/heritage/#L5
Dans joueurs/societes , un index unique devrait suffire non, plutôt que
des clefs primaires ?
D'une part il faut aussi la contrainte NOT NULL et d'autre part cette
clef étrangère sera la colonne de jointure "naturelle". Il me parait
donc normal d'avoir une clef primaire.
Et même comme ça, il peut exister un investisseur qui n'est
référencé ni dans Joueurs, ni dans Societes.
Un trigger peut vérifier cela.
Je ne vois vraiment pas comment. Quand ce trigger serait-il lancé ?
Dans joueurs/societes , un index unique devrait suffire non, plutôt que
des clefs primaires ?
D'une part il faut aussi la contrainte NOT NULL et d'autre part cette
clef étrangère sera la colonne de jointure "naturelle". Il me parait
donc normal d'avoir une clef primaire.
Et même comme ça, il peut exister un investisseur qui n'est
référencé ni dans Joueurs, ni dans Societes.
Un trigger peut vérifier cela.
Je ne vois vraiment pas comment. Quand ce trigger serait-il lancé ?
Dans joueurs/societes , un index unique devrait suffire non, plutôt que
des clefs primaires ?
D'une part il faut aussi la contrainte NOT NULL et d'autre part cette
clef étrangère sera la colonne de jointure "naturelle". Il me parait
donc normal d'avoir une clef primaire.
Et même comme ça, il peut exister un investisseur qui n'est
référencé ni dans Joueurs, ni dans Societes.
Un trigger peut vérifier cela.
Je ne vois vraiment pas comment. Quand ce trigger serait-il lancé ?
> Il reste cependant le possibilité d'avoir un investisseur qui
> n'est ni une société, ni un joueur. Et je ne sais pas comment
> éviter cela.
>
>
C'est possible si votre SGBDR gère la déférabilité des contraintes et
les assertions :
[snip]
Mais rare sont les SGBDR à accepter la déférabilité des contraintes !
> Il reste cependant le possibilité d'avoir un investisseur qui
> n'est ni une société, ni un joueur. Et je ne sais pas comment
> éviter cela.
>
>
C'est possible si votre SGBDR gère la déférabilité des contraintes et
les assertions :
[snip]
Mais rare sont les SGBDR à accepter la déférabilité des contraintes !
> Il reste cependant le possibilité d'avoir un investisseur qui
> n'est ni une société, ni un joueur. Et je ne sais pas comment
> éviter cela.
>
>
C'est possible si votre SGBDR gère la déférabilité des contraintes et
les assertions :
[snip]
Mais rare sont les SGBDR à accepter la déférabilité des contraintes !