Also, je Mehrdad Antwort auf eine ähnliche Frage , ich es bekommen , dass ein „richtiger“ Datenbanktabellenspalt keine Liste speichert. Sie sollten vielmehr eine andere Tabelle erstellen, die die Elemente dieser Liste effektiv enthält, und sie dann direkt oder über eine Junction-Tabelle mit ihr verknüpfen. Die Art der Liste, die ich erstellen möchte, besteht jedoch aus eindeutigen Elementen (im Gegensatz zu den Früchten der verknüpften Frage)Beispiel). Darüber hinaus sind die Elemente in meiner Liste explizit sortiert. Wenn ich die Elemente in einer anderen Tabelle gespeichert habe, muss ich sie jedes Mal sortieren, wenn ich darauf zugegriffen habe. Schließlich ist die Liste im Grunde genommen atomar, da ich jedes Mal, wenn ich auf die Liste zugreifen möchte, auf die gesamte Liste zugreifen möchte und nicht nur auf einen Teil davon. Es erscheint also albern, eine Datenbankabfrage ausgeben zu müssen, um Teile davon zusammenzustellen Die Liste.
Die Lösung von AKX (oben verlinkt) besteht darin, die Liste zu serialisieren und in einer Binärspalte zu speichern. Dies scheint aber auch unpraktisch zu sein, da ich mir Sorgen um Serialisierung und Deserialisierung machen muss.
Gibt es eine bessere Lösung? Wenn es ist keine bessere Lösung, warum dann? Es scheint, dass dieses Problem von Zeit zu Zeit auftreten sollte.
... nur ein bisschen mehr Infos, um dich wissen zu lassen, woher ich komme. Sobald ich gerade angefangen hatte, SQL und Datenbanken im Allgemeinen zu verstehen, wurde ich auf LINQ to SQL umgestellt, und jetzt bin ich ein wenig verwöhnt, weil ich damit rechne, mit meinem Programmierobjektmodell umzugehen, ohne darüber nachdenken zu müssen, wie die Objekte aussehen werden abgefragt oder in der Datenbank gespeichert.
Vielen Dank an alle!
John
UPDATE: In den ersten Antworten, die ich bekomme, sehe ich "Sie können den CSV / XML-Weg gehen ... aber NICHT!". Jetzt suche ich nach Erklärungen, warum. Zeigen Sie mir einige gute Referenzen.
Um Ihnen eine bessere Vorstellung davon zu geben, was ich vorhabe: In meiner Datenbank habe ich eine Funktionstabelle mit einer Liste von (x, y) Paaren. (Die Tabelle enthält auch andere Informationen, die für unsere Diskussion keine Bedeutung haben.) Ich werde niemals einen Teil der Liste der (x, y) -Paare sehen müssen. Vielmehr werde ich sie alle nehmen und auf dem Bildschirm darstellen. Ich werde dem Benutzer erlauben, die Knoten zu ziehen, um die Werte gelegentlich zu ändern oder dem Plot weitere Werte hinzuzufügen.
Sie können SQL einfach alle zusammen vergessen und einen "NoSQL" -Ansatz wählen. RavenDB , MongoDB und CouchDB kommen als mögliche Lösungen in den Sinn. Mit einem NoSQL-Ansatz verwenden Sie nicht das relationale Modell. Sie sind nicht einmal auf Schemata beschränkt.
quelle
Was ich bei vielen Menschen gesehen habe, ist Folgendes (es ist möglicherweise nicht der beste Ansatz, korrigieren Sie mich, wenn ich falsch liege):
Die Tabelle, die ich im Beispiel verwende, ist unten angegeben (die Tabelle enthält Spitznamen, die Sie Ihren spezifischen Freundinnen gegeben haben. Jede Freundin hat eine eindeutige ID):
Angenommen, Sie möchten viele Spitznamen unter einer ID speichern. Aus diesem Grund haben wir ein
seq_no
Feld eingefügt.Füllen Sie nun diese Werte in Ihre Tabelle ein:
Wenn Sie alle Namen finden möchten, die Sie Ihrer Freundin ID 1 gegeben haben, können Sie Folgendes verwenden:
quelle
Einfache Antwort: Wenn und nur wenn Sie sicher sind, dass die Liste immer als Liste verwendet wird, verbinden Sie die Liste an Ihrem Ende mit einem Zeichen (z. B. '\ 0'), das in der Liste nicht verwendet wird Text immer, und speichern Sie das. Wenn Sie es dann abrufen, können Sie es durch '\ 0' teilen. Es gibt natürlich auch andere Möglichkeiten, um diese Dinge zu erledigen, aber diese hängen von Ihrem spezifischen Datenbankanbieter ab.
Beispielsweise können Sie JSON in einer Postgres-Datenbank speichern. Wenn Ihre Liste aus Text besteht und Sie die Liste nur ohne weiteren Aufwand verwenden möchten, ist dies ein vernünftiger Kompromiss.
Andere haben Vorschläge zur Serialisierung gewagt, aber ich halte Serialisierung nicht für eine gute Idee: Das Schöne an Datenbanken ist, dass mehrere in verschiedenen Sprachen geschriebene Programme miteinander kommunizieren können. Und Programme, die im Java-Format serialisiert wurden, würden nicht so gut funktionieren, wenn ein Lisp-Programm es laden wollte.
Wenn Sie eine gute Möglichkeit suchen, dies zu tun, stehen normalerweise Array- oder ähnliche Typen zur Verfügung. Postgres bietet beispielsweise Array als Typ an und ermöglicht das Speichern eines Textarrays , wenn Sie dies wünschen . Es gibt ähnliche Tricks für MySQL und MS SQL mit JSON, und IBMs DB2 bietet auch einen Array-Typ (in deren Form) eigene hilfreich Dokumentation). Dies wäre nicht so häufig, wenn dies nicht erforderlich wäre.
Was Sie verlieren, wenn Sie diesen Weg gehen, ist der Begriff der Liste als eine Reihe von Dingen nacheinander. Zumindest nominell behandeln Datenbanken Felder als Einzelwerte. Aber wenn das alles ist, was Sie wollen, dann sollten Sie es versuchen. Es ist ein Werturteil, das Sie selbst treffen müssen.
quelle
Zusätzlich zu dem, was alle anderen gesagt haben, würde ich vorschlagen, dass Sie Ihren Ansatz länger als jetzt analysieren. Es ist derzeit der Fall , dass Artikel einzigartig sind. Es ist derzeit der Fall , dass die Einzelteile zurückgegriffen würde eine neue Liste erfordern. Es ist fast erforderlich, dass die Liste derzeit kurz ist. Auch wenn ich nicht über die Domain-Details verfüge, ist es nicht schwer zu glauben, dass sich diese Anforderungen ändern könnten. Wenn Sie Ihre Liste serialisieren, backen Sie in einer Inflexibilität, die in einem normalisierten Design nicht erforderlich ist. Übrigens bedeutet das nicht unbedingt eine vollständige Many: Many-Beziehung. Sie könnten einfach eine einzelne untergeordnete Tabelle mit einem Fremdschlüssel für das übergeordnete Element und einer Zeichenspalte für das Element haben.
Wenn Sie die Serialisierung der Liste dennoch fortsetzen möchten, können Sie die Liste in XML speichern. Einige Datenbanken wie SQL Server haben sogar einen XML-Datentyp. Der einzige Grund, warum ich XML vorschlagen würde, ist, dass diese Liste fast per Definition kurz sein muss. Wenn die Liste lang ist, ist die Serialisierung im Allgemeinen ein schrecklicher Ansatz. Wenn Sie die CSV-Route wählen, müssen Sie die Werte berücksichtigen, die das Trennzeichen enthalten. Dies bedeutet, dass Sie gezwungen sind, Bezeichner in Anführungszeichen zu verwenden. Unter der Annahme, dass die Listen kurz sind, wird es wahrscheinlich keinen großen Unterschied machen, ob Sie CSV oder XML verwenden.
quelle
Ich würde es einfach als CSV speichern, wenn es einfache Werte sind, dann sollte es alles sein, was Sie brauchen (XML ist sehr ausführlich und eine Serialisierung zu / von ihm wäre wahrscheinlich übertrieben, aber das wäre auch eine Option).
Hier ist eine gute Antwort, wie Sie CSVs mit LINQ herausziehen können.
quelle
Wenn Sie die Liste abfragen müssen, speichern Sie sie in einer Tabelle.
Wenn Sie die Liste immer möchten, können Sie sie als begrenzte Liste in einer Spalte speichern. Speichern Sie es auch in diesem Fall in einer Nachschlagetabelle, es sei denn, Sie haben SEHR spezifische Gründe, dies nicht zu tun.
quelle
Nur eine Option wird in den Antworten nicht erwähnt. Sie können Ihr DB-Design de-normalisieren. Sie benötigen also zwei Tische. Eine Tabelle enthält eine richtige Liste, ein Element pro Zeile, eine andere Tabelle enthält eine ganze Liste in einer Spalte (z. B. durch Koma getrennt).
Hier ist es "traditionelles" DB-Design:
Hier ist es de-normalisierte Tabelle:
Die Idee hier - Sie pflegen die Lists-Tabelle mithilfe von Triggern oder Anwendungscode. Jedes Mal, wenn Sie den Inhalt von List_Item ändern, werden die entsprechenden Zeilen in den Listen automatisch aktualisiert. Wenn Sie meistens Listen lesen, könnte es ganz gut funktionieren. Vorteile - Sie können Listen in einer Anweisung lesen. Nachteile - Updates erfordern mehr Zeit und Mühe.
quelle
Wenn Sie es wirklich in einer Spalte speichern und abfragbar haben möchten, unterstützen viele Datenbanken jetzt XML. Wenn Sie nicht abfragen, können Sie sie als durch Kommas getrennte Werte speichern und mit einer Funktion analysieren, wenn Sie sie getrennt benötigen. Ich stimme jedoch allen anderen zu, wenn Sie eine relationale Datenbank verwenden möchten, besteht ein großer Teil der Normalisierung in der Trennung solcher Daten. Ich sage jedoch nicht, dass alle Daten in eine relationale Datenbank passen. Sie können jederzeit nach anderen Datenbanktypen suchen, wenn viele Ihrer Daten nicht zum Modell passen.
quelle
Ich denke, in bestimmten Fällen können Sie eine FAKE "Liste" von Artikeln in der Datenbank erstellen, zum Beispiel hat die Ware ein paar Bilder, um ihre Details zu zeigen, Sie können alle IDs von Bildern verketten, die durch Komma getrennt sind, und die Zeichenfolge darin speichern die DB, dann müssen Sie nur noch die Zeichenfolge analysieren, wenn Sie es brauchen. Ich arbeite gerade an einer Website und plane, diese Methode zu verwenden.
quelle
Aufgrund vieler Antworten war ich sehr zurückhaltend bei der Wahl des Weges, für den ich mich schließlich entschieden habe. Während sie SQL und seine Prinzipien besser verstehen, habe ich mich entschlossen, ein Gesetzloser zu werden. Ich zögerte auch, meine Ergebnisse zu veröffentlichen, da es für einige wichtiger ist, jemanden, der gegen die Regeln verstößt, zu frustrieren, als zu verstehen, dass es nur sehr wenige universelle Wahrheiten gibt.
Ich habe es ausgiebig getestet und in meinem speziellen Fall war es weitaus effizienter als sowohl die Verwendung des Array-Typs (großzügig von PostgreSQL angeboten) als auch die Abfrage einer anderen Tabelle.
Hier ist meine Antwort: Ich habe eine Liste erfolgreich in ein einzelnes Feld in PostgreSQL implementiert, indem ich die feste Länge jedes Elements der Liste verwendet habe. Angenommen, jedes Element ist eine Farbe als ARGB-Hex-Wert, es bedeutet 8 Zeichen. Sie können also ein Array mit maximal 10 Elementen erstellen, indem Sie es mit der Länge jedes Elements multiplizieren:
Falls sich die Länge Ihrer Listenelemente unterscheidet, können Sie den Abstand jederzeit mit \ 0 füllen
NB: Offensichtlich ist dies nicht unbedingt der beste Ansatz für die Hex-Zahl, da eine Liste von Ganzzahlen weniger Speicherplatz beanspruchen würde. Dies dient jedoch nur dazu, diese Idee des Arrays zu veranschaulichen, indem jedem Element eine feste Länge zugewiesen wird.
Der Grund warum: 1 / Sehr praktisch: Element i am Teilstring i * n, (i +1) * n abrufen. 2 / Kein Overhead von Kreuztabellenabfragen. 3 / Effizienter und kostensparender auf der Serverseite. Die Liste ist wie ein Mini-Blob, den der Client aufteilen muss.
Obwohl ich die Einhaltung von Regeln respektiere, sind viele Erklärungen sehr theoretisch und erkennen oft nicht an, dass in bestimmten Fällen, insbesondere wenn mit Lösungen mit geringer Latenz ein Kostenoptimum angestrebt wird, einige geringfügige Änderungen mehr als willkommen sind.
"Gott bewahre, dass es gegen ein heiliges, heiliges Prinzip von SQL verstößt": Ein offenerer und pragmatischerer Ansatz vor dem Rezitieren der Regeln ist immer der richtige Weg. Sonst könnten Sie wie ein offener Fanatiker enden, der die drei Gesetze der Robotik rezitiert, bevor Sie von Skynet ausgelöscht werden
Ich behaupte nicht, dass diese Lösung ein Durchbruch ist oder dass sie hinsichtlich Lesbarkeit und Datenbankflexibilität ideal ist, aber sie kann Ihnen sicherlich einen Vorteil in Bezug auf die Latenz verschaffen.
quelle
In vielen SQL-Datenbanken kann eine Tabelle eine Untertabelle als Komponente enthalten. Die übliche Methode besteht darin, die Domäne einer der Spalten als Tabelle zuzulassen. Dies ist zusätzlich zu einer Konvention wie CSV, um die Unterstruktur auf eine Weise zu codieren, die dem DBMS unbekannt ist.
Als Ed Codd 1969-1970 das relationale Modell entwickelte, definierte er speziell eine normale Form , die diese Art der Verschachtelung von Tabellen nicht zuließ. Die Normalform wurde später als Erste Normalform bezeichnet. Anschließend zeigte er, dass es für jede Datenbank eine Datenbank in der ersten normalen Form gibt, die dieselben Informationen enthält.
Warum sich damit beschäftigen? Nun, Datenbanken in der ersten normalen Form ermöglichen den verschlüsselten Zugriff auf alle Daten. Wenn Sie einen Tabellennamen, einen Schlüsselwert für diese Tabelle und einen Spaltennamen angeben, enthält die Datenbank höchstens eine Zelle mit einem Datenelement.
Wenn Sie zulassen, dass eine Zelle eine Liste, eine Tabelle oder eine andere Sammlung enthält, können Sie jetzt keinen verschlüsselten Zugriff auf die Unterelemente gewähren, ohne die Idee eines Schlüssels vollständig zu überarbeiten.
Der verschlüsselte Zugriff auf alle Daten ist für das relationale Modell von grundlegender Bedeutung. Ohne dieses Konzept ist das Modell nicht relational. Um herauszufinden, warum das relationale Modell eine gute Idee ist und was die Grenzen dieser guten Idee sein könnten, müssen Sie sich die 50-jährige Erfahrung mit dem relationalen Modell ansehen.
quelle
Sie können es als Text speichern, der wie eine Liste aussieht, und eine Funktion erstellen, die seine Daten als tatsächliche Liste zurückgeben kann. Beispiel:
Datenbank:
Und die Listen-Compiler-Funktion (in Python geschrieben, sollte aber leicht in die meisten anderen Programmiersprachen übersetzbar sein). TEXT repräsentiert den aus der SQL-Tabelle geladenen Text. Gibt eine Liste der Zeichenfolgen aus der Zeichenfolge zurück, die die Liste enthält. Wenn Sie möchten, dass Ints anstelle von Strings zurückgegeben werden, setzen Sie den Modus auf 'int'. Ebenso mit 'string', 'bool' oder 'float'.
Auch hier ist eine List-to-String-Funktion, falls Sie sie benötigen.
quelle