it-swarm.it

Codice errore 1117 Troppe colonne; Limite di colonne MySQL sulla tabella

Ho una tabella con 1699 colonne e quando provo a inserire più colonne ottengo,

Codice errore: 1117. Troppe colonne

In questa tabella ho solo 1000 righe. Per me la cosa più importante è il numero di colonne. Ci sono delle limitazioni sul tavolo? Voglio creare 2000 colonne. È possibile?

38
OHLÁLÁ

Perché dovresti creare una tabella con anche 20 colonne, figuriamoci 2000 ???

I dati garantiti e denormalizzati possono impedire la necessità di eseguire JOIN per recuperare molte colonne di dati. Tuttavia, se hai più di 10 colonne, dovresti fermarti e pensare a cosa potrebbe accadere sotto il cofano durante il recupero dei dati.

Se una tabella di colonne 2000 subisce SELEZIONA * DA ... DOVE, genererai grandi tabelle temporanee durante l'elaborazione, recuperando colonne non necessarie e creando molti scenari in cui verrebbero inviati pacchetti di comunicazione ( max_allowed_packet ) sull'orlo di ogni domanda.

Nei miei primi giorni come sviluppatore, ho lavorato in un'azienda nel 1995, dove DB2 era il principale RDBMS. La società aveva un'unica tabella con 270 colonne, dozzine di indici e problemi di prestazioni nel recupero dei dati. Hanno contattato IBM e fatto consultare i consulenti sull'architettura del loro sistema, inclusa questa tabella monolitica. Alla società è stato detto "Se non si normalizza questa tabella nei prossimi 2 anni, DB2 fallirà nelle query che eseguono l'elaborazione Stage2 (tutte le query che richiedono l'ordinamento su colonne non indicizzate)." Ciò è stato detto a un'azienda multimiliardaria di normalizzare una tabella di 270 colonne. Quanto più una tabella di colonne 2000.

In termini di mysql, dovresti compensare tale cattiva progettazione impostando opzioni comparabili all'elaborazione DB2 Stage2. In questo caso, tali opzioni sarebbero

La modifica di queste impostazioni per compensare la presenza di dozzine, figuriamoci centinaia, di colonne funziona bene se si dispone di TB di RAM.

Questo problema si moltiplica geometricamente se usi InnoDB poiché dovrai affrontare MVCC (Multiversion Concurrency Control) cercando di proteggere tonnellate di colonne con ogni SELECT, UPDATE e DELETE attraverso l'isolamento delle transazioni.

[~ ~ #] conclusione [~ ~ #]

Non ci sono sostituti o cerotti che possono compensare la cattiva progettazione. Per favore, per il tuo buonsenso in futuro, normalizza quel tavolo oggi !!!

37
RolandoMySQLDBA

Ho difficoltà a immaginare qualcosa in cui il modello di dati potrebbe contenere legittimamente 2000 colonne in una tabella correttamente normalizzata.

La mia ipotesi è che probabilmente stai facendo una sorta di schema denormalizzato "riempi gli spazi vuoti", in cui stai effettivamente memorizzando tutti i diversi tipi di dati in una tabella e invece di suddividere i dati in tabelle separate e creare relazioni , hai vari campi che registrano quale "tipo" di dati è archiviato in una determinata riga e il 90% dei tuoi campi è NULL. Anche allora, però, voler arrivare a 2000 colonne ... yikes.

La soluzione al tuo problema è ripensare il tuo modello di dati. Se stai memorizzando una grande pila di dati chiave/valore associati a un dato record, perché non modellarlo in quel modo? Qualcosa di simile a:

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>
);

Quindi, per ottenere tutte le voci del sensore associate a un dato record "master", puoi semplicemente SELECT sensor_id,value FROM sensor_readings WHERE master_id=<some master ID>. Se è necessario ottenere i dati per un record nella tabella master insieme a tutti i dati del sensore per quel record, è possibile utilizzare un join:

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>

E poi si unisce ulteriormente se hai bisogno di dettagli su cosa sia ciascun sensore.

25
womble

È un sistema di misurazione con 2000 sensori

Ignora tutti i commenti che urlano sulla normalizzazione: quello che stai chiedendo potrebbe essere una progettazione di database sensata (in un mondo ideale) e perfettamente ben normalizzata, è semplicemente molto insolita e, come sottolineato altrove, gli RDBMS di solito non sono progettati per queste colonne .

Anche se non stai colpendo MySQL hard limit , uno degli altri fattori menzionati nel link probabilmente ti impedisce di andare più in alto

Come altri suggeriscono, potresti aggirare questa limitazione disponendo di una tabella figlio con id, sensor_id, sensor_value, o più semplicemente, potresti creare una seconda tabella per contenere solo le colonne che non si adatteranno alla prima (e usare lo stesso PK)

MySQL 5.0 Column-Count Limits (enfasi aggiunta):

Esiste un limite massimo di 4096 colonne per tabella , ma il massimo effettivo potrebbe essere inferiore per una determinata tabella. Il limite esatto dipende da diversi fattori interagenti.

  • Ogni tabella (indipendentemente dal motore di archiviazione) ha una dimensione massima delle righe di 65.535 byte. I motori di archiviazione possono porre ulteriori vincoli su questo limite, riducendo la riga massima effettiva dimensione.

    La dimensione massima della riga limita il numero (e possibilmente la dimensione) delle colonne perché la lunghezza totale di tutte le colonne non può superare questa dimensione.

...

I singoli motori di archiviazione potrebbero imporre ulteriori restrizioni che limitano il conteggio delle colonne della tabella. Esempi:

  • InnoDB consente fino a 1000 colonne.
15
lg_

Prima un po 'più di fuoco, poi una vera soluzione ...

Sono per lo più d'accordo con le fiamme già lanciate contro di te.

Non sono d'accordo con la normalizzazione dei valori-chiave. Le domande finiscono per essere orribili; prestazioni anche peggiori.

Un modo "semplice" per evitare il problema immediato (limitazione del numero di colonne) è "partizionare verticalmente" i dati. Hanno, diciamo, 5 tavoli con 400 colonne ciascuno. Avrebbero tutti la stessa chiave primaria, tranne uno potrebbe essere AUTO_INCREMENT.

Forse sarebbe meglio decidere sulla dozzina di campi più importanti, metterli nella tabella "principale". Quindi raggruppare i sensori in modo logico e inserirli in diverse tabelle parallele. Con il corretto raggruppamento, potrebbe non essere necessario UNIRE tutti i tavoli in ogni momento.

Stai indicizzando qualcuno dei valori? Hai bisogno di cercarli? Probabilmente cerchi su datetime?

Se devi indicizzare molte colonne - punt.

Se devi indicizzarne alcuni, inseriscili nella tabella principale.

Ecco la vera soluzione (se applicabile) ...

Se non hai bisogno della vasta gamma di sensori indicizzati, allora non creare colonne! Sì, mi hai sentito. Invece, raccoglili in JSON, comprimi il JSON, memorizzalo in un campo BLOB. Risparmierai un sacco di spazio; avrai una sola tabella, senza problemi di limite di colonna; ecc. L'applicazione verrà decompressa e quindi utilizzerà JSON come struttura. Indovina un po? Puoi avere una struttura: puoi raggruppare i sensori in array, elementi multilivello, ecc., Proprio come vorrebbe la tua app. Un'altra "caratteristica" - è a tempo indeterminato. Se aggiungi più sensori, non è necessario modificare la tabella. JSON se flessibile in questo modo.

(La compressione è facoltativa; se il set di dati è enorme, aiuterà con lo spazio su disco, quindi le prestazioni complessive.)

7
Rick James

Vedo questo come uno scenario possibile nel mondo dei big data, in cui potresti non eseguire il tradizionale tipo di query select *. Ci occupiamo di questo nel mondo della modellazione predittiva a livello di cliente, dove modelliamo un cliente su migliaia di dimensioni (tutte con valori pari a 0 o 1). Questo modo di archiviazione rende più semplici le attività di costruzione del modello a valle ecc. Quando si hanno i fattori di rischio nella stessa riga e anche il flag di risultato nella stessa riga. Questo può essere normalizzato da un punto di vista dello storage con una struttura figlio principale, ma il modello predittivo a valle dovrà riconvertirlo in schema piatto. Usiamo redshift che fa l'archiviazione colonnare, quindi le tue 1000+ colonne quando carichi i dati, in realtà sono archiviate in un formato colonnare ...

C'è un tempo e un luogo per questo disegno. Assolutamente. La normalizzazione non è la soluzione per ogni problema.

4
BigDataGuy