sql >> Databasteknik >  >> RDS >> Mysql

MySQL 2018:Vad finns i 8.0 och andra observationer

Med det mesta, om inte hela 2018 bakom oss (beroende på när du läser det här inlägget), råder det ingen tvekan om att det var ett fantastiskt år för SQL-databaser med öppen källkod.

PostgreSQL 11 och MySQL 8 släpptes båda, vilket ger båda gemenskaperna mycket att "prata om '. Sanningen att säga har båda leverantörerna infört många betydande ändringar och tillägg i sina respektive utgåvor och förtjänar deras beröm och utmärkelser.

Jag brukar gästinlägga om det förra här på Severalnines-bloggen (Mycket tack till en bra organisation!) men jag har också ett intresse för det senare. Med många blogginlägg på min egen webbplats (länk i min biosektion), mest inriktade på MySQL version 5.7, finns den (MySQL) alltid i min kringutrustning.

Så vad har MySQL 8 som version 5.7 inte har? Vilka är förbättringarna? Tja, det finns många. Faktiskt för många för att täcka i bara ett blogginlägg.

Jag uppgraderade nyligen till version 8 i min nuvarande Linux-inlärnings-/utvecklingsmiljö, så jag tänkte försöka peka ut några av dem.

Jag kan inte garantera dig en djupgående diskussion om din "favorit ' nya egenskaper). Å andra sidan kommer jag att besöka dem som har fångat min uppmärksamhet antingen via ett personligt intresse eller genom de många fantastiska blogginlägg som publicerats under hela året på version 8.

MySQL blir bättre och bättre...Fantastiska förbättringar i version 8!

Roller

Med roller kan DBA:er minska redundans, där många användare delar samma privilegium eller uppsättning privilegier.

Roller är en del av SQL-standarden.

Efter att ha skapat en specifik roll med önskad/krävd behörighet, kan du sedan tilldela användarna den specifika rollen via GRANT-kommandot eller på samma sätt, 'tar bort ' med REVOKE.

Roller har många fördelar och för att göra livet lite enklare finns det ett par tabeller som hjälper dig att hålla reda på dem:

  • mysql.role_edges - Här hittar du dessa roller och användarna de är tilldelade.

    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 - Lagrar alla standardroller och de användare som tilldelats.

    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)

Kombinationen av båda tabellerna (inte i SQL JOIN-bemärkelsen) ger i huvudsak en 'centraliserad plats ' där du kan:känna till, övervaka och utvärdera alla dina implementerade användarrollbehörighetsrelationer och tilldelningar.

Det enklaste exemplet på rollanvändningsscenariot skulle förmodligen vara:

Du har flera användare som behöver skrivskyddad åtkomst ' på en specifik tabell, därför kräver åtminstone SELECT-behörigheten. Istället för att ge det (SELECT) individuellt till varje användare, kan du skapa (skapa) en roll som har den behörigheten och sedan tilldela den rollen till dessa användare.

Men roller kommer med en liten 'fångst '. När den väl har skapats och tilldelats en användare måste den mottagande användaren ha en aktiv standardrolluppsättning under autentisering vid inloggning.

När det gäller roller och användare tycker jag att det är viktigt att nämna förändringen som implementerats i MySQL 8 angående komponenten validate_password, som är en variant av plugin-programmet validate_password som används i version 5.7.

Den här komponenten tillhandahåller olika distinkta 'kategorier ' för lösenordskontroll:låg, medium (standard) och stark. Besök dokumentationen för validate_password-komponenten för en fullständig genomgång av varje nivås valideringsspecifikationer.

NoSQL-mingling med SQL - Dokumentarkivet

Den här funktionen är en jag fortfarande lär mig om, trots ett flyktigt intresse för MongoDB i början av 2016. Hittills har mitt intresse, studier och lärande varit fokuserat enbart på "SQL". Jag är dock medveten om (genom mycket läsning på webben) att många är exalterade över den här typen av strukturering (dokumentorienterad) sammanflätad med 'relationell SQL' som nu finns tillgänglig i MySQL 8-dokumentarkivet.

Nedan finns många fördelar tillgängliga när du använder dokumentarkivet. Var säker och nämn dina favoriter som jag kan ha missat i kommentarsfältet:

  • JSON-datatypen har stöds sedan MySQL version 5.7.8 ännu, version 8 introducerade betydande förbättringar för att arbeta med JSON. Nya JSON-specifika funktioner tillsammans med 'shorthand ' operatörer som kan användas i stället för flera funktionsanrop - med lika resultat/utdata.
  • En av de främsta fördelarna är kanske att du inte längre behöver implementera och arbeta med flera databaslösningar eftersom NoSQL, SQL eller en kombination av de två stöds i dokumentarkivet.
  • En "DevAPI", ger sömlösa arbetsflödesmöjligheter inom en NoSQL-datakontext (samlingar och dokument). (Besök den officiella dokumentationen för DevAPI-användarhandboken för mer information).
  • Kraftfulla kommandoradssessioner med Python, SQL eller Javascript som "skalspråk".
  • ACID-kompatibel.
  • Utforska och upptäck dina data snabbt utan att definiera ett schema som du skulle göra i en relationsmodell.

Vanliga tabelluttryck (CTE eller WITH-satsen)

Vad mer kan du säga om CTE? Dessa saker förändrar spelet! Till att börja med, vad är egentligen ett vanligt tabelluttryck?

Från Wikipedia:

"Ett vanligt tabelluttryck, eller CTE, (i SQL) är en temporär namngiven resultatuppsättning, härledd från en enkel fråga och definierad inom exekveringsomfånget för en SELECT-, INSERT-, UPDATE- eller DELETE-sats."

Jag ska ge ett enkelt exempel som visar CTE. Deras fulla kraft utnyttjas dock inte i det här avsnittet, eftersom det finns många mer komplexa exempel på användningsfall än dessa.

Jag har en enkel namntabell med denna beskrivning och data:

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)

Låt oss ta reda på hur många efternamn som börjar med '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)

Lätt nog.

Men genom att använda WITH-satsen kan du 'åtkomst ' samma frågeresultatuppsättning (som kan ses som en härledd tabell) och hänvisa till den senare inom samma sats - eller 'omfattning ':

 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)

Jag tilldelar i princip ett namn till frågan, lindar in den inom parentes. Välj sedan bara den data jag vill ha från det som nu är last_Z CTE.

Last_Z CTE ger en komplett resultatuppsättning, så att du kan filtrera den ytterligare inom samma uttalande:

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)

Ett par av de mer kraftfulla funktionerna är 'kedja ' flera CTE's tillsammans och hänvisar till andra CTE's inom CTE's.

Här är ett exempel för att ge dig en idé (även om det inte är så användbart):

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)

I ovanstående fråga kan du se var jag separerade last_Z CTE från best_friend CTE med ett kommatecken och satte den frågan inom parentes efter AS-nyckelordet.

Observera att jag då kan hänvisa till (och använda) last_Z CTE för att i huvudsak definiera best_friend CTE.

Här är några anledningar till varför CTE är en så betydande förbättring i version 8:

  • Andra SQL-leverantörer har stött CTE:er (många sedan tidigare versioner inom deras individuella ekosystem) och nu har MySQL 8 täppt till luckan på detta område.
  • En standard SQL-inkludering.
  • I vissa fall (där det är lämpligt) är CTE:er ett bättre alternativ än tillfälliga tabeller, vyer, härledda tabeller (eller inline-vyer) och vissa underfrågor.
  • CTE:er kan tillhandahålla en 'on-the-fly ' beräkningsresultat som du kan fråga efter.
  • En CTE kan referera till sig själv - känd som en rekursiv CTE (visas inte här).
  • CTE:er kan namnge och använda andra CTE:er
ClusterControlSingle Console för hela din databasinfrastrukturTa reda på vad mer som är nytt i ClusterControlInstallera ClusterControl GRATIS

Fönsterfunktioner

Analytiska frågor är nu möjliga i MySQL 8. Eftersom fönsterfunktioner inte är min starka sida är jag fokuserad på en mer djupgående studie och bättre förståelse för dem, i stort, framåt. Dessa nästa exempel är mestadels elementära enligt min uppfattning. Förslag, råd och bästa praxis är välkomna från läsare.

Jag har den här VYN som ger en fiktiv uppsättning rördataresultat (något jag förstår något):

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)

Föreställ dig, jag behöver rörtillgångsposterna presenterade i någon sorts radrankning beroende på längden på varje enskild rör. (T.ex. den längsta längden är "märkt" position nummer 1, den näst längsta längden är "märkt" position 2, etc...)

Baserat på RANK() Window Function-beskrivningen i dokumentationen:

"Återställer rangordningen för den aktuella raden inom dess partition, med luckor. Peers anses vara obundna och får samma rang. Den här funktionen tilldelar inte konsekutiva rangordningar till kamratgrupper om det finns grupper med större storlek än en; resultatet är icke sammanhängande rangnummer ."

Det ser ut att vara väl lämpat för detta krav.

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)

I nästa scenario vill jag bygga ännu mer på det föregående exemplet genom att rangordna posterna för längsta till kortaste längder, men per varje enskild grupp av de distinkta wall_thickness-värdena.

Kanske nedanstående fråga och resultat kommer att förklara bättre var min prosa kanske inte har:

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)

Den här frågan använder PARTITION BY-satsen i kolumnen wall_thickness eftersom vi vill ha rangordningen (som ORDER BY pipe_length DESC tillhandahåller), men vi behöver den i sammanhanget för de individuella wall_thickness-grupperna.

Varje long_to_short kolumnrankning återställs till 1 när du stöter på (eller ändrar) till ett annat wall_thickness kolumnvärde.

Låt oss koncentrera oss på resultaten från en enda grupp.

Med inriktning på posterna med väggtjockleksvärdena 0,893 har raden med pipe_length 44,40 en motsvarande long_to_short 'ranking' på 1 (det är den längsta), medan raden med pipe_length 7,78 har en motsvarande long_to_short 'ranking' på 8 (den kortaste) specifik grupp (0,893) av wall_thickness-värden.

Fönsterfunktioner är ganska kraftfulla och hela deras omfattning och bredd kan omöjligt täckas i en sektion ensam. Var säker och besök fönsterfunktionerna som stöds i MySQL 8-dokumentationen för mer information om de som är tillgängliga för närvarande.

Förbättrad rumslig support och kapacitet

Det här är en enorm uppsättning funktioner som ingår i MySQL 8. Tidigare versioners stöd, eller bristen därav, kunde helt enkelt inte jämföras med andra leverantörers implementering(er) (tänk PostGIS för PostgreSQL).

Under de senaste 10 åren har jag arbetat i fält som en rörledningsmätare och samlat in GPS och tillgångsdata, så denna grupp av förändringar fångar definitivt min uppmärksamhet.

Spatial dataexpertis är ett heltäckande ämne i sin egen rätt och var säker, jag är långt ifrån någon expert på det. Jag hoppas dock kunna sammanfatta de betydande förändringarna mellan version 5.7 och 8 och förmedla dem på ett tydligt och koncist sätt.

Låt oss bekanta oss med två nyckeltermer (och begrepp) för detta avsnitt.

  1. Spatial Reference System eller SRS - Här är en partiell definition från Wikipedia:

    "Ett spatiellt referenssystem (SRS) eller koordinatreferenssystem (CRS) är ett koordinatbaserat lokalt, regionalt eller globalt system som används för att lokalisera geografiska enheter. Ett rumsligt referenssystem definierar en specifik kartprojektion, såväl som transformationer mellan olika rumsliga referenser. system."

  2. Spatial Reference System Identifier eller SRID - Wikipedia har också SRID definierade som sådana:

    "A Spatial Reference System Identifier (SRID) är ett unikt värde som används för att entydigt identifiera projicerade, oprojekterade och lokala definitioner av rumsliga koordinatsystem. Dessa koordinatsystem utgör hjärtat i alla GIS-applikationer."

MySQL stöder många typer av rumsliga data. En av de vanligaste är en PUNKT. Om du använder din GPS för att navigera till din favoritrestaurang är den platsen en PUNKT på en karta.

MySQL 5.7 behandlar i stort sett alla 'rumsliga objekt ' som har ett SRID på 0, vilket är signifikant för beräkningar. Dessa beräkningar beräknas i en kartesisk typ av koordinatsystem. Men vi vet alla att vår jordklot är en sfär och långt ifrån platt. Därför har du i version 8 möjligheten att betrakta den som antingen platt eller sfärisk i beräkningar.

Tillbaka till dessa två termer, vi definierade tidigare.

Även om 0 är standard-SRID i MySQL version 8, stöds många (ungefär 5 000+) andra SRID.

Men varför är det viktigt?

Denna fantastiska förklaring via blogginlägget, Spatial Reference Systems i MySQL 8.0, sammanfattar det fint:

"Som standard, om vi inte anger ett SRID, kommer MySQL att skapa geometrier i SRID 0. SRID 0 är MySQL:s begrepp om ett abstrakt, enhetslöst, oändligt, katesiskt plan. Medan alla andra SRS refererar till någon yta och definierar enheter för axlar, SRID 0 gör det inte."

I huvudsak när man utför beräkningar med SRID:s andra än SRID 0 , då kommer formen på vår jord in i bilden, beaktas och påverkar dessa beräkningar. Detta är avgörande för alla meningsfulla/exakta beräkningar. För en djupgående genomgång och bättre extrapolering, se detta blogginlägg som täcker geografi i MySQL 8.

Jag rekommenderar också starkt MySQL Server Team-blogginlägget, Geographic Spatial Reference Systems i MySQL 8.0, för klarhet om SRS. Se till och läs den!

Slutligen, för rumsliga datauppgraderingar från version 5.7 till 8, besök några av de inkompatibla ändringarna som listas här för mer information.

Andra anmärkningsvärda observationer

Nedan finns andra versionsförbättringar som jag måste erkänna, även om de inte behandlas på djupet i det här blogginlägget:

  • utf8mb4 är nu standardteckenuppsättningen (tidigare latin1) - Bättre stöd för dessa måste ha emojis förutom vissa språk...
  • Transactional Data Dictionary - MySQL-metadata finns nu i InnoDB-tabeller.
  • Osynliga index – Ställ in synligheten för ett index för optimeraren och avgör i slutändan om det är bra eller dåligt att lägga till eller ta bort det (indexet). Att lägga till ett index i en befintlig stor tabell kan vara 'dyrt ' när det gäller låsning och resurser.
  • Fallande index – Bättre prestanda för indexerade värden som lagras i fallande ordning.
  • Instant Add Column - För schemaändringar, specificera ALGORITHM=INSTANT i ALTER TABLE-satser och (om det är möjligt för åtgärden) undvik metadatalås. (För mer information, se det här fantastiska inlägget från MySQL Server Team och avsnittet ALTER TABLE från de officiella dokumenten.)

Bonusavsnitt:Något jag hade hoppats få se...

Relaterade resurser ClusterControl for MySQL Bli en MySQL DBA-bloggserie - Vanliga operationer - Replikeringstopologiändringar Bli en MySQL DBA-bloggserie - Databasuppgraderingar

Kontrollera begränsningar har inte kommit in i MySQL-produkten ännu.

Som med tidigare MySQL-versioner är syntax för kontrollbegränsning tillåten i dina CREATE TABLE-kommandon men den ignoreras. Såvitt jag vet stöder de flesta andra SQL-leverantörer kontrollbegränsningar. Kom och gå med på festen MySQL!

MySQL har avsevärt 'trappats upp dess erbjudande i version 8. Att stödja robusta rumsliga funktioner, bekväma rollalternativ för användarhantering, "hybrid" SQL/NoSQL-datalösningar och analytiska funktioner bland de många ytterligare förbättringarna är verkligen anmärkningsvärt.

Enligt min åsikt, med version 8, fortsätter MySQL att tillhandahålla ett solidt alternativ i det ständigt växande, konkurrenskraftiga SQL-ekosystemet med öppen källkod, fullt av relevanta och funktionsrika lösningar.

Tack för att du läser.


  1. Finns det något sätt att spola ut utdata från PL/SQL i Oracle?

  2. Konvertera ett datum till Julian Day i PostgreSQL

  3. Dapper.NET och lagrad proc med flera resultatuppsättningar

  4. R12.2 Bestämning och konfiguration av upplaga