Normalisation

Le
Jogo
Bonjour,

J'ai suivi avec intérêt les discussions sur la normalisation (ici et
sur le developpez.com). Je me pose pas mal de question sur l'idée
d'économiser le stockage en multipliant les tables.

Par exemple, j'ai :
Articles (id, mid, auteur, sujet)
Posts (article_id, groupe_id, num)
Groupes (id, nom, a_min, a_max)

Les requêtes qui doivent être rapides sont l'insertion dans Articles
et :

SELECT g.nom, p.num
FROM Articles a
JOIN Posts p ON a.id = p.article_id
JOIN Groupes g ON p.groupe_id = g.id
WHERE a.mid = ?

La table Articles a un peu plus de 100 000 lignes, mais je n'ai que
10 000 auteurs et 30 000 sujets distincts. Si je crée 2 tables
supplémentaires pour ces données, il est clair que je vais gagner de la
place. Mais est-ce que la requête précédente sera plus rapide (mid étant
unique donc indexé) ?

Et comment rendre alors l'insertion rapide ? J'ai lu ici ou là qu'il
fallait utiliser des PS (et non pas des triggers qui sont très lents).
Qu'est-ce que ça donne coté utilisation ? Quelque chose comme :

SELECT insert_into_articles('<mid>','auteur','sujet') ;

--
It's useless to try to hold some people to anything they say while
they're madly in love, drunk, or running for office.
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Fred Brouard - SQLpro
Le #21852831
Jogo a écrit :
Bonjour,

J'ai suivi avec intérêt les discussions sur la normalisation (ici et
sur le developpez.com). Je me pose pas mal de question sur l'idée
d'économiser le stockage en multipliant les tables.

Par exemple, j'ai :
Articles (id, mid, auteur, sujet)
Posts (article_id, groupe_id, num)
Groupes (id, nom, a_min, a_max)

Les requêtes qui doivent être rapides sont l'insertion dans Articles
et :

SELECT g.nom, p.num
FROM Articles a
JOIN Posts p ON a.id = p.article_id
JOIN Groupes g ON p.groupe_id = g.id
WHERE a.mid = ?

La table Articles a un peu plus de 100 000 lignes, mais je n'ai que
10 000 auteurs et 30 000 sujets distincts. Si je crée 2 tables
supplémentaires pour ces données, il est clair que je vais gagner de la
place. Mais est-ce que la requête précédente sera plus rapide (mid étant
unique donc indexé) ?

Et comment rendre alors l'insertion rapide ? J'ai lu ici ou là qu'il
fallait utiliser des PS (et non pas des triggers qui sont très lents).
Qu'est-ce que ça donne coté utilisation ? Quelque chose comme :

SELECT insert_into_articles('<mid>','auteur','sujet') ;




vous ne vous posez pas la bonne question...

En effet plus vous économiserez de la place plus vous irez vite et moins
de données seront globalement traitées.
Si redondance il y a alors au lieu de mettre à jous une seule ligne, il
faudra mettre à jours plusieurs lignes.

Or les SGBDR travaillent en cache. Le cache (RAM) n'est pas extensibsle
à l'infini et lorsque la taille de la base est très supérieure à la
taille du cache, un algorithme comme LRU charge et décharge le cache en
fonction des besoins.

Autrement dit, si votre cache est très supérieur à la taille de votre
base petite, la dénormalisation sera bénéfique. Dans le cas contraire il
faudra charger et décharger des données pour chaque requête. Donc plus
vous économisez de la place et plus rapide seront les requêtes car les
données seront maintenues plus longtemps dans le cache.

CQFD !

Pour de plus amples explications, voyez la série d'artticle que j'ai
écrit sur SQL Server Magazine depuis le mois de novembre 2006.

Extrait :

"
...
Il nous faut donc nous intéresser au cache. Comment fonctionne t-il ?
Telle est la question, et pour la résoudre nous devons adopter deux
points de vue différents : celui des données et celui des procédures,
toute en sachant qu'en matière d'alimentation du cache : la règle est
commune, c'est LRU qui dicte sa loi... LRU pour Last Recent Use, c'est à
dire "plus récemment utilisé". Autrement dit pour faire place à une
nouvelle mise en cache, l'espace mémoire le plus anciennement accédé
doit céder sa place.


1.1 – Cache et RAM

En fait LRU ne va se déclencher que si SQL Server manque de mémoire.
Tant que SQL Server constate qu’une partie de la RAM n’est pas mis à sa
disposition , il la prendra, quitte à soutirer toute la mémoire disponible.
[...]
Prenez conscience que le temps de lecture d'un bit dans une RAM est de
l'ordre de 10 nano secondes tandis que celui d'un disque est de l'ordre
de 10 ms. Entre les deux un écart de 1 000 000. Oui, j'ai bien dit UN
MILLION. Une lecture disque est un million de fois moins rapide qu'une
lecture mémoire. Cette différence doit toutefois être amendée par le
fait que d’un côté, entre la mémoire et le processeur il existe tout un
circuit électronique et des micro programmes pour charger et décharger
le processeur, et que de l'autre côté, le disque lui même possède
souvent un cache, ce qui fait que l'un dans l'autre l'écart effectif est
plus proche d'un rapport de mille que du million...
En conclusion, dès que le ratio de mise en cache commence à diminuer
singulièrement, les performances baissent de manière très sensible. Une
baisse de ce ration de 20% est déjà très sensible. Au delà, la file
d’attente des demandes de lecture du disque se met à s’allonger
démesurément et l’on se retrouve dans une situation d’engorgement digne
du périphérique un vendredi soir vers 17 heures avec chaussée extérieur
un accrochage et chaussée intérieure une voie immobilisée par une panne
d’essence !
"

A +

--
Frédéric BROUARD, MVP SQL Server, expert bases de données et langage SQL
Le site sur le langage SQL et les SGBDR : http://sqlpro.developpez.com
Audit, conseil, expertise, formation, modélisation, tuning, optimisation
********************* http://www.datasapiens.com ***********************
Publicité
Poster une réponse
Anonyme