web-dev-qa-db-fra.com

De quelle manière la dénormalisation améliore-t-elle les performances de la base de données?

J'ai beaucoup entendu parler de la dénormalisation, qui visait à améliorer les performances de certaines applications. Mais je n'ai jamais essayé de faire quoi que ce soit lié.

Donc, je suis juste curieux de savoir quels endroits dans les bases de données normalisées aggravent les performances ou, en d'autres termes, quels sont les principes de dénormalisation?

Comment puis-je utiliser cette technique si j'ai besoin d'améliorer les performances? 

58
Roman

La dénormalisation est un compromis espace-temps . Les données normalisées prennent moins d'espace, mais peuvent nécessiter une jointure pour construire l'ensemble de résultats souhaité, donc plus de temps. S'il est dénormalisé, les données sont répliquées à plusieurs endroits. Cela prend alors plus de place, mais la vue souhaitée des données est facilement disponible. 

Il existe d'autres optimisations spatio-temporelles, telles que

  • vue dénormalisée
  • colonnes précalculées

Comme avec n'importe quelle approche, cela améliore la lecture des données (car elles sont facilement disponibles), mais la mise à jour des données devient plus coûteux (car vous devez mettre à jour les données répliquées ou précalculées).

69
ewernli

La dénormalisation est généralement utilisée pour:

  • Eviter un certain nombre de requêtes
  • Supprimer des jointures

L'idée de base de la dénormalisation est que vous allez ajouter des données redondantes, ou en regrouper certaines, pour pouvoir obtenir ces données plus facilement, à moindre coût. ce qui est meilleur pour les performances.


Quelques exemples rapides?

  • Prenons un tableau "Posts" et "Commentaires" pour un blog
    • Pour chaque article, vous aurez plusieurs lignes dans le tableau "Commentaires"
    • Cela signifie que pour afficher une liste de publications avec le nombre de commentaires associé, vous devez:
      • Faire une requête pour lister les posts
      • Faites une requête par publication pour compter le nombre de commentaires qu'il a (Oui, ceux-ci peuvent être fusionnés en un seul pour obtenir le nombre de toutes les publications en même temps)
      • Ce qui signifie plusieurs requêtes.
  • Maintenant, si vous ajoutez un champ "nombre de commentaires" dans la table Posts:
    • Vous n'avez besoin que d'une requête pour lister les articles
    • Et pas besoin d'interroger la table Commentaires: le nombre de commentaires est déjà dé-normalisé dans la table Posts.
    • Et une seule requête qui retourne un champ supplémentaire est préférable à plusieurs requêtes.

Maintenant, il y a des coûts, oui:

  • Premièrement, cela coûte de la place sur le disque et en mémoire, car vous avez des informations redondantes:
    • Le nombre de commentaires est stocké dans la table Posts
    • Et vous pouvez également trouver ces chiffres comptant sur la table Commentaires
  • Deuxièmement, chaque fois que quelqu'un ajoute/supprime un commentaire, vous devez:
    • Enregistrer/supprimer le commentaire, bien sûr
    • Mais aussi, mettez à jour le numéro correspondant dans la table Posts.
    • Mais, si votre blog a beaucoup plus de gens lisant que d’écrire des commentaires, ce n’est probablement pas si grave.
82
Pascal MARTIN

Le mot "dénormalisation" mène à une confusion des problèmes de conception. Obtenir une base de données hautes performances en dénormalisant, c'est comme essayer d'arriver à sa destination en quittant New York. Cela ne vous dit pas quel chemin aller.

Ce dont vous avez besoin, c’est d’une bonne discipline de conception, qui produise une conception simple et solide, même si cette conception est parfois en conflit avec les règles de la normalisation. 

L'une de ces disciplines est le schéma en étoile. Dans un schéma en étoile, une seule table de faits sert de plaque tournante à une étoile de tables. Les autres tables sont appelées tables de dimension et se trouvent au bord du schéma. Les dimensions sont connectées à la table des faits par des relations qui ressemblent aux rayons d'une roue. Le schéma en étoile est fondamentalement un moyen de projeter une conception multidimensionnelle sur une implémentation SQL.

Le schéma en flocon de neige, qui est un peu plus compliqué, est étroitement lié au schéma en étoile.

Si vous avez un bon schéma en étoile, vous pourrez obtenir une grande variété de combinaisons de vos données avec une jointure à trois voies, impliquant deux dimensions et une table de faits. De plus, de nombreux outils OLAP seront en mesure de déchiffrer automatiquement votre conception en étoile et vous donneront accès à vos données par pointer-cliquer, explorer et analyser graphiquement sans aucune autre programmation.

La conception du schéma en étoile enfreint parfois les deuxième et troisième formes normales, mais les résultats et les extraits sont plus rapides et plus flexibles. Il est le plus souvent utilisé dans les entrepôts de données, les dépôts de données et les bases de données de reporting. En règle générale, vous obtiendrez de bien meilleurs résultats avec le schéma en étoile ou une autre conception orientée recherche, qu'avec une "dénormalisation" aléatoire.

11
Walter Mitty

Les problèmes critiques liés à la dénormalisation sont les suivants:

  • Décider quelles données dupliquer et pourquoi 
  • Planification de la synchronisation des données
  • Refactoriser les requêtes pour utiliser les champs dénormalisés.

L'un des types les plus simples de dénormalisation consiste à renseigner un champ d'identité dans des tables afin d'éviter une jointure. Comme les identités ne doivent jamais changer, cela signifie que la question de la synchronisation des données est rarement abordée. Par exemple, nous remplissons notre ID client dans plusieurs tables car nous avons souvent besoin de les interroger par client et nous n'avons pas nécessairement besoin, dans les requêtes, des données contenues dans les tables entre la table client et la table interrogée. si les données étaient totalement normalisées. Vous devez toujours faire une jointure pour obtenir le nom du client, mais cela vaut mieux que de rejoindre 6 tables parent pour obtenir le nom du client lorsque c'est la seule donnée dont vous avez besoin de l'extérieur de la table que vous interrogez. 

Cependant, cela ne présenterait aucun avantage si nous ne posions pas souvent des questions pour lesquelles des données provenant des tables intermédiaires étaient nécessaires.

Une autre dénormalisation courante pourrait consister à ajouter un champ de nom à d'autres tables. Comme les noms sont intrinsèquement modifiables, vous devez vous assurer qu'ils restent synchronisés avec les déclencheurs. Mais si cela vous évite de vous joindre à 5 tables au lieu de 2, cela peut valoir le coût de l'insertion ou de la mise à jour légèrement plus longue.

7
HLGEM

Si vous avez certaines exigences, telles que la création de rapports, etc., il peut être utile de dénormaliser votre base de données de différentes manières:

  • introduisez certaines duplications de données pour économiser certaines jointures (par exemple, renseignez certaines informations dans une table et acceptez les duplications, de sorte que toutes les données de cette table ne soient pas nécessairement retrouvées en rejoignant une autre)

  • vous pouvez pré-calculer certaines valeurs et les stocker dans une colonne de table, afin de les calculer à la volée, pour interroger la base de données à chaque fois. Bien sûr, ces valeurs calculées peuvent devenir "obsolètes" avec le temps et vous aurez peut-être besoin de les recalculer à un moment donné, mais lire une valeur fixe revient généralement moins cher que de calculer quelque chose (par exemple, compter les lignes filles)

Il existe certainement plus de moyens de dénormaliser un schéma de base de données pour améliorer les performances, mais vous devez simplement être conscient du fait que vous rencontrez des difficultés pour le faire. Lorsque vous prenez ces décisions, vous devez peser avec soin les avantages et les inconvénients (avantages en termes de performances) et les problèmes auxquels vous vous exposez.

3
marc_s

Considérons une base de données avec une relation parent-enfant correctement normalisée. 

Disons que la cardinalité est une moyenne de 2x1. 

Vous avez deux tables, Parent, avec p lignes. Enfant avec 2x p rows.

Pour les lignes p parent, vous devez lire les lignes 2x p enfant. Le nombre total de lignes lues est p + 2x p

Envisagez de dénormaliser cela dans une seule table avec uniquement les lignes enfants, 2x p . Le nombre de lignes lues est 2x p

Moins de lignes == moins d'E/S physiques == plus vite.

1
S.Lott

Selon la dernière section de cet article,

https://technet.Microsoft.com/en-us/library/aa224786%28v=sql.80%29.aspx

vous pouvez utiliser la dénormalisation virtuelle, où vous créez des vues avec des données dénormalisées pour exécuter plus rapidement des requêtes SQL simplistes, tandis que les tables sous-jacentes restent normalisées pour des opérations d'ajout/mise à jour plus rapides qu'en temps réel). Je prends moi-même un cours sur les bases de données relationnelles mais, d'après ce que j'ai lu, cette approche me semble logique.

0
RJCurrie