mysql - combien de colonnes est trop?

111

Je mets en place une table qui pourrait avoir plus de 70 colonnes. Je pense maintenant à le diviser car certaines des données dans les colonnes ne seront pas nécessaires à chaque fois que la table est accédée. Là encore, si je fais cela, je suis obligé d'utiliser des jointures.

À quel moment, le cas échéant, est-il considéré comme trop de colonnes?

Brad
la source
6
Nous n'avons pas besoin d'utiliser SELECT * tout le temps. Nous avons toujours la possibilité de sélectionner uniquement les colonnes dont nous avons besoin pour une situation donnée.
APC
3
70 colonnes?! Combien de ceux-ci ne peuvent pas être nuls?
OMG Ponies
1
La grande question est ... est-ce que vous normalisez vos tables? 70 est un montant inhabituel à moins que vous ne dénormalisiez délibérément pour la performance (très peu de choses ont 70 attributs uniques). Si vous dénormalisez pour des raisons de performances, je serais d'accord avec ChssPly76 pour dire que vous pouvez utiliser tout ce que la base de données vous permettra de faire.
Godeke
2
@KM. est-ce censé être une blague? Je suis nouveau sur MySQL et je ne peux pas l'obtenir, voulez-vous dire que JOIN est une bonne chose ou quelque chose à essayer et à éviter?
Elia Iliashenko
2
Autant les jointures sont un élément central de SQL, la jointure pour le plaisir de la jointure dégradera probablement les performances et la maintenabilité pour toutes les applications que vous avez.
jeteon

Réponses:

142

Il est considéré comme trop élevé une fois qu'il est supérieur à la limite maximale prise en charge par la base de données .

Le fait que vous n'ayez pas besoin que chaque colonne soit renvoyée par chaque requête est parfaitement normal; c'est pourquoi l'instruction SELECT vous permet de nommer explicitement les colonnes dont vous avez besoin.

En règle générale, la structure de votre table doit refléter votre modèle de domaine; si vous avez vraiment 70 (100, qu'est-ce que vous avez) attributs qui appartiennent à la même entité, il n'y a aucune raison de les séparer en plusieurs tables.

ChssPly76
la source
29
@KM - c'est pourquoi j'ai dit "attributs appartenant à la même entité sur le modèle de domaine". Un nombre élevé de colonnes dans le tableau ne le rend PAS dénormalisé; c'est ce que les colonnes disent qui compte. De plus, si la normalisation est définitivement une bonne chose, ce n'est PAS une solution à tous les problèmes de la vie. Question piège - pensez-vous que le nombre de votes à côté de la question / réponse SO est calculé comme à select count(*) from voteschaque fois ou pensez-vous qu'il est peut-être dénormalisé? Est-ce que cela rend la base de données SO mauvaise et Jeff Atwood fou?
ChssPly76
@ ChssPly76, c'est une base de données relationnelle pas un modèle objet. il y a des tables, des lignes et des colonnes, travaillez avec cette contrainte si vous voulez des performances maximales, imitez vos objets pour plus de commodité dans un souci de performance. Alors, chaque élément d'information sur une personne devrait-il être stocké dans la même ligne? non, séparez-les et regroupez-les dans différents tableaux (en utilisant mon exemple de mon commentaire précédent): "Personne", "Activités" "HealthRecords". Le stockage d'un SUM pour des raisons de performances est un problème complètement différent de celui de conserver toutes les données dans 70 colonnes pour éviter les jointures.
KM.
20
"NumberOfTeethPulled" doit-il faire partie de l'enregistrement Personne? Non, il ne devrait probablement pas être stocké du tout - vous obtiendrez ces informations de "ToothExtractionRecord" si votre modèle de domaine nécessite un tel niveau de détail. Mais c'est VOTRE exemple (et, oserais-je dire, plutôt artificiel) - cela n'a rien à voir avec mon point: un grand nombre de colonnes dans une table ne signifie PAS que la table est dénormalisée. Pensez aux contrats immobiliers / bons de commande / autres documents financiers pour ne citer que quelques exemples. Peuvent-ils être divisés en plusieurs tables? Oui. Une raison de le faire? Pas vraiment.
ChssPly76
1
+1, c'était hilarant. Si vous créez une autre table, et que ce sera juste une relation 1: 1, vous devriez probablement l'inclure simplement dans la table principale. Cela ne va pas économiser de l'espace, cela ne fonctionnera pas beaucoup mieux si vous ne demandez pas les données plutôt que si elles ne sont pas du tout dans la table. La seule raison légitime qui me vient à l'esprit en ce moment, c'est s'il y a des informations sensibles telles que le SSN, les informations de carte de crédit, etc.
Vandel212
1
Si j'ai une table avec 15 cols et une autre avec 300 cols, la clé primaire des deux tables est la même. Sélectionnez une colonne dans les deux tableaux, les performances seront-elles significativement différentes?
une offre ne peut pas refuser
28

Le fractionnement de la table en plusieurs avec moins de colonnes présente certains avantages, également appelé partitionnement vertical . Voici quelques-uns:

  1. Si vous avez des tables avec de nombreuses lignes, la modification des index peut prendre un temps très long, car MySQL doit reconstruire tous les index de la table. La répartition des index sur plusieurs tables pourrait accélérer les choses.

  2. En fonction de vos requêtes et des types de colonnes, MySQL peut écrire des tables temporaires (utilisées dans des requêtes de sélection plus complexes) sur le disque. C'est mauvais, car les E / S de disque peuvent être un gros goulot d'étranglement. Cela se produit si vous avez des données binaires (texte ou blob) dans la requête.

  3. Une table plus large peut ralentir les performances des requêtes.

N'optimisez pas prématurément, mais dans certains cas, vous pouvez obtenir des améliorations à partir de tables plus étroites.

Jonstjohn
la source
5
Pourquoi MySQL a-t-il besoin de reconstruire tous les index de la table si un seul est modifié?
Petr Peller
Je me demandais la même chose . Pourquoi MySQL reconstruit tous les index de la table? La déclaration mentionnée ci-dessus est-elle correcte?
maj
13

C'est trop quand il enfreint les règles de normalisation. Il est assez difficile d'obtenir autant de colonnes si vous normalisez votre base de données. Concevez votre base de données pour modéliser le problème, pas autour de règles artificielles ou d'idées d'optimisation pour une plate-forme de base de données spécifique.

Appliquez les règles suivantes à la table large et vous aurez probablement beaucoup moins de colonnes dans une seule table.

  1. Pas d'éléments répétitifs ou de groupes d'éléments
  2. Aucune dépendance partielle sur une clé concaténée
  3. Aucune dépendance sur les attributs non clés

Voici un lien pour vous aider.

JohnFx
la source
17
It is pretty hard to get that many columns if you are normalizing your database.Pas aussi difficile qu'il y paraît.
Petr Peller
5
Certainement pas si difficile. Les gens ne semblent pas vraiment comprendre les formes normales autour de ces parties ici. Vous pouvez avoir 10000 colonnes et TOUJOURS être normalisées (même à la forme normale la plus élevée).
Hejazzman
2
@foljs Et c'est exactement là que la pratique acceptée de dénormalisation entre en jeu. Si vous êtes à une intersection et qu'une voiture est sur le point de vous pénétrer, il serait stupide d'attendre que le feu passe au vert. Vous devez vous écarter. Bien que passer le feu rouge ne soit pas techniquement légal, vous faites ce que vous devez évidemment faire étant donné la situation = dénormalisation
user3308043
3
Tu m'as perdu quand tu as commencé à parler de voitures. Aucune idée de la pertinence.
JohnFx
2
Cependant, comment faire des requêtes complexes dans ce scénario avec une seule table de données, vous ne pouvez pas, vous devez fortement compter sur le langage de programmation et divers autres éléments pour que cela fonctionne! Donc, je pourrais aussi bien revenir à une table avec 170 colonnes, car avoir des requêtes "JOIN" et une programmation extra complexe qui nécessite de faire fonctionner des tables séparées me semble être une perte de temps. Je suppose que je suis un grand fan du principe KISS.
Vlad Vladimir Hercules
0

Ce n'est pas un problème à moins que tous les attributs appartiennent à la même entité et ne dépendent pas les uns des autres. Pour vous faciliter la vie, vous pouvez avoir une colonne de texte contenant un tableau JSON. Évidemment, si vous n'avez pas de problème à obtenir tous les attributs à chaque fois. Bien que cela irait totalement à l'encontre de l'objectif de le stocker dans un SGBDR et compliquerait considérablement chaque transaction de base de données. Donc, son approche n'est pas recommandée à suivre dans toute la base de données.

Zeeshan Ch
la source
0

Avoir trop de colonnes dans la même table peut également entraîner d'énormes problèmes dans la réplication. Vous devez savoir que les changements qui se produisent dans le maître seront répliqués sur l'esclave .. par exemple, si vous mettez à jour un champ dans la table, la ligne entière sera w

Aujourd'hui
la source