* Bonjour, *
J'ai un problème de conception sur une base de donnée mais je veux aussi savoir s'il existe une solution universelle en SQL.
Les tables ont été définies comme ceci (je ne peux rien y changer) :
Voici la liste des règles suivies :
- dossier
pk : d_id
Nombre d'enregistrements : 10 000 + 1000/an- utilisateur
pk : u_id,
fk sur groupe_utilisateur: g_id not null
Nombre d'enregistrements : 5000- groupe_utilisateur
pk: g_id
boolean: can_see_b
aucune idée du nombre d'enregistrement- alpha
pk: a_id
fk sur groupe_utilisateur:g_id not null
fk sur dossier: d_id not null
Nombre d'enregistrements : 800 000 + 100 000 / an- version
pk : v_id
fk sur alpha : a_id not null
Nombre d'enregistrements : 5 / alpha en moyenne- beta
pk : (b1_id, b2_id, b3_id, b4_id, b5_id)
fk sur groupe_utilisateur: g_id not null
fk sur dossier: d_id
Nombre d'enregistrements : 2 000 000 + 200 000 / an- comment
pk: c_id
fk sur beta: (b1_id, b2_id, b3_id, b4_id, b5_id)
fk sur groupe_utilisateur: g_id not null
c_type_id [a|b|other] not null
Nombre d'enregistrements : 3 000 000 + 300 000/an- associative_v_c
pk : (v_id,c_id)
fk sur version : v_id not null
fk sur comment : c_id not null
Nombre d'enregistrement : 3 / version en moyenne- acces_groupe
pk: ag_id
fk sur groupe_utilisateur: g_id not null
fk sur dossier: d_id
fk sur beta: (b1_id, b2_id, b3_id, b4_id, b5_id)
fk sur alpha: a_id
ak sur alpha+beta: (b1_id, b2_id, b3_id, b4_id, b5_id, a_id))
Nombre d'enregistrements : dépendra de la réponse!
Le but est d'afficher les listes de alpha, dossier, beta ou comment en testant les droits de visualisation suivants pour un utilisateur d'un groupe_utilisateur :* un groupe utilisateur peut avoir 0 ou plusieurs utilisateurs (0, n)
* un utilisateur appartient toujours à un unique groupe_utilisateur(1,1)
* groupe_utilisateur peut avoir plusieurs alpha (0,n)
* un alpha appartient toujours à un unique groupe_utilisateur (1,1)
* un alpha a au moins une version (1,n)
* version appartient toujours à un unique alpha (1,1)
* un dossier peut contenir plusieurs alpha (0,n)
* alpha appartient toujours à un unique dossier (n,1)
* beta appartient toujours à un unique groupe_utilisateur (n,1)
* beta peut appartenir à un dossier (0,1)
* un dossier peut contenir plusieurs beta (1,n)
* alpha et beta peuvent appartenir au même dossier
* un beta peut avoir plusieurs comment (0,n)
* comment peut appartenir à un beta (0,1)
* une version peut avoir plusieurs comments et un comment peut être sur plusieurs versions (n,n)
* comment peut appartenir à plusieurs versions de plusieurs alpha du même groupe_utilisateur
* comment ne peut pas appartenir à la fois à un beta et à la fois à un alpha
* comment appartient au même groupe_utilisateur que alpha ou beta (il y a donc redondance dans les colonnes)
* On identifie plus facilement le type de comment grâce à c_type_id.
(a : alpha, b: beta, other : autre... car il y en a d'autres...)
* acces_groupe est défini soit pour alpha, soit pour beta (i.e. a_id is null ou (b1_id, b2_id, b3_id, b4_id, b5_id) is null) et appartient forcément au même dossier que alpha ou beta (il y a donc redondance dans les colonnes)
* Si on nomme le groupe_utilisateur définit sur un alpha ou un beta 'propriétaire', on peut dire que acces_groupe contient les groupe_utilisateurs qui ont accès à un alpha ou un beta dont ils ne sont pas propriétaires.
La question est :
groupe_utilisateur peut voir :
- alpha si alpha appartient à groupe_utilisateur ou il existe un acces_groupe entre alpha et groupe_utilisateur
- beta si (beta appartient à groupe_utilisateur et groupe_utilisateur.can_see_b est vrai) OU il existe un acces_groupe entre beta et groupe_utilisateur
- dossier s'il existe un alpha ou un beta du dossier que groupe_utilisateur peut voir
- comment si comment appartient à un alpha ou un beta que groupe_utilisateur peut voir
Vaut-il mieux faire des vues pour les listes ou introduire de la redondance de donnée dans acces_groupe? ou bien existe-t-il une solution à laquelle on n'a pas pensé?
- créer des vues
on crée une vue par type de table vue_alpha(a_id, g_id), vue_beta(b_id,g_id), vue_dossier(d_id, g_id), vue_comment(c_id,g_id)).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63 Exemple utilisant des union (pas forcément optimisé) : CREATE OR REPLACE VIEW VUE_ALPHA (a_id, d_id, g_id) AS ( -- Liste des alpha de groupe_utilisateur (SELECT a_id, d_id, g_id FROM alpha) UNION -- Liste des accès de groupe_utilisateurs sur alpha (SELECT a_id, d_id, g_id FROM acces_groupe WHERE a_id is not null) ); CREATE OR REPLACE VIEW VUE_BETA (b1_id, b2_id, b3_id, b4_id, b5_id, d_id, g_id) AS ( -- Liste de beta visible par son groupe_utilisateur (SELECT b1_id, b2_id, b3_id, b4_id, b5_id, beta.d_id, beta.g_id FROM beta, groupe_utilisateur WHERE beta.g_id = groupe_utilisateur.g_id AND groupe_utilisateur.can_see_b = true) -- Liste des accès de groupe_utilisateur sur beta UNION (SELECT b1_id, b2_id, b3_id, b4_id, b5_id, d_id, g_id FROM acces_groupe WHERE a_id is null) ); CREATE OR REPLACE VIEW VUE_DOSSIER (d_id, g_id) AS ( -- Liste des dossiers pour lesquels un groupe_utilisateur peut voir un alpha (SELECT d_id, g_id FROM VUE_ALPHA) UNION -- Liste des dossiers pour lesquels un groupe_utilisateur peut voir un beta (SELECT d_id, g_id FROM VUE_BETA) ); CREATE OR REPLACE VIEW VUE_COMMENT (c_id, g_id) AS ( -- Liste des comments sur un alpha d'un groupe_utilisateur (SELECT c_id, g_id FROM comment WHERE c_type_id = 'a') -- Liste des comments sur un beta d'un groupe_utilisateur que celui-ci peut voir UNION (SELECT c_id, comment.g_id FROM comment, groupe_utilisateur WHERE c_type_id = 'b' AND comment.g_id = groupe_utilisateur.g_id AND groupe_utilisateur.can_see_b = true) UNION -- Liste des commentaires d'un alpha pour lequel un acces_groupe a été défini (SELECT associative_v_c.c_id, acces_groupe.g_id FROM acces_groupe, version, associative_v_c WHERE acces_groupe.a_id = version.a_id AND version.v_id = associative_v_c.v_id) UNION -- Liste des commentaires d'un beta pour lequel un acces_groupe a été défini (SELECT comment.c_id, acces_groupe.g_id FROM comment, acces_groupe WHERE comment.b1_id = acces_groupe.b1_id AND comment.b2_id = acces_groupe.b2_id AND comment.b3_id = acces_groupe.b3_id AND comment.b4_id = acces_groupe.b4_id AND comment.b5_id = acces_groupe.b5_id) );- introduire de la redondance de donnée
on remplit l'associative acces_groupe avec les données suivantes :
ça n'empêchera pas le besoin d'une vue pour Comment car ça a été mal conçu
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 insert into acces_groupe (ag_id, g_id, d_id, a_id) -- Liste des alpha qui sont visibles par leur propriétaire (donc tous) (select seq.nextval, g_id, d_id, a_id from alpha) insert into acces_groupe (ag_id, g_id, d_id, b1_id, b2_id, b3_id, b4_id, b5_id) -- Liste des beta qui sont visibles par leur propriétaire (select seq.nextval, beta.g_id, d_id, b1_id, b2_id, b3_id, b4_id, b5_id from beta, groupe_utilisateur where beta.g_id = groupe_utilisateur.g_id and groupe_utilisateur.can_see_b = true)- autre solution?
Note : rencontré dans une base de donnée Oracle
* Merci *
Partager