sql >> Base de Datos >  >> RDS >> Mysql

MySQL en 2018:Qué hay en 8.0 y otras observaciones

Con la mayor parte, si no todo, de 2018 detrás de nosotros (dependiendo de cuándo esté leyendo esta publicación), no hay duda de que fue un año fantástico para las bases de datos SQL de código abierto.

Se lanzaron PostgreSQL 11 y MySQL 8, proporcionando a ambas comunidades mucho de lo que 'hablar '. A decir verdad, ambos proveedores han introducido muchos cambios y adiciones significativos en sus respectivos lanzamientos y merecen sus elogios y elogios.

Normalmente publico como invitado sobre el primero aquí en el blog de Variousnines (¡Muchas gracias a una gran organización!), Pero también tengo interés en el segundo. Con muchas publicaciones de blog en mi propio sitio web (enlace en mi sección de biografía), en su mayoría dirigidas a la versión 5.7 de MySQL, (MySQL) siempre está en mis periféricos.

Entonces, ¿qué tiene MySQL 8 que no tiene la versión 5.7? ¿Cuáles son las mejoras? Bueno, hay muchos. De hecho, son demasiados para cubrirlos en una sola entrada de blog.

Recientemente actualicé a la versión 8 en mi entorno actual de aprendizaje/desarrollo de Linux, así que pensé en intentar señalar algunos de ellos.

No puedo garantizarle una discusión en profundidad sobre su 'favorito ' nuevas características). Por otro lado, visitaré aquellos que me han llamado la atención ya sea a través de un interés personal o a través de las muchas y excelentes publicaciones de blog publicadas a lo largo del año en la versión 8.

MySQL está mejorando cada vez más... ¡Fantásticas mejoras en la versión 8!

Funciones

Con Roles, los DBA pueden mitigar la redundancia, donde muchos usuarios compartirían el mismo privilegio o conjunto de privilegios.

Los roles son parte del estándar SQL.

Después de crear una función específica con los privilegios deseados/requeridos, puede asignar a los usuarios esa función en particular a través del comando GRANT o, de la misma manera, 'quitar ' con REVOCAR.

Los roles vienen con numerosos beneficios y para hacer la vida un poco más fácil, hay un par de tablas para ayudarlo a realizar un seguimiento de ellos:

  • mysql.role_edges:aquí encontrará esos roles y los usuarios a los que están asignados.

    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:almacena los roles predeterminados y los usuarios asignados.

    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 combinación de ambas tablas (no en el sentido de SQL JOIN) proporciona esencialmente una 'ubicación centralizada ' donde puede:conocer, monitorear y evaluar todas sus asignaciones y relaciones de privilegios de función de usuario implementadas.

Probablemente, el escenario de uso de rol de ejemplo más simple sería:

Tiene varios usuarios que necesitan 'acceso de solo lectura ' en una tabla específica, por lo tanto, requiere al menos el privilegio SELECT. En lugar de otorgarlo (SELECCIONAR) individualmente a cada usuario, puede establecer (crear) una función que tenga ese privilegio y luego asignar esa función a esos usuarios.

Pero, los roles vienen con un pequeño 'trampa '. Una vez creado y asignado a un usuario, el usuario receptor debe tener un conjunto de roles predeterminado activo durante la autenticación al iniciar sesión.

En cuanto al tema de los roles y los usuarios, creo que es importante mencionar el cambio implementado en MySQL 8 con respecto al componente validate_password, que es una variante del complemento validate_password utilizado en la versión 5.7.

Este componente proporciona varias 'categorías distintas ' de verificación de contraseña:bajo, medio (predeterminado) y fuerte. Visite la documentación del componente validate_password para obtener un resumen completo de las especificaciones de validación de cada nivel.

Mezclando NoSQL con SQL - The Document Store

Todavía estoy aprendiendo sobre esta característica, a pesar de un interés fugaz en MongoDB a principios de 2016. Hasta la fecha, mi interés, estudio y aprendizaje se han centrado únicamente en 'SQL'. Sin embargo, soy consciente (a través de mucha lectura en la web) de que muchos están entusiasmados con este tipo de estructuración (orientada a documentos) entrelazada con 'SQL relacional' ahora disponible en el almacén de documentos de MySQL 8.

A continuación se presentan muchos beneficios disponibles cuando se utiliza el almacén de documentos. Asegúrate de mencionar tus favoritos que me haya perdido en la sección de comentarios:

  • El tipo de datos JSON ha sido compatible desde la versión 5.7.8 de MySQL; sin embargo, la versión 8 introdujo mejoras significativas para trabajar con JSON. Nuevas funciones específicas de JSON junto con 'taquigrafía ' operadores que se pueden usar en lugar de varias llamadas a funciones, con los mismos resultados/salida.
  • Quizás uno de los principales beneficios es que ya no necesita implementar y trabajar con múltiples soluciones de base de datos, ya que NoSQL, SQL o una combinación de ambos son compatibles con el almacén de documentos.
  • Una "DevAPI" proporciona capacidades de flujo de trabajo perfectas dentro de un contexto de datos NoSQL (colecciones y documentos). (Visite la documentación de la guía del usuario oficial de DevAPI para obtener más información).
  • Poderosas sesiones de línea de comandos que usan Python, SQL o Javascript como el lenguaje de 'shell'.
  • Cumple con ACID.
  • Explore y descubra rápidamente sus datos sin definir un esquema como lo haría en un modelo relacional.

Expresiones de tabla comunes (CTE o cláusula WITH)

¿Qué más puedes decir sobre los CTE? ¡Estas cosas son un cambio de juego! Para empezar, ¿qué es exactamente una expresión de tabla común?

De Wikipedia:

"Una expresión de tabla común, o CTE, (en SQL) es un conjunto de resultados con nombre temporal, derivado de una consulta simple y definido dentro del ámbito de ejecución de una instrucción SELECT, INSERT, UPDATE o DELETE".

Proporcionaré un ejemplo simple, demostrando CTE. Sin embargo, no se aprovecha toda su potencia en esta sección, ya que hay muchos ejemplos de casos de uso más complejos que estos.

Tengo una tabla de nombres simple con esta descripción y datos:

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)

Averigüemos cuántos apellidos comienzan 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)

Bastante fácil.

Sin embargo, al usar la cláusula WITH, puede 'acceder ' este mismo conjunto de resultados de consulta (que se puede considerar como una tabla derivada) y hacer referencia a él más adelante dentro de la misma declaración, o 'scope ':

 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)

Básicamente asigno un nombre a la consulta, envolviéndola entre paréntesis. Luego simplemente seleccione los datos que quiero de lo que ahora es el último_Z CTE.

El last_Z CTE proporciona un conjunto de resultados completo, por lo que puede filtrarlo aún más dentro de la misma declaración:

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 par de funciones más potentes son 'encadenamiento ' varios CTE juntos y haciendo referencia a otros CTE dentro de CTE.

Aquí tienes un ejemplo para que te hagas una idea (aunque no muy útil):

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)

En la consulta anterior, puede ver dónde separé la CTE last_Z de la CTE best_friend con una coma y luego envolví esa consulta entre paréntesis después de la palabra clave AS.

Observe que puedo referirme a (y usar) el CTE de last_Z para definir esencialmente el CTE de best_friend.

Aquí hay algunas razones por las que los CTE son una mejora tan significativa en la versión 8:

  • Otros proveedores de SQL han admitido CTE (muchos desde versiones anteriores dentro de sus ecosistemas individuales) y ahora MySQL 8 ha cerrado la brecha en esta área.
  • Una inclusión de SQL estándar.
  • En algunos casos (cuando corresponda), las CTE son una mejor opción que las tablas temporales, las vistas, las tablas derivadas (o las vistas en línea) y algunas subconsultas.
  • Los CTE pueden proporcionar un 'sobre la marcha ' conjunto de resultados de cálculos que puede consultar.
  • Un CTE puede hacer referencia a sí mismo, lo que se conoce como CTE recursivo (no se muestra aquí).
  • Los CTE pueden nombrar y usar otros CTE
ClusterControlConsola única para toda su infraestructura de base de datosDescubra qué más hay de nuevo en ClusterControlInstale ClusterControl GRATIS

Funciones de ventana

Las consultas analíticas ahora son posibles en MySQL 8. Como las funciones de Windows no son mi fuerte, me estoy enfocando en un estudio más profundo y una mejor comprensión de ellas, en general, en el futuro. Estos siguientes ejemplos son en su mayoría elementales según mi entendimiento. Las sugerencias, los consejos y las mejores prácticas son bienvenidos por parte de los lectores.

Tengo esta VISTA que proporciona un conjunto de resultados de datos de tubería ficticios (algo que entiendo un poco):

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)

Imagínese, necesito que los registros de activos de tuberías se presenten en algún tipo de clasificación de filas según la longitud de cada tubería individual. (Por ejemplo, la longitud más larga está 'etiquetada' en la posición número 1, la segunda longitud más larga está 'etiquetada' en la posición 2, etc...)

Basado en la descripción de la función de ventana RANK() en la documentación:

"Devuelve el rango de la fila actual dentro de su partición, con espacios. Los pares se consideran empates y reciben el mismo rango. Esta función no asigna rangos consecutivos a grupos de pares si existen grupos de tamaño mayor que uno; el resultado son números de rango no contiguos ."

Parece ser adecuado para este 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)

En el siguiente escenario, quiero desarrollar aún más el ejemplo anterior clasificando los registros de longitudes más largas a más cortas, pero, por cada grupo individual de los distintos valores de wall_thickness.

Tal vez la consulta y los resultados a continuación expliquen mejor dónde mi prosa puede no haberlo hecho:

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)

Esta consulta usa la cláusula PARTITION BY en la columna wall_thickness porque queremos la clasificación (que ORDER BY pipe_length DESC proporciona), sin embargo, la necesitamos en el contexto de los grupos wall_thickness individuales.

Cada clasificación de columna long_to_short se restablece a 1 cuando encuentra (o cambia) a un valor de columna wall_thickness diferente.

Concentrémonos en los resultados de un solo grupo.

Dirigiéndose a los registros con valores de grosor de pared de 0,893, la fila con longitud de tubería de 44,40 tiene una "clasificación" de largo a corto correspondiente de 1 (es la más larga), mientras que la fila con longitud de tubería de 7,78 tiene una "clasificación" de largo a corto correspondiente de 8 (la más corta), todo dentro de ese grupo específico (0.893) de valores wall_thickness.

Las funciones de la ventana son bastante poderosas y su alcance y amplitud no podrían cubrirse en una sola sección. Asegúrese de visitar las funciones de ventana admitidas en la documentación de MySQL 8 para obtener más información sobre las funciones disponibles actualmente.

Apoyo y capacidades espaciales mejorados

Este es un tremendo conjunto de funciones incluidas en MySQL 8. El soporte de versiones anteriores, o la falta del mismo, simplemente no se podía comparar con las implementaciones de otros proveedores (piense en PostGIS para PostgreSQL).

Durante los últimos 10 años o más, he trabajado en el campo como topógrafo de tuberías, recopilando datos GPS y de activos, por lo que este grupo de cambios definitivamente llama mi atención.

La experiencia en datos espaciales es un tema integral por derecho propio y puede estar seguro de que estoy lejos de ser un experto en el tema. Sin embargo, espero resumir los cambios significativos entre las versiones 5.7 y 8 y transmitirlos de manera clara y concisa.

Familiaricémonos con 2 términos (y conceptos) clave para los fines de esta sección.

  1. Sistema de referencia espacial o SRS:aquí hay una definición parcial de Wikipedia:

    "Un sistema de referencia espacial (SRS) o sistema de referencia de coordenadas (CRS) es un sistema local, regional o global basado en coordenadas que se utiliza para ubicar entidades geográficas. Un sistema de referencia espacial define una proyección de mapa específica, así como transformaciones entre diferentes referencias espaciales. sistemas".

  2. Identificador del sistema de referencia espacial o SRID:además, Wikipedia tiene SRID definidos como tales:

    "Un identificador de sistema de referencia espacial (SRID) es un valor único que se utiliza para identificar sin ambigüedades las definiciones de sistemas de coordenadas espaciales proyectadas, no proyectadas y locales. Estos sistemas de coordenadas forman el corazón de todas las aplicaciones GIS".

MySQL admite muchos tipos de datos espaciales. Uno de los más comunes es un PUNTO. Si usa su GPS para navegar a su restaurante favorito, entonces esa ubicación es un PUNTO en un mapa.

MySQL 5.7 trata prácticamente todos los 'objetos espaciales ' como si tuviera un SRID de 0, lo cual es significativo para los cálculos. Esos cálculos se calculan en un sistema de coordenadas de tipo cartesiano. Sin embargo, todos sabemos que nuestro globo es una esfera y está lejos de ser plano. Por lo tanto, en la versión 8, tiene la capacidad de considerarlo plano o esférico en los cálculos.

Volviendo a esos dos términos que definimos anteriormente.

Aunque 0 es el SRID predeterminado en la versión 8 de MySQL, se admiten muchos (aproximadamente más de 5000) SRID.

Pero, ¿por qué es eso importante?

Esta fantástica explicación a través de la publicación del blog, Sistemas de referencia espacial en MySQL 8.0, lo resume muy bien:

"De forma predeterminada, si no especificamos un SRID, MySQL creará geometrías en SRID 0. SRID 0 es la noción de MySQL de un plano catesiano abstracto, sin unidades, infinito. Mientras que todos los demás SRS se refieren a alguna superficie y definen unidades para el ejes, SRID 0 no".

Esencialmente, al realizar cálculos con SRID que no sea SRID 0 , entonces la forma de nuestra Tierra entra en juego, se considera y afecta esos cálculos. Esto es crucial para cualquier cálculo significativo/preciso. Para obtener un resumen detallado y una mejor extrapolación, consulte esta publicación de blog que cubre la geografía en MySQL 8.

También recomiendo encarecidamente la publicación del blog del equipo de servidores MySQL, Sistemas de referencia espacial geográfica en MySQL 8.0, para mayor claridad sobre los SRS. ¡Asegúrate y léelo!

Por último, si tiene dudas sobre la actualización de datos espaciales de la versión 5.7 a la 8, visite algunos de los cambios incompatibles que se enumeran aquí para obtener más información.

Otras observaciones notables

A continuación se presentan otras mejoras de lanzamiento que debo reconocer, aunque no se tratan en profundidad en esta publicación de blog:

  • utf8mb4 es ahora el conjunto de caracteres predeterminado (anteriormente latin1):mejor soporte para aquellos que deben tener emojis además de algunos idiomas...
  • Diccionario de datos transaccionales:los metadatos de MySQL ahora se encuentran en las tablas de InnoDB.
  • Índices invisibles:establezca la visibilidad de un índice para el optimizador y, en última instancia, determine si agregarlo o eliminarlo (el índice) es bueno o malo. Agregar un índice a una tabla grande existente puede ser 'caro ' en términos de bloqueo y recursos.
  • Índices descendentes:mejor rendimiento en valores indexados que se almacenan en orden descendente.
  • Columna agregada instantánea:para cambios de esquema, especifique ALGORITHM=INSTANT en declaraciones ALTER TABLE y (si es factible para la operación) evite bloqueos de metadatos. (Para obtener más información, consulte esta excelente publicación del equipo del servidor MySQL y la sección ALTER TABLE de los documentos oficiales).

Sección adicional:Algo que esperaba ver...

Recursos relacionados ClusterControl para MySQL Serie de blogs Convertirse en un DBA de MySQL - Operaciones comunes - Cambios en la topología de replicación Serie de blogs Convertirse en un DBA de MySQL - Actualizaciones de la base de datos

Las restricciones de comprobación aún no se han introducido en el producto MySQL.

Al igual que con las versiones anteriores de MySQL, se permite verificar la sintaxis de restricciones en los comandos CREATE TABLE, pero se ignora. Que yo sepa, la mayoría de los demás proveedores de SQL admiten restricciones de verificación. ¡Únete a la fiesta MySQL!

MySQL ha 'intensificado significativamente ' su oferta en la versión 8. La compatibilidad con capacidades espaciales robustas, opciones convenientes de roles de administración de usuarios, soluciones de datos SQL/NoSQL 'híbridas' y funciones analíticas entre las numerosas mejoras adicionales, es verdaderamente notable.

En mi opinión, con la versión 8, MySQL continúa brindando una opción sólida en el ecosistema SQL de código abierto competitivo y en constante crecimiento, lleno de soluciones relevantes y ricas en funciones.

Gracias por leer.