it-swarm.com.de

Fehlercode 1117 Zu viele Spalten; MySQL-Spaltenlimit für Tabelle

Ich habe eine Tabelle mit 1699 Spalten und wenn ich versuche, mehr Spalten einzufügen, bekomme ich:

Fehlercode: 1117. Zu viele Spalten

In dieser Tabelle habe ich nur 1000 Zeilen. Für mich ist das Wichtigste die Anzahl der Spalten. Gibt es irgendwelche Einschränkungen auf dem Tisch? Ich möchte 2000 Spalten erstellen. Ist das möglich?

38
OHLÁLÁ

Warum sollten Sie eine Tabelle mit sogar 20 Spalten erstellen müssen, geschweige denn 2000 ???

Zugegeben, denormalisierte Daten können verhindern, dass JOINs ausgeführt werden müssen, um viele Datenspalten abzurufen. Wenn Sie jedoch mehr als 10 Spalten haben, sollten Sie anhalten und darüber nachdenken, was beim Abrufen von Daten unter der Haube passieren würde.

Wenn eine 2000-Spaltentabelle SELECT * FROM ... WHERE durchläuft, würden Sie während der Verarbeitung große temporäre Tabellen generieren, unnötige Spalten abrufen und viele Szenarien erstellen, in denen Kommunikationspakete ( max_allowed_packet ) übertragen würden bei jeder Anfrage an den Rand.

In meinen früheren Tagen als Entwickler arbeitete ich 1995 in einem Unternehmen, in dem DB2 das wichtigste RDBMS war. Das Unternehmen hatte eine einzige Tabelle mit 270 Spalten, Dutzenden von Indizes und Leistungsproblemen beim Abrufen von Daten. Sie kontaktierten IBM und ließen Berater die Architektur ihres Systems überprüfen, einschließlich dieser einen monolithischen Tabelle. Dem Unternehmen wurde mitgeteilt: "Wenn Sie diese Tabelle in den nächsten 2 Jahren nicht normalisieren, schlägt DB2 bei Abfragen fehl, die die Stage2-Verarbeitung ausführen (alle Abfragen, die nach nicht indizierten Spalten sortiert werden müssen)." Dies wurde einem Multi-Billionen-Dollar-Unternehmen mitgeteilt, um eine 270-Spalten-Tabelle zu normalisieren. Wie viel mehr eine 2000-Spalten-Tabelle.

In Bezug auf MySQL müssten Sie dieses schlechte Design kompensieren, indem Sie Optionen festlegen, die mit der DB2 Stage2-Verarbeitung vergleichbar sind. In diesem Fall wären diese Optionen

Das Tweeken dieser Einstellungen, um das Vorhandensein von Dutzenden, geschweige denn Hunderten von Spalten auszugleichen, funktioniert gut, wenn Sie über TB RAM verfügen.

Dieses Problem vervielfacht sich geometrisch, wenn Sie InnoDB verwenden, da Sie sich mit MVCC (Multiversion Concurrency Control) befassen müssen, um Tonnen von Spalten mit jedem SELECT, UPDATE und DELETE durch Transaktionsisolation zu schützen.

[~ # ~] Schlussfolgerung [~ # ~]

Es gibt keinen Ersatz oder Pflaster, das schlechtes Design ausgleichen kann. Bitte normalisieren Sie diesen Tisch heute, um Ihrer geistigen Gesundheit in Zukunft willen !!!

37
RolandoMySQLDBA

Ich habe Probleme, mir etwas vorzustellen, bei dem das Datenmodell zu Recht 2000 Spalten in einer ordnungsgemäß normalisierten Tabelle enthalten könnte.

Ich vermute, dass Sie wahrscheinlich eine Art denormalisiertes Schema zum Ausfüllen der Lücken ausführen, in dem Sie tatsächlich alle Arten von Daten in einer Tabelle speichern und anstatt die Daten in separate Tabellen aufzuteilen und Beziehungen herzustellen Sie haben verschiedene Felder, die aufzeichnen, welcher "Datentyp" in einer bestimmten Zeile gespeichert ist, und 90% Ihrer Felder sind NULL. Aber auch dann, um auf 2000 Spalten zu kommen ... yikes.

Die Lösung für Ihr Problem besteht darin, Ihr Datenmodell zu überdenken. Wenn Sie einen großen Stapel von Schlüssel-/Wertdaten speichern, die einem bestimmten Datensatz zugeordnet sind, können Sie ihn dann so modellieren. Etwas wie:

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

Um dann alle Sensoreinträge zu erhalten, die einem bestimmten "Stamm" -Datensatz zugeordnet sind, können Sie einfach SELECT sensor_id,value FROM sensor_readings WHERE master_id=<some master ID>. Wenn Sie die Daten für einen Datensatz in der Tabelle master zusammen mit allen Sensordaten für diesen Datensatz abrufen müssen, können Sie einen Join verwenden:

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>

Und dann weitere Verknüpfungen, wenn Sie Details zu den einzelnen Sensoren benötigen.

25
womble

Es ist ein Messsystem mit 2000 Sensoren

Ignorieren Sie alle Kommentare, die über Normalisierung schreien - was Sie verlangen, könnte ein vernünftiges Datenbankdesign (in einer idealen Welt) und perfekt normalisiert sein, es ist nur sehr ungewöhnlich, und wie an anderer Stelle erwähnt, sind RDBMS normalerweise nicht für diese vielen Spalten ausgelegt .

Obwohl Sie MySQL Hard Limit nicht erreichen, verhindert einer der anderen im Link genannten Faktoren wahrscheinlich, dass Sie höher steigen

Wie andere vorschlagen, können Sie diese Einschränkung umgehen, indem Sie eine untergeordnete Tabelle mit id, sensor_id, sensor_value oder einfacher gesagt, Sie können eine zweite Tabelle erstellen, die nur die Spalten enthält, die nicht in die erste passen (und dieselbe PK verwenden).

MySQL 5.0 Column-Count Limits (Hervorhebung hinzugefügt):

Es gibt eine feste Grenze von 4096 Spalten pro Tabelle , aber das effektive Maximum kann für eine bestimmte Tabelle geringer sein. Die genaue Grenze hängt von mehreren Wechselwirkungsfaktoren ab.

  • Jede Tabelle (unabhängig von der Speicher-Engine) hat eine maximale Zeilengröße von 65.535 Byte. Speicher-Engines können diese Grenze zusätzlich einschränken, wodurch die effektive maximale Zeile verringert wird Größe.

    Die maximale Zeilengröße beschränkt die Anzahl (und möglicherweise die Größe) der Spalten, da die Gesamtlänge aller Spalten diese Größe nicht überschreiten darf.

...

Einzelne Speicher-Engines können zusätzliche Einschränkungen auferlegen, die die Anzahl der Tabellenspalten begrenzen. Beispiele:

  • InnoDB erlaubt bis zu 1000 Spalten.
15
lg_

Erst noch mehr Flammen, dann eine echte Lösung ...

Ich stimme größtenteils den Flammen zu, die bereits auf dich geworfen wurden.

Ich bin mit der Normalisierung von Schlüsselwerten nicht einverstanden. Anfragen werden schrecklich. Leistung noch schlechter.

Eine "einfache" Möglichkeit, das unmittelbare Problem (Begrenzung der Anzahl der Spalten) zu vermeiden, besteht darin, die Daten vertikal zu partitionieren. Haben Sie beispielsweise 5 Tabellen mit jeweils 400 Spalten. Sie hätten alle den gleichen Primärschlüssel, außer man könnte ihn als AUTO_INCREMENT haben.

Vielleicht wäre es besser, sich für das Dutzend Felder zu entscheiden, die am wichtigsten sind, und sie in die Haupttabelle zu legen. Gruppieren Sie dann die Sensoren auf logische Weise und fügen Sie sie in mehrere parallele Tabellen ein. Mit der richtigen Gruppierung müssen Sie möglicherweise nicht immer alle Tabellen verbinden.

Indizieren Sie einen der Werte? Müssen Sie nach ihnen suchen? Wahrscheinlich suchen Sie nach Datum/Uhrzeit?

Wenn Sie viele Spalten indizieren müssen - punt.

Wenn Sie einige indizieren müssen, legen Sie sie in die Haupttabelle.

Hier ist die wirkliche Lösung (falls zutreffend) ...

Wenn Sie nicht die große Anzahl indizierter Sensoren benötigen, erstellen Sie keine Spalten! Ja, du hast mich gehört. Sammeln Sie sie stattdessen in JSON, komprimieren Sie den JSON und speichern Sie ihn in einem BLOB-Feld. Sie sparen eine Menge Platz; Sie haben nur eine Tabelle ohne Probleme mit Spaltenbeschränkungen. usw. Ihre Anwendung wird dekomprimiert und verwendet dann JSON als Struktur. Erraten Sie, was? Sie können eine Struktur haben - Sie können die Sensoren in Arrays, Mehrebenen usw. gruppieren, so wie es Ihre App möchte. Ein weiteres "Feature" - es ist offen. Wenn Sie weitere Sensoren hinzufügen, müssen Sie die Tabelle nicht ÄNDERN. JSON ist auf diese Weise flexibel.

(Die Komprimierung ist optional. Wenn Ihr Dataset sehr groß ist, hilft dies beim Speicherplatz und damit bei der Gesamtleistung.)

7
Rick James

Ich sehe dies als ein mögliches Szenario in der Welt der Big Data, in der Sie möglicherweise nicht die herkömmlichen Abfragen vom Typ select * ausführen. Wir beschäftigen uns damit in der Welt der Vorhersagemodelle auf Kundenebene, in der wir einen Kunden über Tausende von Dimensionen modellieren (alle mit Werten von 0 oder 1). Diese Art der Speicherung erleichtert die nachgelagerten Modellbauaktivitäten usw., wenn Sie die Risikofaktoren in derselben Zeile und das Ergebnisflag in derselben Zeile haben. Dies kann jedoch vom Speicherstandpunkt aus mit einer übergeordneten untergeordneten Struktur normalisiert werden Das nachgeschaltete Vorhersagemodell muss es wieder in ein flaches Schema konvertieren. Wir verwenden Rotverschiebung, um Spalten zu speichern, sodass Ihre über 1000 Spalten beim Laden der Daten tatsächlich in einem Spaltenformat gespeichert werden ...

Es gibt eine Zeit und einen Ort für dieses Design. Absolut. Normalisierung ist nicht die Lösung für jedes Problem.

4
BigDataGuy