Ist das Speichern einer Liste von Zeichenfolgen in einem einzelnen Datenbankfeld eine schlechte Idee? Warum?

14

Vor kurzem habe ich angefangen, an einem Legacy-System zu arbeiten. Die Leute, die es entwickelt haben, kamen auf die Idee, eine Liste von Zeichenfolgen in einem einzigen Feld der Datenbanktabelle zu speichern. Nehmen wir an, es handelt sich um eine Kennung für ein Objekt, das weder eine Darstellung noch Daten in der Datenbank enthält. Der Bereich dieser Kennungen wird in der Produktion relativ klein sein.

Andererseits sagt mir meine Intuition und mein "guter Designgeschmack", dass es in einer separaten Tabelle dargestellt werden sollte (ähnlich einer Tabelle, die zur Darstellung von Viele-zu-Viele-Beziehungen verwendet wird).

Ist ihr Ansatz wirklich schlecht und es wäre besser, ein Refactoring zu starten? Wenn ja, welche schlimmen Folgen kann das ursprüngliche Design in Zukunft haben? Gibt es relationale Gestaltungsprinzipien, die diesen Ansatz erklären?

Zur Antwort auf Kommentare bearbeiten:

Wie ich vermute, haben sie diesen Ansatz nicht verwendet, um ein bestimmtes Problem wie die hierarchische Strukturierung auf knifflige Weise zu lösen. Das wahrscheinlichste Szenario war der Fall, dass sie einfach unter Zeitdruck arbeiteten und neue Funktionen so schnell wie möglich implementieren mussten.

Ich bin sicher, dass das Feld zuvor einen einzelnen Wert darstellte. Sie wollten eine Funktion implementieren, um mehr als einen Wert zu speichern, und versuchten, Datenbankmigrationen zu vermeiden.

mpasko256
quelle
6
Ob es ein schlechter Ansatz ist oder nicht, hängt davon ab, welches Problem es zu lösen versuchte und wie gut es es löste. Können Sie dazu genauere Informationen geben?
Robert Harvey
1
Es wird nur dann zu einem Problem, wenn Sie die Liste abfragen oder Berichte aus der Liste schreiben möchten. Wenn dies Anforderungen sind, wäre möglicherweise ein relationalerer Ansatz erforderlich. Wenn es nur Ausdauer ist, sollte eine große Sache sein.
Jon Raynor
2
Selbst wenn dies das Richtige ist, würde ich erst mit dem Refactoring beginnen, wenn Sie eine neue Anforderung erhalten, die etwas erfordert, das diese Strategie nicht berücksichtigen kann, z. B. die Notwendigkeit einer schnellen Indizierung der Sammlungselemente.
Graham
Aktualisierungen einer solchen Spalte können ebenfalls problematisch sein.
1
@graham die neue Anforderung wird sein: "Hey, wir brauchen eine Abfrage, die damit funktioniert". Indem Sie darauf aufbauen und es nicht bald töten, erschweren Sie es tatsächlich, das Richtige loszuwerden und zu tun. Das Problem ist, dass Sie mit dieser Strategie immer noch die meisten Dinge erledigen können: SELECT * FROM Products AS p JOIN Accounts AS a ON p.account_id REGEXP '[[: <:]]' || a.account_id || '[[:>:]]' WHERE p.product_id = 123;
Pieter B

Antworten:

16

Das Datenmodell ist nicht normalisiert. um so zu sein, würde es eine separate Tabelle brauchen, wie Sie sagen. In dieser Hinsicht ist es keine besonders gute Datenmodellierungspraxis.

Ob dies aus gutem Grund geschehen ist oder nicht, ist schwer zu bestimmen. Möglicherweise war die Vereinfachung oder Leistung der Codierung ein Motivator. Es ist wahrscheinlich, dass das Feld ursprünglich eine Kennung enthielt, die Anforderungen sich änderten und die Entwickler keine Zeit oder Neigung hatten, neu zu faktorisieren.

Wahrscheinlich wichtiger ist, ob Sie sich selbst umgestalten sollten oder nicht. Unter ähnlichen Umständen würde ich einen solchen Fall standardmäßig nicht präventiv umgestalten. Ich würde es in Betracht ziehen, wenn eine der folgenden Bedingungen zutrifft:

  1. Sie haben Hinweise darauf, dass dies Probleme verursacht, z. B. durch ältere Problemprotokolle
  2. Sie wissen, dass Sie in diesem Bereich funktionale Änderungen vornehmen werden
  3. Der Code, der die Daten verarbeitet, ist besonders komplex und schwer zu verstehen.

Was ich tun würde und TBH würde ich empfehlen, wenn Sie eine Legacy-Anwendung übernehmen, ist ein Wiki (oder ein gleichwertiges) zu starten und Fälle wie diesen zu dokumentieren. Zum Beispiel,

  • Probleme, die Sie gefunden haben, wie z. B. die Datenmodellierungsfalte
  • Änderungen, die Sie implementieren möchten
  • Änderungen, die Sie nicht implementieren möchten, aber würden, wenn es Zeit gäbe
  • Bereiche des Codes, über die man nur schwer nachdenken kann
  • Codebereiche, die Sie nur schwer pflegen können.

Ich habe festgestellt, dass dies ein nützliches Hilfsmittel für mich ist, wenn ich in einer Codebasis arbeite und / oder zu dieser zurückkehre. Dies kann für Ihren Nachfolger auch sehr hilfreich sein, wenn er seinerseits mit dem Erlernen der Codebasis beginnen muss.

Alex
quelle
10

Ist das Speichern einer Liste von Zeichenfolgen in einem einzelnen Datenbankfeld eine schlechte Idee?

Dies würde im Allgemeinen als Verstoß gegen die Normalisierung angesehen.

Manchmal wird dies jedoch als Lösung für ein Problem verwendet, z. B. bei der hierarchischen Strukturierung, bei der eine Pfadzeichenfolge mit variabler Länge eine Struktur darstellt.

Zu den Problemen mit einer Liste von Elementen in einer einzelnen Zeichenfolge können gehören:

  • In der Abfrage bedeutet dies, dass anstelle der relationalen Berechnung eine Zeichenfolgensuche verwendet wird. Die Indizierung der Daten kann problematisch sein.
  • Es stellt sich die Frage, welche Bedeutung die Reihenfolge der Einträge in der Liste hat und ob Sie höchstwahrscheinlich keine Einschränkung für die Reihenfolge als Einschränkung für die Datenbank erzwingen können.
  • Es gibt das Problem des Trennzeichens und das Potenzial für das Entkommen / Entkommen von Zeichen mit den einzelnen Elementen.
  • Es besteht die Möglichkeit, dass doppelte Einträge in derselben Liste vorhanden sind. Dies ist wiederum darauf zurückzuführen, dass Einschränkungen nicht direkt durchgesetzt werden können (obwohl eine Triggerfunktion möglicherweise Einschränkungen überprüfen könnte).
  • Ein einzelnes Element allein ist immer noch eine Liste, kann aber als nicht verwechselt werden, da wir der Datenbank nicht sagen (oder fragen) können, dass der wahre Typ eine Liste ist. Dies kann problematisch sein, wenn die meisten Zeilen nur ein Element in der Liste haben, wenn einige mehr als eines haben: Es gibt keine Möglichkeit, die ordnungsgemäße Verwendung der Spalte als Liste zu erzwingen.
Erik Eidt
quelle
Ich schätze beide Antworten, wähle aber Alex'es, weil es wertvolle Hinweise gibt, wie ich den besten Entscheidungsprozess selbst durchführen kann.
mpasko256
3

Es ist ein übliches Gegenmuster, dies zu tun.

Ihre Anforderungen ändern sich und jetzt benötigen Sie mehr Werte an einem Ort, an dem Sie früher nur einen benötigten. Wie ein Buch hat nur ein Autor Recht? Wer hätte ahnen können, dass ein Buch mehrere Autoren hat? Dies ist eine einfache Möglichkeit, diese Anforderungsänderung zu erfüllen, ohne Ihr Datenbankschema ändern zu müssen.

Es gibt jedoch einige Nachteile.

  • Abfragen werden schwieriger, da Sie jetzt identifizierende Daten in einem Feld zusammengefasst haben.
  • Sie können "=" nicht mehr verwenden, sondern müssen so etwas wie "like" verwenden. Welches wird Leistung töten.
  • Sie verlieren die Fähigkeit, sich diesem Feld anzuschließen.
  • Versuchen Sie zählen / Summe usw., es wird nicht funktionieren.
  • Das Aktualisieren wird umständlich.
  • Sie erhalten künstliche Grenzen, weil Sie einen Varchar (10) gewählt haben, um Ihre durch Kommas getrennte Liste zu speichern.
  • und mehr.

Bitte tun Sie dies im Grunde genommen nicht.

Grundsätzlich nehmen Sie das "relationale" in "relationale Datenbank" heraus.

Pieter B.
quelle
0

Es gibt viele Argumente dafür, dass wir bereits eine schlechte Idee sind. Ich denke, es wäre fair, einige Gründe hinzuzufügen, warum es eine gute oder zumindest gute Idee wäre. Ich bin mir nicht sicher, wie viele davon in diesem speziellen Fall zutreffen, aber es scheint, dass zumindest durchgeführte Leistungshinweise relevant sind:

  • Wenn die Anzahl und Länge der Zeichenfolgen streng begrenzt ist, sollte der Leistungsunterschied vernachlässigbar sein. Zumindest für einige Randfälle ist die Leistung besser, da Sie den Join nicht benötigen.
  • Abhängig von der Hauptverwendung des Feldes ist dieses Formular möglicherweise einfacher zu handhaben.
  • Wenn die Liste geordnet ist und für die Daten keine Fremdschlüssel erforderlich sind, sind Listenfelder den relationalen Datenbanken in dieser Hinsicht weit überlegen.
  • In Systemen, in denen die Schema-Migration kostspielig ist, kann es eine umsichtige Wahl sein, ein einfaches Huckepack auf einem vorhandenen singulären Feld zu verwenden. Es ist sicherlich eine technische Schuld, aber es kann die Art sein, die es wert ist, genommen zu werden und niemals zurückzuzahlen, selbst wenn Sie ab und zu etwas Interesse bluten müssen.

Wenn Sie versuchen, ein Refactoring durchzuführen, ist es immer eine gute Idee, zuerst den Grund für die vorherigen Entwurfsentscheidungen zu verstehen. Stellen Sie sicher, dass sich die Bedingungen und Anforderungen tatsächlich genug geändert haben, um die Kosten und das Risiko zu rechtfertigen.

Frax
quelle