web-dev-qa-db-fra.com

Quelle est la plus efficace: plusieurs tables MySQL ou une grande table?

Je stocke divers détails d'utilisateur dans ma base de données MySQL. À l'origine, il a été configuré dans diverses tables, ce qui signifie que les données sont liées aux UserIds et émises via des appels parfois compliqués pour afficher et manipuler les données selon les besoins. La mise en place d'un nouveau système, il est presque logique de combiner toutes ces tables en une seule grande table de contenu connexe.

  • Est-ce que ça va être une aide ou un obstacle?
  • Considérations relatives à la vitesse d'appel, de mise à jour ou de recherche/manipulation?

Voici un exemple de certaines de mes structures de table:

  • utilisateurs - UserId, nom d'utilisateur, email, mot de passe crypté, date d'enregistrement, ip
  • user_details - données de cookie, nom, adresse, coordonnées, affiliation, données démographiques
  • user_activity - contributions, dernière connexion, dernière consultation
  • user_settings - paramètres d'affichage du profil
  • user_interests - publicité des variables ciblables
  • user_levels - droits d'accès
  • user_stats - hits, recoupements

Edit: J'ai voté pour l'instant toutes les réponses, ils ont tous des éléments qui répondent essentiellement à ma question.

La plupart des tableaux ont une relation 1: 1 qui était la principale raison de leur dénormalisation.

Y aura-t-il des problèmes si le tableau s'étend sur plus de 100 colonnes alors qu'une grande partie de ces cellules est susceptible de rester vide?

95
Peter Craig

Plusieurs tables aident dans les cas/manières suivants:

(a) si différentes personnes vont développer des applications impliquant différentes tables, il est logique de les diviser.

(b) Si vous souhaitez attribuer différents types d'autorités à différentes personnes pour différentes parties de la collecte de données, il peut être plus pratique de les diviser. (Bien sûr, vous pouvez envisager de définir des vues et de leur donner une autorisation appropriée).

(c) Pour déplacer des données vers différents endroits, en particulier pendant le développement, il peut être judicieux d'utiliser des tables entraînant des tailles de fichier plus petites.

(d) Une empreinte plus petite peut vous rassurer pendant que vous développez des applications sur la collecte de données spécifiques d'une seule entité.

(e) C'est une possibilité: ce que vous pensiez en tant que données à valeur unique pourrait se révéler être de multiples valeurs à l'avenir. par exemple. la limite de crédit est un champ de valeur unique à partir de maintenant. Mais demain, vous pouvez décider de changer les valeurs comme (date de, date à, valeur de crédit). Les tableaux divisés pourraient être utiles maintenant.

Mon vote serait pour plusieurs tableaux - avec des données correctement réparties.

Bonne chance.

59
user115905

La combinaison des tables est appelée dénormalisation.

Cela peut (ou peut ne pas) aider à faire des requêtes (qui font beaucoup de JOINs) pour s'exécuter plus rapidement au détriment de la création d'un enfer de maintenance.

MySQL est capable d'utiliser uniquement la méthode JOIN, à savoir NESTED LOOPS.

Cela signifie que pour chaque enregistrement de la table de pilotage, MySQL localise un enregistrement correspondant dans la table pilotée dans une boucle.

La localisation d'un enregistrement est une opération assez coûteuse qui peut prendre des dizaines de fois aussi longtemps que le balayage d'enregistrement pur.

Déplacer tous vos enregistrements dans une seule table vous aidera à vous débarrasser de cette opération, mais la table elle-même s'agrandit et l'analyse de la table prend plus de temps.

Si vous avez beaucoup d'enregistrements dans d'autres tables, l'augmentation de l'analyse de la table peut surpondérer les avantages des enregistrements analysés séquentiellement.

L'enfer de maintenance, en revanche, est garanti.

33
Quassnoi

Sont-ils tous des relations 1: 1? Je veux dire, si un utilisateur peut appartenir, par exemple, à différents niveaux d'utilisateurs, ou si les intérêts des utilisateurs sont représentés sous la forme de plusieurs enregistrements dans la table des intérêts des utilisateurs, la fusion de ces tables serait hors de question immédiatement.

En ce qui concerne les réponses précédentes sur la normalisation, il faut dire que les règles de normalisation de la base de données ont complètement ignoré les performances et ne regardent que ce qui est une conception de base de données soignée. C'est souvent ce que vous voulez atteindre, mais il y a des moments où il est logique de dénormaliser activement dans la poursuite de la performance.

Dans l'ensemble, je dirais que la question se résume au nombre de champs dans les tableaux et à la fréquence à laquelle ils sont consultés. Si l'activité des utilisateurs n'est souvent pas très intéressante, alors il pourrait être gênant de toujours l'avoir sur le même enregistrement, pour des raisons de maintenance et. Si certaines données, comme les paramètres, par exemple, sont consultées très souvent, mais contiennent simplement trop de champs, il peut également ne pas être pratique de fusionner les tables. Si vous êtes uniquement intéressé par le gain de performances, vous pouvez envisager d'autres approches, telles que conserver les paramètres séparés, mais les enregistrer dans une variable de session qui leur est propre afin que vous n'ayez pas à interroger la base de données à leur place très souvent.

17
David Hedlund

tous de ces tableaux ont-ils un 1-to-1 relation? Par exemple, chaque ligne utilisateur n'aura-t-elle qu'une seule ligne correspondante dans user_stats ou user_levels? Si c'est le cas, il pourrait être judicieux de les combiner en une seule table. Si la relation n'est pas1 to 1 cependant, cela n'aurait probablement aucun sens de les combiner (dénormaliser).

Les avoir dans des tables distinctes par rapport à une table aura probablement peu d'effet sur les performances, sauf si vous avez des centaines de milliers ou des millions d'enregistrements utilisateur. Le seul véritable gain que vous obtiendrez sera de simplifier vos requêtes en les combinant.

ETA:

Si votre préoccupation est d'avoir trop de colonnes, alors pensez à ce que vous utilisez généralement ensemble et combinez-les, en laissant le reste dans une autre table (ou plusieurs tables séparées si nécessaire).

Si vous regardez la façon dont vous utilisez les données, je suppose que vous constaterez que quelque chose comme 80% de vos requêtes utilisent 20% de ces données, les 80% restants n'étant utilisés qu'occasionnellement. Combinez les 20% fréquemment utilisés dans une seule table et laissez les 80% que vous n'utilisez pas souvent dans des tables séparées et vous aurez probablement un bon compromis.

14
Eric Petroelje

La création d'une table massive va à l'encontre des principes de la base de données relationnelle. Je ne les combinerais pas tous en une seule table. Vous allez obtenir plusieurs instances de données répétées. Si votre utilisateur a trois intérêts par exemple, vous disposerez de 3 lignes, avec les mêmes données utilisateur juste pour stocker les trois intérêts différents. Optez sans aucun doute pour l'approche des tables multiples "normalisées". Voir this page Wiki pour la normalisation de la base de données.

Edit: J'ai mis à jour ma réponse, comme vous avez mis à jour votre question ... Je suis encore plus d'accord avec ma réponse initiale depuis ...

une grande partie de ces cellules est susceptible de rester vide

Si, par exemple, un utilisateur n'a aucun intérêt, si vous vous normalisez, vous n'aurez simplement pas de ligne dans la table des intérêts pour cet utilisateur. Si vous avez tout dans une seule table massive, vous aurez alors des colonnes (et apparemment beaucoup d'entre elles) qui ne contiennent que des NULL.

J'ai travaillé pour une entreprise de téléphonie où il y avait des tonnes de tables, l'obtention de données pourrait nécessiter de nombreuses jointures. Lorsque les performances de lecture de ces tables étaient critiques, des procédures ont été créées qui pourraient générer une table plate (c'est-à-dire une table dénormalisée) qui ne nécessiterait pas de jointures, de calculs, etc. vers lesquels les rapports pourraient pointer. Ceux-ci étaient ensuite utilisés en conjonction avec un agent SQL Server pour exécuter le travail à certains intervalles (c'est-à-dire qu'une vue hebdomadaire de certaines statistiques s'exécuterait une fois par semaine, etc.).

8
user110714

Pourquoi ne pas utiliser la même approche Wordpress le fait en ayant une table d'utilisateurs avec les informations utilisateur de base que tout le monde possède, puis en ajoutant une table "user_meta" qui peut être essentiellement n'importe quelle paire clé/valeur associée à l'utilisateur id. Donc, si vous avez besoin de trouver toutes les métadonnées pour l'utilisateur, vous pouvez simplement les ajouter à votre requête. Vous ne devrez pas toujours ajouter la requête supplémentaire si elle n'est pas nécessaire pour des choses comme la connexion. L'avantage de cette approche est également laisse votre table ouverte à l'ajout de nouvelles fonctionnalités à vos utilisateurs, telles que le stockage de leur identifiant Twitter ou de chaque intérêt individuel. Vous n'aurez pas non plus à gérer un labyrinthe d'ID associés, car vous avez une table qui règle toutes les métadonnées et vous la limiterez à une seule association au lieu de 50.

Wordpress le fait spécifiquement pour permettre l'ajout de fonctionnalités via des plugins, permettant ainsi à votre projet d'être plus évolutif et ne nécessitera pas une refonte complète de la base de données si vous devez ajouter une nouvelle fonctionnalité.

7
Rudy Garcia

Je pense que c'est une de ces situations "ça dépend". Avoir plusieurs tables est plus propre et probablement mieux en théorie. Mais lorsque vous devez joindre 6-7 tables pour obtenir des informations sur un seul utilisateur, vous pouvez commencer à repenser cette approche.

3
Tundey

Je dirais que cela dépend de la signification réelle des autres tableaux. Est-ce qu'un user_details contient plus de 1 de plus/users et ainsi de suite. Le niveau de normalisation le mieux adapté à vos besoins dépend de vos exigences.

Si vous avez une table avec un bon index, ce serait probablement plus rapide. Mais d'un autre côté probablement plus difficile à maintenir.

Pour moi, il semble que vous pouvez ignorer les détails de l'utilisateur, car il s'agit probablement d'une relation 1 à 1 avec les utilisateurs. Mais le reste est probablement beaucoup de lignes par utilisateur?

1
Richard L