ProgrammierungFullstack Entwickler

Wie man mit Arrays und arrayähnlichen Strukturen in SQL arbeitet, um mehrere Werte in einer Zelle zu speichern und zu analysieren, und wann dieser Ansatz gerechtfertigt ist?

Bestehen Sie Vorstellungsgespräche mit dem Hintsage-KI-Assistenten

Antwort.

Hintergrund der Frage

Klassisches SQL sieht nicht vor, mehrere Werte in einer Zelle zu speichern — das relationale Modell erfordert Normalisierung. In modernen Anwendungen sind jedoch häufig Felder vom Typ „Tag-Liste“, „Bewertungsskala“ anzutreffen, bei denen es praktisch ist, in einer einzelnen Zeile mit mehreren Werten zu operieren. Einige DBMS (PostgreSQL, Oracle) bieten Datentypen wie ARRAY oder ähnliche Mechanismen an.

Problem

Die Verwendung von Arrays verletzt das Prinzip der Normalisierung, erschwert viele Operationen (Filterung, Aktualisierung, Indizierung) und macht den Code weniger portabel zwischen den DBMS. Manchmal ist es jedoch praktisch oder unvermeidlich — z. B. zur Caching oder schnellen Suche in kleinen Werte Listen.

Lösung

  • In PostgreSQL gibt es native Unterstützung für Arrays. Beispiel:
CREATE TABLE products ( id SERIAL PRIMARY KEY, tags TEXT[] ); -- Einfügen: INSERT INTO products(tags) VALUES (ARRAY['eco','sale','hot']); -- Suche über das Array: SELECT * FROM products WHERE 'eco' = ANY (tags);
  • In MySQL 5.x gibt es keine Arrays, häufig werden JSON oder durch Kommas getrennte Strings und Funktionen zur Analyse verwendet.
  • In Oracle — Sammlungen, nested table/varray.
  • Für optimale analytische Aufgaben ist es besser zu normalisieren (eine verbundene sekundäre Tabelle product_tags zu erstellen) und JOIN zu verwenden, während Arrays nur in besonderen Fällen (Performance oder spezifische Anforderungen) gespeichert werden.

Wichtige Merkmale:

  • Praktisch, wenn das Array tatsächlich benötigt wird und vom DBMS unterstützt wird.
  • Probleme mit Indizes und Filterung bei großen Arrays.
  • Nicht portabel zwischen DBMS, erschwert die Wartung.

Trickfragen.

Kann man einzelne Elemente eines Arrays indizieren?

In PostgreSQL — ja, über GIN/GIST-Indizes:

CREATE INDEX idx_tags ON products USING GIN (tags);

Wie kann man schneller prüfen, ob ein Wert in einem Array in einer String-Spalte über einen Separator enthalten ist?

SQL kann das standardmäßig nicht, man verwendet die Suche nach Mustern:

SELECT * FROM users WHERE ',admin,' like concat('%,',role,',%');

Aber dieser Ansatz ist unzuverlässig und langsam.

Wie viele Werte kann man in einem Array speichern, und was schränkt ein?

Die Einschränkung hängt vom DBMS ab — zum Beispiel liegt in PostgreSQL die Einschränkung nur auf der Größe der Zeile (1–2 MB).

Typische Fehler und Anti-Muster

  • Arrays in einer Zelle zur „Einfachheit“ speichern und die Analyse erschweren
  • Werte fälschlicherweise mit LIKE ohne Berücksichtigung der Separatoren filtern
  • Auf Eindeutigkeit und Indizierung von String-Arrays verlassen

Beispiel aus dem Leben

Negativer Fall

In einem Ecommerce-Projekt wurden die Tags von Produkten als durch Kommas getrennte Strings in einer Spalte gespeichert. Die schnelle Suche nach Produkten nach Tags wurde stark erschwert, Fehler in der Filterung traten auf, und wiederholte Tags passierten aufgrund von Parsing-Fehlern.

Vorteile:

  • „Einfach“ und schnell umsetzbar

Nachteile:

  • Sehr langsam bei großen Datenmengen, schwer zu warten, keine Garantie für die Eindeutigkeit der Werte

Positiver Fall

In PostgreSQL wurden für kleine, unveränderliche Sätze (Benutzerrollen) ARRAY und GIN-Index verwendet. Für größere — eine separate Rollentabelle.

Vorteile:

  • Schnelle Suche über ARRAY durch den Index
  • Bleibt kompatibel mit dem relationalen Modell, wo nötig

Nachteile:

  • Nicht portabel, erfordert Wissen über erweiterte Funktionen des DBMS