Remodéliser votre base de données,
étude de cas en SQL Server par StringBuilder

Le , par StringBuilder, Expert confirmé
Il arrive souvent que vous soyez face à une base de données mal pensée à l'origine, et qui a mal évolué.
Vous vous retrouvez avec des tables "mamouth", au nombre incalculable de colonnes nulles.

Le problème, c'est que de nombreux outils accèdent souvent à cette base de données, et qu'il vous semble insurmontable de devoir tout réécrire afin de réagencer quelques tables dans votre base.

Pourtant, même si la tâche reste ardue, il n'est aucunement nécessaire de réécrire vos applications pour utiliser des tables dont vous aurez modifié la structure.
En effet, la plupart des SGBD modernes permettent :
  • de faire des vues
  • de faire du CRUD dessus
  • d'étendre les possibilités du CRUD sur les vues à l'aide de triggers positionnés directement sur les vues


Les exemple de cet article sont basés sur SQL Server. La syntaxe peut varier d'un SGBD à l'autre. Cet article n'a pas pour vocation de fournir des exemple s'adaptant à tous les SGBD, mais avant tout à proposer une méthodologie.

Soit une base de données de contacts, très mal modélisée :
  • Une seule table
  • Des colonnes nullables
  • Une sémantique redondante entre certaines colonnes


Code sql : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
  
create table contact 
( 
	id int primary key not null identity, 
	nom varchar(50) not null, 
	prenom varchar(50) not null, 
	telephone_maison varchar(10) null check (telephone_maison like replicate('[0-9]', 10)), 
	telephone_mobile varchar(10) null check (telephone_mobile like replicate('[0-9]', 10)), 
	telephone_boulot varchar(10) null check (telephone_boulot like replicate('[0-9]', 10)), 
	unique (nom, prenom) 
  
);

On remarque tout de suite que la présente de 3 colonnes "numéro de téléphone", nullables, est une aberration : en effet, si on souhaite rechercher une personne par un numéro de téléphone, il est impossible d'utiliser le moindre index. Et la présence de NULL dans une table, c'est la preuve d'une modélisation hasardeuse.

On souhaite donc effectuer des recherches simples en saisissant un numéro de téléphone.
La recherche doit alors retourner toutes les lignes de contact où l’un des trois numéros de téléphone est égal au numéro recherché.
La table étant très mal modélisée, on a au départ tenté :

Code sql : Sélectionner tout
1
2
3
4
  
select * 
from contact 
where telephone_maison = '0123456789' or telephone_mobile = '0123456789' or telephone_boulot = '0123456789';

Mais malgré la création d’index, cette requête est très lente (le OR est non sargable) et franchement pas très jolie. Surtout qu’on a pour objectif, d'ici quelques temps, d’ajouter un “telephone_conjoint”, donc il faudra modifier la requête, recréer des index.

On a donc créé une vue permettant d’effectuer cette recherche plus facilement, et de façon plus performante (le union permet d'utilisation des index) :

Code sql : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
  
create view contact_telephone (id, nom, prenom, type_telephone, numero_telephone) 
as 
select id, nom, prenom, 'MAISON', telephone_maison 
from contact 
union 
select id, nom, prenom, 'MOBILE', telephone_mobile 
from contact 
union 
select id, nom, prenom, 'BOULOT', telephone_boulot 
from contact;

Après mure réflexion, cette modélisation est parfaitement pourrie, et on souhaite l’améliorer.
Les NULL polluent l'utilisation des index, rendent la maintenance des données difficile (dédoublonnage par exemple) : comment mettre en place une clause d'unicité portant sur trois colonnes et toutes les lignes d'une table ?

Seulement, on a un programme qui permet de faire du CRUD sur la table “contact”, afin de remplir notre base de contacts.
Et une autre application web, qui fait des recherches à l’aide de la vue “contact_telephone”, permettant aux utilisateur de trouver rapidement le contact à partir de son numéro.

Ce programme étant écrit en COBOL, et son auteur étant parti à la retraite à l’époque où vous ne saviez même pas encore lire, vous préférez éviter d’avoir à le toucher, même si, à terme, vous serez certainement amenés à le remplacer.
Quant au site web, c'est un stagiaire qui vous a fait ça en PHP entre deux parties de jeu vidéo, et vous n'osez pas vous approcher du code, tellement il est incompréhensible.

Pourtant, vous n'allez pas abandonner. Vous pouvez rendre votre base de données propre et performante, en la remodélisant.

Voici donc comment procéder.

On va, dans un premier temps, créer les tables “propres”.

Code sql : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  
create table personne 
( 
	id int primary key not null identity, 
	nom varchar(50) not null, 
	prenom varchar(50) not null, 
	unique (nom, prenom) 
); 
  
create table telephone 
( 
	id int primary key not null identity, 
	personne_id int not null references personne(id), 
	type_telephone varchar(6) not null check (type_telephone in ('MAISON', 'MOBILE', 'BOULOT')), 
	numero_telephone varchar(10) not null check (numero_telephone like replicate('[0-9]', 10)) 
);

Ce nouveau modèle des données est loin d'être parfait. Il faudrait notamment avoir une table "type_telephone" plutôt qu'une contrainte sur une colonne littérale. Il s'agit ici simplement d'un exemple.

Puis recopier notre table poubelle dedans :

Code sql : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
  
set identity_insert personne on; 
insert into personne (id, nom, prenom) 
select id, nom, prenom 
from contact; 
set identity_insert personne off; 
  
insert into telephone (personne_id, type_telephone, numero_telephone) 
select id, type_telephone, numero_telephone 
from contact_telephone 
where numero_telephone is not null;

Et on va maintenant transformer la table poubelle en vue toute propre :

Code sql : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
  
drop table contact; 
go 
  
create view contact (id, nom, prenom, telephone_maison, telephone_mobile, telephone_boulot) 
as 
select p.id, p.nom, p.prenom, t1.numero_telephone, t2.numero_telephone, t3.numero_telephone 
from personne p 
left outer join telephone t1 on t1.personne_id = p.id and t1.type_telephone = 'MAISON' 
left outer join telephone t2 on t2.personne_id = p.id and t2.type_telephone = 'MOBILE' 
left outer join telephone t3 on t3.personne_id = p.id and t3.type_telephone = 'BUREAU'; 
go

Seul hic, si on tente de créer/modifier/supprimer des lignes, ça ne fait pas trop ce qu’on veut :

Lorsqu'on tente d'enregistrer un nouveau contact :
Msg 4405, Level 16, State 1, Line 75
View or function 'contact' is not updatable because the modification affects multiple base tables.

Lorsqu’on tente de mettre à jour un numéro de téléphone existant :
(0 row(s) affected)

Lorsqu'on tente de supprimer un contact :
Msg 4405, Level 16, State 1, Line 79
View or function 'contact' is not updatable because the modification affects multiple base tables.

On va donc devoir créer quelques triggers pour gérer correctement les différents cas :

Code sql : Sélectionner tout
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
64
65
66
67
68
69
70
71
72
73
74
  
create trigger trg_contact_ins 
on contact 
instead of insert 
as 
begin 
	insert into personne (nom, prenom) 
	select nom, prenom 
	from inserted; 
  
	insert into telephone (personne_id, type_telephone, numero_telephone) 
	select personne.id, 'MAISON', inserted.telephone_maison 
	from inserted 
	inner join personne on personne.nom = inserted.nom and personne.prenom = inserted.prenom 
	where telephone_maison is not null 
	union 
	select personne.id, 'MOBILE', inserted.telephone_mobile 
	from inserted 
	inner join personne on personne.nom = inserted.nom and personne.prenom = inserted.prenom 
	where telephone_mobile is not null 
	union 
	select personne.id, 'BOULOT', inserted.telephone_boulot 
	from inserted 
	inner join personne on personne.nom = inserted.nom and personne.prenom = inserted.prenom 
	where telephone_boulot is not null; 
end; 
go 
  
create trigger trg_contact_del 
on contact 
instead of delete 
as 
begin 
	delete telephone where personne_id in (select id from deleted); 
	delete personne where id in (select id from deleted); 
end; 
go 
  
create trigger trg_contact_upd 
on contact 
instead of update 
as 
begin 
	update personne 
	set nom = i.nom, prenom = i.prenom 
	from inserted i 
	where personne.id = i.id and (personne.nom <> i.nom or personne.prenom <> i.prenom); 
  
	insert into telephone (personne_id, type_telephone, numero_telephone) 
	select i.id, 'MAISON', i.telephone_maison from inserted i left outer join deleted d on d.id = i.id where d.telephone_maison is null and i.telephone_maison is not null 
	union 
	select i.id, 'MOBILE', i.telephone_mobile from inserted i left outer join deleted d on d.id = i.id where d.telephone_mobile is null and i.telephone_mobile is not null 
	union 
	select i.id, 'BOULOT', i.telephone_boulot from inserted i left outer join deleted d on d.id = i.id where d.telephone_boulot is null and i.telephone_boulot is not null; 
  
	update telephone 
	set numero_telephone = tmp.numero_telephone 
	from ( 
		select i.id personne_id, 'MAISON' type_telephone, i.telephone_maison numero_telephone from inserted i inner join deleted d on d.id = i.id where d.telephone_maison <> i.telephone_maison 
		union 
		select i.id, 'MOBILE', i.telephone_mobile from inserted i inner join deleted d on d.id = i.id where d.telephone_mobile <> i.telephone_mobile 
		union 
		select i.id, 'BOULOT', i.telephone_boulot from inserted i inner join deleted d on d.id = i.id where d.telephone_boulot <> i.telephone_boulot 
	) tmp 
	where telephone.personne_id = tmp.personne_id and telephone.type_telephone = tmp.type_telephone; 
  
	delete telephone 
	from inserted 
	inner join deleted on deleted.id = inserted.id 
	where (deleted.telephone_maison is not null and inserted.telephone_maison is null and telephone.type_telephone = 'MAISON') 
	or (deleted.telephone_mobile is not null and inserted.telephone_mobile is null and telephone.type_telephone = 'MOBILE') 
	or (deleted.telephone_boulot is not null and inserted.telephone_boulot is null and telephone.type_telephone = 'BOULOT') 
end; 
go

Et enfin, la vue “contact_telephone” est réécrite, de façon très simple.

Code sql : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  
drop view contact_telephone; 
go 
  
create view contact_telephone (id, nom, prenom, type_telephone, numero_telephone) 
as 
with type_telephone (libelle) 
as 
( 
	select 'MAISON' 
	union all 
	select 'MOBILE' 
	union all 
	select 'BOULOT' 
) 
select p.id, p.nom, p.prenom, type_telephone.libelle, t.numero_telephone 
from personne p 
cross join type_telephone 
left outer join telephone t on t.personne_id = p.id and t.type_telephone = type_telephone.libelle;

Et voilà ! Maintenant, vos programmes existants travaillent dans une jolie base bien modélisée sans même s'en rendre compte !
Et les performances, malgré la taille imposante des triggers, seront au rendez-vous, je vous le garanti !


Vous avez aimé cette actualité ? Alors partagez-la avec vos amis en cliquant sur les boutons ci-dessous :


 Poster un commentaire

Avatar de Artemus24 Artemus24 - Expert éminent https://www.developpez.com
le 23/09/2015 à 4:52
Salut StringBuiler

Bon travailStringBuilder , mais j'ai quand même quelques remarques à faire !

Citation Envoyé par stringBuiler
Le problème, c'est que de nombreux outils accèdent souvent à cette base de données, et qu'il vous semble insurmontable de devoir tout réécrire afin de réagencer quelques tables dans votre base.

Pourquoi tout réécrire ?
Une solution consiste à extraire les valeurs dont on a besoin dans une nouvelle base de données afin de les exploiter au mieux.
Ce genre d'outil se nomme un entrepot de données (en anglais 'data warehouse').

Citation Envoyé par stringBuiler
Et la présence de NULL dans une table, c'est la preuve d'une modélisation hasardeuse.

Un 'null' exprime l'absence de valeur pour une colonne donnée.
Son usage n'est pas une aberration comme tu sembles le souligner, mais cela à son utilité.
Il ne faut pas confondre l'absence de valeur avec une valeur renseignée qui est soit à zéro ou soit à blanc.

Ce n'est pas le NULL qui pose problème mais la redondance des colonnes de même type comme dans ton exemple avec les numéros de téléphones.
C'est la première forme normale qui est enfreinte.
Voici la définition de cette forme issue du livre "SQL et DB2, le relationnel et sa pratique" de M. Koutchouk :
On dit qu'une table est en première forme normale quand elle possède uniquement des données élémentaires pour chaque colonne dans chaque ligne (pas de données répétitives).

De ce fait, cette table n'est pas normalisée correctement, d'où le problème que l'on rencontre par la suite.

Citation Envoyé par stringBuiler
Vous pouvez rendre votre base de données propre et performante, en la remodélisant.

Le problème de ton exemple est que tu transformes une usine à gaz en une autre usine à gaz.
La question des triggers peut grandement pénaliser la performance du traitement des mises à jour de ta base de données transformées.
Si les mises à jour sont peu nombreuses, oui, en effet cela peut être une solution.
Mais en procédant ainsi tu vas créer un Goulot d'étranglement qui peut nuire à la performance.

La question fondamentale reste la performance.
Une table qui n'est pas normalisée, ou devrais-je dire dénormalisée, est peut-être la réponse à cette question fondamentale.
Donc une mauvaise modélisation n'est pas nécessairement un handicap.

Citation Envoyé par stringBuiler
de faire des vues

L'exemple que tu donnes est juste une façon d'illustrer l'usage des view.
Oui mais tu fais un usage à contre emploi de ce qu'il faut faire.

Les view sont destinées à créer des sous-ensembles de données à partir d'une table unique.
On le fait dans le respect de la mise en place de la sécurité au niveau d'une entreprise.
L'exemple des données comptables est soumise à des restrictions selon les services qui ont accès à ces données.

Mais à ma connaissance, je ne connais aucun exemples rencontrés en gros système (donc en DB2) faisant un usage comme tu le fais des view.
Vous avez certainement plus de liberté pour entreprendre vos modélisations qu'en gros système sur des grands comptes.
Quand je faisais du développement, nous étions soumis à des contrôles de qualités avant les livraisons de nos programmes.
Et si nous ne respections pas les normes de l'entreprise, nous devions réécrire nos programmes.

@+
Avatar de ixpe ixpe - Membre actif https://www.developpez.com
le 23/09/2015 à 9:13
De mon coté je préconise l'utilisation de procédures stockées pour la BDD, interdiction de faire autrement; si bien que toute la structure table peut être changée sans modification des applis... ça me parait plus simple, plus pérenne et sécurisé en plus.

Méfiance sur l'utilisation des triggers : comme dit précédemment, pas top pour les perf, il ne faut pas se planter dans ces triggers sinon rien n'arrive dans les tables et en cas de problème ou modif de schéma on ne pense plus trop au trigger...
Avatar de iberserk iberserk - Membre expert https://www.developpez.com
le 25/09/2015 à 15:21
Je vais (pour une fois?) prendre la défense de StringBuilder
Je ne suis absolument pas daccord avec toi Artemus
Citation Envoyé par Artemus24;bt1260
Salut StringBuiler

Bon travailStringBuilder , mais j'ai quand même quelques remarques à faire !

Pourquoi tout réécrire ?
Une solution consiste à extraire les valeurs dont on a besoin dans une nouvelle base de données afin de les exploiter au mieux.
Ce genre d'outil se nomme un entrepot de données (en anglais 'data warehouse').
@+

Je ne vois pas le rapport avec le problème que soulève ici Stringbuilder? un datawarehouse est en générale utilisée dans un cadre analytique, avec de l'aggregation de données, et en général plutôt en lecture seule.
C'est donc complètement hors sujet pour moi...

Citation Envoyé par Artemus24;bt1260
Un 'null' exprime l'absence de valeur pour une colonne donnée.
Son usage n'est pas une aberration comme tu sembles le souligner, mais cela à son utilité.
Il ne faut pas confondre l'absence de valeur avec une valeur renseignée qui est soit à zéro ou soit à blanc.

Ce n'est pas le NULL qui pose problème mais la redondance des colonnes de même type comme dans ton exemple avec les numéros de téléphones.
C'est la première forme normale qui est enfreinte.
Voici la définition de cette forme issue du livre "SQL et DB2, le relationnel et sa pratique" de M. Koutchouk :

De ce fait, cette table n'est pas normalisée correctement, d'où le problème que l'on rencontre par la suite.

J'abonde sur le fait que le problème viennent de la modélisation mais on peut toujours se poser la question de l'utilité d'une colonne à 95% NULL et donc de la possibilité de faire un découpage horizontal de la table sur un ensemble de colonnes (informations sécu par exemple) qui sont en générales soi toutes présentes soit aucune.

Une colonne NULL induit souvent des traitement particulier pour le prendre (ou pas) en compte.
Citation Envoyé par Artemus24;bt1260
Le problème de ton exemple est que tu transformes une usine à gaz en une autre usine à gaz.
La question des triggers peut grandement pénaliser la performance du traitement des mises à jour de ta base de données transformées.
Si les mises à jour sont peu nombreuses, oui, en effet cela peut être une solution.
Mais en procédant ainsi tu vas créer un Goulot d'étranglement qui peut nuire à la performance.

Si vous trouvez qu'un INSTEAD OFF TRIGGER est une usine à gaz, vous n'avez pas du faire beaucoup de SQL poussé dans votre vie!
De plus un trigger si bien codé ne pénalise pas la performance, il fait de plus partie intégrante de la transaction : idées reçu que tous cela, je suis d'ailleurs en train de faire faire un retour en arrière sur ces idées préconçues dans la société dans laquelle j'interviens en ce moment.
Citation Envoyé par Artemus24;bt1260
La question fondamentale reste la performance.
Une table qui n'est pas normalisée, ou devrais-je dire dénormalisée, est peut-être la réponse à cette question fondamentale.
Donc une mauvaise modélisation n'est pas nécessairement un handicap.

La performance... et la cohérence des données
De plus j'ai le sentiment que vous ne voyez que les performances en lectures...

Citation Envoyé par Artemus24;bt1260
L'exemple que tu donnes est juste une façon d'illustrer l'usage des view.
Oui mais tu fais un usage à contre emploi de ce qu'il faut faire.

Les view sont destinées à créer des sous-ensembles de données à partir d'une table unique.
On le fait dans le respect de la mise en place de la sécurité au niveau d'une entreprise.
L'exemple des données comptables est soumise à des restrictions selon les services qui ont accès à ces données.

Ce n'est qu'une facon d'utiliser les vues, il y en à bien d'autre! dont la principale est de masquer la complexité/propreté d'une modélisation.
Très important par les temps qui court avec ces fichus ORM que nos développeurs aiment tant mais dont il ne comprenne rien!

Cordialement
Avatar de Artemus24 Artemus24 - Expert éminent https://www.developpez.com
le 26/09/2015 à 5:02
Salut iberserk.

Citation Envoyé par iberserk
Je vais (pour une fois?) prendre la défense de StringBuilder

Si je me permets de répondre à StringBuilder au sujet de "Remodéliser votre base de données", ce n'est pas pour le discréditer, tout au contraire.
J'ai déjà échangé avec lui, et je l'apprécie grandement ! Mais nous n'avons pas tous la même expérience professionnelle, d'autant que je viens du monde du gros système où les contraintes sont plus importantes.

Citation Envoyé par iberserk
Je ne suis absolument pas d'accord avec toi Artemus

C'est ton droit. Ce blog est un droit de réponse, alors exprimons-nous, mais avec courtoisie.

Citation Envoyé par iberserk
Je ne vois pas le rapport avec le problème que soulève ici Stringbuilder?

C'est juste une idée que j'expose suite à ce qu'il dit ici :
Citation Envoyé par StringBuilder
Le problème, c'est que de nombreux outils accèdent souvent à cette base de données ...

J'ai travaillé sur un 'data warehouse' (=DW) dans le cadre de la 'BAFI'.
Pour réaliser ce travail, je devais récolter les données, les agréger et ensuite les stocker dans le DW.
Ce qu'expose StringBuilder m'a rappelé le travaille que j'avais fait. Ce travail consistait à créer une interface de conversion. N'est-ce pas l'idée de ce sujet ?

Citation Envoyé par iberserk
un datawarehouse est en générale utilisée dans un cadre analytique, avec de l'agrégation de données, et en général plutôt en lecture seule.

Oui, c'est tout à fait exacte. Mais toutes les bases de données ne sont pas destinés à des applications tournées vers les utilisateurs.
Il y en a où l'on fait uniquement des statistiques pour des organismes demandeurs de ce genre de résultat.
Extraire et triturer des données, on peut le faire soit dans le cadre d'une migration de données, soit en tant qu'interface.

Citation Envoyé par iberserk
C'est donc complètement hors sujet pour moi...

Dans le sens stricto sensus du sujet, oui, je veux bien, mais pas dans l'idée qu'expose StringBuilder, celle de créer une interface.

Citation Envoyé par iberserk
on peut toujours se poser la question de l'utilité d'une colonne à 95% NULL.

De ce point de vue (celui des 95%), je suis d'accord avec toi. Mais je n'ai pas compris cela de cette façon. Quand je lis les propos de StringBuilder :
Citation Envoyé par StringBuilder
Et la présence de NULL dans une table, c'est la preuve d'une modélisation hasardeuse.

Je comprends que l'usage des NULL dans une table est la cause d'une mauvaise modélisation.
Avoir quelques valeurs à NULL, n'est pas une raison valable pour remettre en cause la modélisation.

Mais comme je le souligne, c'est le nom respect de la première forme normale qui est en cause, et non les NULL.
Donc sa remarque est juste une façon de montrer que le modèle choisi n'est pas adapté à ce que l'on cherche à faire.

Citation Envoyé par iberserk
Si vous trouvez qu'un INSTEAD OFF TRIGGER est une usine à gaz, vous n'avez pas du faire beaucoup de SQL poussé dans votre vie!

Vous n'avez pas compris mon point de vue. Créer une interface comme le fait StringBuilder est une façon de pénaliser les performances.
Une vue, ce n'est pas une table temporaire déjà existante, mais bien un traitement qui va extraire les données à partir de la requête contenue dans le VIEW, et cela à un cout.

Citation Envoyé par View DB2
A view is represented internally to DB2 by SQL statements, not by stored data

C'est comme si vous faisiez dans un select, un sous-select. Et chacun sait, que ce genre de requête est d'une performance dégradée.

Quand on se retrouve avec des milliards de lignes en ligne, les questions de performances sont cruciaux.
J'ai travaillé sur la numérisation des images chèques, et quand chaque jour quelques millions de chèques sont produits dans une banque internationale, je peux vous assurer que faire une recherche sur 10 ans, ce n'est pas anodin.
Je pense que vous sous-estimez la question de la performance ! Et pour votre gouverne, j'étais administrateur DB2.
Il y a encore quelques temps, il était interdit de faire l'usage des procédures, triggers, functions et events. Et à votre avis pourquoi ?

Il y a une énorme différence entre un serveur Mysql où 50 personnes au maximum viennent consulter une base de données, et là, je suis d'accord avec vous. Avec une base DB2 ou plusieurs milliers de personnes dans le monde viennent faire des opérations (je parle des utilisateurs et non des clients).

Citation Envoyé par iberserk
et la cohérence des données

On ne parle pas de cohérence, mais d'intégrité des données.
Ceci est géré par le mode transactionnel qui est connu dans DB2 depuis fort longtemps, à l'inverse de MySql.
Cela se gère au niveau application, par l'intermédiaire du RollBack et du Commit, en faisant en sorte de rejeter ou valider une grappe de données.

Citation Envoyé par iberserk
De plus j'ai le sentiment que vous ne voyez que les performances en lectures...

Oui, vous avez raison car là où je travaillais, c'était la raison même d'être administrateur.
Mais ce n'est pas pour autant que j'ai délaissé l'intégrité des données.
Je ne sais pas chez vous, mais là où je travaillais, les développeurs passaient par des contrôles de qualités avant de livrer leur travail.
Et ensuite, nous devions soumettre nos applications à une chaîne de tests assez contraignante, avant la mise en production définitive.

Citation Envoyé par iberserk
la principale est de masquer la complexité/propreté d'une modélisation.

Dans les grands comptes du domaine bancaire, je n'ai jamais vu des VIEW sous DB2 autrement que sur des questions de sécurités.
La plupart du temps, les accès aux bases de données se font en lecture uniquement.
Les mises à jour se font par des voies non applicatives comme par exemple un batch durant la nuit, ou des accès via des DAB ...

Dans la mini et micro informatique, vous avez plus de liberté que nous en gros système, et donc tu ne peux pas généraliser ainsi.

@+
Avatar de escartefigue escartefigue - Expert éminent https://www.developpez.com
le 09/02/2016 à 14:28
Citation Envoyé par Artemus24
Dans les grands comptes du domaine bancaire, je n'ai jamais vu des VIEW sous DB2 autrement que sur des questions de sécurités.
La plupart du temps, les accès aux bases de données se font en lecture uniquement.
Les mises à jour se font par des voies non applicatives comme par exemple un batch durant la nuit, ou des accès via des DAB ...

Dans la mini et micro informatique, vous avez plus de liberté que nous en gros système, et donc tu ne peux pas généraliser ainsi.

J'ai fait de nombreuses mission pour de grandes banques françaises et aussi chez certains de leurs fournisseurs, et je ne confirme nullement ces propos !
  • je n'ai jamais vu la sécurité gérée au travers de VIEW dans les banques dans lesquelles je suis intervenu, ni même au travers des grant DB2
    La sécurité est le plus souvent gérée par RACF ou TSS d'une part, et par des habilitations applicatives d'autre part
  • j'ai rencontré quelques cas de vue de type jointure mais aussi et surtout des vues servant à versionner les modifications des tables afin de ne pas impacter les traitements lors des évolutions faites sur les tables
  • quand aux accès aux bases de données en lecture seulement, je ne sais pas dans quelle banque vous êtes intervenus, mais ça non plus ne correspond en rien à ce que j'ai connu par le passé ou que je connais actuellement dans les grandes banques françaises.


D'ailleurs, que ce soit dans le monde bancaire, ou dans les autres corps de métier où je suis intervenu (industrie, assurance et retraite), je n'ai encore jamais vu de plate-forme mainframe (jadis OS/370 puis OS/390 et aujourd'hui Z/OS) qui gère la sécurité au travers de view.
Mais toujours une sécurité de 1er niveau via RACF ou TSS, puis des sécurités gérées dans les applications elles mêmes.
Contacter le responsable de la rubrique SGBD & SQL