Recentemente un cliente mi ha contattato per aggiornare il proprio Moodle, dove ho trovato un db PostgreSQL anziché il "solito" MySQL/MariaDB.
La soluzione è più che legittima: PostgreSQL rientra tra i db supportati da Moodle (così come Aurora MySQL e Microsoft SQL Server), al contrario di Oracle, il cui supporto è stato abbandonato dalla versione 5.0.
Ma quando è che PostgreSQL diventa preferibile a MySQL?
Battute iniziali del match...
Un po' come due pugili che impiegano i primi round per studiarsi e chiudono in sostanziale pareggio, una prima analisi delle differenze tra MySQL e PostgreSQL non ha evidenziato grossi vantaggi nell'impiego dell'una o dell'altra soluzione.
PostgreSQL utilizza un processo backend dedicato per ogni connessione. Questo garantisce un buon isolamento tra le sessioni, ma ogni processo continua a competere con gli altri per CPU, RAM, I/O e risorse condivise. Tuttavia, davanti a un incremento delle connessioni, rende fondamentale un buon connection pooling, una specie di "vigile urbano" che gestisce il traffico tra i vari dispositivi.
Di contro, MySQL/InnoDB utilizza i thread, quindi più connessioni condividono la memoria dentro un singolo processo. Gestione efficiente, ma un singolo thread può influire sugli altri. Nella realtà, questo accade raramente.
Insomma, differenze sostanziali, ma non sono quelle che incidono sulla scelta dell'una o dell'altra piattaforma nella comune vita di uno sviluppatore web.
Discorso simile per il MVCC (controllo della concorrenza usando versioni multiple dei dati).
PostgreSQL implementa il MVCC memorizzando nella tabella le diverse versioni delle tuple generate dagli aggiornamenti. Le versioni non più visibili vengono successivamente recuperate da VACUUM.
MySQL (InnoDB) mantiene nella struttura principale la versione corrente e utilizza gli undo log per ricostruire le versioni precedenti quando necessario.
Query di ricerca
Come prevedibile, è sulle query che il discorso inizia a farsi molto pratico. Secondo vari benchmark, su query secche basate su chiave primaria, MySQL è più veloce, così come eccelle in insert di milioni di righe al secondo su una tabella semplice.
PostgreSQL tende a mostrare i suoi punti di forza soprattutto nelle query complesse, nei join multipli e nelle elaborazioni analitiche, grazie a un optimizer molto sofisticato. Questo non significa, però, che MySQL sia necessariamente più veloce nelle query semplici o nelle operazioni di scrittura: le prestazioni dipendono fortemente dal caso d'uso e dalla configurazione.
Le CTE, comprese quelle ricorsive, permettono di gestire in modo elegante strutture gerarchiche come alberi di categorie annidate. PostgreSQL offre inoltre strumenti particolarmente ricchi per questo tipo di elaborazioni.
Il campo di tipo JSONB consente query avanzate su strutture complesse, così come i campi di tipo array.
Anche MySQL dispone di un tipo JSON nativo, quindi non è corretto considerarlo semplicemente un campo TEXT. PostgreSQL offre però con JSONB un'integrazione particolarmente ricca con il proprio sistema di tipi e di indicizzazione, che può risultare molto interessante quando il database deve interrogare frequentemente strutture semi-strutturate.
Inoltre PostgreSQL gestisce ricerche full-text ottimizzate in base alla lingua.
Questo si traduce in diverse opportunità: gestione del multi-tenant già a livello di query, statistiche aggregate, supporto diretto a campi JSON (JSONB).
Estensioni, queste sconosciute
Non c'è partita tra il mondo delle estensioni di PostgreSQL e MySQL: PostGIS per avere un db spaziale, TimescaleDB per hypertable e dati di serie temporali, pgvector per dati vettoriali tanto cari al mondo dell'AI, pg_cron per pianificare processi stile cron e via dicendo.
Anche MySQL dispone di plugin, ma è tutto molto più limitato.
Conclusioni
Finché siamo su un livello di sistemi già pronti, come Moodle, non dobbiamo aspettarci sostanziali differenze nell'utilizzo dell'uno o dell'altro database. È semmai fondamentale seguire le linee guida di Moodle dedicate all'ottimizzazione delle prestazioni (query cache per MySQL, autovacuum per PostgreSQL).
La differenza può diventare rilevante quando ci spostiamo su un livello di fascia enterprise, magari per software custom e multi-tenant. A quel punto PostgreSQL può risultare la prima scelta.