Stellen Sie sich ein Webformular mit einer Reihe von Kontrollkästchen vor (einige oder alle können ausgewählt werden). Ich habe sie in einer durch Kommas getrennten Liste von Werten gespeichert, die in einer Spalte der Datenbanktabelle gespeichert sind.
Jetzt weiß ich, dass die richtige Lösung darin besteht, eine zweite Tabelle zu erstellen und die Datenbank ordnungsgemäß zu normalisieren. Die einfache Lösung war schneller zu implementieren, und ich wollte schnell und ohne zu viel Zeit damit einen Proof-of-Concept für diese Anwendung haben.
Ich dachte, die eingesparte Zeit und der einfachere Code haben sich in meiner Situation gelohnt. Ist dies eine vertretbare Designentscheidung, oder hätte ich sie von Anfang an normalisieren sollen?
Etwas mehr Kontext, dies ist eine kleine interne Anwendung, die im Wesentlichen eine Excel-Datei ersetzt, die in einem freigegebenen Ordner gespeichert wurde. Ich frage auch, weil ich darüber nachdenke, das Programm zu bereinigen und es wartbarer zu machen. Es gibt einige Dinge, mit denen ich nicht ganz zufrieden bin. Eines davon ist das Thema dieser Frage.
quelle
Antworten:
Kommagetrennte Listen verletzen nicht nur die erste Normalform aufgrund der sich wiederholenden Gruppe von Werten, die in einer einzelnen Spalte gespeichert sind, sondern haben auch viele andere praktischere Probleme:
idlist REGEXP '[[:<:]]2[[:>:]]'
*Um diese Probleme zu lösen, müssen Sie Tonnen von Anwendungscode schreiben und die Funktionen neu erfinden, die das RDBMS bereits wesentlich effizienter bietet .
Durch Kommas getrennte Listen sind so falsch, dass ich dies zum ersten Kapitel in meinem Buch gemacht habe: SQL Antipatterns: Vermeiden der Fallstricke der Datenbankprogrammierung .
Es gibt Zeiten, in denen Sie eine Denormalisierung anwenden müssen, aber wie @OMG Ponies erwähnt , sind dies Ausnahmefälle. Jede nicht relationale „Optimierung“ kommt einer Art von Abfrage auf Kosten anderer Verwendungszwecke der Daten zugute. Stellen Sie daher sicher, dass Sie wissen, welche Ihrer Abfragen so speziell behandelt werden müssen, dass sie eine Denormalisierung verdienen.
* MySQL 8.0 unterstützt diese Wortgrenzen-Ausdruckssyntax nicht mehr.
quelle
"Ein Grund war Faulheit".
Dies läutet Alarmglocken. Der einzige Grund, warum Sie so etwas tun sollten, ist, dass Sie wissen, wie man es "richtig" macht, aber Sie sind zu dem Schluss gekommen, dass es einen konkreten Grund gibt, es nicht so zu machen.
Allerdings: Wenn es sich bei den Daten, die Sie auf diese Weise speichern möchten, um Daten handelt, nach denen Sie niemals abfragen müssen, kann es sinnvoll sein, sie so zu speichern, wie Sie es ausgewählt haben.
(Einige Benutzer bestreiten die Aussage in meinem vorherigen Absatz und sagen, dass "Sie nie wissen können, welche Anforderungen in Zukunft hinzugefügt werden". Diese Benutzer sind entweder irregeführt oder geben eine religiöse Überzeugung an. Manchmal ist es vorteilhaft, an den Anforderungen zu arbeiten, die Sie haben vor dir haben.)
quelle
Es gibt zahlreiche Fragen zu SO:
Ein weiteres Problem mit der durch Kommas getrennten Liste besteht darin, sicherzustellen, dass die Werte konsistent sind. Das Speichern von Text bedeutet die Möglichkeit von Tippfehlern ...
Dies sind alles Symptome von denormalisierten Daten und zeigen, warum Sie immer für normalisierte Daten modellieren sollten. Denormalisierung kann eine Abfrageoptimierung sein, die angewendet wird, wenn sich der Bedarf tatsächlich ergibt .
quelle
Im Allgemeinen kann alles verteidigt werden, wenn es den Anforderungen Ihres Projekts entspricht. Dies bedeutet nicht, dass die Leute Ihrer Entscheidung zustimmen oder sie verteidigen wollen ...
Im Allgemeinen ist das Speichern von Daten auf diese Weise nicht optimal (z. B. schwieriger, effiziente Abfragen durchzuführen) und kann zu Wartungsproblemen führen, wenn Sie die Elemente in Ihrem Formular ändern. Vielleicht hätten Sie einen Mittelweg finden und stattdessen eine Ganzzahl verwenden können, die eine Reihe von Bit-Flags darstellt?
quelle
Ja, ich würde sagen, dass es wirklich so schlimm ist. Es ist eine vertretbare Wahl, aber das macht es nicht richtig oder gut.
Es bricht die erste Normalform.
Ein zweiter Kritikpunkt ist, dass das direkte Einfügen von Roheingabeergebnissen in eine Datenbank ohne Validierung oder Bindung Sie für SQL-Injection-Angriffe offen lässt.
Was Sie Faulheit und mangelndes SQL-Wissen nennen, ist das Zeug, aus dem Neophyten bestehen. Ich würde empfehlen, sich die Zeit zu nehmen, um es richtig zu machen und es als Gelegenheit zum Lernen zu betrachten.
Oder lassen Sie es wie es ist und lernen Sie die schmerzhafte Lektion eines SQL-Injection-Angriffs.
quelle
Nun, ich verwende seit mehr als 4 Jahren eine durch Tabulatoren getrennte Liste von Schlüssel / Wert-Paaren in einer NTEXT-Spalte in SQL Server und sie funktioniert. Sie verlieren zwar die Flexibilität, Abfragen zu stellen, aber wenn Sie andererseits eine Bibliothek haben, die das Schlüsselwertpaar beibehält / ableitet, ist dies keine so schlechte Idee.
quelle
Ich brauchte eine mehrwertige Spalte, die als XML-Feld implementiert werden konnte
Es kann bei Bedarf in ein Komma umgewandelt werden
Abfragen einer XML-Liste in SQL Server mit Xquery .
Als XML-Feld können einige der Probleme behoben werden.
Mit CSV: kann nicht sichergestellt werden, dass jeder Wert der richtige Datentyp ist: Keine Möglichkeit, 1,2,3, Banane, 5 zu verhindern
Mit XML: Werte in einem Tag können gezwungen werden, den richtigen Typ zu haben
Mit CSV: können keine Fremdschlüsseleinschränkungen verwendet werden, um Werte mit einer Nachschlagetabelle zu verknüpfen. Keine Möglichkeit, die referenzielle Integrität durchzusetzen.
Mit XML: immer noch ein Problem
Mit CSV: Eindeutigkeit kann nicht erzwungen werden: Keine Möglichkeit, 1,2,3,3,3,5 zu verhindern
Mit XML: immer noch ein Problem
Mit CSV: Ein Wert kann nicht aus der Liste gelöscht werden, ohne die gesamte Liste abzurufen.
Mit XML: Einzelne Elemente können entfernt werden
Mit CSV: schwierig, nach allen Entitäten mit einem bestimmten Wert in der Liste zu suchen. Sie müssen einen ineffizienten Tabellenscan verwenden.
Mit XML: XML-Feld kann indiziert werden
Mit CSV: Schwer zu zählende Elemente in der Liste oder andere aggregierte Abfragen. **
Mit XML: nicht besonders schwer
Mit CSV: Es ist schwierig, die Werte mit der Nachschlagetabelle zu verknüpfen, auf die sie verweisen. **
Mit XML: nicht besonders schwer
Mit CSV: Es ist schwierig, die Liste in sortierter Reihenfolge abzurufen.
Mit XML: nicht besonders schwer
Mit CSV: Das Speichern von Ganzzahlen als Zeichenfolgen benötigt etwa doppelt so viel Speicherplatz wie das Speichern von binären Ganzzahlen.
Mit XML: Speicher ist noch schlechter als ein CSV
Mit CSV: Plus viele Kommazeichen.
Bei XML werden Tags anstelle von Kommas verwendet
Kurz gesagt, die Verwendung von XML umgeht einige der Probleme mit der begrenzten Liste UND kann bei Bedarf in eine begrenzte Liste konvertiert werden
quelle
Ja, es ist so schlimm. Meiner Ansicht nach gibt es viele interessante "NOSQL" -Projekte mit einigen wirklich erweiterten Funktionen, wenn Sie keine relationalen Datenbanken verwenden möchten und nach einer Alternative suchen, die besser zu Ihnen passt.
quelle
Ich würde wahrscheinlich den Mittelweg einschlagen: Machen Sie jedes Feld in der CSV zu einer separaten Spalte in der Datenbank, aber machen Sie sich (zumindest vorerst) keine großen Sorgen um die Normalisierung. Irgendwann wird die Normalisierung vielleicht interessant, aber wenn alle Daten in einer einzigen Spalte gespeichert sind, profitieren Sie praktisch nicht mehr von der Verwendung einer Datenbank. Sie müssen die Daten in logische Felder / Spalten / wie auch immer Sie sie aufrufen möchten, trennen, bevor Sie sie überhaupt sinnvoll bearbeiten können.
quelle
Wenn Sie eine feste Anzahl von Booleschen Feldern haben, können Sie für jedes ein
INT(1) NOT NULL
(oderBIT NOT NULL
falls vorhanden) oderCHAR (0)
(nullbar) verwenden. Sie können auch a verwendenSET
(ich vergesse die genaue Syntax).quelle
INT(1)
dauert 4 Bytes; das(1)
ist bedeutungslos.