sql >> Databáze >  >> RDS >> Mysql

MySQL v roce 2018:Co je ve verzi 8.0 a další pozorování

S většinou, ne-li celý rok 2018 za námi (v závislosti na tom, kdy čtete tento příspěvek), není pochyb o tom, že to byl fantastický rok pro open-source SQL databáze.

PostgreSQL 11 a MySQL 8 byly vydány, což oběma komunitám poskytlo spoustu toho, o čem 'hovořit '. Po pravdě řečeno, oba prodejci zavedli mnoho významných změn a doplňků ve svých příslušných vydáních a zaslouží si jejich chválu a uznání.

Normálně zveřejňuji příspěvky o prvním zde na blogu Somenines (Moc děkuji skvělé organizaci!), ale zajímá mě i ten druhý. Díky mnoha blogovým příspěvkům na mém vlastním webu (odkaz v mé bio sekci), většinou zaměřených na MySQL verze 5.7, je (MySQL) vždy v mých periferních zařízeních.

Co tedy má MySQL 8 a co verze 5.7 nemá? Jaká jsou vylepšení? No, je jich mnoho. Ve skutečnosti je jich příliš mnoho, než aby je pokryl jeden blogový příspěvek.

Nedávno jsem upgradoval na verzi 8 ve svém současném prostředí pro výuku/vývoj Linuxu, tak mě napadlo zkusit některé z nich ukázat.

Nemohu vám zaručit podrobnou diskusi o vašem 'oblíbeném ' nové vlastnosti). Na druhou stranu navštívím ty, které mě zaujaly buď osobním zájmem, nebo prostřednictvím mnoha skvělých blogových příspěvků publikovaných v průběhu roku ve verzi 8.

MySQL je stále lepší a lepší...Skvělá vylepšení ve verzi 8!

Role

Pomocí rolí mohou správci databází zmírnit nadbytečnost, kdy by mnoho uživatelů sdílelo stejné oprávnění nebo sadu oprávnění.

Role jsou součástí standardu SQL.

Po vytvoření konkrétní role s požadovanými/požadovanými oprávněními pak můžete uživatelům přiřadit tuto konkrétní roli pomocí příkazu GRANT nebo podobně, 'take away ' s REVOKE.

Role mají řadu výhod a aby byl život o něco jednodušší, existuje několik tabulek, které vám pomohou je sledovat:

  • mysql.role_edges – Zde najdete tyto role a uživatele, kterým jsou přiřazeny.

    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 – Ukládá všechny výchozí role a přiřazené uživatele.

    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)

Kombinace obou tabulek (nikoli ve smyslu SQL JOIN) v podstatě poskytuje 'centralizované umístění kde můžete:znát, monitorovat a posuzovat všechny vaše implementované vztahy a přiřazení uživatelských rolí.

Nejjednodušší příklad scénáře použití role by pravděpodobně byl:

Máte několik uživatelů, kteří potřebují 'přístup pouze pro čtení ' na konkrétní tabulce, proto vyžaduje alespoň oprávnění SELECT. Namísto udělování (SELECT) jednotlivě každému uživateli můžete vytvořit (vytvořit) roli s tímto oprávněním a poté tuto roli přiřadit těmto uživatelům.

Role však přicházejí s malým „úlovkem '. Po vytvoření a přiřazení uživateli musí mít přijímající uživatel nastavenou aktivní výchozí roli během ověřování při přihlášení.

Pokud jde o role a uživatele, považuji za důležité zmínit změnu implementovanou v MySQL 8 týkající se komponenty validate_password, což je varianta pluginu validate_password používaného ve verzi 5.7.

Tato komponenta poskytuje různé odlišné 'kategorie ' kontroly hesla:nízké, střední (výchozí) a silné. Navštivte dokumentaci ke komponentě validate_password, kde najdete úplný přehled specifikací ověřování jednotlivých úrovní.

Propojení NoSQL s SQL – úložiště dokumentů

Tato funkce je jednou z funkcí, o které se stále učím, navzdory letmému zájmu o MongoDB na začátku roku 2016. Doposud se můj zájem, studium a učení soustředily pouze na „SQL“. Jsem si však vědom (při četném čtení na webu), že mnozí jsou nadšeni z tohoto typu strukturování (orientovaného na dokumenty) propojeného s „relačním SQL“, který je nyní k dispozici v úložišti dokumentů MySQL 8.

Níže je mnoho výhod dostupných při používání úložiště dokumentů. Ujistěte se a zmiňte své oblíbené, které jsem možná přehlédl, v sekci komentářů:

  • Datový typ JSON je podporován od verze MySQL 5.7.8, ale verze 8 přinesla významná vylepšení pro práci s JSON. Nové funkce specifické pro JSON spolu s 'shorthand ' operátory, které lze použít místo volání více funkcí – se stejnými výsledky/výstupem.
  • Možná jednou z hlavních výhod je, že již nemusíte implementovat a pracovat s více databázovými řešeními, protože úložiště dokumentů podporuje NoSQL, SQL nebo kombinaci obou.
  • Rozhraní "DevAPI" poskytuje možnosti bezproblémového pracovního postupu v kontextu dat NoSQL (sbírky a dokumenty). (Další informace naleznete v oficiální dokumentaci uživatelské příručky k DevAPI).
  • Výkonné relace příkazového řádku využívající jazyk Python, SQL nebo Javascript jako „shell“.
  • Vyhovuje ACID.
  • Rychle prozkoumávejte a objevujte svá data, aniž byste museli definovat schéma, jako byste to dělali v relačním modelu.

Běžné tabulkové výrazy (CTE nebo klauzule WITH)

Co dalšího můžete říci o CTE? Tyto věci mění hru! Pro začátek, co přesně je běžný tabulkový výraz?

Z Wikipedie:

"Běžný tabulkový výraz nebo CTE (v SQL) je dočasná pojmenovaná sada výsledků, odvozená z jednoduchého dotazu a definovaná v rozsahu provádění příkazu SELECT, INSERT, UPDATE nebo DELETE."

Uvedu jednoduchý příklad demonstrující CTE. V této části však není využita jejich plná síla, protože existuje mnoho složitějších příkladů použití než tyto.

Mám jednoduchou jmennou tabulku s tímto popisem a údaji:

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)

Pojďme zjistit, kolik příjmení začíná na „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)

Dost snadné.

Pomocí klauzule WITH však můžete 'přístup ' stejnou sadu výsledků dotazu (kterou lze považovat za odvozenou tabulku) a odkazovat na ni později ve stejném příkazu - nebo 'rozsah ':

 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)

Dotazu v zásadě přiřadím název a zabalím jej do závorek. Pak stačí vybrat data, která chci, z toho, co je nyní last_Z CTE.

CTE last_Z poskytuje kompletní sadu výsledků, takže je můžete ještě dále filtrovat v rámci stejného příkazu:

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)

Několik výkonnějších funkcí je „řetězení ' více CTE společně a odkazování na další CTE v rámci CTE.

Zde je příklad pro představu (i když ne tak užitečný):

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)

Ve výše uvedeném dotazu můžete vidět, kde jsem oddělil CTE last_Z od CTE nejlepšího přítele čárkou a pak jsem tento dotaz zabalil do závorek za klíčové slovo AS.

Všimněte si, že pak mohu odkazovat (a používat) last_Z CTE k v podstatě definování CTE nejlepšího přítele.

Zde je několik důvodů, proč jsou CTE ve verzi 8 tak významným vylepšením:

  • Ostatní dodavatelé SQL podporovali CTE (mnoho od dřívějších verzí v rámci jejich jednotlivých ekosystémů) a nyní MySQL 8 zaplnil mezeru v této oblasti.
  • Standardní zahrnutí SQL.
  • V některých případech (pokud je to vhodné) jsou CTE lepší volbou než dočasné tabulky, pohledy, odvozené tabulky (nebo vložené pohledy) a některé dílčí dotazy.
  • CTE mohou poskytovat „on-the-fly ' sada výsledků výpočtů, na kterou se můžete dotazovat.
  • CTE může odkazovat sám na sebe – známé jako rekurzivní CTE (zde není ukázáno).
  • CTE mohou pojmenovat a používat další CTE
ClusterControlSingle Console pro celou vaši databázovou infrastrukturu Zjistěte, co je ještě nového v ClusterControl Nainstalujte ClusterControl ZDARMA

Funkce okna

Analytické dotazy jsou nyní možné v MySQL 8. Protože funkce okna nejsou mou silnou stránkou, soustředím se na jejich hlubší studium a lepší pochopení jako celek a posouvám se kupředu. Tyto další příklady jsou podle mého chápání většinou elementární. Od čtenářů jsou vítány návrhy, rady a osvědčené postupy.

Mám tento VIEW, který poskytuje sadu výsledků fiktivních dat potrubí (něco, čemu trochu rozumím):

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)

Představte si, že potřebuji záznamy o aktivech potrubí prezentované v nějakém pořadí řádků v závislosti na délce každého jednotlivého potrubí. (Např. nejdelší délka je „označená“ pozicí číslo 1, druhá nejdelší délka je „označená“ pozice 2 atd...)

Na základě popisu funkce okna RANK() v dokumentaci:

"Vrátí pořadí aktuálního řádku v rámci jeho oddílu s mezerami. Vrstvení jsou považováni za shodné a dostávají stejnou úroveň. Tato funkce nepřiřazuje po sobě jdoucí pořadí skupinám vrstevníků, pokud existují skupiny o velikosti větší než jedna; výsledkem jsou nesouvislá čísla pořadí." ."

Zdá se, že je pro tento požadavek velmi vhodný.

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)

V dalším scénáři chci ještě dále stavět na předchozím příkladu tím, že seřadím záznamy nejdelší a nejkratší délky, ale pro každou jednotlivou skupinu různých hodnot wall_thickness.

Možná, že níže uvedený dotaz a výsledky lépe vysvětlí, kde moje próza možná ne:

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)

Tento dotaz používá klauzuli PARTITION BY ve sloupci wall_thickness, protože chceme hodnocení (které poskytuje ORDER BY pipe_length DESC), ale potřebujeme ho v kontextu jednotlivých skupin wall_thickness.

Hodnocení každého sloupce long_to_short se resetuje zpět na 1, když narazíte (nebo změníte) na jinou hodnotu sloupce wall_thickness.

Soustřeďme se na výsledky jedné jediné skupiny.

Při cílení na záznamy s hodnotami wall_thickness 0,893 má řádek s pipe_length 44,40 odpovídající long_to_short 'hodnocení' 1 (je nejdelší), zatímco řádek s pipe_length 7,78 má odpovídající long_to_short 'ranking' 8 (nejkratší) vše v tomto specifická skupina (0,893) hodnot wall_thickness.

Funkce oken jsou poměrně výkonné a celý jejich rozsah a šíři nelze pokrýt pouze v jedné sekci. Ujistěte se a navštivte Window Functions podporované v dokumentaci MySQL 8, kde najdete další informace o těch, které jsou aktuálně dostupné.

Vylepšená prostorová podpora a schopnosti

Toto je ohromná sada funkcí obsažených v MySQL 8. Podpora předchozích verzí nebo její absence se jednoduše nedala srovnávat s implementacemi jiných dodavatelů (například PostGIS pro PostgreSQL).

Posledních více než 10 let jsem pracoval v terénu jako Pipeline Surveyor a sbíral data z GPS a majetku, takže tato skupina změn rozhodně upoutá mou pozornost.

Odbornost v oblasti prostorových dat je sama o sobě komplexní téma a buďte si jisti, že nejsem odborníkem na ně. Doufám však, že shrnu významné změny mezi verzemi 5.7 a 8 a sdělím je jasným a stručným způsobem.

Pojďme se pro účely této části seznámit se 2 klíčovými pojmy (a koncepty).

  1. Prostorový referenční systém neboli SRS – Zde je částečná definice z Wikipedie:

    "Prostorový referenční systém (SRS) nebo souřadnicový referenční systém (CRS) je souřadnicový lokální, regionální nebo globální systém používaný k lokalizaci geografických entit. Prostorový referenční systém definuje konkrétní mapovou projekci, stejně jako transformace mezi různými prostorovými referencemi. systémy."

  2. Identifikátor prostorového referenčního systému nebo SRID – Wikipedia má SRID také definována takto:

    "Identifikátor prostorového referenčního systému (SRID) je jedinečná hodnota používaná k jednoznačné identifikaci projektovaných, nepromítnutých a místních definic prostorových souřadnicových systémů. Tyto souřadnicové systémy tvoří jádro všech aplikací GIS."

MySQL podporuje mnoho typů prostorových dat. Jedním z nejběžnějších je BOD. Pokud k navigaci do své oblíbené restaurace používáte GPS, pak je toto místo BOD na mapě.

MySQL 5.7 zpracovává téměř každý 'prostorový objekt ' jako mající SRID 0, což je významné pro výpočty. Tyto výpočty jsou počítány v kartézském typu souřadnicového systému. Všichni však víme, že naše zeměkoule je koule a zdaleka není plochá. Proto ve verzi 8 máte možnost jej při výpočtech považovat buď za plochý, nebo sférický.

Zpět k těmto dvěma termínům, které jsme definovali dříve.

I když 0 je výchozí SRID v MySQL verze 8, je podporováno mnoho (přibližně 5 000+) dalších SRID.

Ale proč je to důležité?

Toto fantastické vysvětlení prostřednictvím příspěvku na blogu Spatial Reference Systems in MySQL 8.0 to pěkně shrnuje:

"Ve výchozím nastavení, pokud neurčíme SRID, MySQL vytvoří geometrie v SRID 0. SRID 0 je představa MySQL o abstraktní, bezjednotkové, nekonečné, katesiánské rovině. Zatímco všechny ostatní SRS odkazují na nějaký povrch a definují jednotky pro osy, SRID 0 nikoli."

V podstatě při provádění výpočtů s jiným SRID než SRID 0 , pak vstupuje do hry tvar naší Země, je zvažován a ovlivňuje tyto výpočty. To je klíčové pro jakékoli smysluplné/přesné výpočty. Hloubkové shrnutí a lepší extrapolaci najdete v tomto příspěvku na blogu o geografii v MySQL 8.

Vřele také doporučuji blogový příspěvek týmu MySQL Server, Geographic Spatial Reference Systems in MySQL 8.0, pro jasnost SRS. Ujistěte se a přečtěte si to!

A konečně, pokud jde o upgrade prostorových dat z verze 5.7 na 8, navštivte některé z nekompatibilních změn uvedených zde, kde najdete další informace.

Další pozoruhodné připomínky

Níže jsou uvedena další vylepšení vydání, která musím uznat, i když nejsou podrobně popsána v tomto příspěvku na blogu:

  • utf8mb4 je nyní výchozí znaková sada (dříve latin1) – Lepší podpora pro tyto znaky musí mít kromě některých jazyků i emotikony...
  • Transakční datový slovník – metadata MySQL jsou nyní uložena v tabulkách InnoDB.
  • Neviditelné indexy – Nastavte viditelnost indexu pro optimalizátor a nakonec určíte, zda je jeho přidání nebo odebrání (indexu) dobrá nebo špatná věc. Přidání indexu do existující velké tabulky může být „nákladné z hlediska zamykání a zdrojů.
  • Sestupné indexy – lepší výkon u indexovaných hodnot, které jsou uloženy v sestupném pořadí.
  • Sloupec okamžitého přidání – pro změny schématu zadejte ALGORITHM=INSTANT v příkazech ALTER TABLE a (pokud je to pro operaci možné) vyhněte se uzamčení metadat. (Další informace naleznete v tomto skvělém příspěvku týmu MySQL Server a v sekci ALTER TABLE z oficiálních dokumentů.)

Bonusová sekce:Něco, co jsem doufal, že uvidím...

Související zdroje ClusterControl for MySQL Staňte se seriálem MySQL DBA – Běžné operace – Změny topologie replikace Staňte se seriálem MySQL DBA – Upgrady databáze

Kontrolní omezení se do produktu MySQL ještě nedostala.

Stejně jako u předchozích verzí MySQL je ve vašich příkazech CREATE TABLE povolena syntaxe kontrolního omezení, ale je ignorována. Pokud je mi známo, většina ostatních prodejců SQL podporuje kontrolní omezení. Přijďte na party MySQL!

MySQL se výrazně 'rozšířilo Jeho nabídka ve verzi 8. Podpora robustních prostorových možností, pohodlné možnosti správy rolí, „hybridní“ datová řešení SQL/NoSQL a analytické funkce mezi mnoha dalšími vylepšeními jsou skutečně pozoruhodné.

Podle mého názoru, s verzí 8, MySQL nadále poskytuje solidní možnost ve stále rostoucím, konkurenčním open source SQL ekosystému, plném relevantních a funkčně bohatých řešení.

Děkuji za přečtení.


  1. Připojovací dotaz MySQL pomocí like?

  2. Správa uživatelských účtů, role, oprávnění, autentizace PHP a MySQL - 6. část

  3. Referenční hodnota sériového sloupce v jiném sloupci při stejném INSERT

  4. 7 způsobů, jak vrátit duplicitní řádky, které mají primární klíč v MariaDB