J'ai une table avec 1699 colonnes et quand j'essaye d'insérer plus de colonnes j'obtiens,
Code d'erreur: 1117. Trop de colonnes
Dans ce tableau, je n'ai que 1000 lignes. Pour moi, la chose la plus importante est le nombre de colonnes. Y a-t-il des limites sur la table? Je veux créer 2000 colonnes. Est-ce possible?
Pourquoi auriez-vous besoin de créer un tableau avec même 20 colonnes, sans parler de 2000 ???
Des données dénormalisées accordées peuvent éviter d'avoir à faire des JOIN pour récupérer de nombreuses colonnes de données. Cependant, si vous avez plus de 10 colonnes, vous devez vous arrêter et réfléchir à ce qui se passerait sous le capot pendant la récupération des données.
Si une table de 2000 colonnes subit SELECT * FROM ... WHERE, vous généreriez de grandes tables temporaires pendant le traitement, récupérant des colonnes inutiles et créant de nombreux scénarios où les paquets de communication ( max_allowed_packet ) seraient poussés au bord de chaque requête.
À mes débuts en tant que développeur, j'ai travaillé dans une entreprise en 1995, où DB2 était le principal SGBDR. La société disposait d'une seule table contenant 270 colonnes, des dizaines d'index et des problèmes de performances lors de la récupération des données. Ils ont contacté IBM et ont demandé à des consultants d'examiner l'architecture de leur système, y compris cette seule table monolithique. La société a été informée que "si vous ne normalisez pas ce tableau au cours des 2 prochaines années, DB2 échouera sur les requêtes effectuant le traitement Stage2 (toutes les requêtes nécessitant un tri sur des colonnes non indexées)." Cela a été demandé à une entreprise de plusieurs billions de dollars, de normaliser un tableau à 270 colonnes. Combien plus si un tableau de 2000 colonnes.
En termes de mysql, vous devrez compenser une telle mauvaise conception en définissant des options comparables au traitement DB2 Stage2. Dans ce cas, ces options seraient
Tweeking ces paramètres pour compenser la présence de dizaines, sans parler de centaines, de colonnes fonctionne bien si vous avez des To de RAM.
Ce problème se multiplie géométriquement si vous utilisez InnoDB car vous devrez faire face à MVCC (Multiversion Concurrency Control) essayant de protéger des tonnes de colonnes avec chaque SELECT, UPDATE et DELETE via l'isolement des transactions.
[~ # ~] conclusion [~ # ~]
Il n'y a aucun substitut ou pansement qui peut compenser une mauvaise conception. S'il vous plaît, pour le bien de votre santé mentale à l'avenir, normalisez cette table aujourd'hui !!!
J'ai du mal à imaginer quoi que ce soit où le modèle de données pourrait légitimement contenir 2000 colonnes dans une table correctement normalisée.
Je suppose que vous faites probablement une sorte de schéma dénormalisé "remplir les blancs", où vous stockez en fait toutes sortes de données dans une seule table, et au lieu de diviser les données en tables séparées et d'établir des relations , vous disposez de plusieurs champs qui enregistrent quel "type" de données est stocké dans une ligne donnée, et 90% de vos champs sont NULL. Même alors, cependant, pour vouloir atteindre 2 000 colonnes ... oui.
La solution à votre problème est de repenser votre modèle de données. Si vous stockez un grand tas de données clés/valeurs associées à un enregistrement donné, pourquoi ne pas le modéliser de cette façon? Quelque chose comme:
CREATE TABLE master (
id INT PRIMARY KEY AUTO_INCREMENT,
<fields that really do relate to the
master records on a 1-to-1 basis>
);
CREATE TABLE sensor_readings (
id INT PRIMARY KEY AUTO_INCREMENT,
master_id INT NOT NULL, -- The id of the record in the
-- master table this field belongs to
sensor_id INT NOT NULL,
value VARCHAR(255)
);
CREATE TABLE sensors (
id INT PRIMARY KEY AUTO_INCREMENT,
<fields relating to sensors>
);
Ensuite, pour obtenir toutes les entrées de capteur associées à un enregistrement "maître" donné, vous pouvez simplement SELECT sensor_id,value FROM sensor_readings WHERE master_id=<some master ID>
. Si vous devez obtenir les données d'un enregistrement dans la table master
avec toutes les données de capteur pour cet enregistrement, vous pouvez utiliser une jointure:
SELECT master.*,sensor_readings.sensor_id,sensor_readings.value
FROM master INNER JOIN sensor_readings on master.id=sensor_readings.master_id
WHERE master.id=<some ID>
Et puis se joint encore si vous avez besoin de détails sur ce qu'est chaque capteur.
C'est un système de mesure avec 2000 capteurs
Ignorez tous les commentaires criant sur la normalisation - ce que vous demandez pourrait être une conception de base de données sensée (dans un monde idéal) et parfaitement bien normalisée, c'est juste très inhabituel, et comme indiqué ailleurs, les SGBDR ne sont généralement tout simplement pas conçus pour ces nombreuses colonnes .
Bien que vous ne frappiez pas le MySQL limite stricte , l'un des autres facteurs mentionnés dans le lien vous empêche probablement d'aller plus haut
Comme d'autres le suggèrent, vous pouvez contourner cette limitation en ayant une table enfant avec id, sensor_id, sensor_value
, ou plus simplement, vous pouvez créer une deuxième table pour contenir uniquement les colonnes qui ne rentreront pas dans la première (et utiliser le même PK)
MySQL 5.0 Column-Count Limits (emphase ajoutée):
Il existe une limite stricte de 4096 colonnes par table , mais le maximum effectif peut être inférieur pour une table donnée. La limite exacte dépend de plusieurs facteurs en interaction.
Chaque table (quel que soit le moteur de stockage) a une taille de ligne maximale de 65 535 octets. Les moteurs de stockage peuvent imposer des contraintes supplémentaires sur cette limite, ce qui réduit la ligne maximale effective Taille.
La taille de ligne maximale limite le nombre (et éventuellement la taille) de colonnes car la longueur totale de toutes les colonnes ne peut pas dépasser cette taille.
...
Les moteurs de stockage individuels peuvent imposer des restrictions supplémentaires qui limitent le nombre de colonnes de table. Exemples:
- InnoDB autorise jusqu'à 1000 colonnes.
D'abord un peu plus flamboyant, puis une vraie solution ...
Je suis surtout d'accord avec les flammes déjà lancées sur vous.
Je ne suis pas d'accord avec la normalisation des valeurs-clés. Les requêtes finissent par être horribles; performance encore pire.
Une façon "simple" d'éviter le problème immédiat (limitation du nombre de colonnes) consiste à "partitionner verticalement" les données. Disons, disons, 5 tableaux de 400 colonnes chacun. Ils auraient tous la même clé primaire, sauf que l'un pourrait avoir AUTO_INCREMENT.
Il serait peut-être préférable de décider des douzaines de champs les plus importants, de les mettre dans le tableau "principal". Regroupez ensuite les capteurs de manière logique et placez-les dans plusieurs tableaux parallèles. Avec le bon regroupement, vous n'aurez peut-être pas à REJOINDRE toutes les tables tout le temps.
Êtes-vous en train d'indexer l'une des valeurs? Avez-vous besoin de les rechercher? Vous recherchez probablement sur datetime?
Si vous avez besoin d'indexer beaucoup de colonnes - punt.
Si vous devez en indexer quelques-uns, placez-les dans le 'tableau principal.
Voici la vraie solution (si elle s'applique) ...
Si vous n'avez pas besoin d'indexer la vaste gamme de capteurs, ne faites pas de colonnes! Oui, tu m'as entendu. Au lieu de cela, collectez-les dans JSON, compressez le JSON, stockez-le dans un champ BLOB. Vous économiserez une tonne d'espace; vous n'aurez qu'une seule table, sans problèmes de limite de colonne; etc. Votre application décompressera, puis utilisera le JSON comme structure. Devine quoi? Vous pouvez avoir une structure - vous pouvez regrouper les capteurs dans des tableaux, des éléments à plusieurs niveaux, etc., tout comme votre application le souhaiterait. Une autre "fonctionnalité" - elle est ouverte. Si vous ajoutez plus de capteurs, vous n'avez pas besoin de MODIFIER le tableau. JSON si flexible de cette façon.
(La compression est facultative; si votre jeu de données est énorme, cela contribuera à l'espace disque, donc aux performances globales.)
Je vois cela comme un scénario possible dans le monde des mégadonnées, où vous n'effectuez peut-être pas le type traditionnel de requêtes select *. Nous traitons cela dans le monde de la modélisation prédictive au niveau du client où nous modélisons un client sur des milliers de dimensions (toutes ayant des valeurs de 0 ou 1). Ce mode de stockage facilite les activités de création de modèle en aval, etc., lorsque vous avez également les facteurs de risque dans la même ligne et l'indicateur de résultat dans la même ligne. Cela peut être normalisé à partir d'un point de stockage avec une structure enfant parent, mais le modèle prédictif en aval devra le reconvertir en schéma plat. Nous utilisons redshift qui fait du stockage en colonnes, donc vos 1000+ colonnes lorsque vous chargez les données, sont en fait stockées dans un format en colonnes ...
Il y a un temps et un lieu pour cette conception. Absolument. La normalisation n'est pas la solution à tous les problèmes.