Während unseres letzten wöchentlichen Treffens hat eine Person, die keine Hintergrunderfahrung in der Datenbankverwaltung hat, folgende Frage aufgeworfen:
"Gibt es ein Szenario, das das Speichern von Daten in einer Zeile (Zeichenfolge) anstelle mehrerer Zeilen rechtfertigt?"
Nehmen wir eine Tabelle countryStates
an, in der die Bundesstaaten eines Landes gespeichert werden sollen. Ich werde die USA für dieses Beispiel verwenden und der Faulheit halber nicht alle Staaten auflisten.
Dort hätten wir zwei Spalten; einer rief an Country
und der andere rief an States
. Wie hier besprochen und in der Antwort von @ srutzky vorgeschlagen , PK
ist dies der Code, der durch ISO 3166-1 alpha-3 definiert ist .
Unser Tisch würde so aussehen:
+---------+-----------------------+-------------------------------------------------------+
| Country | States | StateName |
+---------+-----------------------+-------------------------------------------------------+
| USA | AL, CA, FL,OH, NY, WY | Alabama, California, Florida, Ohio, New York, Wyoming |
+---------+-----------------------+-------------------------------------------------------+
Als er einem befreundeten Entwickler dieselbe Frage stellte, sagte er, dass dies aus Sicht der Datenverkehrsgröße nützlich sein könnte, aber nicht, wenn wir diese Daten manipulieren müssen. In diesem Fall müsste der Anwendungscode eine Intelligenz enthalten, die diese Zeichenfolge in eine Liste umwandeln könnte (sagen wir, dass die Software, die Zugriff auf diese Tabelle hat, ein Kombinationsfeld erstellen muss).
Wir kamen zu dem Schluss, dass dieses Modell nicht sehr nützlich ist, aber ich wurde misstrauisch, dass es einen Weg geben könnte, dies nützlich zu machen.
Ich möchte fragen, ob einer von Ihnen so etwas bereits auf eine Weise gesehen, gehört oder getan hat, die wirklich funktioniert .
quelle
a;b;c
, verwenden Sie das vordere Ende der Zeichenfolge analysieren Sie dann erhaltena
,b
,c
und tragen auf der Ausführung etwas mit ihnen zu tun, vielleicht ?. Ich glaube, es könnte auf diese Weise zu einem bestimmten Bedürfnis passen ... Beim zweiten Gedanken, nein. Sie können jederzeit IDs speichern, Ihre Tabellen verbinden und eine verkettete Zeichenfolge erstellen, um Inhalte an die FE zu senden ...Antworten:
Zunächst ist der aktuelle Fragentitel, der sich auf "Speichern von Daten als Zeichenfolge anstelle von Spalten" bezieht, etwas verwirrend. Wenn Sie davon sprechen, Daten als Zeichenfolgen anstelle von etwas anderem zu speichern, bezieht sich dies normalerweise auf die Serialisierung aller Daten in ein Zeichenfolgenformat anstelle eines richtigen / starken Datentyps (z . B.
INT
oderDATETIME
). Wenn Sie jedoch nach dem Speichern von Daten als mehrere Werte in einem einzelnen Feld im Gegensatz zu separaten Zeilen fragen, ist dies etwas anders. Und um fair zu sein, während das Verketten von Werten mit Strings am einfachsten ist, kann es auch mitINT
undBINARY
Typen gemacht werden, entweder durch Bitmaskierung oder auf ähnliche Weise, indem bestimmte Positionen mit unterschiedlichen Bedeutungen reserviert werden. Da die zweite Interpretation das ist, worüber tatsächlich gefragt wird, basierend auf dem Text der Frage, wollen wir das ansprechen.Mit einem Wort: Nein. Wenn Sie tatsächliche Datenpunkte speichern, verursacht dies nur Schmerzen (in Bezug auf Code und Leistung), da dies unnötige Komplikationen darstellt. Wenn es sich um einen Wert handelt, der immer nur als einzelne Einheit gespeichert, als einzelne Einheit aktualisiert und niemals in der Datenbank zerlegt wird, kann dies in Ordnung sein, da dies in etwa dem Speichern eines Bildes oder einer PDF-Datei entspricht. Andernfalls wird jeder Versuch, die Daten zu analysieren, unter Verwendung von Indizes ungültig (z. B. unter Verwendung von
LIKE '%something%'
oderCHARINDEX
oderPATINDEX
oder oderSUBSTRING
usw.).Wenn Sie separate Werte in einem einzelnen Feld einer einzelnen Zeile speichern müssen, gibt es dafür geeignetere Methoden: XML oder JSON. Dies sind analysierbare Formate ( XML / JSON ) und XML kann sogar indiziert werden . Idealerweise werden diese Daten jedoch in richtig eingegebenen Feldern gespeichert, damit sie wirklich nützlich sind.
Und bitte vergessen Sie nicht, dass der Zweck eines RDBMS darin besteht, Daten so zu speichern, dass sie im Rahmen der ACID- Konformität so effizient wie möglich abgerufen und bearbeitet werden können. Das Abrufen verketteter Werte ist schlecht genug, da die Werte zuerst analysiert werden müssen, und das ist nicht indizierbar. Manipulieren bedeutet jedoch häufig, den gesamten Blob zu ersetzen, um nur einen Teil davon zu aktualisieren (vorausgesetzt, es gibt kein Muster, das für eine Funktion verwendet werden kann). Der XML-Datentyp ermöglicht zumindest XML-DML für vereinfachte Aktualisierungen, obwohl diese immer noch nicht so schnell sind wie eine einfache Aktualisierung ordnungsgemäß modellierter Daten.
REPLACE
In einem Szenario wie dem in der obigen Frage gezeigten können Sie diese Werte nicht miteinander verknüpfen, indem Sie alle StateCodes miteinander verketten.
Und was ist, wenn sich die Geschäftsanforderungen im Laufe der Zeit ändern und Sie zusätzliche Eigenschaften dieser Elemente verfolgen müssen? Was ist in Bezug auf "Staaten" mit den Hauptstädten oder der Bevölkerung oder einer Sortierreihenfolge oder irgendetwas anderem? Richtig als Zeilen gespeichert, können Sie weitere Spalten für zusätzliche Eigenschaften hinzufügen. Sicher, Sie können mehrere Ebenen von analysierbaren Daten haben, wie zum Beispiel,
|StateCode,Capital,Population |StateCode,Capital,Populate|...
aber hoffentlich kann jeder sehen, dass das Problem exponentiell außer Kontrolle gerät . Natürlich lässt sich dieses spezielle Problem mit den XML- und JSON-Formaten ziemlich leicht lösen, und das ist ihr Wert, wie oben erwähnt. Sie benötigen jedoch noch einen sehr guten Grund, um eines dieser beiden Elemente als anfängliches Modellierungsmittel zu verwenden, da keines davon jemals so effizient sein wird wie die Verwendung diskreter Felder in separaten Zeilen.quelle
Ich habe so etwas tatsächlich für einen sehr begrenzten Zweck verwendet. Wir haben eine Tabelle mit Headern für Ausgabedateien erstellt. Sie wurden speziell konstruiert und waren meist nur die Spaltenüberschriften, aber nicht ganz. Die Daten sahen also ungefähr so aus
Im Wesentlichen sah es so aus, als wäre es eine begrenzte Liste. Und in gewisser Weise war es. Aber für unsere Zwecke war es eine einzelne lange Saite.
Das ist der Trick hier. Wenn Sie nie vorhaben, die Liste zu analysieren, lohnt es sich, die Liste zu speichern. Wenn Sie die Liste jedoch analysieren müssen oder müssen, lohnt sich der zusätzliche Platz und die zusätzliche Zeit, um sie aufzuteilen und in separaten Zeilen zu speichern.
quelle
Ich habe es einmal mit einem eher kleinen Tisch benutzt, zum Beispiel:
Und dann Werte speichern
CRM,SMS,SELF-CARE
invalid_channel
.Die gesamte Tabelle enthält ungefähr 10 Datensätze.
valid_channel
enthält Werte, die sich eigentlich in einer Verknüpfungstabelle befinden sollten, die die Viele-zu-Viele-Beziehung darstellt. Der Tischt1
wird nicht intensiv genutzt, deshalb haben wir uns entschlossen, diesen Weg zu gehen. An dieser Entscheidung war jedoch etwas Politik beteiligt (siehe unten).Aber im Allgemeinen vermeide ich es, es ist nicht 3NF.
Der Ort, an dem ich arbeite, hat derzeit Dutzende solcher Spalten überall. Ihre Rechtfertigung ist, dass es ihre Abfragen einfacher macht: Anstatt drei Tabellen mithilfe der Verknüpfungstabelle zu verbinden, können sie direkt zur Definitionstabelle mit gehen
LIKE
. Z.BHorrible + unter Oracle deaktiviert die Verwendung von Index aufgrund des Starts
'%,'
.quelle
LIKE
oder eine einfache Verbindung?LIKE
wäre langsamer, insbesondere wenn die Daten richtig modelliert sind, um einTINYINT
PK-Feld in zu verwendenchannel_def
. Dann muss nur noch ein einziges Byte zwischen den beiden Tabellen verglichen werden. Hier muss die Zeichenfolge zeichenweise analysiert werden (zumindest bis die Bedingung erfüllt ist), und es wird eine Suche ohne Berücksichtigung der Groß- und Kleinschreibung durchgeführt (basierend auf der angegebenen Tabelle def wird keine verwendete Kollatierung_BIN2
angezeigt). Dadurch werden Indizes auch in SQL Server ungültig. Ich habe dies in meiner Antwort angesprochen, indem ich sagte, dass beim Parsen keine Indizes verwendet werden können. Ich habe gerade meine Antwort aktualisiert, um es klarer zu machen.LIKE
Klausel übereinstimmt und ungerade Ergebnisse liefert, kann es dennoch andere Probleme verursachen oder zumindest das Debuggen erschweren / verlängern). Diesvalid_channels
erschwert auch die Aktualisierung des Feldes. Das soll nicht heißen, dass dies nicht funktioniert, es gibt einfach keinen guten Grund dafür.Dies wurde hier auf SE gemacht. Wie Marc Gravell schreibt :
Dieses "neue Format" war der nächste Schritt gegenüber dem "alten Format", das etwas anders war und ausgewählt wurde, um die SQL Server-Volltextsuchfunktion zu verwenden. Daher sind einige der Vorteile nicht relevant, wenn Sie es von Grund auf neu ausführen.
Vermutlich haben sie die Sache sowohl aus Arbeits- als auch aus Leistungsgründen nicht vollständig normalisiert.
quelle
Ein möglicher Hauptvorteil der Verwendung von Zeichenfolgen und anderen Datentypen besteht darin, sie mithilfe der SQLCLR von SQL Server an C #, C, C ++ (usw.) zu senden, wenn möglicherweise eine reine Leistung erforderlich ist. Sie können sogar eine Ansicht oder eine gespeicherte Prozedur erstellen, um relationale Daten nicht relational darzustellen - wie Sie es in Ihrem obigen Beispiel zu diesem Zweck getan haben.
Siehe dieses Beispiel:
http://aboutsqlserver.com/2013/07/22/clr-vs-t-sql-performance-considerations/
per Wikipedia: SQL CLR oder SQLCLR (SQL Common Language Runtime) ist eine Technologie zum Hosten der Microsoft .NET Common Language Runtime Engine in SQL Server. Mit SQLCLR kann verwalteter Code von der Microsoft SQL Server-Umgebung gehostet und ausgeführt werden.
quelle
Meiner Meinung nach wäre die Antwort nein. Ich habe diesen Ansatz nicht verwendet und würde ihn vermeiden - ich kann mir keinen Grund vorstellen, warum ich diesen Weg gehen würde. Sie neigen mit einem Array zur Welt von JSON / NoSQL.
In einer früheren Rolle hatten wir ähnliche Entwurfsentscheidungen, wobei das Architektenteam ein "Daten" -Feld haben wollte, das abgegrenzt und dann in eine Binärdatei konvertiert wurde. Wir sind diesen Weg am Ende aus mehreren Gründen nicht gegangen.
Wenn Sie sich dieser Art von Daten anschließen müssten, wäre dies eine hässliche Erfahrung. Das Aktualisieren einzelner Elemente der Zeichenfolge wäre ebenfalls unangenehm.
quelle