ProgrammatieFullstack ontwikkelaar

Hoe te werken met arrays en array-achtige structuren in SQL voor het opslaan en analyseren van meerdere waarden in één cel, en wanneer is deze aanpak gerechtvaardigd?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord.

Geschiedenis van de vraag

Klassiek SQL biedt geen mogelijkheid om meerdere waarden in één cel op te slaan — het relationele model vereist normalisatie. Echter, in moderne taken komen vaak velden voor zoals "lijst van tags", "waarderingsschaal", waar het handig is om met een set waarden op het niveau van een enkele rij te werken. Sommige databasesystemen (PostgreSQL, Oracle) bieden ARRAY-gegevens typen of vergelijkbare mechanismen.

Probleem

Het gebruik van arrays schaadt het principe van normalisatie, bemoeilijkt veel operaties (filteren, bijwerken, indexeren), en maakt de code ook minder draagbaar tussen databases. Maar het kan handig of onvermijdelijk zijn — bijvoorbeeld voor caching of snelle zoekopdrachten op kleine lijsten van waarden.

Oplossing

  • In PostgreSQL is de ondersteuning voor arrays native. Voorbeeld:
CREATE TABLE products ( id SERIAL PRIMARY KEY, tags TEXT[] ); -- Invoegen: INSERT INTO products(tags) VALUES (ARRAY['eco','sale','hot']); -- Zoeken in de array: SELECT * FROM products WHERE 'eco' = ANY (tags);
  • In MySQL 5.x zijn er geen arrays, vaak worden JSON of gescheiden strings en functies voor parsing gebruikt.
  • In Oracle — collecties, nested table/varray.
  • Voor optimale analytische taken is het beter om te normaliseren (een gerelateerde secundaire tabel product_tags aan te maken) en JOIN te gebruiken, terwijl de array slechts in speciale gevallen (prestaties of specifieke vereisten) wordt opgeslagen.

Belangrijke kenmerken:

  • Handig wanneer een array echt nodig is en de database dit ondersteunt.
  • Problemen met indexering en filtering bij grote arrays.
  • Niet draagbaar tussen databases, bemoeilijkt onderhoud.

Lastige vragen.

Kun je afzonderlijke elementen van een array indexeren?

In PostgreSQL — ja, via GIN/GIST-indexen:

CREATE INDEX idx_tags ON products USING GIN (tags);

Hoe kun je sneller controleren of een waarde voorkomt in een array in een stringkolom via een scheidingsteken?

SQL kan dit van nature niet, men gebruikt patroonmatching:

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

Maar deze aanpak is onbetrouwbaar en traag.

Hoeveel waarden kunnen er in een array worden opgeslagen, en wat beperkt dat?

De beperking hangt af van de database — bijvoorbeeld, in PostgreSQL is er alleen een beperking op de grootte van de string (1–2 MB).

Typische fouten en anti-patronen

  • Arrays opslaan in één cel voor "simpliciteit" en de analyse bemoeilijken
  • Waarden verkeerd filteren via LIKE zonder rekening te houden met scheidingstekens
  • Vertrouwen op uniciteit en indexering op string-arrays

Voorbeeld uit het leven

Negatieve case

In een e-commerce project besloten ze de tags van producten als een string gescheiden door komma's in één kolom op te slaan. Dit bemoeilijkte de snelle zoekopdracht van producten op tags, fouten in de filtering vonden plaats, en het herhalen van tags gebeurde door parsing fouten.

Voordelen:

  • "Simpel" en snel te implementeren

Nadelen:

  • Zeer traag bij opschaling, moeilijk te onderhouden, onmogelijk om uniciteit van waarden te garanderen

Positieve case

In PostgreSQL voor kleine, onveranderlijke sets (user roles) gebruikten ze ARRAY en GIN-index. Voor grotere sets — een aparte rolentabel.

Voordelen:

  • Snelle zoektocht via ARRAY door index
  • Behoudt compatibiliteit met het relationele model waar nodig

Nadelen:

  • Niet draagbaar, vereist kennis van geavanceerde kenmerken van de database