Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

conception base avec relation deux à plusieurs

10 réponses
Avatar
Benoit Izac
Bonjour,

Je bute sur la modélisation de ma base de donnée et j'ai beau tourner le
problème dans tous les sens, je ne vois pas quelle solution adopter.

J'ai une table SITE :
- site_id -> clé primaire
- nom
- longitude
- latitude
- adresse
- etc.

Je souhaite créer des liaisons point à point entre ces sites. J'ai donc
une relation deux à plusieurs : si je crée une table LIEN, un lien
contient exactement 2 sites et un site peut apparaître dans 0 ou
plusieurs liens.

J'ai des informations
- qui sont propres au lien : bande de fréquence utilisée, débit,
etc.
- qui sont dépendantes du lien et du site : hauteur de
l'installation sur le site, type d'antenne, etc.

Jusqu'ici, pas de problème, je crée une table LIEN :
- site_id -> clé primaire
- bande de fréquence
- débit

puis une table intermédiaire SITE_LIEN :
- site_id -+
- lien_id -+-> clé primaire
- hauteur
- antenne

Rajoutons une contrainte : je dois conserver le sens du lien : site de
départ (A), site de départ (B). Je modifie donc ma table SITE_LIEN :
- lien_id -+
- coté (A ou B) -+-> clé primaire
- site_id
- hauteur
- antenne

À ce stade, j'ai déjà quelques questions :
1) comment afficher une ligne avec les informations suivantes ?
- lien_id
- site_id où le coté est A
- site_id où le coté est B
2) comment afficher tous les sites qui appartiennent à un lien comme il
suit ?
- site_id
- site_id du distant

Autre chose : j'ai lu qu'il ne fallait pas stocker des informations que
l'on pouvait calculer. Il se trouve qu'il y des informations que je peux
calculer si je connais une extrémité ; par exemple, l'azimut (angle par
rapport au nord) est égal à celui du site distant + ou - 180°. La
fréquence est dite « haute » si celle d'en face est dite « basse ».

Avec toutes ces contraintes, j'en arrive à me dire qu'il est plus simple
de supprimer la table intermédiaire et d'avoir une table LIEN comme il
suit :
- lien_id
- bande de fréquence
- débit
- id_site_A
- antenne_A
- hauteur_A
- azimut_A
- fréquence_A
- id_site_B
- antenne_B
- hauteur_B

Mais ça me crée d'autre problème. Pour répondre à la question 2), je
dois faire deux requêtes puis une union (non testé) :
CREATE VIEW site_A AS
SELECT id_site_A AS local, id_site_B AS distant FROM LIEN;
CREATE VIEW site_B AS
SELECT id_site_B AS local, id_site_A AS distant FROM LIEN;
SELECT * FROM site_A
UNION
SELECT * FROM site_B;

Bref, mon manque d'expérience m'empêche de savoir quelle solution
adopter. Pouvez-vous m'indiquer d'une part si ces deux solutions sont
viables et d'autres part quels sont leurs avantages/inconvénients ?

Merci.
--
Benoit Izac

10 réponses

Avatar
pif34
Bonjour, pas évident, les explications sont pas super claires, mais
c'est aussi un peu logique, car sinon, pas de problème pour modéliser...



Le 01/11/2011 09:59, Benoit Izac a écrit :
Bonjour,

Je bute sur la modélisation de ma base de donnée et j'ai beau tourner le
problème dans tous les sens, je ne vois pas quelle solution adopter.

J'ai une table SITE :
- site_id -> clé primaire
- nom
- longitude
- latitude
- adresse
- etc.

Je souhaite créer des liaisons point à point entre ces sites. J'ai donc
une relation deux à plusieurs : si je crée une table LIEN, un lien
contient exactement 2 sites et un site peut apparaître dans 0 ou
plusieurs liens.

J'ai des informations
- qui sont propres au lien : bande de fréquence utilisée, débit,
etc.
- qui sont dépendantes du lien et du site : hauteur de
l'installation sur le site, type d'antenne, etc.

Jusqu'ici, pas de problème, je crée une table LIEN :
- site_id -> clé primaire
- bande de fréquence
- débit

puis une table intermédiaire SITE_LIEN :
- site_id -+
- lien_id -+-> clé primaire
- hauteur
- antenne

Rajoutons une contrainte : je dois conserver le sens du lien : site de
départ (A), site de départ (B). Je modifie donc ma table SITE_LIEN :
- lien_id -+
- coté (A ou B) -+-> clé primaire
- site_id
- hauteur
- antenne




bon, alors je résume, en gros t'as un graphe orienté, ce qui reste une
structure de données des plus élémentaires: des sites (les sommets) et
des liens (les aretes):

donc t'as grossomodo 2 entités:

Site (id, nom, gps_x, gps_y, ... )
Lien (id_src, id_dst, bande_frequence, debit, ...).

L'id du site est la PK, les deux ids de liens sont des FK et constituent
toutes les deux une PK de ta table lien (tu peux créer un identifiant si
tu peux avoir plusieurs connexions entre deux meme site ou pour diverses
raison techniques).

si t'as une info dépendante du site (ex: affaiblissement, tu as
grossomodo deux solutions:

- si les attributs ne sont pas tres nombreux, tu modifie la table lien:
Lien (id_src, id_trg, bande_frequence, debit, affaiblissement_src,
affaiblissement_trg, ...).

, tu créé en effet une entité lien avec une laison many to many genre:

Site (id, nom, gps_x, gps_y, ... )
Lien (id, bande_frequence, debit, ...)
et une table d'association:
Lien_Sites (id_site, id_lien, orientation (src ou cible),
affaiblissemet, etc.).

dans ce cas, tu peux mettre une contrainte d'unicité sur (id_lien,
orientation) pour éviter d'avoir plusieurs sources ou destinations
tu peut avoir une PK (ou unicité) sur (id_site,id_lien)...

À ce stade, j'ai déjà quelques questions :
1) comment afficher une ligne avec les informations suivantes ?
- lien_id
- site_id où le coté est A
- site_id où le coté est B



dans le premier cas le plus simple:

select src.id, l.debit, trg.id
from lien l
join site src on lien.id_src = site.id
join site trg on lien.id_trg = site.id


dans le second cas:
select ....
from lien l
join lien_site ls_src on l.id = ls_src.id_lien
and ls_src.orientation = 1
join site src on ls_src.id_site = src.id
join lien_site ls_trg on l.id = ls_trg.id_lien
and ls_trg.orientation = 0
join site trg on ls_trg.id_site = trg.id


2) comment afficher tous les sites qui appartiennent à un lien comme il
suit ?
- site_id
- site_id du distant



premier cas: select * from site where id in (select id_src from lien
where id lien = ?)
union select * from site where id in (select id_trg from lien....)

deuxieme cas:
select * from site where id in (select * id_site from lien_site where
id_lien = ? )


Autre chose : j'ai lu qu'il ne fallait pas stocker des informations que
l'on pouvait calculer. Il se trouve qu'il y des informations que je peux
calculer si je connais une extrémité ; par exemple, l'azimut (angle par
rapport au nord) est égal à celui du site distant + ou - 180°. La
fréquence est dite « haute » si celle d'en face est dite « basse ».



en général, on parle d'attribut calculé:

par exemple t'as la TVA, le HT et le TTC... stocker les 3 n'a pas de
sens car à partir de 2 tu peux en recalculer un 3°...

par contre, en effet, si tu prend l'état civil d'une personne, t'as sexe
M/F sur un seul champ: tu vas pas dire qu'il faut pas stocker F parce
que tu peux le déduire si t'as pas M....

donc si t'as deux type de fréquence H/B... ben tu créé un champ et tu
met la valeur qui va bien...

si par contre t'as une règle qui dit si bande_de_frequence = ??? alors
c'est bas... et que tu stocke la bande de fréquence, en effet, tu stocke
pas la fréquence basse...

au pire, si t'as des règles lourdes à coder et que tu veux éviter la
redondances, tu peux utiliser des mécanismes de vues par exemple,

Avec toutes ces contraintes, j'en arrive à me dire qu'il est plus simple
de supprimer la table intermédiaire et d'avoir une table LIEN comme il
suit :
- lien_id
- bande de fréquence
- débit
- id_site_A
- antenne_A
- hauteur_A
- azimut_A
- fréquence_A
- id_site_B
- antenne_B
- hauteur_B



oui, dépend de l'évolution de ton logiciel... tu va pas créer une table
et plein de jointure pour 1 attributs... si a terme t'en a 10 la
question se pose... si a terme t'as des connexion multiples aussi...

Bref, mon manque d'expérience m'empêche de savoir quelle solution
adopter. Pouvez-vous m'indiquer d'une part si ces deux solutions sont
viables et d'autres part quels sont leurs avantages/inconvénients ?



en l'état avec aussi peu de champs, les deux solutions sont correctes...
la solution compliquées sera cependant plus évolutive dans le temps...

dans tous les cas, tu peux utiliser des vues (j'ai le terme "requete
nommées") pour simplifier un certain nombre de requetes...

d'ailleurs, si tu base tout sur ces vues (sauf insert/delete/update), tu
pourras plus facilement faire évoluer ton schéma sans trop impacter le
reste de l'application ultérieurement....
Avatar
Benoit Izac
Bonjour,

le 01/11/2011 à 11:24, pif a écrit dans le message
<4eafc8ee$0$24233$ :

Bonjour, pas évident, les explications sont pas super claires, mais
c'est aussi un peu logique, car sinon, pas de problème pour
modéliser...



Effectivement. Je pensais avoir tout de même bien décrit le problème.

bon, alors je résume, en gros t'as un graphe orienté, ce qui reste une
structure de données des plus élémentaires: des sites (les sommets) et
des liens (les aretes):



Peut-être, je ne connais absolument rien en théorie des graphes. Si tu
me dis que c'est indispensable pour résoudre mon problème, je veux bien
y jeter un ½il.

donc t'as grossomodo 2 entités:

Site (id, nom, gps_x, gps_y, ... )
Lien (id_src, id_dst, bande_frequence, debit, ...).

L'id du site est la PK, les deux ids de liens sont des FK et
constituent toutes les deux une PK de ta table lien (tu peux créer un
identifiant si tu peux avoir plusieurs connexions entre deux meme site
ou pour diverses raison techniques).

si t'as une info dépendante du site (ex: affaiblissement, tu as
grossomodo deux solutions:

- si les attributs ne sont pas tres nombreux, tu modifie la table lien:
Lien (id_src, id_trg, bande_frequence, debit, affaiblissement_src,
affaiblissement_trg, ...).

, tu créé en effet une entité lien avec une laison many to many genre:

Site (id, nom, gps_x, gps_y, ... )
Lien (id, bande_frequence, debit, ...)
et une table d'association:
Lien_Sites (id_site, id_lien, orientation (src ou cible),
affaiblissemet, etc.).

dans ce cas, tu peux mettre une contrainte d'unicité sur (id_lien,
orientation) pour éviter d'avoir plusieurs sources ou destinations
tu peut avoir une PK (ou unicité) sur (id_site,id_lien)...



Ok, c'est ce que j'ai décrit.

À ce stade, j'ai déjà quelques questions :
1) comment afficher une ligne avec les informations suivantes ?
- lien_id
- site_id où le coté est A
- site_id où le coté est B



dans le premier cas le plus simple:



[je le rappelle pour plus de clarté
Site (id, nom, gps_x, gps_y, ... )
Lien (id_src, id_dst, bande_frequence, debit, ...).
]
select src.id, l.debit, trg.id
from lien l
join site src on lien.id_src = site.id
join site trg on lien.id_trg = site.id



Pour moi c'est un peu plus simple (tu as supprimé lien_id mais ça ne
change rien) :
SELECT id_src, id_dst FROM lien;

dans le second cas:



[
Site (id, nom, gps_x, gps_y, ... )
Lien (id, bande_frequence, debit, ...)
Lien_Sites (id_site, id_lien, orientation (src ou cible),
affaiblissemet, etc.)
]

select ....
from lien l
join lien_site ls_src on l.id = ls_src.id_lien
and ls_src.orientation = 1
join site src on ls_src.id_site = src.id
join lien_site ls_trg on l.id = ls_trg.id_lien
and ls_trg.orientation = 0
join site trg on ls_trg.id_site = trg.id



Il faut que je teste car j'ai du mal a suivre la requête (sans doute
parce que je n'ai pas l'habitude de lire cette syntaxe).

2) comment afficher tous les sites qui appartiennent à un lien comme il
suit ?
- site_id
- site_id du distant



premier cas: select * from site where id in (select id_src from lien
where id lien = ?)
union select * from site where id in (select id_trg from lien....)



Non, pour moi, ça liste tous les sites, mais pas le distant. Ça
correspond à ce que je faisais à la fin de mon post initial avec des
CREATE VIEW et UNION.

deuxieme cas:
select * from site where id in (select * id_site from lien_site where
id_lien = ? )



Même remarque que précédemment et c'est justement ça mon problème,
lister tous les sites de la table de liaison, c'est facile mais faire la
liaison entre src et dst, je ne sais pas faire.

Autre chose : j'ai lu qu'il ne fallait pas stocker des informations que
l'on pouvait calculer. Il se trouve qu'il y des informations que je peux
calculer si je connais une extrémité ; par exemple, l'azimut (angle par
rapport au nord) est égal à celui du site distant + ou - 180°. La
fréquence est dite « haute » si celle d'en face est dite « basse ».



en général, on parle d'attribut calculé:

par exemple t'as la TVA, le HT et le TTC... stocker les 3 n'a pas de
sens car à partir de 2 tu peux en recalculer un 3°...

par contre, en effet, si tu prend l'état civil d'une personne, t'as
sexe M/F sur un seul champ: tu vas pas dire qu'il faut pas stocker
F parce que tu peux le déduire si t'as pas M....



Non, c'est différent, dans le cas de l'état civil, tu peux avoir soit
M ou F et tu n'as pas de contrainte. Si par contre tu prends un couple
(non homosexuel), c'est différent tu ne peux pas avoir deux M ou deux
F dans le même couple. Je veux éviter d'une part, d'avoir des
incohérences (deux bandes hautes dans le même lien, la somme des azimut
qui n'est pas égal à 360°), d'autre part de consommer de l'espace
lorsque ce n'est pas nécessaire. Je pense que seule la table à plat
(sans la table de liaison) me le permet.

donc si t'as deux type de fréquence H/B... ben tu créé un champ et tu
met la valeur qui va bien...

si par contre t'as une règle qui dit si bande_de_frequence = ??? alors
c'est bas... et que tu stocke la bande de fréquence, en effet, tu
stocke pas la fréquence basse...



Il y a une fréquence basse et une fréquence haute dans la bande de
fréquence.

au pire, si t'as des règles lourdes à coder et que tu veux éviter la
redondances, tu peux utiliser des mécanismes de vues par exemple,

Avec toutes ces contraintes, j'en arrive à me dire qu'il est plus simple
de supprimer la table intermédiaire et d'avoir une table LIEN comme il
suit :
- lien_id
- bande de fréquence
- débit
- id_site_A
- antenne_A
- hauteur_A
- azimut_A
- fréquence_A
- id_site_B
- antenne_B
- hauteur_B



oui, dépend de l'évolution de ton logiciel... tu va pas créer une
table et plein de jointure pour 1 attributs... si a terme t'en a 10 la
question se pose... si a terme t'as des connexion multiples aussi...

Bref, mon manque d'expérience m'empêche de savoir quelle solution
adopter. Pouvez-vous m'indiquer d'une part si ces deux solutions sont
viables et d'autres part quels sont leurs avantages/inconvénients ?



en l'état avec aussi peu de champs, les deux solutions sont correctes...



Il y en a bien plus, c'était juste pour l'exemple.

la solution compliquées sera cependant plus évolutive dans le temps...



C'est ce qui me semble aussi.

dans tous les cas, tu peux utiliser des vues (j'ai le terme "requete
nommées") pour simplifier un certain nombre de requetes...

d'ailleurs, si tu base tout sur ces vues (sauf insert/delete/update),
tu pourras plus facilement faire évoluer ton schéma sans trop impacter
le reste de l'application ultérieurement....



Ok, merci pour la réponse.
--
Benoit Izac
Avatar
pif34
Le 01/11/2011 13:56, Benoit Izac a écrit :
Peut-être, je ne connais absolument rien en théorie des graphes. Si tu
me dis que c'est indispensable pour résoudre mon problème, je veux bien
y jeter un ½il.



non, en informatique, on retrouve grossomodo deux structures des données
essentiellement: les espaces multidimensionner et les graphes (réseau de
transport de communication, sociaux, etc ...). T'as pas besoin de
connaitre la théorie des graphes, mais je t'en recommande la lecture,
c'est au programme de la première année d'IUT...

je mentionnais ca c'est c'est un terme on ne peut plus courant dans le
métier...

Pour moi c'est un peu plus simple (tu as supprimé lien_id mais ça ne
change rien) :
SELECT id_src, id_dst FROM lien;



ben la jointure que j'avais indiqué, c'était pour retrouver le nom du
site ou autre....

Il faut que je teste car j'ai du mal a suivre la requête (sans doute
parce que je n'ai pas l'habitude de lire cette syntaxe).



c'est du SQL standard

Non, pour moi, ça liste tous les sites, mais pas le distant. Ça
correspond à ce que je faisais à la fin de mon post initial avec des
CREATE VIEW et UNION.



ben les sites sont toujours distants les un des autres... dans tous les
cas, t'as toutes les billes... ce que tu as a faire c'est de requetes
SQL de base avec des jointures, si t'en a jamais fait, je te recommande
une formation ou te d'intéresser un peu plus à ca avant de te lancer...
de toute façon tu y couperas pas...

Même remarque que précédemment et c'est justement ça mon problème,
lister tous les sites de la table de liaison, c'est facile mais faire la
liaison entre src et dst, je ne sais pas faire.



tu fais 2 jointures, c'est tout...


Non, c'est différent, dans le cas de l'état civil, tu peux avoir soit
M ou F et tu n'as pas de contrainte. Si par contre tu prends un couple
(non homosexuel), c'est différent tu ne peux pas avoir deux M ou deux
F dans le même couple. Je veux éviter d'une part, d'avoir des
incohérences (deux bandes hautes dans le même lien, la somme des azimut
qui n'est pas égal à 360°), d'autre part de consommer de l'espace
lorsque ce n'est pas nécessaire. Je pense que seule la table à plat
(sans la table de liaison) me le permet.



l'espace te pose pas trop de question... une base correcte devrait
largement tenir ce que tu lui demande... je connais pas la volumétrie,
mais j'ai pas peur pour quelques champs vides...

la; je maitrise pas les questions métiers, donc c'est pas la peine
d'aller plus loin.. t'as les éléments de base, je t'ai expliqué ce qu'on
appelle champ calculé... c'est un attribut qui peut etre calculé à
partir des autres. A toi de voir si tu peux le faire ou pas...
Avatar
Benoit Izac
Bonjour,

le 01/11/2011 à 14:22, pif a écrit dans le message
<4eaff2af$0$8436$ :

Peut-être, je ne connais absolument rien en théorie des graphes. Si tu
me dis que c'est indispensable pour résoudre mon problème, je veux bien
y jeter un ½il.



non, en informatique, on retrouve grossomodo deux structures des
données essentiellement: les espaces multidimensionner et les graphes
(réseau de transport de communication, sociaux, etc ...). T'as pas
besoin de connaitre la théorie des graphes, mais je t'en recommande la
lecture, c'est au programme de la première année d'IUT...

je mentionnais ca c'est c'est un terme on ne peut plus courant dans le
métier...



Je n'ai pas précisé : j'ai terminé mes études il y a plus de 15 ans et
je ne travaille pas dans l'informatique. J'admets donc bien volontiers
mes lacunes dans ce domaine et c'est pourquoi je demandais si ça avait
un quelquonque intérêt pour mon besoin.

[...]
Même remarque que précédemment et c'est justement ça mon problème,
lister tous les sites de la table de liaison, c'est facile mais faire la
liaison entre src et dst, je ne sais pas faire.



tu fais 2 jointures, c'est tout...



Par exemple avec la table link_site (site_id, link_id, side) ?

CREATE VIEW site_A SELECT * FROM link_site WHERE side = "A";
CREATE VIEW site_B SELECT * FROM link_site WHERE side = "B";
SELECT site_A.site_id AS site_A, site_B.site_id AS site_B
FROM site_A, site_B
WHERE site_A.link_id = site_B.link_id;

Je pense que c'est correct mais je ne sais pas le faire en une seule
requête.

Non, c'est différent, dans le cas de l'état civil, tu peux avoir soit
M ou F et tu n'as pas de contrainte. Si par contre tu prends un couple
(non homosexuel), c'est différent tu ne peux pas avoir deux M ou deux
F dans le même couple. Je veux éviter d'une part, d'avoir des
incohérences (deux bandes hautes dans le même lien, la somme des azimut
qui n'est pas égal à 360°), d'autre part de consommer de l'espace
lorsque ce n'est pas nécessaire. Je pense que seule la table à plat
(sans la table de liaison) me le permet.



l'espace te pose pas trop de question... une base correcte devrait
largement tenir ce que tu lui demande... je connais pas la volumétrie,
mais j'ai pas peur pour quelques champs vides...

la; je maitrise pas les questions métiers, donc c'est pas la peine
d'aller plus loin.. t'as les éléments de base, je t'ai expliqué ce
qu'on appelle champ calculé... c'est un attribut qui peut etre calculé
à partir des autres. A toi de voir si tu peux le faire ou pas...



Est-ce qu'une contrainte CHECK serait la solution pour éviter les
incohérences ?

--
Benoit Izac
Avatar
pif34
Le 01/11/2011 15:24, Benoit Izac a écrit :

je mentionnais ca c'est c'est un terme on ne peut plus courant dans le
métier...



Je n'ai pas précisé : j'ai terminé mes études il y a plus de 15 ans et
je ne travaille pas dans l'informatique. J'admets donc bien volontiers
mes lacunes dans ce domaine et c'est pourquoi je demandais si ça avait
un quelquonque intérêt pour mon besoin.



c'est bien ce que je pensais après ta réponse ;)


Par exemple avec la table link_site (site_id, link_id, side) ?

CREATE VIEW site_A SELECT * FROM link_site WHERE side = "A";
CREATE VIEW site_B SELECT * FROM link_site WHERE side = "B";
SELECT site_A.site_id AS site_A, site_B.site_id AS site_B
FROM site_A, site_B
WHERE site_A.link_id = site_B.link_id;



quand tu fais une jointure, c'est plus propre (lisible) de l'exprimer
avec un join plutot qu'avec un where et des "="... conformément à la
norme SQL ANSI

un create view, c'est pareil qu'un select :

si t'as une table lien avec src et dest:

create view v1 as select sa.*, sb.* from
lien ls
join site sa on ls.idsrc = sa.id
join site sb on ls.idtrg = sb.id

si t'as une table avec une orientation (donc deux lignes pour les deux
sites associés à un seul lien)

create view v2 as
select sa.*, sb.*
from lien_site lsa
join site sa on ls.id_site = sa.id

join lien_site lsb on lsa.id_lien = lsb.id_lien
and lsa.orientation = 1 and lsb.orientation = 0
join site sb on lsb.id_site = sb.id


Je pense que c'est correct mais je ne sais pas le faire en une seule
requête.

Est-ce qu'une contrainte CHECK serait la solution pour éviter les
incohérences ?



quelques incohérences ?
t'as des contraintes d'intégrité (unicité, etc. ) qui sont déjà
intéressantes... tu peux ajouter des contraintes checks, et meme faire
bien plus complexe en associant une fonction stockée à tes contraintes
check...

tu peux meme aller plus loin avec des triggers et du PL sql...
mais étant donné que t'es débutant en matière de SQL, je te recommande
d'y aller progressivement... commence pas bétonner ton schéma avec les
contraintes existantes, tu verras ensuite pour les check et triggers....
Avatar
Benoit Izac
Bonjour,

le 01/11/2011 à 17:51, pif a écrit dans le message
<4eb02393$0$14468$ :

Est-ce qu'une contrainte CHECK serait la solution pour éviter les
incohérences ?



quelques incohérences ?



C'est expliqué dans ce que tu as coupé : deux bandes hautes dans le même
lien, la somme des azimut qui n'est pas égal à 360°.

t'as des contraintes d'intégrité (unicité, etc. ) qui sont déjà
intéressantes... tu peux ajouter des contraintes checks, et meme faire
bien plus complexe en associant une fonction stockée à tes contraintes
check...

tu peux meme aller plus loin avec des triggers et du PL sql...
mais étant donné que t'es débutant en matière de SQL, je te recommande
d'y aller progressivement... commence pas bétonner ton schéma avec les
contraintes existantes, tu verras ensuite pour les check et
triggers....



Tu as sans doute raison, avant de m'occuper de détail, il faut que je
mette tout cela en place. Je vais essayer le schéma avec la table
intermédiaire, c'est ce qui me semble le plus facile à maintenir (mais
pas à mettre en place). Je reviendrais si j'ai des soucis (et après un
peu de lecture).

--
Benoit Izac
Avatar
pif34
Le 01/11/2011 20:47, Benoit Izac a écrit :
Bonjour,

le 01/11/2011 à 17:51, pif a écrit dans le message
<4eb02393$0$14468$ :

Est-ce qu'une contrainte CHECK serait la solution pour éviter les
incohérences ?



quelques incohérences ?



C'est expliqué dans ce que tu as coupé : deux bandes hautes dans le même
lien, la somme des azimut qui n'est pas égal à 360°.



un contrainte check ne peut porter que sur un tuple (ligne) à la fois...
par conséquent, si tu reste sur un lien, c'est facile:

ALTER TABLE lien ADD CHECK (azimuth_src + azimuth_trg = 360);
pour les bandes:

ALTER TABLE lien ADD CHECK ((b1 = "H" and b2 = 'B') or (b1 = 'B' and b2
= 'B') );

si t'as plusieurs ligne à gérer, tu vas avoir un problème: quand tu
inseres la première ligne, la contrainte n'est pas respectée...

par conséquent il faut que tu procede par transaction et désactive la
contrainte au début puis la réactive à la fin pour pour faire propre....

souvent, meme si c'est pas l'idéal, on code sans dans la partie
applicative (en faisant en sorte que ce soit relativement propre et
centralisé).

Tu as sans doute raison, avant de m'occuper de détail, il faut que je
mette tout cela en place. Je vais essayer le schéma avec la table
intermédiaire, c'est ce qui me semble le plus facile à maintenir (mais
pas à mettre en place). Je reviendrais si j'ai des soucis (et après un
peu de lecture).



c'est guere plus long, surtout si tu mets en place une vue... par la
suite, t'auras un usage assez simple....

de toute facon, cette seconde solution reste relativement rudimentaire
en matière d'informatique... dans une application, tu seras rapidement
amené à consulter des cas plus complexes...

bon courrage
Avatar
Benoit Izac
Bonjour,

le 01/11/2011 à 21:40, pif a écrit dans le message
<4eb05927$0$2836$ :

Est-ce qu'une contrainte CHECK serait la solution pour éviter les
incohérences ?



quelques incohérences ?



C'est expliqué dans ce que tu as coupé : deux bandes hautes dans le même
lien, la somme des azimut qui n'est pas égal à 360°.



un contrainte check ne peut porter que sur un tuple (ligne) à la
fois... par conséquent, si tu reste sur un lien, c'est facile:

ALTER TABLE lien ADD CHECK (azimuth_src + azimuth_trg = 360);
pour les bandes:

ALTER TABLE lien ADD CHECK ((b1 = "H" and b2 = 'B') or (b1 = 'B' and
b2 = 'B') );



Dommage car si je mets tout dans une seule table, du coup, je n'ai plus
besoin de contrainte car je ne vais pas rentrer les informations pour le
deuxième site vu que je les ai déjà (indirectement).

si t'as plusieurs ligne à gérer, tu vas avoir un problème: quand tu
inseres la première ligne, la contrainte n'est pas respectée...

par conséquent il faut que tu procede par transaction et désactive la
contrainte au début puis la réactive à la fin pour pour faire
propre....

souvent, meme si c'est pas l'idéal, on code sans dans la partie
applicative (en faisant en sorte que ce soit relativement propre et
centralisé).



Je comprends. En revanche, je peux faire une requête qui fait le calcul
et la vérification et qui me prévient des entrées qui sont en désaccord.
Je verrai l'erreur plus tard mais au moins j'aurai l'information.

bon courrage



Merci.

--
Benoit Izac
Avatar
SQLpro
Bonjour,

la modélisation d'une base se fait au niveau conceptuel. Au niveau
physique vous n'y comprendrez rien.

Voici une solution générique :
MCD avec deux entités :
http://blog.developpez.com/media/MCD_deux_entites_et_deux_liens.gif

MPD correspondant
http://blog.developpez.com/media/MPD_deux_entites_et_deux_liens.gif

et en auto référence, MCD :
http://blog.developpez.com/media/MCD_une_entites_et_deux_liens.gif

MPD correspondant :
http://blog.developpez.com/media/MPD_une_entites_et_deux_liens.gif

A +


--
Frédéric BROUARD - expert SGBDR et SQL - MVP SQL Server - 06 11 86 40 66
Le site sur le langage SQL et les SGBDR : http://sqlpro.developpez.com
Enseignant Arts & Métiers PACA, ISEN Toulon et CESI/EXIA Aix en Provence
Audit, conseil, expertise, formation, modélisation, tuning, optimisation
*********************** http://www.sqlspot.com *************************


Avec un MCD merise, la solution est assez simple :

Le 01/11/2011 09:59, Benoit Izac a écrit :
Bonjour,

Je bute sur la modélisation de ma base de donnée et j'ai beau tourner le
problème dans tous les sens, je ne vois pas quelle solution adopter.

J'ai une table SITE :
- site_id -> clé primaire
- nom
- longitude
- latitude
- adresse
- etc.

Je souhaite créer des liaisons point à point entre ces sites. J'ai donc
une relation deux à plusieurs : si je crée une table LIEN, un lien
contient exactement 2 sites et un site peut apparaître dans 0 ou
plusieurs liens.

J'ai des informations
- qui sont propres au lien : bande de fréquence utilisée, débit,
etc.
- qui sont dépendantes du lien et du site : hauteur de
l'installation sur le site, type d'antenne, etc.

Jusqu'ici, pas de problème, je crée une table LIEN :
- site_id -> clé primaire
- bande de fréquence
- débit

puis une table intermédiaire SITE_LIEN :
- site_id -+
- lien_id -+-> clé primaire
- hauteur
- antenne

Rajoutons une contrainte : je dois conserver le sens du lien : site de
départ (A), site de départ (B). Je modifie donc ma table SITE_LIEN :
- lien_id -+
- coté (A ou B) -+-> clé primaire
- site_id
- hauteur
- antenne

À ce stade, j'ai déjà quelques questions :
1) comment afficher une ligne avec les informations suivantes ?
- lien_id
- site_id où le coté est A
- site_id où le coté est B
2) comment afficher tous les sites qui appartiennent à un lien comme il
suit ?
- site_id
- site_id du distant

Autre chose : j'ai lu qu'il ne fallait pas stocker des informations que
l'on pouvait calculer. Il se trouve qu'il y des informations que je peux
calculer si je connais une extrémité ; par exemple, l'azimut (angle par
rapport au nord) est égal à celui du site distant + ou - 180°. La
fréquence est dite « haute » si celle d'en face est dite « basse ».

Avec toutes ces contraintes, j'en arrive à me dire qu'il est plus simple
de supprimer la table intermédiaire et d'avoir une table LIEN comme il
suit :
- lien_id
- bande de fréquence
- débit
- id_site_A
- antenne_A
- hauteur_A
- azimut_A
- fréquence_A
- id_site_B
- antenne_B
- hauteur_B

Mais ça me crée d'autre problème. Pour répondre à la question 2), je
dois faire deux requêtes puis une union (non testé) :
CREATE VIEW site_A AS
SELECT id_site_A AS local, id_site_B AS distant FROM LIEN;
CREATE VIEW site_B AS
SELECT id_site_B AS local, id_site_A AS distant FROM LIEN;
SELECT * FROM site_A
UNION
SELECT * FROM site_B;

Bref, mon manque d'expérience m'empêche de savoir quelle solution
adopter. Pouvez-vous m'indiquer d'une part si ces deux solutions sont
viables et d'autres part quels sont leurs avantages/inconvénients ?

Merci.
Avatar
Benoit Izac
Bonjour,

le 29/11/2011 à 15:33, SQLpro a écrit dans le message
<4ed4ed1c$0$2269$ :

la modélisation d'une base se fait au niveau conceptuel. Au niveau
physique vous n'y comprendrez rien.

Voici une solution générique :
MCD avec deux entités :
http://blog.developpez.com/media/MCD_deux_entites_et_deux_liens.gif

MPD correspondant
http://blog.developpez.com/media/MPD_deux_entites_et_deux_liens.gif

et en auto référence, MCD :
http://blog.developpez.com/media/MCD_une_entites_et_deux_liens.gif

MPD correspondant :
http://blog.developpez.com/media/MPD_une_entites_et_deux_liens.gif



Je ne comprends pas ce dernier exemple. Si « Entité A » dans mon cas est
un site, je comprends le MCD comme :
1) zéro ou un site peut avoir zéro ou plusieurs sites distants
2) un ou plusieurs sites peuvent être le(s) distant(s) de zéro ou
plusieurs sites.

Le MDP si je comprends bien est une table site dans laquelle on liste
les distants. Ça me parait un peu bancal car il faut ajouter un champ
à chaque nouveau site distant.

Mais il se peut que je n'ai rien compris...

--
Benoit Izac