Mysql
 sql >> база данни >  >> RDS >> Mysql

MySQL през 2018 г.:Какво има в 8.0 и други наблюдения

Тъй като повечето, ако не и цялата 2018 г. зад нас (в зависимост от това кога четете тази публикация), няма съмнение, че това беше фантастична година за SQL бази данни с отворен код.

PostgreSQL 11 и MySQL 8 бяха пуснати, предоставяйки на двете общности много за „разговор '. Честно казано, и двамата доставчици са въвели много значителни промени и допълнения в съответните си издания и заслужават тяхната похвала и признания.

Обикновено гостувам на публикация за първото тук в блога на Severalnines (Много благодаря на страхотна организация!), но също имам интерес към второто. С много публикации в блога на моя собствен уебсайт (връзка в моя раздел с биография), насочени предимно към MySQL версия 5.7, той (MySQL) винаги е в периферните ми устройства.

И така, какво има MySQL 8, което версията 5.7 няма? Какви са подобренията? Е, има много. Всъщност твърде много, за да бъдат обхванати само в една публикация в блога.

Наскоро надстроих до версия 8 в настоящата си среда за обучение/разработване на Linux, така че реших да опитам да посоча някои от тях.

Не мога да ви гарантирам задълбочена дискусия относно вашия „любим ' нови функции). От друга страна, ще посетя онези, които са привлекли вниманието ми или чрез личен интерес, или чрез многото страхотни публикации в блога, публикувани през годината във версия 8.

MySQL става все по-добър и по-добър... Страхотни подобрения във версия 8!

Роли

С ролите DBA могат да смекчат излишъка, когато много потребители споделят една и съща привилегия или набор от привилегии.

Ролите са част от стандарта SQL.

След като създадете конкретна роля с желаните/изискваните привилегии, можете да присвоите на потребителите тази конкретна роля чрез командата GRANT или по подобен начин „отнема ' с REVOKE.

Ролите идват с многобройни предимства и за да улесните живота малко, има няколко таблици, които да ви помогнат да ги следите:

  • mysql.role_edges - Тук намирате тези роли и потребителите, които са им назначени.

    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 – Съхранява всички роли по подразбиране и присвоените потребители.

    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)

Комбинацията от двете таблици (не в смисъла на SQL JOIN) по същество осигурява „централизирано местоположение ' където можете:да познавате, наблюдавате и оценявате всички ваши внедрени привилегии и присвоения на потребителска роля.

Вероятно най-простият примерен сценарий за използване на роли би бил:

Имате няколко потребители, които се нуждаят от „достъп само за четене ' на конкретна таблица, следователно, изискваща поне привилегията SELECT. Вместо да го предоставяте (SELECT) поотделно на всеки потребител, можете да установите (създадете) роля с тази привилегия, след което да присвоите тази роля на тези потребители.

Но ролите идват с малка „уловка '. Веднъж създаден и присвоен на потребител, получаващият потребител трябва да има активна зададена роля по подразбиране по време на удостоверяване при влизане.

Докато става въпрос за роли и потребители, смятам, че е важно да спомена промяната, внедрена в MySQL 8 по отношение на компонента validate_password, който е вариант на плъгина validate_password, използван във версия 5.7.

Този компонент предоставя различни отделни „категории ' на проверка на паролата:ниска, средна (по подразбиране) и силна. Посетете документацията на компонента validate_password за пълен преглед на спецификата за валидиране на всяко ниво.

NoSQL се смесва със SQL – Магазинът за документи

Тази функция все още научавам, въпреки мимолетния интерес към MongoDB в началото на 2016 г. Към днешна дата интересът, изучаването и ученето ми бяха фокусирани единствено върху „SQL“. Въпреки това съм наясно (чрез много четене в мрежата), че мнозина са развълнувани от този тип структуриране (ориентирано към документи), преплетено с „релационен SQL“, който вече е наличен в хранилището за документи на MySQL 8.

По-долу са изброени много предимства, налични при използване на хранилището за документи. Уверете се и споменете вашите любими, които може да съм пропуснал в секцията за коментари:

  • Типът данни JSON се поддържа от MySQL версия 5.7.8, но версия 8 въведе значителни подобрения за работа с JSON. Нови функции, специфични за JSON, заедно със „стенография ' оператори, които могат да се използват вместо множество извиквания на функции - с еднакви резултати/изход.
  • Може би едно от най-важните предимства е, че вече няма нужда да внедрявате и работите с множество решения за бази данни, тъй като NoSQL, SQL или комбинация от двете се поддържат в хранилището за документи.
  • „DevAPI“ предоставя безпроблемни възможности за работен поток в контекста на NoSQL данни (колекции и документи). (Посетете официалното ръководство за потребителя на DevAPI за повече информация).
  • Мощни сесии на команден ред, използващи Python, SQL или Javascript като език на „обвивка“.
  • Съвместим с ACID.
  • Бързо изследвайте и откривайте данните си, без да дефинирате схема, както бихте направили в релационен модел.

Общи таблични изрази (CTE или клаузата WITH)

Какво друго можете да кажете за CTE? Тези неща променят играта! Като за начало, какво точно е общ израз на таблица?

От Уикипедия:

„Общ табличен израз или CTE (в SQL) е временен набор от резултати, извлечен от проста заявка и дефиниран в рамките на обхвата на изпълнение на оператор SELECT, INSERT, UPDATE или DELETE.

Ще дам прост пример, демонстриращ CTE. Пълната им мощ обаче не е впрегната в този раздел, тъй като има много по-сложни примери за използване от тези.

Имам проста таблица с имена с това описание и данни:

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)

Нека разберем колко фамилни имена започват с „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)

Достатъчно лесно.

Въпреки това, като използвате клаузата WITH, можете да „достъп ' същия набор от резултати от заявка (който може да се разглежда като извлечена таблица) и се позовава на него по-късно в рамките на същия израз - или 'обхват ':

 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)

По принцип присвоявам име на заявката, увивайки го в скоби. След това просто изберете данните, които искам от това, което сега е last_Z CTE.

Last_Z CTE предоставя пълен набор от резултати, така че можете да го филтрирате още повече в рамките на същия израз:

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)

Няколко от по-мощните функции са „верижно ' множество CTE заедно и препратка към други CTE в CTE.

Ето един пример, който да ви даде идея (макар и не толкова полезен):

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)

В горната заявка можете да видите къде отделих last_Z CTE от best_friend CTE със запетая, след което увих тази заявка в скоби след ключовата дума AS.

Забележете, че тогава мога да се позова на (и да използвам) last_Z CTE, за да дефинирам по същество CTE на най-добрия_приятел.

Ето няколко причини, поради които CTE са толкова значително подобрение във версия 8:

  • Други доставчици на SQL поддържат CTE (много от по-ранните версии в рамките на тяхната индивидуална екосистема) и сега MySQL 8 запълни празнината в тази област.
  • Стандартно включване на SQL.
  • В някои случаи (където е уместно) CTE са по-добър вариант от временни таблици, изгледи, извлечени таблици (или вградени изгледи) и някои подзаявки.
  • CTE могат да осигурят „в движение ' набор от резултати от изчисления, към който можете да правите запитвания.
  • Един CTE може да се позовава на себе си – известен като рекурсивен CTE (не е демонстриран тук).
  • CTE могат да назовават и използват други CTE
ClusterControlЕдинична конзола за цялата ви инфраструктура на базата данни Открийте какво още е новото в ClusterControlИнсталирайте ClusterControl БЕЗПЛАТНО

Функции на прозореца

Аналитичните заявки вече са възможни в MySQL 8. Тъй като функциите на прозореца не са моята силна страна, аз съм фокусиран върху по-задълбочено проучване и по-добро разбиране за тях като цяло, продължавайки напред. Следващите примери са предимно елементарни според моето разбиране. Предложения, съвети и най-добри практики са добре дошли от читателите.

Имам този VIEW, който предоставя фиктивен набор от данни за канали (нещо, което донякъде разбирам):

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)

Представете си, имам нужда от записите на активите на тръбите, представени в някакъв вид класиране на редове в зависимост от дължината на всяка отделна тръба. (Напр., най-дългата дължина е „маркирана“ като позиция номер 1, втората най-дълга дължина е „маркирана“ позиция 2 и т.н.)

Въз основа на описанието на функцията на прозореца RANK() в документацията:

„Връща ранга на текущия ред в рамките на неговия дял, с пропуски. Връстниците се считат за връзки и получават същия ранг. Тази функция не присвоява последователни рангове на партньорски групи, ако съществуват групи с размер, по-голям от един; резултатът е несвързани рангови номера ."

Изглежда, че е много подходящ за това изискване.

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)

В следващия сценарий искам да надградя още повече предишния пример, като класирам записите от най-дълга към най-къса дължина, но за всяка отделна група от различни стойности wall_thickness.

Може би заявката и резултатите по-долу ще обяснят по-добре къде моята проза може да не е:

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)

Тази заявка използва клаузата PARTITION BY в колоната wall_thickness, защото искаме класирането (което ORDER BY pipe_length DESC предоставя), но ни е необходимо в контекста на отделните групи wall_thickness.

Класирането на всяка колона long_to_short се връща обратно на 1, когато срещнете (или промените) на различна стойност на колоната wall_thickness.

Нека се концентрираме върху резултатите от една единствена група.

При насочване към записите със стойности на wall_thickness 0,893, редът с pipe_length 44,40 има съответното long_to_short 'класиране' от 1 (това е най-дългият), докато редът с pipe_length 7,78 има съответстващо long_to_short 'класиране' от всички в рамките на това късо от 8 специфична група (0,893) стойности за дебелина на стената.

Функциите на прозореца са доста мощни и целият им обхват и широчина не биха могли да бъдат обхванати само в един раздел. Уверете се и посетете функциите на прозореца, поддържани в документацията на MySQL 8, за повече информация относно наличните в момента.

Подобрена пространствена поддръжка и възможности

Това е огромен набор от функции, включени в MySQL 8. Поддръжката на предишни версии или липсата на такава просто не можеше да се сравни с реализацията(ите) на други доставчици (помислете за PostGIS за PostgreSQL).

През последните 10 и повече години работих в областта като инспектор на тръбопроводи, събирайки GPS и данни за активи, така че тази група промени определено привлича вниманието ми.

Експертизата в областта на пространствените данни е изчерпателна тема сама по себе си и бъдете сигурни, че далеч не съм експерт по нея. Въпреки това се надявам да обобщя значителните промени между версии 5.7 и 8 и да ги предам по ясен и сбит начин.

Нека се запознаем с 2 ключови термина (и понятия) за целите на този раздел.

  1. Пространствена референтна система или SRS - Ето частична дефиниция от Wikipedia:

    „Пространствена референтна система (SRS) или координатна референтна система (CRS) е базирана на координати локална, регионална или глобална система, използвана за локализиране на географски обекти. системи."

  2. Идентификатор на пространствена референтна система или SRID - Също така, Уикипедия има SRID, дефинирани като такива:

    „Идентификаторът на пространствената референтна система (SRID) е уникална стойност, използвана за недвусмислено идентифициране на проектирани, непрожектирани и локални дефиниции на пространствена координатна система. Тези координатни системи формират сърцето на всички ГИС приложения.“

MySQL поддържа много типове пространствени данни. Един от най-често срещаните е ТОЧКА. Ако използвате вашия GPS, за да навигирате до любимия си ресторант, това местоположение е ТОЧКА на картата.

MySQL 5.7 третира почти всеки „пространствен обект ' като имащ SRID от 0, което е важно за изчисления. Тези изчисления се изчисляват в декартов тип координатна система. Всички обаче знаем, че нашият глобус е сфера и далеч не е плосък. Следователно във версия 8 имате възможност да го разглеждате като плосък или сферичен при изчисления.

Обратно към тези два термина, които дефинирахме по-рано.

Въпреки че 0 е SRID по подразбиране в MySQL версия 8, много (приблизително 5000+) други SRID се поддържат.

Но защо това е важно?

Това фантастично обяснение чрез публикацията в блога, Spatial Reference Systems в MySQL 8.0, го обобщава добре:

„По подразбиране, ако не посочим SRID, MySQL ще създаде геометрии в SRID 0. SRID 0 е понятието на MySQL за абстрактна, безединична, безкрайна катесова равнина. Докато всички други SRS се отнасят до някаква повърхност и дефинират единици за оси, SRID 0 не го прави."

По същество, когато извършвате изчисления с SRID, различни от SRID 0 , тогава формата на нашата Земя влиза в игра, разглежда се и влияе на тези изчисления. Това е от решаващо значение за всякакви смислени/точни изчисления. За задълбочен преглед и по-добра екстраполация вижте тази публикация в блога, обхващаща географията в MySQL 8.

Също така силно препоръчвам публикацията в блога на MySQL Server Team, Географски пространствени референтни системи в MySQL 8.0, за яснота относно SRS. Уверете се и го прочетете!

И накрая, за проблеми с надстройката на пространствените данни от версия 5.7 до 8, посетете някои от изброените тук несъвместими промени за повече информация.

Други забележителни наблюдения

По-долу са други подобрения на версията, които трябва да призная, въпреки че не са обхванати задълбочено в тази публикация в блога:

  • utf8mb4 вече е наборът от знаци по подразбиране (по-рано latin1) – По-добра поддръжка за тях трябва да имат емоджи в допълнение към някои езици...
  • Речник на транзакционни данни – MySQL метаданните вече се помещават в таблици на InnoDB.
  • Невидими индекси – Задайте видимостта на индекс за оптимизатора, като в крайна сметка определяте дали добавянето или премахването му (индексът) е добро или лошо нещо. Добавянето на индекс към съществуваща голяма таблица може да бъде „скъпо ' по отношение на заключването и ресурсите.
  • Низходящи индекси – По-добра производителност на индексирани стойности, които се съхраняват в низходящ ред.
  • Колона за незабавно добавяне – За промени в схемата посочете ALGORITHM=INSTANT в изразите ALTER TABLE и (ако е възможно за операцията) избягвайте заключванията на метаданни. (За повече информация вижте тази страхотна публикация от екипа на MySQL Server и секцията ALTER TABLE от официалните документи.)

Бонус раздел:Нещо, което се надявах да видя...

Свързани ресурси ClusterControl за MySQL Станете серия от блогове на MySQL DBA – Общи операции – Промени в топологията на репликацията Станете серия от блогове на MySQL DBA – Надстройки на база данни

Ограниченията за проверка все още не са проникнали в продукта MySQL.

Както при предишните версии на MySQL, синтаксисът за проверка на ограничението е разрешен във вашите команди CREATE TABLE, но се игнорира. Доколкото ми е известно, повечето други доставчици на SQL поддържат ограничения за проверка. Елате да се присъедините към партито MySQL!

MySQL значително 'ускори ' предлагането му във версия 8. Поддържането на стабилни пространствени възможности, удобни опции за управление на потребители, „хибридни“ решения за SQL/NoSQL данни и аналитични функции сред многобройните допълнителни подобрения е наистина забележително.

Според мен с версия 8 MySQL продължава да предоставя солидна опция в непрекъснато растящата, конкурентна SQL екосистема с отворен код, пълна с подходящи и богати на функции решения.

Благодаря ви, че прочетохте.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Показване на пълната SQL заявка в Покажи списък с процеси на MySQL

  2. Групирайте mysql заявката на интервали от 15 минути

  3. Amazon EC2, mysql прекратява стартирането, защото InnoDB:mmap (x байта) не успя; грешка 12

  4. Как да предоставим разрешения за отдалечен достъп до mysql сървър за потребител?

  5. Как да импортирам .sql файл в mysql база данни с помощта на PHP?