MySQL vs MongoDB

Bij het ontwerpen van een Drupal-website kiest men vaak voor een relationele database om de data van een website te bewaren. MySQL is daar een goed voorbeeld van. Maar vanaf men veel data bezit, met een grote hoeveelheid aan velden, is een relationele database niet meer performant genoeg. In zo'n situatie is het interessant om te kiezen voor een NoSQL-database, zoals MongoDB. Maar wat zijn nu juist de grote verschillen tussen een relationele en een NoSQL-database? Wij lichten dit graag even voor je toe.

Voor de ontwikkeling van een Drupal-website met veel velden en data is MongoDB de ideale keuze.
Tom Hollevoet
 / 
Webdeveloper Calibrate
Tom
Database schema

Relationele database

Bij het installeren van een Drupal-website zal er standaard gekozen worden voor een relationeel database management systeem (RDBMS). Meestal wordt er voor een  MySQL-database gekozen, maar andere relationele databases die beschikbaar zijn voor Drupal zijn MariaDBSQLite en PostgreSQL.

De data waarover men beschikt, wordt opgeslagen in verschillende tabellen. In deze verschillende tabellen wordt de data dan verdeeld over verschillende kolommen.

Relaties in een RDBMS

In een RDBMS kan een tabel een relatie hebben met de tweede tabel. Zo kan  een tabel 'cities' een verwijzing hebben naar de tabel 'countries' door middel van een foreign key, een sleutel die verwijst naar een andere tabel.

Drupal fields

Relationele database toegepast op een Drupal-website

Tijdens het creëren van velden op een content type, worden verschillende tabellen aangemaakt in de database. Bijvoorbeeld voor het content type 'Person', met velden 'field_person_name', 'field_person_email' en 'field_person_country', zal men drie tabellen terugvinden in de MySQL-database.

In Drupal is het echter mogelijk een relatie te maken naar een ander content type, door middel van een 'Entity Reference'-veld. In bovenstaande voorbeeld is 'Country' een content type en is 'field_person_country', een entity reference-veld.

Relationele database: Problemen in Drupal

In de back-end van Drupal zal de data van een bepaalde node opgehaald worden door een SELECT query met verschillende JOINs naar de verschillende velden en tabellen. Hoe meer JOINs er moeten toegepast worden bij een query, hoe meer tijd het zal kosten om deze query uit te voeren. Aangezien een RDBMS verticaal geschaald is, zal men de resources (CPU/RAM) van de webserver moeten verhogen om de snelheid en de haalbaarheid van deze queries  te verhogen.

Indien een bepaalde node 500 velden bezit, dan moeten er in de back-end 500 JOINs uitgevoerd worden. Dit kan leiden tot performantieproblemen. De webserver moet een grotere capaciteit hebben om deze query uit te voeren, en de uitvoertijd van deze query zal meer tijd in beslag nemen. In zo'n situatie is een relationele database geen goeie optie meer. Een NoSQL-database is dan een betere keuze.

NoSQL-database

Bij een NoSQL-database gebruikt men niet langer de typische JOINs die voorkomen bij een RDBMS. De data wordt niet meer opgeslagen in verschillende tabellen, maar bij de NoSQL-database zal de data worden opgeslagen in verschillende structuren zoals documents en collections.

Het grote voordeel van NoSQL is dat het horizontaal geschaald kan worden. Dat betekent dat de load kan verdeeld worden over de verschillende resources van de webserver.

MongoDB logo

MongoDB

MongoDB zal de data opslaan onder de vorm van een documentstructuur. Een document is te vergelijken met één grote JSON-file, waar de data opgeslagen wordt aan de hand van veldnamen en waardes. Zo kan een veldnaam heel snel aangepast worden en moet, zoals bij een RDBMS, niet de tabelstructuur worden aangepast. De data zit dus in één document en is niet langer verdeeld over verschillende tabellen, wat bij een RDBMS wel het geval is.

Mongo_db_drupal

MongoDB toegepast op een Drupal-website

Voor Drupal 6, 7 en 8 is er een contrib module die de mogelijkheid biedt om Drupal-data op te slaan in MongoDB. De contrib module heeft verschillende submodules om verschillende functionaliteiten van Drupal in een MongoDB-database te implementeren.

Door deze verschillende submodules kan de functionaliteit cache, field_storage, session, watchdog, block en/of queue opgeslagen worden in een MongoDB-database, en niet meer in een RDBMS zoals MySQL.

Het zijn één of meerdere van bovenstaande functionaliteiten die opgeslagen worden in de MongoDB-database. De andere functionaliteiten en (standaard-) tabellen van Drupal blijven opgeslagen in de RDBMS (MySQL). Dit betekent dat de RDBMS nog steeds gebruikt zal worden.

In dit artikel zullen we de field_storage submodule van naderbij bekijken.

Drupal fields 0

Drupal 7 Field Storage in MongoDB

In Drupal 7 is er in de RDBMS (MySQL) een 'field_config' tabel waar alle veldconfiguratie (machine name, type veld, cardinaliteit...) opgeslagen zit. In deze tabel is er ook een storage_type/storage_module-kolom aanwezig. Standaard staat dit bij een Drupal installatie ingesteld op field_sql_storage, zodat de data van deze velden opgeslagen worden in de RDBMS.

Van zodra je kiest om de mongo_field_storage contrib submodule te installeren, zullen nieuwe velden aangemaakt worden met als storage_type/storage_module waarde mongodb_field_storage. Deze instelling wordt standaard geïnstalleerd bij het activeren van de mongo_field_storage module door de Drupal variabele field_storage_default gelijk te stellen aan mongodb_field_storage.

mongo db node object

hook_field_storage_X

In de backend van de mongodb_field_storage module zijn er verschillende 'hook_field_storage_X' functions terug te vinden die opgeroepen worden bij de velden die mongodb_field_storage als storage_module/storage_type hebben.

De belangrijkste implementaties zijn: 

  • Het wegschrijven van een waarde naar de MongoDB-database (mongodb_field_storage_field_storage_write)
  • Het ophalen van een veld uit de MongoDB-database (mongodb_field_storage_field_storage_load)
  • Het uitvoeren van een Entity Field Query (mongodb_field_storage_query).

1 document per node

De belangrijkste verandering in vergelijking met MySQL is dat een node zal opgeslagen worden als één groot document en niet meer verspreid over verschillende tabellen.

De node wordt nog steeds met zijn Node ID en andere parameters opgeslagen in de node-tabel in het RDBMS. Alle data van de velden van de node worden opgeslagen in MongoDB. Per node zal er één document aangemaakt worden.

Het grote voordeel is dat bij het ophalen van een node, slechts één document moet opgehaald worden uit de MongoDB-database. Bij de standaard RDBMS zouden er voor vijfhonderd velden effectief vijfhonderd verschillende joins uitgevoerd moeten worden om de data op te halen uit de verschillende tabellen.

Revisions en andere data

Zowel de revisions als de huidige data (bij mongodb_field_storage) worden opgeslagen in de MongoDB-database. De verschillende elementen die men bij de 'field_sql_storage' kon terugvinden in de verschillende kolommen van de tabel (zoals taal, delta...) zullen als object opgeslagen worden in het document.

MongoDB Field Storage module in praktijk

In de praktijk zal de MongoDB Field Storage module gebruikt worden in een situatie met veel velden/data.
Er zijn enkele opmerkingen om deze submodule te gebruiken.

Problemen met Views

De contrib module Views zal standaard queries aanmaken die geschikt zijn voor relationele databanken. Hiervoor zijn er enkele oplossingen:

Oplossing 1: Zoeken met facets (Search API/Solr)

Er wordt gekozen voor MongoDB bij een grote hoeveelheid aan nodes/velden. In zo'n situatie wordt er vaak gekozen voor de Solr-technologie (Search API). Die technologie zal de nodes met de gekozen velden indexeren, om  zo sneller in de data te zoeken. Views kan gebruikmaken van de data die geïndexeerd zijn door Solr.

Oplossing 2: Niet alle content types 'converteren' naar MongoDB

Zoals we eerder al vertelden, kan er altijd een keuze gemaakt worden om bepaalde velden/content types niet te 'converteren' naar MongoDB, maar om nog steeds de standaard storage_type/storage_module te gebruiken als opslag (field_sql_storage).

Oplossing 3: Gebruikmaken van EFQ Views

Contrib module EFQ Views zal gebruikmaken van EntityFieldQuery als query back-end.

Paragraphs/Field Collections 

Aangezien MongoDB nog niet veel gebruikt wordt (zo'n vijfhonderd Drupal-websites), zijn er nog wat bugs in deze module.

Calibrate is maintainer van de MongoDB contrib module en we hebben ervoor gezorgd dat MongoDB zal werken met Paragraphs en Field Collections.

Rechtstreeks aanspreken van MySQL-databank (db_query)

Er is altijd kans dat bepaalde (contrib) modules rechtstreeks gebruikmaken van een MySQL-query door middel van db_query. Een gouden tip is om altijd alle nieuwe functionaliteiten te testen bij het gebruik nieuwe contrib modules. Hiermee kan men eventuele problemen sneller oplossen.

Indien je kiest om MongoDB te gebruiken, installeer en configureer je dit best vanaf het begin van je project, zodat men bovenstaande problemen sneller kan opmerken.

Conclusie: MongoDB in Drupal

VOORDELEN

  • Een node met zijn verschillende velden kan je in één keer ophalen. 
  • Horizontale schaalbaarheid.
  • Het is geschikt voor grote data volumes en grote hoeveelheden nodes/velden.

NADELEN

  • Het maakt geen gebruik van relaties (JOINs).
  • Het is niet standaard compatibel met Views.
  • Bepaalde (contrib) modules zijn niet direct compatibel, aanpassingen zijn dan noodzakelijk.