Je stocke divers détails utilisateur dans ma base de données MySQL. À l'origine, il a été mis en place dans diverses tables, ce qui signifie que les données sont liées aux UserIds et sont sorties via des appels parfois compliqués pour afficher et manipuler les données selon les besoins. Lors de 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.
- Cela va-t-il être une aide ou un obstacle?
- Considérations de vitesse lors de l'appel, de la mise à jour ou de la 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 - variables ciblables publicitaires
- user_levels - droits d'accès
- user_stats - hits, comptes
Edit: J'ai voté pour toutes les réponses jusqu'à présent, elles ont toutes des éléments qui répondent essentiellement à ma question.
La plupart des tables 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?
la source
Réponses:
Plusieurs tableaux aident des manières / cas 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 répartir. (Bien sûr, vous pouvez envisager de définir des vues et de les autoriser de manière 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 résultant en des fichiers de plus petite taille.
(d) Une empreinte plus petite peut être plus confortable pendant que vous développez des applications sur la collecte de données spécifique d'une seule entité.
(e) C'est une possibilité: ce que vous pensiez comme une donnée à valeur unique peut s'avérer être en réalité plusieurs valeurs à l'avenir. Par exemple, la limite de crédit est un champ à valeur unique à partir de maintenant. Mais demain, vous pouvez décider de changer les valeurs comme (date du, date au, valeur du crédit). Les tables fractionnées pourraient être utiles maintenant.
Mon vote serait pour plusieurs tables - avec des données convenablement réparties.
Bonne chance.
la source
La combinaison des tables s'appelle la dénormalisation.
Cela peut (ou non) aider à
JOIN
accélérer certaines requêtes (qui font beaucoup de s) au détriment de la création d'un enfer de maintenance.MySQL
est capable d'utiliser uniquement laJOIN
méthode, à savoirNESTED LOOPS
.Cela signifie que pour chaque enregistrement de la table
MySQL
pilotée , 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 plus longtemps que la simple numérisation de l'enregistrement.
Le fait de déplacer tous vos enregistrements dans une 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 table peut surpondérer les avantages des enregistrements analysés de manière séquentielle.
L'enfer d'entretien, en revanche, est garanti.
la source
Sont-ils tous des relations 1: 1? Je veux dire, si un utilisateur pouvait appartenir, disons, à différents niveaux d'utilisateurs, ou si les intérêts des utilisateurs sont représentés sous forme de plusieurs enregistrements dans la table des intérêts des utilisateurs, alors fusionner ces tables serait immédiatement hors de question.
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 qu'est une conception de base de données soignée. C'est souvent ce que vous voulez réaliser, mais il y a des moments où il est logique de se dénormaliser activement à la recherche de la performance.
Dans l'ensemble, je dirais que la question se résume à combien de champs il y a dans les tableaux et à quelle fréquence ils sont consultés. Si l'activité de l'utilisateur n'est souvent pas très intéressante, il peut être gênant de toujours l'avoir sur le même enregistrement, pour des raisons de performances et de maintenance. 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 n'êtes intéressé que par le gain de performances, vous pouvez envisager d'autres approches, telles que garder les paramètres séparés, mais les enregistrer dans une variable de session qui leur est propre afin de ne pas avoir à interroger la base de données très souvent.
la source
3NF
normalisation, alors profitez d'une deuxième table pour résoudre cela, mais cela ne semble pas être ce à quoi OP fait référence pour les autres tables.)Faites toutes ces tables ont une
1-to-1
relation? Par exemple, chaque ligne utilisateur aura-t-elle une seule ligne correspondante dansuser_stats
ouuser_levels
? Si tel est le cas, il peut être judicieux de les combiner en un seul tableau. Si la relation ne l'est pas1 to 1
, il n'aurait probablement pas de sens de les combiner (dénormaliser).Les avoir dans des tables séparées 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 réel gain que vous obtiendrez est de simplifier vos requêtes en les combinant.
ETA:
Si vous craignez d'avoir trop de colonnes , pensez à ce que vous utilisez généralement ensemble et combinez-les , en laissant le reste dans une table séparée (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 ces 20% fréquemment utilisés dans une table et laissez les 80% que vous n'utilisez pas souvent dans des tables séparées et vous aurez probablement un bon compromis.
la source
La création d'une table massive va à l'encontre des principaux 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 aurez 3 lignes, avec les mêmes données utilisateur juste pour stocker les trois intérêts différents. Optez définitivement pour l'approche de table multiple «normalisée». Consultez cette page Wiki pour la normalisation de la base de données.
Edit: J'ai mis à jour ma réponse, car vous avez mis à jour votre question ... Je suis encore plus d'accord avec ma réponse initiale depuis ...
Si, par exemple, un utilisateur n'avait aucun intérêt, si 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 table massive, alors vous aurez 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 pouvait nécessiter de nombreuses jointures. Lorsque les performances de lecture de ces tables étaient critiques, des procédures ont été créées pour générer une table plate (c'est-à-dire une table dénormalisée) qui ne nécessiterait aucune jointure, aucun calcul, etc. vers lequel les rapports pourraient pointer. Ceux-ci étaient ensuite utilisés en conjonction avec un agent serveur SQL pour exécuter le travail à certains intervalles (c'est-à-dire qu'une vue hebdomadaire de certaines statistiques s'exécuterait une fois par semaine et ainsi de suite).
la source
Pourquoi ne pas utiliser la même approche que Wordpress en ayant une table des utilisateurs avec des informations utilisateur de base que tout le monde possède, puis en ajoutant une table "user_meta" qui peut essentiellement être n'importe quelle paire clé / valeur associée à l'ID utilisateur. Donc, si vous avez besoin de trouver toutes les méta-informations pour l'utilisateur, vous pouvez simplement les ajouter à votre requête. Vous ne devrez pas non plus toujours ajouter la requête supplémentaire si cela n'est pas nécessaire pour des choses comme la connexion. L'avantage de cette approche laisse également 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'identifiants associés, car vous avez une table qui régit 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é.
la source
wp_usermeta
tableau Wordpress se développe géométriquement. Chaque utilisateur ajoute X lignes à lawp_usermeta
table, une ligne pour chaque méta-information que nous voulons conserver pour cet utilisateur. Si vous conservez 8 champs personnalisés pour chaque utilisateur, cela signifie que wp_usermeta comportera desusers * 8
lignes. Cela semble causer des problèmes de performances, mais je ne sais pas si c'est le problème ou non…get_users()
) juste pour calculer la pagination. Une fois que nous avons corrigé le code pour utiliser uneSELECT COUNT(…)
requête pour la pagination à la place, le temps de chargement de la page est passé de 28 secondes à environ 400 ms. Je me demande toujours comment les performances se comparent aux tables jointes ou à une seule table plate… J'ai eu du mal à trouver des mesures de performances sur le Web.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.
la source
Je dirais que cela dépend de ce que signifient vraiment les autres tableaux. Un user_details contient-il plus de 1 de plus / users et ainsi de suite. Le niveau de normalisation le mieux adapté à vos besoins dépend de vos demandes.
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 pourriez ignorer User_Details car il s'agit probablement d'une relation 1 à 1 avec les utilisateurs. Mais le reste est probablement beaucoup de lignes par utilisateur?
la source