Con la maggior parte, se non tutto il 2018 alle spalle (a seconda di quando stai leggendo questo post), non c'è dubbio che è stato un anno fantastico per i database SQL open source.
PostgreSQL 11 e MySQL 8 sono stati entrambi rilasciati, fornendo a entrambe le comunità molto di cui "parlare '. A dire il vero, entrambi i fornitori hanno introdotto molte modifiche e aggiunte significative nelle rispettive versioni e meritano lodi e riconoscimenti.
Di solito scrivo come guest post sul primo qui sul blog di Diversinines (molte grazie a un'ottima organizzazione!), ma ho anche un interesse per il secondo. Con molti post di blog sul mio sito web (link nella mia sezione bio), per lo più destinati a MySQL versione 5.7, (MySQL) è sempre nelle mie periferiche.
Quindi cosa ha MySQL 8 che la versione 5.7 non ha? Quali sono i miglioramenti? Bene, ce ne sono molti. In effetti, troppi da coprire in un solo post sul blog.
Di recente ho eseguito l'aggiornamento alla versione 8 nel mio attuale ambiente di apprendimento/sviluppo Linux, quindi ho pensato di provare a indicarne alcuni.
Non posso garantirti una discussione approfondita sul tuo "preferito". ' nuove caratteristiche). D'altra parte, visiterò quelli che hanno attirato la mia attenzione sia per un interesse personale che per mezzo dei tanti fantastici post del blog pubblicati durante l'anno sulla versione 8.
MySQL sta migliorando sempre di più... Fantastici miglioramenti nella versione 8!
Ruoli
Con i ruoli, i DBA possono mitigare la ridondanza, in cui molti utenti condividerebbero lo stesso privilegio o insieme di privilegi.
I ruoli fanno parte dello standard SQL.
Dopo aver creato un ruolo specifico con il/i privilegio/i desiderato/i, puoi quindi assegnare agli utenti quel particolare ruolo tramite il comando GRANT o allo stesso modo, 'porta via ' con REVOCA.
I ruoli hanno numerosi vantaggi e per semplificarti la vita, ci sono un paio di tabelle che ti aiutano a tenerne traccia:
-
mysql.role_edges - Qui trovi quei ruoli e gli utenti a cui sono assegnati.
mysql> DESC mysql.role_edges; +-------------------+---------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------------------+---------------+------+-----+---------+-------+ | FROM_HOST | char(60) | NO | PRI | | | | FROM_USER | char(32) | NO | PRI | | | | TO_HOST | char(60) | NO | PRI | | | | TO_USER | char(32) | NO | PRI | | | | WITH_ADMIN_OPTION | enum('N','Y') | NO | | N | | +-------------------+---------------+------+-----+---------+-------+ 5 rows in set (0.01 sec)
-
mysql.default_roles - Memorizza tutti i ruoli predefiniti e gli utenti assegnati.
mysql> DESC mysql.default_roles; +-------------------+----------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------------------+----------+------+-----+---------+-------+ | HOST | char(60) | NO | PRI | | | | USER | char(32) | NO | PRI | | | | DEFAULT_ROLE_HOST | char(60) | NO | PRI | % | | | DEFAULT_ROLE_USER | char(32) | NO | PRI | | | +-------------------+----------+------+-----+---------+-------+ 4 rows in set (0.00 sec)
La combinazione di entrambe le tabelle (non nel senso di SQL JOIN) fornisce essenzialmente una "posizione centralizzata ' dove puoi:conoscere, monitorare e valutare tutte le relazioni e le assegnazioni dei privilegi utente-ruolo implementate.
Probabilmente lo scenario di utilizzo del ruolo di esempio più semplice sarebbe:
Hai diversi utenti che necessitano di 'accesso in sola lettura ' su una tabella specifica, quindi, richiedendo almeno il privilegio SELECT. Invece di concederlo (SELECT) individualmente a ciascun utente, puoi stabilire (creare) un ruolo con quel privilegio, quindi assegnare quel ruolo a quegli utenti.
Ma i ruoli hanno un piccolo 'cattura '. Una volta creato e assegnato a un utente, l'utente ricevente deve avere un ruolo predefinito attivo impostato, durante l'autenticazione all'accesso.
In tema di ruoli e utenti, ritengo sia importante menzionare la modifica implementata in MySQL 8 relativa al componente validate_password, che è una variante del plugin validate_password utilizzato nella versione 5.7 .
Questo componente fornisce varie 'categorie distinte ' di controllo password:basso, medio (predefinito) e forte. Visita la documentazione del componente validate_password per una panoramica completa delle specifiche di convalida di ciascun livello.
NoSQL che si mescola a SQL:l'archivio documenti
Questa è una caratteristica su cui sto ancora imparando, nonostante un fugace interesse per MongoDB all'inizio del 2016. Ad oggi, il mio interesse, studio e apprendimento si sono concentrati esclusivamente su "SQL". Tuttavia, sono consapevole (attraverso molte letture sul Web) che molti sono entusiasti di questo tipo di strutturazione (orientata ai documenti) intrecciata con "SQL relazionale" ora disponibile nell'archivio documenti di MySQL 8.
Di seguito sono riportati molti vantaggi disponibili quando si utilizza l'archivio documenti. Assicurati di menzionare i tuoi preferiti che potrei aver perso nella sezione commenti:
- Il tipo di dati JSON è stato supportato dalla versione 5.7.8 di MySQL, tuttavia la versione 8 ha introdotto miglioramenti significativi per l'utilizzo di JSON. Nuove funzioni specifiche per JSON insieme a 'stenografia ' operatori che possono essere utilizzati al posto di più chiamate di funzione - con risultati/output uguali.
- Forse uno dei principali vantaggi è che non è più necessario implementare e lavorare con più soluzioni di database poiché NoSQL, SQL o una combinazione dei due sono supportati nell'archivio documenti.
- Una "DevAPI", fornisce funzionalità di flusso di lavoro senza interruzioni all'interno di un contesto di dati NoSQL (raccolte e documenti). (Per ulteriori informazioni, visitare la documentazione ufficiale della guida utente DevAPI).
- Potenti sessioni da riga di comando che utilizzano Python, SQL o Javascript come linguaggio "shell".
- Conforme agli ACIDI.
- Esplora e scopri rapidamente i tuoi dati senza definire uno schema come faresti in un modello relazionale.
Espressioni di tabelle comuni (CTE o clausola WITH)
Cos'altro puoi dire sui CTE? Queste cose sono un punto di svolta! Per cominciare, cos'è esattamente un'espressione di tabella comune?
Da Wikipedia:
"Un'espressione di tabella comune, o CTE, (in SQL) è un set di risultati denominato temporaneo, derivato da una semplice query e definito nell'ambito di esecuzione di un'istruzione SELECT, INSERT, UPDATE o DELETE."
Fornirò un semplice esempio, dimostrando i CTE. Tuttavia, la loro piena potenza non è sfruttata in questa sezione, poiché ci sono molti esempi di casi d'uso più complessi di questi.
Ho una semplice tabella dei nomi con questa descrizione e dati:
mysql> DESC name;
+--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| f_name | varchar(20) | YES | | NULL | |
| l_name | varchar(20) | YES | | NULL | |
+--------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> SELECT * FROM name;
+--------+------------+
| f_name | l_name |
+--------+------------+
| Jim | Dandy |
| Johhny | Applesauce |
| Ashley | Zerro |
| Ashton | Zerra |
| Ashmon | Zerro |
+--------+------------+
5 rows in set (0.00 sec)
Scopriamo quanti cognomi iniziano con 'Z':
mysql> SELECT *
-> FROM name
-> WHERE l_name LIKE 'Z%';
+--------+--------+
| f_name | l_name |
+--------+--------+
| Ashley | Zerro |
| Ashton | Zerra |
| Ashmon | Zerro |
+--------+--------+
3 rows in set (0.00 sec)
Abbastanza facile.
Tuttavia, utilizzando la clausola WITH, puoi 'accedere ' questo stesso insieme di risultati della query (che può essere considerato una tabella derivata) e vi si fa riferimento in seguito all'interno della stessa istruzione - o 'ambito ':
WITH last_Z AS (
SELECT *
FROM name
WHERE l_name LIKE 'Z%')
SELECT * FROM last_Z;
+--------+--------+
| f_name | l_name |
+--------+--------+
| Ashley | Zerro |
| Ashton | Zerra |
| Ashmon | Zerro |
+--------+--------+
3 rows in set (0.00 sec)
Fondamentalmente assegno un nome alla query, racchiudendolo tra parentesi. Quindi seleziona i dati che voglio da quello che ora è l'ultimo_Z CTE.
Last_Z CTE fornisce un set di risultati completo, quindi puoi filtrarlo ulteriormente all'interno della stessa istruzione:
WITH last_Z AS (
SELECT *
FROM name
WHERE l_name LIKE 'Z%')
SELECT f_name, l_name FROM last_Z WHERE l_name LIKE '%a';
+--------+--------+
| f_name | l_name |
+--------+--------+
| Ashton | Zerra |
+--------+--------+
1 row in set (0.00 sec)
Un paio delle funzionalità più potenti sono "concatenamento". ' più CTE insieme e facendo riferimento ad altri CTE all'interno di CTE.
Ecco un esempio per darvi un'idea (anche se non molto utile):
WITH last_Z AS (
SELECT *
FROM name
WHERE l_name LIKE 'Z%'),
best_friend AS (
SELECT f_name, l_name
FROM last_Z
WHERE l_name LIKE '%a')
SELECT * from best_friend;
+--------+--------+
| f_name | l_name |
+--------+--------+
| Ashton | Zerra |
+--------+--------+
1 row in set (0.00 sec)
Nella query precedente, puoi vedere dove ho separato il CTE last_Z dal CTE best_friend con una virgola, quindi ho racchiuso quella query tra parentesi dopo la parola chiave AS.
Si noti che sono quindi in grado di fare riferimento (e utilizzare) il CTE last_Z per definire essenzialmente il CTE migliore_amico.
Ecco alcuni motivi per cui i CTE sono un miglioramento così significativo nella versione 8:
- Altri fornitori di SQL hanno supportato CTE (molti sin dalle versioni precedenti all'interno dei loro singoli ecosistemi) e ora MySQL 8 ha colmato il divario in quest'area.
- Un'inclusione SQL standard.
- In alcuni casi (ove appropriato), i CTE sono un'opzione migliore rispetto a tabelle temporanee, viste, tabelle derivate (o viste in linea) e alcune sottoquery.
- I CTE possono fornire un 'al volo ' set di risultati di calcolo su cui eseguire query.
- Un CTE può fare riferimento a se stesso, noto come CTE ricorsivo (non illustrato qui).
- I CTE possono nominare e utilizzare altri CTE
Funzioni della finestra
Le query analitiche sono ora possibili in MySQL 8. Poiché le funzioni Window non sono il mio forte, mi concentro su uno studio più approfondito e su una migliore comprensione di esse, nel complesso, andando avanti. Questi prossimi esempi sono per lo più elementari secondo la mia comprensione. Suggerimenti, consigli e best practice sono i benvenuti dai lettori.
Ho questa VIEW che fornisce un set di risultati di pipe fittizi (qualcosa che in qualche modo capisco):
mysql> SELECT * FROM pipe_vw;
+---------+-------------+-----------+-------+-------------+------------+----------------+
| pipe_id | pipe_name | joint_num | heat | pipe_length | has_degree | wall_thickness |
+---------+-------------+-----------+-------+-------------+------------+----------------+
| 181 | Joint-278 | 39393A | 9111 | 17.40 | 1 | 0.393 |
| 182 | Joint-8819 | 19393Y | 9011 | 16.60 | 0 | 0.427 |
| 183 | Joint-9844 | 39393V | 8171 | 10.40 | 0 | 0.393 |
| 184 | Joint-2528 | 34493U | 9100 | 11.50 | 1 | 0.427 |
| 185 | Joint-889 | 18393z | 9159 | 13.00 | 0 | 0.893 |
| 186 | Joint-98434 | 19293Q | 8174 | 9.13 | 0 | 0.893 |
| 187 | Joint-78344 | 17QTT | 179 | 44.40 | 1 | 0.893 |
| 188 | Joint-171C | 34493U | 17122 | 9.45 | 1 | 0.893 |
| 189 | Joint-68444 | 17297Q | 6114 | 11.34 | 0 | 0.893 |
| 190 | Joint-4841R | 19395Q | 5144 | 25.55 | 0 | 0.115 |
| 191 | Joint-1224C | 34493U | 8575B | 15.22 | 1 | 0.893 |
| 192 | Joint-2138 | 34493C | 91 | 13.55 | 1 | 0.893 |
| 193 | Joint-122B | 34493U | 9100B | 7.78 | 1 | 0.893 |
+---------+-------------+-----------+-------+-------------+------------+----------------+
13 rows in set (0.00 sec)
Immagina, ho bisogno dei record delle risorse del tubo presentati in una sorta di classifica di riga a seconda della lunghezza di ogni singolo tubo. (Ad esempio, la lunghezza più lunga è 'etichettata' alla posizione numero 1, la seconda lunghezza più lunga è 'etichettata' alla posizione 2, ecc...)
Basato sulla descrizione della funzione finestra RANK() nella documentazione:
"Restituisce il rango della riga corrente all'interno della sua partizione, con spazi vuoti. I pari sono considerati pari e ricevono lo stesso rango. Questa funzione non assegna ranghi consecutivi ai gruppi di pari se esistono gruppi di dimensioni maggiori di uno; il risultato sono numeri di rango non contigui ."
Sembra essere adatto a questo requisito.
mysql> SELECT pipe_name, pipe_length,
-> RANK() OVER(ORDER BY pipe_length DESC) AS long_to_short
-> FROM pipe_vw;
+-------------+-------------+---------------+
| pipe_name | pipe_length | long_to_short |
+-------------+-------------+---------------+
| Joint-78344 | 44.40 | 1 |
| Joint-4841R | 25.55 | 2 |
| Joint-278 | 17.40 | 3 |
| Joint-8819 | 16.60 | 4 |
| Joint-1224C | 15.22 | 5 |
| Joint-2138 | 13.55 | 6 |
| Joint-889 | 13.00 | 7 |
| Joint-2528 | 11.50 | 8 |
| Joint-68444 | 11.34 | 9 |
| Joint-9844 | 10.40 | 10 |
| Joint-171C | 9.45 | 11 |
| Joint-98434 | 9.13 | 12 |
| Joint-122B | 7.78 | 13 |
+-------------+-------------+---------------+
13 rows in set (0.01 sec)
Nello scenario successivo, voglio sviluppare ulteriormente l'esempio precedente classificando i record dalle lunghezze più lunghe a quelle più brevi, ma, per ogni singolo gruppo di valori distinti di wall_thickness.
Forse la query e i risultati di seguito spiegheranno meglio dove la mia prosa potrebbe non averlo fatto:
mysql> SELECT pipe_name, pipe_length, wall_thickness,
-> RANK() OVER(PARTITION BY wall_thickness ORDER BY pipe_length DESC) AS long_to_short
-> FROM pipe_vw;
+-------------+-------------+----------------+---------------+
| pipe_name | pipe_length | wall_thickness | long_to_short |
+-------------+-------------+----------------+---------------+
| Joint-4841R | 25.55 | 0.115 | 1 |
| Joint-278 | 17.40 | 0.393 | 1 |
| Joint-9844 | 10.40 | 0.393 | 2 |
| Joint-8819 | 16.60 | 0.427 | 1 |
| Joint-2528 | 11.50 | 0.427 | 2 |
| Joint-78344 | 44.40 | 0.893 | 1 |
| Joint-1224C | 15.22 | 0.893 | 2 |
| Joint-2138 | 13.55 | 0.893 | 3 |
| Joint-889 | 13.00 | 0.893 | 4 |
| Joint-68444 | 11.34 | 0.893 | 5 |
| Joint-171C | 9.45 | 0.893 | 6 |
| Joint-98434 | 9.13 | 0.893 | 7 |
| Joint-122B | 7.78 | 0.893 | 8 |
+-------------+-------------+----------------+---------------+
13 rows in set (0.00 sec)
Questa query utilizza la clausola PARTITION BY nella colonna wall_thickness perché vogliamo la classifica (fornita da ORDER BY pipe_length DESC), tuttavia, ne abbiamo bisogno nel contesto dei singoli gruppi wall_thickness.
Ogni classifica di colonna long_to_short torna a 1 quando incontri (o cambi) un valore di colonna wall_thickness diverso.
Concentriamoci sui risultati di un unico gruppo.
Mirando ai record con wall_thickness valori 0.893, la riga con pipe_length 44.40 ha una 'classifica' long_to_short corrispondente di 1 (è la più lunga), mentre la riga con pipe_length 7.78 ha una 'classifica' long_to_short corrispondente di 8 (la più corta) tutto all'interno di quella gruppo specifico (0,893) di valori wall_thickness.
Le funzioni della finestra sono piuttosto potenti e la loro intera portata e ampiezza non potrebbe essere trattata in una sola sezione. Assicurati di visitare la finestra Funzioni supportate nella documentazione di MySQL 8 per ulteriori informazioni su quelle attualmente disponibili.
Supporto spaziale e capacità migliorate
Questo è un insieme straordinario di funzionalità incluse in MySQL 8. Il supporto delle versioni precedenti, o la sua mancanza, semplicemente non poteva essere confrontato con l'implementazione di altri fornitori (pensa a PostGIS per PostgreSQL).
Negli ultimi 10 anni ho lavorato sul campo come Pipeline Surveyor, raccogliendo dati GPS e risorse, quindi questo gruppo di modifiche attira sicuramente la mia attenzione.
La competenza sui dati spaziali è un argomento completo a sé stante e vi assicuro che sono tutt'altro che un esperto in materia. Tuttavia, spero di riassumere i cambiamenti significativi tra le versioni 5.7 e 8 e di trasmetterli in modo chiaro e conciso.
Familiarizziamo con 2 termini (e concetti) chiave ai fini di questa sezione.
-
Sistema di riferimento spaziale o SRS - Ecco una definizione parziale da Wikipedia:
"Un sistema di riferimento spaziale (SRS) o un sistema di riferimento di coordinate (CRS) è un sistema locale, regionale o globale basato su coordinate utilizzato per localizzare entità geografiche. Un sistema di riferimento spaziale definisce una proiezione cartografica specifica, nonché trasformazioni tra diversi riferimenti spaziali sistemi."
-
Identificatore del sistema di riferimento spaziale o SRID - Inoltre, Wikipedia ha SRID definiti come tali:
"Uno Spatial Reference System Identifier (SRID) è un valore univoco utilizzato per identificare inequivocabilmente le definizioni dei sistemi di coordinate spaziali previste, non proiettate e locali. Questi sistemi di coordinate costituiscono il cuore di tutte le applicazioni GIS."
MySQL supporta molti tipi di dati spaziali. Uno dei più comuni è un PUNTO. Se utilizzi il tuo GPS per navigare verso il tuo ristorante preferito, quella posizione è un PUNTO su una mappa.
MySQL 5.7 tratta praticamente ogni 'oggetto spaziale ' come avente un SRID pari a 0, che è significativo per i calcoli. Questi calcoli sono calcolati in un tipo cartesiano di sistema di coordinate. Tuttavia, sappiamo tutti che il nostro globo è una sfera e tutt'altro che piatto. Pertanto, nella versione 8, hai la possibilità di considerarlo come piatto o sferico nei calcoli.
Tornando a quei due termini, che abbiamo definito in precedenza.
Anche se 0 è l'SRID predefinito in MySQL versione 8, sono supportati molti (circa 5.000+) altri SRID.
Ma perché è così importante?
Questa fantastica spiegazione tramite il post del blog, Spatial Reference Systems in MySQL 8.0, lo riassume bene:
"Per impostazione predefinita, se non specifichiamo un SRID, MySQL creerà geometrie in SRID 0. SRID 0 è la nozione di MySQL di un piano catesiano astratto, senza unità, infinito. Mentre tutti gli altri SRS si riferiscono ad alcune superfici e definiscono le unità per il assi, SRID 0 no."
In sostanza, quando si eseguono calcoli con SRID diversi da SRID 0 , allora la forma della nostra Terra entra in gioco, viene considerata e influenza quei calcoli. Questo è fondamentale per qualsiasi calcolo significativo/accurato. Per una panoramica approfondita e una migliore estrapolazione, consulta questo post del blog che copre la geografia in MySQL 8.
Consiglio vivamente anche il post sul blog di MySQL Server Team, Geographic Spatial Reference Systems in MySQL 8.0, per chiarezza sugli SRS. Assicurati e leggilo!
Infine, per problemi di aggiornamento dei dati spaziali dalla versione 5.7 alla 8, visita alcune delle modifiche incompatibili elencate qui per ulteriori informazioni.
Altre osservazioni degne di nota
Di seguito sono riportati altri miglioramenti alla versione che devo riconoscere, sebbene non siano trattati in modo approfondito in questo post del blog:
- utf8mb4 è ora il set di caratteri predefinito (in precedenza latin1) - Supporto migliore per coloro che devono avere emoji oltre ad alcune lingue...
- Dizionario dei dati transazionali:i metadati MySQL sono ora contenuti nelle tabelle InnoDB.
- Indici invisibili:imposta la visibilità di un indice per l'ottimizzatore, determinando in definitiva se aggiungerlo o rimuoverlo (l'indice) è una cosa buona o cattiva. L'aggiunta di un indice a una tabella di grandi dimensioni esistente può essere "costoso". ' in termini di blocco e risorse.
- Indici decrescenti:prestazioni migliori sui valori indicizzati archiviati in ordine decrescente.
- Colonna aggiunta istantanea:per le modifiche allo schema, specificare ALGORITHM=INSTANT nelle istruzioni ALTER TABLE e (se possibile per l'operazione) evitare i blocchi dei metadati. (Per ulteriori informazioni, vedere questo fantastico post del MySQL Server Team e la sezione ALTER TABLE dai documenti ufficiali.)
Sezione bonus:qualcosa che speravo di vedere...
Risorse correlate ClusterControl per MySQL Diventa una serie di blog DBA MySQL - Operazioni comuni - Modifiche alla topologia di replica Diventa una serie di blog DBA MySQL - Aggiornamenti del databaseI vincoli di controllo non sono ancora entrati nel prodotto MySQL.
Come con le versioni precedenti di MySQL, la sintassi del vincolo di controllo è consentita nei comandi CREATE TABLE ma viene ignorata. A mia conoscenza, la maggior parte degli altri fornitori di SQL supporta i vincoli di controllo. Unisciti alla festa MySQL!
MySQL è notevolmente 'innalzato ' la sua offerta nella versione 8. Il supporto di solide capacità spaziali, comode opzioni di ruolo di gestione degli utenti, soluzioni di dati SQL/NoSQL "ibride" e funzioni analitiche tra i numerosi miglioramenti aggiuntivi, è davvero notevole.
A mio parere, con la versione 8, MySQL continua a fornire una solida opzione nell'ecosistema SQL open source in continua crescita e competitivo, pieno di soluzioni pertinenti e ricche di funzionalità.
Grazie per aver letto.