Comprenda a fondo el ensayo de ocho partes de la entrevista de MySQL

El contenido está extraído de mi sitio web de aprendizaje: topjavaer.cn

¿Qué es MySQL?

MySQL es una base de datos relacional que almacena datos en forma de tablas. Puede considerarlo como una tabla de Excel. Dado que los datos se almacenan en forma de tabla, tiene una estructura de tabla (filas y columnas). Las filas representan cada fila de datos y las columnas representan cada valor de esa fila. Los valores de la columna tienen tipos de datos, como números enteros, cadenas, fechas, etc.

Tres paradigmas principales de bases de datos.

Primera forma normal 1NF

Garantizar la atomicidad de los campos de la tabla de la base de datos. Un sitio web de entrevistas Java muy completo

Por ejemplo, el campo userInfo: 广东省 10086'debe dividirse en userInfo: 广东省 userTel: 10086dos campos según la primera forma normal.

Segunda forma normal 2NF

En primer lugar, debe cumplir con la primera forma normal y también incluye dos partes: primero, la tabla debe tener una clave primaria; segundo, las columnas de clave no primaria deben depender completamente de la clave primaria y no pueden depender solo de parte de la clave primaria.

Por ejemplo. Supongamos que la tabla de relaciones de selección de cursos es student_course(nº_estudiante, nombre_estudiante, edad, nombre_curso, calificación, crédito) y la clave principal es (nº_estudiante, nombre_curso). Los créditos dependen completamente del nombre del curso, y el nombre y la edad dependen completamente del número de estudiantes, lo que no se ajusta al segundo paradigma y provocará redundancia de datos (los estudiantes eligen n cursos y hay n registros de nombre y edad) y anomalías de inserción (insertar un nuevo curso, debido a que no hay una identificación de estudiante, no se pueden guardar nuevos registros de clase) y otros problemas.

Debe dividirse en tres tablas: estudiantes: student(nº_estudiante, nombre_estudiante, edad); cursos: course(nombre_curso, crédito); relaciones de selección de cursos: student_course_relation(nº_estudiante, nombre_curso, calificación).

Tercera forma normal 3NF

En primer lugar, debe satisfacer la segunda forma normal. Además, las columnas de clave no primaria deben depender directamente de la clave primaria y no puede haber dependencias transitivas. Es decir, no puede existir: la columna de clave no principal A depende de la columna de clave no principal B, y la columna de clave no principal B depende de la clave principal.

Supongamos que la tabla de relaciones de estudiantes es Estudiante (número_estudiante, nombre_estudiante, edad, id_academia, teléfono_academia) y la clave principal es "número de estudiante". La identificación de la universidad depende del número de estudiante, y la ubicación y el número de teléfono de la universidad dependen del ID de la universidad. Hay una dependencia transitiva, que no es consistente. Tercer paradigma.

La tabla de relaciones de estudiantes se puede dividir en las siguientes dos tablas: estudiante: (nro. de estudiante, nombre_estudiante, edad, id_academia); universidad: (id_academia, teléfono_academia).

¿Cuál es la diferencia entre 2NF y 3NF?

  • 2NF se basa en si la columna de clave no principal depende completamente de la clave principal o depende de parte de la clave principal.
  • 3NF se basa en si la columna de clave no principal depende directamente de la clave principal o de la clave no principal.

Este artículo se ha incluido en el repositorio de Github, que incluye conceptos básicos de informática, conceptos básicos de Java, subprocesos múltiples, JVM, bases de datos, Redis, Spring, Mybatis, SpringMVC, SpringBoot, distribuido, microservicios, patrones de diseño, arquitectura, reclutamiento escolar y reclutamiento social. compartir, etc. Puntos de conocimiento básicos, ¡bienvenido a protagonizar!

Enlace (en el que se puede hacer clic): dirección de Github

Si no puede acceder a Github, puede acceder a la dirección del albergue.

Enlace (en el que se puede hacer clic): dirección de la casa rural

¿Cuáles son las cuatro características principales de las transacciones?

Características de la transacción ACID : atomicidad ( Atomicity), consistencia ( Consistency), aislamiento ( Isolation), durabilidad ( Durability).

  • Atomicidad significa que todas las operaciones incluidas en una transacción tienen éxito o fallan y se revierten.
  • Coherencia significa que una transacción debe estar en un estado consistente antes y después de su ejecución. Por ejemplo, las cuentas de a y b tienen un total de 1000 yuanes. Después de que la transferencia entre las dos personas tenga éxito o fracase, la suma de sus cuentas seguirá siendo 1000.
  • Aislamiento . En relación con el nivel de aislamiento, por ejemplo read committed, una transacción solo puede leer las modificaciones enviadas.
  • Durabilidad significa que una vez que se confirma una transacción, los cambios en los datos de la base de datos son permanentes y la operación de confirmación de la transacción no se perderá incluso si el sistema de la base de datos encuentra una falla.

¿Cuáles son los niveles de aislamiento de transacciones?

Primero comprenda los siguientes conceptos: lectura sucia, lectura no repetible y lectura fantasma.

  • La lectura sucia se refiere a la lectura de datos en otra transacción no confirmada durante una transacción.
  • Lectura no repetible significa que para una determinada fila de registros en la base de datos, varias consultas dentro de un rango de transacciones devuelven valores de datos diferentes, esto se debe a que otra transacción modificó los datos y los envió durante el intervalo de consulta.
  • La lectura fantasma ocurre cuando una transacción lee registros en un rango determinado y otra transacción inserta un nuevo registro en el rango. La comprensión correcta de la lectura fantasma es que la conclusión de una operación de lectura dentro de una transacción no puede respaldar la ejecución comercial posterior. Supongamos que la transacción desea agregar un nuevo registro, la clave principal es id, se ejecuta una selección antes de agregar y no se encuentra ningún registro con id xxx, pero se produce un conflicto de clave principal durante la inserción. Esta es una lectura fantasma. No El registro se puede leer, pero se encuentra un conflicto de clave principal. Esto se debe a que otras transacciones han insertado el registro, pero no es visible para la transacción actual.

La diferencia entre lectura no repetible y lectura sucia es que la lectura sucia es cuando una transacción lee los datos sucios no confirmados de otra transacción, mientras que la lectura no repetible es cuando se leen los datos enviados por la transacción anterior.

El aislamiento de transacciones tiene como objetivo resolver los problemas de lecturas sucias, lecturas no repetibles y lecturas fantasma mencionados anteriormente.

Los cuatro niveles de aislamiento proporcionados por la base de datos MySQL son:

  • Serializable : resuelva el problema de lectura fantasma obligando a que las transacciones se ordenen para que no puedan entrar en conflicto entre sí.
  • Lectura repetible : el nivel de aislamiento de transacciones predeterminado de MySQL, que garantiza que varias instancias de la misma transacción vean las mismas filas de datos al leer datos al mismo tiempo, resolviendo el problema de la lectura no repetible.
  • Leer comprometido : una transacción solo puede ver los cambios realizados por transacciones confirmadas. Se pueden evitar las lecturas sucias.
  • Leer no confirmado : todas las transacciones pueden ver los resultados de ejecución de otras transacciones no confirmadas.

Verifique el nivel de aislamiento:

select @@transaction_isolation;

Establecer nivel de aislamiento:

set session transaction isolation level read uncommitted;

¿Qué nivel de aislamiento se utiliza generalmente para las bases de datos del entorno de producción?

La mayoría de los entornos de producción utilizan RC . ¿Por qué no RR?

Lectura repetible, denominada RR
Lectura confirmada, denominada RC

Razón 1: bajo el nivel de aislamiento RR, hay un bloqueo de brecha, lo que conduce a una probabilidad de punto muerto mucho mayor que RC.
Segunda razón: bajo el nivel de aislamiento RR, si la columna condicional no incluye el índice, la tabla se bloqueará. ¡Bajo el nivel de aislamiento RC, solo las filas están bloqueadas!

En otras palabras, RC tiene mayor concurrencia que RR.

Y en la mayoría de los escenarios, el problema de lectura no repetible es aceptable. Después de todo, los datos ya han sido enviados, por lo que no hay gran problema en leerlos.

Enlace (en el que se puede hacer clic): un sitio web de entrevistas Java muy completo

La relación entre codificación y juego de caracteres.

Por lo general, podemos ingresar varias letras en chino e inglés en el editor, pero son para que las lean los humanos, no las computadoras. De hecho, las computadoras en realidad guardan y transmiten datos en el formato binario 0101 .

Entonces es necesario que exista una regla para convertir las letras chinas e inglesas a binarias. Entre ellos, d corresponde a 64 en hexadecimal, que se puede convertir a 01 formato binario. Entonces las letras y los números corresponden uno a uno, y este es el formato de codificación ASCII .

Utiliza un byte para identificar caracteres . 8位Hay 128 símbolos básicos y 128 símbolos extendidos. Sólo puede representar letras y números en inglés .

Evidentemente esto no es suficiente. Por lo tanto, para identificar el chino , apareció el formato de codificación GB2312 . Para identificar el griego , apareció el formato de codificación griego y para identificar el ruso , se ajustó el formato de codificación cp866 .

Para unificarlos apareció el formato de codificación Unicode , que utiliza de 2 a 4 bytes para representar los caracteres, por lo que teóricamente se pueden incluir todos los símbolos, además es totalmente compatible con la codificación ASCII, es decir, la misma letra. d está representado por 64 en ASCII, pero todavía está representado por 64 en Unicode.

Pero la diferencia es que la codificación ASCII está representada por 1 byte, mientras que Unicode está representada por dos bytes.

También son la letra D. Unicode usa un byte más que ascii, de la siguiente manera:

D   ASCII:           01100100
D Unicode:  00000000 01100100

Como puede ver, la codificación Unicode anterior tiene 0 al frente, lo que en realidad no es útil, pero aún ocupa 1 byte, lo cual es un poco derrochador. Si podemos ocultarnos cuando deberíamos, podemos ahorrar mucho espacio. Según esta idea, existe la codificación UTF-8 .

En resumen, hacer coincidir símbolos y códigos binarios de acuerdo con ciertas reglas se llama codificación . Y reunir muchos de estos caracteres codificados es lo que a menudo llamamos un conjunto de caracteres .

Por ejemplo, el juego de caracteres utf-8 es la colección de todos los caracteres en el formato de codificación utf-8.

Me gustaría ver qué juegos de caracteres admite MySQL. Puede ser ejecutadoshow charset;

La diferencia entre utf8 y utf8mb4

Como se mencionó anteriormente, utf-8 es una optimización basada en Unicode. Dado que Unicode tiene una forma de representar todos los caracteres, utf-8 también puede representar todos los caracteres. Para evitar confusiones, lo llamaré utf8 más adelante .

Los conjuntos de caracteres admitidos por mysql incluyen utf8 y utf8mb4.

Hablemos primero de la codificación utf8mb4 . mb4 significa la mayoría de los bytes 4. Como puede ver en la imagen de arriba a la derecha Maxlen, admite un máximo de 4 bytes para representar caracteres. Se puede usar para representar casi todos los caracteres conocidos actualmente.

Hablemos de utf8 en el juego de caracteres mysql , que es el juego de caracteres predeterminado de la base de datos . Pero tenga en cuenta que este utf8 no es ese utf8 , lo llamamos el pequeño conjunto de caracteres utf8 . ¿Por qué dices esto? Porque se puede ver en Maxlen que admite hasta 3 bytes para representar caracteres. Según el método de nomenclatura de utf8mb4, debería llamarse con mayor precisión utf8mb3 .

utf8 es como una versión castrada de utf8mb4, que sólo admite algunos caracteres. Por ejemplo emoji, no admite emoticonos.

En los juegos de caracteres admitidos por mysql, la tercera columna, intercalación , se refiere a las reglas de comparación de juegos de caracteres .

Por ejemplo, "depurar" y "depurar" son la misma palabra, pero sus mayúsculas son diferentes, ¿deberían considerarse la misma palabra?

Aquí es cuando necesitas usar la intercalación.

Puede SHOW COLLATION WHERE Charset = 'utf8mb4';comprobar utf8mb4qué reglas de comparación son compatibles.

Si es collation = utf8mb4_general_ci, significa que bajo la premisa de utilizar el juego de caracteres utf8mb4, la comparación se realiza carácter por carácter ( general) y no distingue entre mayúsculas y minúsculas ( _ci,case insensitice).

En este caso, "depurar" y "Depurar" son la misma palabra.

Si se cambia a collation=utf8mb4_bin, significa comparar los tamaños de bits binarios uno por uno .

Entonces "depurar" y "Depurar" no son la misma palabra.

Entonces, ¿cuáles son las desventajas de utf8mb4 en comparación con utf8?

Sabemos que en la tabla de la base de datos, si el tipo de campo es char(2), se 2refiere al número de caracteres , lo que significa que no importa qué conjunto de caracteres de codificación se utilice en esta tabla , se pueden colocar 2 caracteres.

Y char tiene una longitud fija . Para que quepan 2 caracteres utf8mb4, char reservará 2*4(maxlen=4)= 81 byte de espacio de forma predeterminada.

Si es utf8mb3, 2 * 3 (maxlen=3) = 6se reservarán bytes de espacio de forma predeterminada. Es decir, en este caso, utf8mb4 utilizará más espacio que utf8mb3.

índice

¿Qué es un índice?

Un índice es una estructura de datos utilizada por los motores de almacenamiento para mejorar la velocidad de acceso a las tablas de la base de datos . Se puede comparar con el índice de un diccionario, lo que puede ayudarle a encontrar rápidamente los registros correspondientes.

Los índices generalmente se almacenan en archivos en el disco, que ocupan espacio físico.

¿Cuáles son las ventajas y desventajas de la indexación?

ventaja:

  • Acelerar las búsquedas de datos
  • Agregar índices a los campos utilizados para ordenar o agrupar puede acelerar la agrupación y la clasificación.
  • Acelerar las uniones entre tablas

defecto:

  • La indexación requiere espacio físico
  • Reducirá la eficiencia de las adiciones, eliminaciones y modificaciones de la tabla, porque cada vez que se agrega, elimina o modifica un registro de la tabla, el índice debe mantenerse dinámicamente, lo que resulta en un mayor tiempo de adición, eliminación y modificación .

Permítanme compartir con ustedes un repositorio de Github, que contiene más de 300 archivos PDF de libros de computadora clásicos compilados por Dabin, incluidos lenguaje C, C ++, Java, Python, interfaz de usuario, base de datos, sistema operativo, red de computadoras, estructura y algoritmo de datos, máquina. aprendizaje, programación de la vida , etc., puede marcarlo y buscar directamente en él la próxima vez que busque un libro. ¡El almacén se actualiza continuamente! dirección de github

¿Cuál es el papel del índice?

Los datos se almacenan en el disco. Al consultar los datos, si no hay un índice, todos los datos se cargarán en la memoria y se recuperarán en secuencia, y el disco se leerá más veces. Con el índice, no es necesario cargar todos los datos, porque la altura del árbol B + es generalmente de 2 a 4 capas, y solo se necesitan de 2 a 4 lecturas de disco como máximo, lo que mejora en gran medida la velocidad de consulta.

¿En qué circunstancias es necesario crear un índice?

  1. Campos utilizados frecuentemente en consultas.
  2. Los campos de indexación que se utilizan con frecuencia para las conexiones pueden acelerar la conexión.
  3. A menudo se requiere indexación para campos que deben ordenarse, porque el índice ya está ordenado, lo que puede acelerar las consultas de clasificación.

¿En qué circunstancias no se crea la indexación?

  1. whereLos campos no utilizados en las condiciones no son adecuados para la indexación.
  2. La tabla tiene menos registros. Por ejemplo, si solo hay unos pocos cientos de datos, no es necesario agregar un índice.
  3. Se requieren adiciones, eliminaciones y modificaciones frecuentes. Necesidad de evaluar si la indexación es adecuada
  4. Las columnas que participan en los cálculos de columnas no son adecuadas para la creación de índices
  5. Los campos que no son muy distinguibles no son adecuados para la indexación, como el género, que solo tiene tres valores: masculino/femenino/desconocido. Agregar un índice no mejorará la eficiencia de las consultas.

estructura de datos del índice

Las estructuras de datos del índice incluyen principalmente el árbol B+ y la tabla hash, y los índices correspondientes son el índice de árbol B+ y el índice hash, respectivamente. Los tipos de índice del motor InnoDB incluyen el índice de árbol B+ y el índice hash, y el tipo de índice predeterminado es el índice de árbol B+.

índice de árbol B+

El árbol B+ se implementa en base a punteros de acceso secuencial del árbol B y del nodo hoja, tiene el equilibrio del árbol B y mejora el rendimiento de la consulta de intervalo a través de punteros de acceso secuencial.

En el árbol B +, los nodos en el nodo keyestán organizados en orden ascendente de izquierda a derecha. Si los vecinos izquierdo y derecho de un puntero keyson la clave i y la clave i + 1 respectivamente , entonces el puntero apunta a todos los nodos del nodo. que keyson mayores o iguales a la clave i y menores o iguales a la clave i+ 1 .

[La transferencia de la imagen del enlace externo falló. El sitio de origen puede tener un mecanismo anti-leeching. Se recomienda guardar la imagen y cargarla directamente (img-sBews5yP-1691456619394) (http://img.topjavaer.cn/img/ B+índice de árbol 0.png) ]

Al realizar una operación de búsqueda, primero realice una búsqueda binaria en el nodo raíz para encontrar keyel puntero y luego busque recursivamente en el nodo señalado por el puntero. Hasta que se encuentre el nodo hoja, realice una búsqueda binaria en el nodo hoja para encontrar keyel elemento de datos correspondiente.

El tipo de índice más utilizado en la base de datos MySQL es BTREEel índice, que se implementa en función de la estructura de datos del árbol B+.

mysql> show index from blog\G;
*************************** 1. row ***************************
        Table: blog
   Non_unique: 0
     Key_name: PRIMARY
 Seq_in_index: 1
  Column_name: blog_id
    Collation: A
  Cardinality: 4
     Sub_part: NULL
       Packed: NULL
         Null:
   Index_type: BTREE
      Comment:
Index_comment:
      Visible: YES
   Expression: NULL

índice hash

El índice hash se implementa en función de la tabla hash. Para cada fila de datos, el motor de almacenamiento realizará un hash en la columna de índice para obtener el código hash, y el algoritmo hash debe intentar garantizar que el valor del código hash se calcule para diferentes valores de columna. ​Es diferente, el valor del código hash se usa como el valor clave de la tabla hash y el puntero a la fila de datos se usa como el valor del valor de la tabla hash. La complejidad temporal de buscar datos de esta manera es O (1), que generalmente se usa para búsquedas precisas.

¿Cuál es la diferencia entre el índice Hash y el índice de árbol B+?

  • Los índices hash no admiten la clasificación porque las tablas hash están desordenadas.
  • Los índices hash no admiten búsquedas de rango .
  • Los índices hash no admiten consultas difusas ni coincidencias de prefijos más a la izquierda para índices de varias columnas.
  • Debido a que habrá conflictos de hash en la tabla hash , el rendimiento del índice hash es inestable, mientras que el rendimiento del índice del árbol B + es relativamente estable. Cada consulta es desde el nodo raíz hasta el nodo hoja.

¿Por qué el árbol B+ es más adecuado para implementar el índice de la base de datos que el árbol B?

  • Dado que todos los datos del árbol B+ se almacenan en nodos de hoja, y todos los nodos de hoja son índices, es conveniente escanear la base de datos. Solo necesita escanear los nodos de hoja una vez. Sin embargo, el árbol B también almacena datos porque su nodos de rama, necesitamos encontrar datos específicos que deben escanearse en orden mediante un recorrido en orden, por lo que el árbol B + es más adecuado para consultas de intervalo. En la base de datos, las consultas basadas en rangos son muy frecuentes, por lo que el árbol B + es Generalmente se utiliza para índices de bases de datos.

  • Los nodos del árbol B+ solo almacenan el valor de la clave de índice y la dirección de la información específica existe en la dirección del nodo hoja. Esto permite almacenar más nodos en el índice basado en páginas. Reduzca más gastos de E/S.

  • La eficiencia de la consulta del árbol B + es más estable: cualquier búsqueda de palabras clave debe tomar una ruta desde el nodo raíz hasta el nodo hoja. La longitud de la ruta de todas las consultas de palabras clave es la misma, lo que da como resultado la misma eficiencia de consulta para cada dato.

¿Cuáles son las categorías de índices?

1. Índice de clave primaria : el único índice no vacío llamado primario, no se permiten valores nulos.

2. Índice único : el valor en la columna de índice debe ser único, pero se permiten valores nulos. La diferencia entre un índice único y un índice de clave principal es que el campo de índice único puede ser nulo y puede haber varios valores nulos, mientras que el campo de índice de clave principal no puede ser nulo. El propósito del índice único: identificar de forma única cada registro en la tabla de la base de datos, principalmente para evitar la inserción repetida de datos. La declaración SQL para crear un índice único es la siguiente:

ALTER TABLE table_name
ADD CONSTRAINT constraint_name UNIQUE KEY(column_1,column_2,...);

3. Índice combinado : un índice creado en una combinación de múltiples campos en la tabla se usará solo cuando los campos izquierdos de estos campos se usen en las condiciones de consulta. Cuando se usa un índice combinado, se debe seguir el principio del prefijo más a la izquierda.

4. Índice de texto completo : el índice de texto completo solo se puede utilizar en campos de tipo y .CHARVARCHARTEXT

5. Índice ordinario : El índice ordinario es el índice más básico, no tiene restricciones y el valor puede estar vacío.

¿Cuál es el principio de coincidencia más a la izquierda?

Si el índice más a la izquierda en el índice combinado se usa en la declaración SQL, entonces esta declaración SQL puede usar este índice combinado para realizar coincidencias. Cuando se encuentra una consulta de rango ( >,,, ), la coincidencia se detendrá y el índice no se utilizará para los campos posteriores <.betweenlike

Para (a,b,c)la indexación, si la condición de consulta es a/ab/abc, se utilizará el índice, pero si se utiliza bc, no se utilizará el índice.

Para (a,b,c,d)la indexación, la condición de consulta es a = 1 and b = 2 and c > 3 and d = 4, entonces los tres campos a, byc pueden usar el índice, pero d no puede usar el índice. Porque se encontró una consulta de rango.

Como se muestra en la figura siguiente, se crea el índice (a, b), a está ordenado globalmente en el árbol de índice, mientras que b está globalmente desordenado y localmente ordenado (cuando a es igual, se ordenará según b). Los índices no se pueden utilizar para ejecutar directamente b = 2esta condición de consulta.

[La transferencia de la imagen del enlace externo falló. El sitio de origen puede tener un mecanismo anti-leeching. Se recomienda guardar la imagen y cargarla directamente (img-e4IVib9u-1691456619394) (http://img.topjavaer.cn/img/ prefijo más a la izquierda.png)]

Cuando se determina el valor de a, se ordena b. Por a = 1ejemplo, el valor b es 1 y 2 es un estado ordenado. En ese a = 2momento, el valor de b es 1 y 4 también está en un estado ordenado. a = 1 and b = 2Los campos a y b pueden usar el índice al ejecutar . Durante la ejecución a > 1 and b = 2, el campo a puede usar el índice, pero el campo b no puede usar el índice. Debido a que el valor de a es un rango en este momento y no es fijo, el valor de b no está ordenado dentro de este rango, por lo que el índice no se puede usar para el campo b.

¿Qué es un índice agrupado?

InnoDB utiliza la clave principal de la tabla para construir un árbol de índice de clave principal y los nodos hoja almacenan los datos de registro de toda la tabla. El almacenamiento de nodos de hoja de índice agrupados es lógicamente continuo y utiliza una conexión de lista doblemente enlazada. Los nodos de hoja se ordenan en el orden de la clave primaria, por lo que la búsqueda de clasificación y la búsqueda de rango de la clave primaria son más rápidas.

Los nodos hoja del índice agrupado son los registros de fila de toda la tabla. InnoDB utiliza un índice agrupado como clave principal. Los índices agrupados son mucho más eficientes que las consultas de índices no agrupados.

Para InnoDB, el índice agrupado es generalmente el índice de clave principal en la tabla. Si la clave principal especificada no se muestra en la tabla, se NULLseleccionará el primer índice único de la tabla que no esté permitido. Si no hay una clave primaria ni un índice único adecuado, InnoDBse generará internamente una clave primaria oculta como un índice agrupado. La longitud de esta clave primaria oculta es de 6 bytes y su valor aumentará automáticamente a medida que se inserten los datos.

¿Qué es un índice de cobertura?

selectLas columnas de datos solo se pueden obtener del índice y no es necesario volver a la tabla para una segunda consulta, lo que significa que la columna de consulta debe estar cubierta por el índice utilizado. Para innodbel índice secundario de la tabla, si el índice puede cubrir la columna consultada, entonces se puede evitar una consulta secundaria del índice de clave principal.

No todos los tipos de índices pueden cubrir índices. Los índices de cobertura almacenan los valores de las columnas de índice, mientras que los índices hash y los índices de texto completo no almacenan los valores de las columnas de índice, por lo que MySQL usa índices de árbol b + como índices de cobertura.

Para consultas que utilizan índices de cobertura, si se usan delante de la consulta explain, la columna adicional de salida se mostrará como using index.

Por ejemplo, en user_likela tabla "Me gusta" del usuario, el índice combinado es y (user_id, blog_id)ninguno de los dos es .user_idblog_idnull

explain select blog_id from user_like where user_id = 13;

explainExtraLa columna del resultado Using indexes que la columna consultada está cubierta por el índice y la condición de filtrado donde cumple con el principio del prefijo más a la izquierda. Puede encontrar directamente los datos que cumplen las condiciones a través de la búsqueda de índice sin volver a la tabla para consultar. los datos.

explain select user_id from user_like where blog_id = 1;

explainExtraLa columna del resultado Using where; Using indexes que la columna consultada está cubierta por el índice. La condición de filtrado donde no cumple con el principio del prefijo más a la izquierda. Los datos calificados no se pueden encontrar mediante la búsqueda de índice, pero los datos calificados se pueden encontrar mediante el escaneo del índice. y no es necesario devolver la tabla para consultar los datos .

¿Principios de diseño de índices?

  • Para los campos que se utilizan a menudo como condiciones de consulta, se deben crear índices para mejorar la velocidad de la consulta.
  • Campos de índice que frecuentemente requieren operaciones de clasificación, agrupación y unión.
  • Cuanto mayor sea la discriminación de la columna del índice , mejor será el efecto del índice. Por ejemplo, si utiliza una columna con baja distinción, como el género, como índice, el efecto será muy pobre.
  • Evite indexar "campos grandes". Intente utilizar campos con pequeños volúmenes de datos como índices. Debido a que MySQLlos valores de los campos se mantienen juntos al mantener el índice, esto inevitablemente hará que el índice ocupe más espacio y también llevará más tiempo compararlo durante la clasificación.
  • Intente utilizar índices cortos . Al indexar cadenas más largas, debe especificar una longitud de prefijo más corta, porque los índices más pequeños implican menos E/S de disco y las velocidades de consulta son más rápidas.
  • Cuantos más índices, mejor. Cada índice requiere espacio físico adicional y el mantenimiento lleva tiempo.
  • No cree índices para campos que se agregan, eliminan o modifican con frecuencia. Suponiendo que un determinado campo se modifica con frecuencia, significa que el índice debe reconstruirse con frecuencia, lo que inevitablemente afectará el rendimiento de MySQL.
  • Utilice el principio del prefijo más a la izquierda .

¿Cuándo caducará un índice?

Situaciones que conducen al fallo del índice:

  • Para índices compuestos, si no se utiliza el campo más a la izquierda del índice compuesto, no se utilizará el índice.
  • Las consultas similares que comienzan con %, por ejemplo %abc, no pueden usar índices; las consultas similares que no comienzan con %, por ejemplo abc%, son equivalentes a consultas de rango y se usarán índices.
  • El tipo de columna en la condición de consulta es una cadena y no se utilizan comillas. Puede ocurrir una conversión implícita debido a diferentes tipos, lo que invalida el índice.
  • Al determinar si una columna de índice no es igual a un determinado valor
  • Realizar operaciones en columnas de índice.
  • Las condiciones de consulta que utilizan orconexiones también provocarán errores en el índice.

¿Qué es un índice de prefijo?

A veces es necesario crear un índice en una columna de caracteres muy larga, lo que hace que el índice sea extremadamente grande y lento. El uso de índices de prefijo evita este problema.

El índice de prefijo se refiere a indexar los primeros caracteres de un texto o cadena, de modo que la longitud del índice sea más corta y la velocidad de consulta sea más rápida.

La clave para crear un índice de prefijo es elegir un prefijo lo suficientemente largo para garantizar una alta selectividad del índice . Cuanto mayor sea la selectividad del índice, mayor será la eficiencia de la consulta, porque un índice altamente selectivo permite a MySQL filtrar más filas de datos durante la búsqueda.

Cómo crear un índice de prefijo:

// email列创建前缀索引
ALTER TABLE table_name ADD KEY(column_name(prefix_length));

empuje hacia abajo del índice

Consulte mi otro artículo: ¡ Pushdown de índice ilustrado!

¿Cuáles son los motores de almacenamiento comunes?

Los cuatro motores de almacenamiento comúnmente utilizados en MySQL son: MyISAM , InnoDB , MEMORY y ARCHIVE . El motor de almacenamiento predeterminado después de MySQL 5.5 es InnoDB.

Motor de almacenamiento InnoDB

InnoDB es el motor de almacenamiento transaccional predeterminado de MySQL , el más utilizado, y está construido en base a índices agrupados. InnoDB ha realizado muchas optimizaciones internamente, como la capacidad de crear automáticamente índices hash adaptativos en la memoria para acelerar las operaciones de lectura.

Ventajas : admite transacciones y capacidades de recuperación ante fallos; introduce bloqueos a nivel de fila y restricciones de clave externa.

Desventajas : El espacio de datos ocupado es relativamente grande.

Escenarios aplicables : se requiere soporte de transacciones y hay una alta frecuencia de lecturas y escrituras simultáneas.

Motor de almacenamiento MyISAM

Los datos se almacenan en un formato compacto. Para datos de solo lectura, o la tabla es relativamente pequeña y puede tolerar operaciones de reparación, se puede utilizar el motor MyISAM. MyISAM almacena tablas en dos archivos, el archivo de datos .MYDy el archivo de índice .MYI.

Ventajas : Acceso rápido.

Desventajas : MyISAM no admite transacciones ni bloqueos a nivel de fila, no admite recuperación segura después de una falla y no admite claves externas.

Escenarios aplicables : no existe ningún requisito de integridad de la transacción; todos los datos de la tabla serán de solo lectura.

Motor de almacenamiento de MEMORIA

El motor MEMORIA coloca todos los datos en la memoria y la velocidad de acceso es más rápida, pero una vez que el sistema falla, los datos se perderán.

El motor MEMORY utiliza índices hash de forma predeterminada, guardando el valor hash de la clave y el puntero a la fila de datos en el índice hash.

Ventajas : Acceso más rápido.

Desventajas :

  1. Los datos del índice hash no se almacenan en el orden de los valores del índice y no se pueden utilizar para ordenar.
  2. No se admiten búsquedas de coincidencias de índices parciales porque los índices hash utilizan todo el contenido de la columna de índice para calcular el valor hash.
  3. Solo se admite la comparación de igualdad, no se admite la consulta de rango.
  4. Cuando ocurre un conflicto de hash, el motor de almacenamiento necesita recorrer todos los punteros de fila en la lista vinculada y compararlos fila por fila hasta encontrar una fila que cumpla con las condiciones.

motor de almacenamiento ARCHIVO

El motor de almacenamiento ARCHIVE es muy adecuado para almacenar grandes cantidades de datos independientes como registros históricos. ARCHIVE proporciona función de compresión y tiene una velocidad de inserción eficiente, pero este motor no admite índices, por lo que el rendimiento de las consultas es deficiente.

¿Cuál es la diferencia entre MyISAM e InnoDB?

  1. Diferencias en las estructuras de almacenamiento . Cada MyISAM se almacena como tres archivos en el disco. El nombre del archivo comienza con el nombre de la tabla y la extensión indica el tipo de archivo. Los archivos .frm almacenan definiciones de tablas. La extensión del archivo de datos es .MYD (MYData). La extensión del archivo de índice es .MYI (MYIndex). Todas las tablas InnoDB se almacenan en el mismo archivo de datos (o en varios archivos, o archivos de espacio de tabla independientes). El tamaño de la tabla InnoDB solo está limitado por el tamaño del archivo del sistema operativo, que generalmente es de 2 GB.
  2. La diferencia en el espacio de almacenamiento . MyISAM admite tres formatos de almacenamiento diferentes: tabla estática (predeterminado, pero tenga en cuenta que no puede haber espacios al final de los datos, se eliminarán), tabla dinámica y tabla comprimida. Una vez creada la tabla y importados los datos, no se realizarán operaciones de modificación. Puede utilizar tablas comprimidas para reducir en gran medida el uso de espacio en disco. InnoDB requiere más memoria y almacenamiento, y establecerá su propio grupo de búfer dedicado en la memoria principal para almacenar en caché datos e índices.
  3. Portabilidad, respaldo y recuperación . Los datos de MyISAM se almacenan en forma de archivos, por lo que es muy conveniente para la transferencia de datos entre plataformas. Puede realizar operaciones en una tabla individualmente durante la copia de seguridad y la recuperación. Para InnoDB, las soluciones factibles son copiar archivos de datos, hacer una copia de seguridad de binlog o usar mysqldump, lo cual es relativamente problemático cuando el volumen de datos alcanza docenas de gigabytes.
  4. Si se admite el bloqueo a nivel de fila . MyISAM solo admite bloqueos a nivel de tabla. Cuando los usuarios operan una tabla myisam, las declaraciones de selección, actualización, eliminación e inserción bloquearán automáticamente la tabla. Si la tabla bloqueada cumple con la condición de simultaneidad de inserción, se pueden insertar nuevos datos al final del tabla datos. InnoDB admite bloqueos a nivel de fila y bloqueos a nivel de tabla, y el valor predeterminado son bloqueos a nivel de fila. Los bloqueos de fila mejoran enormemente el rendimiento de las operaciones simultáneas de múltiples usuarios.
  5. Ya sea para admitir una recuperación segura después de transacciones y fallas . MyISAM no proporciona soporte para transacciones. InnoDB brinda soporte para transacciones y tiene capacidades de transacción, reversión y reparación de fallas.
  6. Ya sea para admitir claves externas . MyISAM no lo admite, pero InnoDB sí.
  7. Ya sea para admitir MVCC . MyISAM no lo admite, pero InnoDB sí. Para manejar transacciones de alta concurrencia, MVCC es más eficiente que el simple bloqueo.
  8. Si se admiten índices agrupados . MyISAM no admite índices agrupados, pero InnoDB admite índices agrupados.
  9. Índice de texto completo . MyISAM admite índices de texto completo de tipo FULLTEXT. InnoDB no admite el índice de texto completo de tipo FULLTEXT, pero innodb puede usar el complemento Sphinx para admitir el índice de texto completo y el efecto es mejor.
  10. Clave primaria de la tabla . MyISAM permite que existan tablas sin índices ni claves primarias. Los índices son las direcciones donde se guardan las filas. Para InnoDB, si no hay una clave principal o un conjunto de índice único no vacío, se generará automáticamente una clave primaria de 6 bytes (no visible para el usuario).
  11. El número de filas de la tabla . MyISAM guarda el número total de filas de la tabla, si select count(*) from table; el valor se sacará directamente. InnoDB no guarda el número total de filas en la tabla. Si usa select count(*) from table, atravesará toda la tabla, lo que consume mucho dinero. Sin embargo, después de agregar la condición donde, MyISAM e InnoDB manejan de la misma manera.

¿Qué bloqueos tiene MySQL?

Clasificados por granularidad de bloqueo , hay bloqueos a nivel de fila, bloqueos a nivel de tabla y bloqueos a nivel de página.

  1. Los bloqueos a nivel de fila son los bloqueos más granulares en MySQL. Indica que solo la fila actualmente operada está bloqueada. El bloqueo a nivel de fila puede reducir en gran medida los conflictos en las operaciones de la base de datos. Su granularidad de bloqueo es la más pequeña, pero la sobrecarga de bloqueo también es la mayor. Hay tres tipos principales de bloqueos a nivel de fila:
    • Bloqueo de registro, bloqueo de registro, es decir, bloquear solo un registro;
    • Gap Lock, bloqueo de espacios, bloquea un rango, pero no incluye el registro en sí;
    • Bloqueo de tecla siguiente: una combinación de bloqueo de registro + bloqueo de espacio, bloquea un rango y bloquea el registro en sí.
  2. El bloqueo a nivel de tabla es el bloqueo con mayor granularidad en MySQL, lo que significa bloquear toda la tabla de la operación actual. Es simple de implementar, consume menos recursos y es compatible con la mayoría de los motores MySQL. Los MyISAM e InnoDB más utilizados admiten el bloqueo a nivel de tabla.
  3. Los bloqueos a nivel de página son un tipo de bloqueo en MySQL cuya granularidad de bloqueo se encuentra entre bloqueos a nivel de fila y bloqueos a nivel de tabla. Los bloqueos a nivel de tabla son rápidos pero tienen muchos conflictos. Los bloqueos a nivel de fila tienen pocos conflictos pero son lentos. Por lo tanto, se adopta un bloqueo a nivel de página comprometido, bloqueando un grupo de registros adyacentes a la vez.

Clasificados por nivel de bloqueo , hay bloqueos compartidos, bloqueos exclusivos y bloqueos de intención.

  1. Los bloqueos compartidos, también conocidos como bloqueos de lectura, son bloqueos creados mediante operaciones de lectura. Otros usuarios pueden leer los datos simultáneamente, pero ninguna transacción puede modificarlos (adquirir un bloqueo exclusivo sobre los datos) hasta que se hayan liberado todos los bloqueos compartidos.
  2. Los bloqueos exclusivos también se denominan bloqueos de escritura y bloqueos exclusivos. Si la transacción T agrega un bloqueo exclusivo a los datos A, otras transacciones no pueden agregar ningún tipo de bloqueo a A. Las transacciones a las que se les otorgan bloqueos exclusivos pueden leer y modificar datos.
  3. Los bloqueos de intención son bloqueos a nivel de tabla diseñados principalmente para revelar el tipo de bloqueo que se solicitará para la siguiente fila de una transacción. Dos bloqueos de tabla en InnoDB:

Bloqueo compartido intencional (IS): indica que la transacción se está preparando para agregar un bloqueo compartido a la fila de datos, lo que significa que antes de agregar un bloqueo compartido a una fila de datos, primero se debe obtener el bloqueo IS de la tabla;

Bloqueo exclusivo de intención (IX): similar a lo anterior, indica que la transacción se está preparando para agregar un bloqueo exclusivo a la fila de datos, lo que indica que la transacción primero debe obtener el bloqueo IX de la tabla antes de agregar un bloqueo exclusivo a un dato. fila.

InnoDB agrega automáticamente los bloqueos de intención y no requieren la intervención del usuario.

Para INSERTAR, ACTUALIZAR y ELIMINAR, InnoDB agregará automáticamente bloqueos exclusivos a los datos involucrados; para declaraciones SELECT generales, InnoDB no agregará ningún bloqueo y las transacciones pueden agregar explícitamente bloqueos compartidos o bloqueos exclusivos a través de las siguientes declaraciones.

Bloqueo compartido:SELECT … LOCK IN SHARE MODE;

Bloqueo exclusivo:SELECT … FOR UPDATE;

¿Principio de implementación de MVCC?

MVCC( Multiversion concurrency control) es una forma de conservar múltiples versiones de los mismos datos, logrando así el control de la concurrencia. Al realizar una consulta, read viewlos datos de la versión correspondiente se encuentran a través de la cadena de versiones.

Función: mejorar el rendimiento de la concurrencia. Para escenarios de alta concurrencia, MVCC es menos costoso que los bloqueos a nivel de fila.

El principio de implementación de MVCC es el siguiente:

La implementación de MVCC se basa en la cadena de versiones, que se implementa a través de tres campos ocultos de la tabla.

  • DB_TRX_ID: ID de transacción actual, la secuencia temporal de la transacción se juzga por el tamaño de la identificación de la transacción.
  • DB_ROLL_PTR: El puntero de reversión apunta a la versión anterior del registro de fila actual. A través de este puntero, se conectan varias versiones de los datos para formar una undo logcadena de versiones.
  • DB_ROW_ID: Clave primaria. Si la tabla de datos no tiene una clave primaria, InnoDB generará automáticamente una clave primaria.

Cada registro de la tabla probablemente se vea así:

Cuando se utiliza una transacción para actualizar un registro de fila, se generará una cadena de versiones y el proceso de ejecución es el siguiente:

  1. Bloquear la fila con un candado exclusivo;
  2. Copie el valor original de la fila undo loga la versión anterior para revertirla;
  3. Modifique el valor de la fila actual, genere una nueva versión, actualice el ID de la transacción y haga que el puntero de reversión apunte al registro de la versión anterior, formando así una cadena de versiones.

Aquí hay un ejemplo para que todos lo entiendan.

1. Los datos iniciales son los siguientes DB_ROW_IDy la suma DB_ROLL_PTRestá vacía.

2. La transacción A modificó los datos de la fila y agelos cambió a 12. El efecto es el siguiente:

3. Posteriormente, la transacción B también modificó el registro de fila y agelo cambió a 8. El efecto es el siguiente:

4. En este momento, el registro de deshacer tiene dos líneas de registros y están conectados a través del puntero de reversión.

A continuación, comprenda el concepto de vista de lectura.

read viewPuede entenderse como tomar una "foto" para registrar el estado de los datos en cada momento. Al obtener datos en un momento t determinado, los datos se obtienen de la "foto" tomada en el momento t.

read viewInternamente se mantiene una lista de transacciones activas, que indica las read viewtransacciones que aún están activas en el momento de la generación. Esta lista vinculada contiene read viewtransacciones que no se confirmaron antes de la creación, pero no incluye read viewtransacciones que se confirmaron después de la creación.

Los diferentes niveles de aislamiento tienen diferentes tiempos para crear vistas de lectura.

  • lectura confirmada: cada vez que se ejecuta select, se creará una nueva read_view para garantizar que se puedan leer las modificaciones enviadas por otras transacciones.

  • Lectura repetible: dentro del alcance de una transacción, esta vista_lectura se actualiza durante la primera selección y no se actualizará nuevamente. Todas las selecciones posteriores reutilizan la vista_lectura anterior. Esto garantiza que el contenido leído dentro del alcance de la transacción sea el mismo cada vez y pueda leerse repetidamente.

Método de filtrado de registros de vista de lectura

Requisito previo : DATA_TRX_IDindica el ID de transacción más reciente de cada fila de datos; up_limit_idindica la transacción iniciada más tempranamente en la instantánea actual; low_limit_idindica la transacción iniciada más lenta en la instantánea actual, es decir, la última transacción.

  • Si DATA_TRX_ID< up_limit_id: significa que read viewla transacción que modificó la fila de datos se confirmó cuando se creó y la transacción actual puede leer el registro de esta versión.
  • Si DATA_TRX_ID> = low_limit_id: significa que la transacción de la versión actual del registro se read viewgeneró después de la creación y la transacción actual no puede acceder a las filas de datos de esta versión. En este momento, debe encontrar la versión anterior a través de la cadena de versiones y luego volver a juzgar la visibilidad de los registros de esta versión para la transacción actual.
  • si up_limit_id<= DATA_TRX_ID< low_limit_i:
    1. Debe encontrar si hay una transacción con el valor de ID en la lista de transacciones activas DATA_TRX_ID.
    2. Si existe, el registro no es visible porque la transacción en la lista de transacciones activas no está confirmada. En este momento, debe encontrar la versión anterior a través de la cadena de versiones y luego volver a juzgar la visibilidad de esta versión.
    3. Si no existe, significa que la transacción trx_id se ha confirmado y esta fila de registros es visible.

Resumen : InnoDB se implementa MVCCa través de una cadena de versiones. La cadena de versiones guarda registros de versiones históricas. Al juzgar si la versión actual de los datos es visible, si no es visible, busque la versión anterior de la cadena de versiones y continúe juzgando hasta que encuentra una versión visible.read viewread view

Lectura instantánea y lectura actual

Hay dos formas de leer registros de tablas.

  • Lectura de instantánea: lee la versión de la instantánea. El más común SELECTes la lectura de instantáneas. El control de concurrencia se realiza a través de mvcc sin bloqueo.

  • Lectura actual: Se lee la última versión. UPDATE、DELETE、INSERT、SELECT … LOCK IN SHARE MODE、SELECT … FOR UPDATEestá leyendo actualmente.

En el caso de la lectura de instantáneas, InnoDB mvccevita la lectura fantasma mediante mecanismos. El mecanismo mvccno puede evitar el fenómeno de lectura fantasma que ocurre en la situación de lectura actual. Debido a que la lectura actual lee los datos más recientes cada vez, si hay otras transacciones que insertan datos entre las dos consultas, se producirán lecturas fantasma.

Aquí hay un ejemplo para ilustrar:

1. En primer lugar, la tabla de usuarios tiene solo dos registros, de la siguiente manera:

2. La transacción ay la transacción b abren transacciones al mismo tiempo start transaction;

3. La transacción A inserta datos y luego los envía;

insert into user(user_name, user_password, user_mail, user_state) values('tyson', 'a', 'a', 0);

4. La transacción b ejecuta una actualización de toda la tabla;

update user set user_name = 'a';

5. Luego, la transacción b ejecuta la consulta y encuentra los datos insertados en la transacción a. (El lado izquierdo de la figura siguiente es la transacción by el lado derecho es la transacción a. Antes de que comenzara la transacción, solo había dos registros. Después de que la transacción a insertó un dato, la transacción b consultó tres datos)

[La transferencia de la imagen del enlace externo falló. El sitio de origen puede tener un mecanismo anti-leeching. Se recomienda guardar la imagen y cargarla directamente (img-c6OMxuPD-1691456619399) (http://img.topjavaer.cn/img/ lectura fantasma 1.png)]

Lo anterior es el fenómeno de lectura fantasma que ocurre en la lectura actual.

Entonces, ¿cómo evita MySQL las lecturas fantasmas?

  • En el caso de lecturas instantáneas, MySQL mvccevita las lecturas fantasma.
  • En la situación de lectura actual, MySQL next-keyevita las lecturas fantasmas (implementadas agregando bloqueos de fila y bloqueos de espacio).

La siguiente clave consta de dos partes: bloqueo de fila y bloqueo de espacio. Los bloqueos de fila son bloqueos que se agregan a los índices y los bloqueos de espacios se agregan entre índices.

SerializableEl nivel de aislamiento también puede evitar lecturas fantasmas, que bloquearán toda la tabla. La concurrencia es extremadamente baja y generalmente no se utiliza.

Cerraduras compartidas y cerraduras exclusivas

El bloqueo de lectura de SELECT se divide principalmente en dos métodos: bloqueo compartido y bloqueo exclusivo.

select * from table where id<6 lock in share mode;--共享锁
select * from table where id<6 for update;--排他锁

La principal diferencia entre estos dos métodos es que LOCK IN SHARE MODE es fácil provocar un punto muerto cuando varias transacciones actualizan el mismo formulario al mismo tiempo.

El requisito previo para solicitar un bloqueo exclusivo es que ningún subproceso utilice un bloqueo exclusivo o un bloqueo compartido para los datos de fila en el conjunto de resultados; de lo contrario, la aplicación se bloqueará. Al realizar una operación de transacción, MySQL agregará un bloqueo exclusivo a cada fila de datos en el conjunto de resultados de la consulta. Los cambios o eliminaciones de estos datos por parte de otros subprocesos se bloquearán (solo operaciones de lectura) hasta que la transacción de la declaración sea ejecutada por el declaración o commitdeclaración rollback... hasta el final.

SELECT... FOR UPDATEPrecauciones de uso:

  1. for updateSe aplica solo a innodb y debe estar dentro del alcance de la transacción para que surta efecto.
  2. Consulta basada en la clave principal. Si la condición de consulta es likeo no igual a, el campo de clave principal generará un bloqueo de tabla .
  3. Las consultas basadas en campos no indexados generarán bloqueos de tabla .

registro bin/rehacer registro/deshacer registro

Los registros de MySQL incluyen principalmente registros de consultas, registros de consultas lentas, registros de transacciones, registros de errores, registros binarios, etc. Los más importantes son bin log(registro binario), redo log(registro de rehacer) y undo log(registro de reversión).

registro de contenedor

bin logEs un archivo a nivel de base de datos MySQL. Registra todas las operaciones que modifican la base de datos MySQL. No registra declaraciones de selección y presentación. Se utiliza principalmente para restaurar la base de datos y sincronizar la base de datos.

rehacer registro

redo logEs el nivel del motor innodb y se utiliza para registrar el registro de transacciones del motor de almacenamiento innodb. Se registrará independientemente de si la transacción se envía para recuperación de datos. Cuando ocurre una falla en la base de datos, el motor de almacenamiento innoDB utilizará redo logla recuperación hasta el momento anterior a la falla para garantizar la integridad de los datos. Establezca el parámetro innodb_flush_log_at_tx_commiten 1, luego la confirmación se redo logescribirá en el disco de forma sincrónica.

deshacer registro

Además de grabar redo log, cuando se modifican datos undo log, también se grabarán undo logpara las operaciones de recuperación de datos y conserva el contenido antes de la modificación del registro. undo logSe puede lograr la reversión de transacciones y se puede implementar MVCC basándose en el retroceso aundo log una versión específica de los datos .

¿Cuál es la diferencia entre el registro bin y el registro de rehacer?

  1. bin logSe registrarán todos los registros, incluidos los registros de motores de almacenamiento como InnoDB y MyISAM; redo logsolo se registrarán los registros de transacciones propios de innoDB.
  2. bin logSolo se escribe en el disco antes de que se confirme la transacción, y una transacción solo se escribe una vez; mientras la transacción esté en progreso, habrá redo logescrituras continuas en el disco.
  3. bin logEs un registro lógico, que registra la lógica original de la declaración SQL; redo loges un registro físico, que registra qué modificaciones se realizaron en una determinada página de datos.

¿Cuéntame sobre la arquitectura MySQL?

MySQL se divide principalmente en capa de servidor y capa de motor de almacenamiento:

  • Capa de servidor : Incluye principalmente conectores, cachés de consultas, analizadores, optimizadores, ejecutores, etc. Todas las funciones del motor de almacenamiento cruzado se implementan en esta capa, como procedimientos almacenados, activadores, vistas, funciones, etc., y también hay una capa general. El módulo de registro módulo de registro de binglog.
  • Motor de almacenamiento : Principalmente responsable del almacenamiento y lectura de datos. La capa del servidor se comunica con el motor de almacenamiento a través de la API.

Componentes básicos de la capa de servidor

  • Conector: cuando el cliente se conecta a MySQL, la capa del servidor realizará la autenticación de identidad y la verificación de permisos.
  • Caché de consulta: al ejecutar una declaración de consulta, primero se consultará el caché para verificar si se ha ejecutado el SQL. Si el SQL está en caché, se devolverá directamente al cliente. Si no hay resultados, se realizarán operaciones posteriores. .
  • Analizador: si no se accede al caché, la declaración SQL pasará por el analizador, que se divide principalmente en dos pasos, análisis léxico y análisis de sintaxis. Primero, vea qué hace la declaración SQL y luego verifique si la sintaxis del SQL la afirmación es correcta.
  • Optimizador: el optimizador optimiza la consulta, incluida la reescritura de la consulta, determinando el orden de lectura y escritura de la tabla, seleccionando los índices apropiados, etc., y generando un plan de ejecución.
  • Ejecutor: Primero, antes de la ejecución, verificará si el usuario tiene permiso. Si no hay permiso, se devolverá un mensaje de error. Si hay permiso, se llamará a la interfaz del motor de acuerdo con el plan de ejecución y se obtendrá el resultado. regresó.

Subbase de datos y subtabla

Cuando el volumen de datos de una sola tabla alcanza los 1000 W o 100 G, es posible que la optimización del índice, la adición de bases de datos esclavas, etc. no tengan un efecto significativo en la mejora del rendimiento de la base de datos. En este momento, es necesario considerar dividirla. El propósito de la segmentación es reducir la carga de la base de datos y acortar el tiempo de consulta.

La segmentación de datos se puede dividir en dos formas: partición vertical y partición horizontal.

división vertical

La partición vertical de la base de datos se basa en el negocio. Por ejemplo, en escenarios de compras, las tablas que involucran productos, pedidos y usuarios en la base de datos se pueden dividir en una base de datos respectivamente para mejorar el rendimiento al reducir el tamaño de una sola base de datos. De manera similar, el caso de dividir tablas es dividir una tabla grande en una subtabla según las funciones comerciales, como la información básica del producto y la descripción del producto. La información básica del producto generalmente se muestra en la lista de productos y la descripción del producto está en La página de detalles del producto. El producto puede ser La información básica y la descripción del producto se dividen en dos tablas.

[La transferencia de la imagen del enlace externo falló. El sitio de origen puede tener un mecanismo anti-leeching. Se recomienda guardar la imagen y cargarla directamente (img-cSyfknhd-1691456619400) (http://img.topjavaer.cn/img/ división vertical.png)]

Ventajas : los registros de fila se vuelven más pequeños, las páginas de datos pueden almacenar más registros y los tiempos de E/S se reducen durante las consultas.

Desventajas :

  • La clave principal es redundante y es necesario gestionar las columnas redundantes;
  • Hará que la conexión de la tabla se una a la operación JOIN, que se puede realizar en el servidor empresarial para reducir la presión de la base de datos;
  • Todavía existe el problema del volumen excesivo de datos en una sola tabla.

división horizontal

La partición horizontal consiste en dividir datos de acuerdo con ciertas reglas, como el tiempo o los valores de secuencia de identificación. Por ejemplo, divida diferentes bases de datos según el año. Cada base de datos tiene la misma estructura, pero los datos se dividen para mejorar el rendimiento.

[La transferencia de la imagen del enlace externo falló. El sitio de origen puede tener un mecanismo anti-leeching. Se recomienda guardar la imagen y cargarla directamente (img-Q97IJSOD-1691456619401) (http://img.topjavaer.cn/img/ división horizontal.png)]

Ventajas : Se reduce la cantidad de datos en una sola base de datos (tabla) y se mejora el rendimiento; las tablas divididas tienen la misma estructura y menos cambios de programa.

Desventajas :

  • La coherencia de las transacciones de fragmentación es difícil de resolver
  • Mal rendimiento entre nodos joiny lógica compleja
  • Es necesario migrar la fragmentación de datos al expandirse

¿Qué es una tabla de particiones?

Particionar es dividir los datos de una tabla en N bloques. Una tabla particionada es una tabla lógica independiente, pero la capa subyacente está compuesta de múltiples subtablas físicas.

Cuando los datos de la condición de consulta se distribuyen en una determinada partición, el motor de consulta solo consultará una determinada partición en lugar de atravesar toda la tabla. A nivel de gestión, si necesita eliminar datos en una determinada partición, solo necesita eliminar la partición correspondiente.

Las particiones generalmente se colocan en una sola máquina y la partición por rango de tiempo se usa más comúnmente para facilitar el archivado. Es solo que la subbase de datos y la tabla deben implementarse en código, y la partición se implementa internamente en MySQL. La subbase de datos, la subtabla y la partición no entran en conflicto y se pueden usar juntas.

Tipo de tabla de particiones

La partición de rango se basa en la partición de rango. Por ejemplo, dividir por rango de tiempo

CREATE TABLE test_range_partition(
       id INT auto_increment,
       createdate DATETIME,
       primary key (id,createdate)
   ) 
   PARTITION BY RANGE (TO_DAYS(createdate) ) (
      PARTITION p201801 VALUES LESS THAN ( TO_DAYS('20180201') ),
      PARTITION p201802 VALUES LESS THAN ( TO_DAYS('20180301') ),
      PARTITION p201803 VALUES LESS THAN ( TO_DAYS('20180401') ),
      PARTITION p201804 VALUES LESS THAN ( TO_DAYS('20180501') ),
      PARTITION p201805 VALUES LESS THAN ( TO_DAYS('20180601') ),
      PARTITION p201806 VALUES LESS THAN ( TO_DAYS('20180701') ),
      PARTITION p201807 VALUES LESS THAN ( TO_DAYS('20180801') ),
      PARTITION p201808 VALUES LESS THAN ( TO_DAYS('20180901') ),
      PARTITION p201809 VALUES LESS THAN ( TO_DAYS('20181001') ),
      PARTITION p201810 VALUES LESS THAN ( TO_DAYS('20181101') ),
      PARTITION p201811 VALUES LESS THAN ( TO_DAYS('20181201') ),
      PARTITION p201812 VALUES LESS THAN ( TO_DAYS('20190101') )
   );

/var/lib/mysql/data/Se pueden encontrar los archivos de datos correspondientes. Cada tabla de partición tiene un archivo de tabla llamado usando # para separarlo :

   -rw-r----- 1 MySQL MySQL    65 Mar 14 21:47 db.opt
   -rw-r----- 1 MySQL MySQL  8598 Mar 14 21:50 test_range_partition.frm
   -rw-r----- 1 MySQL MySQL 98304 Mar 14 21:50 test_range_partition#P#p201801.ibd
   -rw-r----- 1 MySQL MySQL 98304 Mar 14 21:50 test_range_partition#P#p201802.ibd
   -rw-r----- 1 MySQL MySQL 98304 Mar 14 21:50 test_range_partition#P#p201803.ibd
...

partición de lista

La partición de listas es similar a la partición de rangos. La principal diferencia es que la lista es una colección de listas de valores enumerados y el rango es una colección de valores de intervalo continuo. Para la partición de listas, se debe conocer el campo de partición. Si el campo insertado no está en el valor de enumeración durante la partición, no se insertará.

create table test_list_partiotion
   (
       id int auto_increment,
       data_type tinyint,
       primary key(id,data_type)
   )partition by list(data_type)
   (
       partition p0 values in (0,1,2,3,4,5,6),
       partition p1 values in (7,8,9,10,11,12),
       partition p2 values in (13,14,15,16,17)
   );

partición hash

Los datos se pueden distribuir uniformemente en particiones predefinidas.

create table test_hash_partiotion
   (
       id int auto_increment,
       create_date datetime,
       primary key(id,create_date)
   )partition by hash(year(create_date)) partitions 10;

¿Problema de partición?

  1. Abrir y bloquear todas las tablas subyacentes puede resultar costoso. Cuando una consulta accede a una tabla particionada, MySQL necesita abrir y bloquear todas las tablas subyacentes. Esta operación ocurre antes del filtrado de particiones, por lo que el filtrado de particiones no se puede utilizar para reducir esta sobrecarga, lo que afectará la velocidad de la consulta. Esta sobrecarga se puede reducir mediante operaciones por lotes, como la inserción y LOAD DATA INFILEeliminación por lotes de varias filas de datos a la vez.
  2. El mantenimiento de las particiones puede resultar costoso. Por ejemplo, para reorganizar una partición, primero se creará una partición temporal, luego se copiarán los datos en ella y finalmente se eliminará la partición original.
  3. Todas las particiones deben utilizar el mismo motor de almacenamiento.

¿Proceso de ejecución de la declaración de consulta?

El proceso de ejecución de la declaración de consulta es el siguiente: verificación de permisos, caché de consultas, analizador, optimizador, verificación de permisos, ejecutor y motor.

Por ejemplo, la declaración de consulta es la siguiente:

select * from user where id > 1 and name = '大彬';
  1. Primero verifique los permisos, si no hay permiso, se devolverá un error;
  2. Antes de MySQL 8.0, se consultaba el caché. Si el caché llega, se devolverá directamente. De lo contrario, se ejecutará el siguiente paso.
  3. Análisis léxico y análisis sintáctico. Extraiga el nombre de la tabla y las condiciones de la consulta, y verifique si hay errores de sintaxis;
  4. Dos planes de ejecución, verifique primero id > 1o name = '大彬'el optimizador elige el que tiene la mejor eficiencia de ejecución en función de su propio algoritmo de optimización;
  5. Verificar permisos. Si tiene permiso, llame a la interfaz del motor de base de datos y devuelva los resultados de ejecución del motor.

¿Actualizar el proceso de ejecución de la declaración?

El proceso de ejecución de la declaración de actualización es el siguiente: analizador, verificación de permisos, ejecutor, motor, redo log( prepareestado), binlog( redo logestado commit)

Por ejemplo, la declaración de actualización es la siguiente:

update user set name = '大彬' where id = 1;
  1. Primero consulte el registro con ID 1. Si hay un caché, se utilizará el caché.
  2. Obtenga los resultados de la consulta, actualice el nombre a Dabin y luego llame a la interfaz del motor para escribir los datos actualizados. El motor innodb guarda los datos en la memoria y los registra al mismo tiempo. En este momento, ingresa redo logal redo logestado prepare.
  3. El ejecutor registra la notificación después de recibirla binlog, luego llama a la interfaz del motor y la envía redo logcomo commitestado.
  4. actualización completada.

¿Por qué no lo envía directamente después de la grabación redo loge ingresa prepareel estado primero?

Supongamos que escribe redo logy envía directamente primero, y luego escribe . Después de binlogescribir redo log, la máquina se cuelga y binlogel registro no se escribe. Luego, después de que la máquina se reinicia, la máquina restaurará los datos, pero los datos no se registran redo logen este momento . Se realizará una copia de seguridad de la máquina binlogmás tarde, este dato se perderá y, al mismo tiempo, la sincronización maestro-esclavo también perderá este dato.

¿Cuál es la diferencia entre existir y en?

existsSe utiliza para filtrar registros de apariencia. existsSe recorrerá la tabla externa y cada fila de la tabla de consulta externa se sustituirá en la consulta interna para su evaluación. Cuando existsla declaración condicional puede devolver filas de registros, la condición es verdadera y se devuelve el registro actual de la tabla. Por otro lado, si existsla declaración condicional contenida no puede devolver filas de registros y la condición es falsa, se descartará el registro actual en la tabla.

select a.* from A awhere exists(select 1 from B b where a.id=b.id)

inEl método consiste en encontrar primero las siguientes declaraciones y colocarlas en la tabla temporal, luego recorrer la tabla temporal y sustituir cada fila de la tabla temporal en la consulta externa para buscar.

select * from Awhere id in(select id from B)

Cuando la tabla de la subconsulta es relativamente grande , su uso existspuede reducir efectivamente el número total de bucles para mejorar la velocidad; cuando la tabla de la consulta externa es relativamente grande , su uso inpuede reducir efectivamente el recorrido del bucle de la tabla de consulta externa a mejorar la velocidad.

¿Cuál es la diferencia entre int(10) y char(10) en MySQL?

El 10 en int(10) representa la longitud de los datos mostrados, mientras que char(10) representa la longitud de los datos almacenados.

¿Cuál es la diferencia entre truncar, eliminar y soltar?

Mismo punto:

  1. truncatey sin wherecláusulas delete, y dropeliminará los datos de la tabla.

  2. dropSon truncatetodas DDLdeclaraciones (lenguaje de definición de datos) que se enviarán automáticamente después de la ejecución.

diferencia:

  1. truncar y eliminar solo eliminar datos sin eliminar la estructura de la tabla; la declaración drop eliminará las restricciones, activadores e índices de los que depende la estructura de la tabla;
  2. En términos generales, velocidad de ejecución: soltar > truncar > eliminar.

¿Cuál es la diferencia entre tener y dónde?

  • Los objetos sobre los que actúan son diferentes: wherela cláusula actúa sobre tablas y vistas, y havingsobre grupos.
  • whereFiltrar antes de agrupar datos y havingfiltrar después de agrupar datos.

¿Por qué necesitamos realizar una sincronización maestro-esclavo?

  1. La separación de lectura y escritura permite que la base de datos admita una mayor concurrencia.
  2. Los datos en tiempo real se generan en el servidor maestro y se analizan en el servidor esclavo, mejorando así el rendimiento del servidor maestro.
  3. Copia de seguridad de datos para garantizar la seguridad de los datos.

¿Qué es la sincronización maestro-esclavo de MySQL?

La sincronización maestro-esclavo permite copiar datos de un servidor de base de datos a otros servidores. Al copiar datos, un servidor actúa como servidor maestro ( ) mastery los servidores restantes actúan como servidores esclavos ( slave).

Debido a que la replicación se realiza de forma asincrónica, no es necesario que el servidor esclavo esté conectado al servidor maestro todo el tiempo. El servidor esclavo puede incluso conectarse al servidor maestro de manera intermitente mediante acceso telefónico. A través del archivo de configuración, puede especificar copiar todas las bases de datos, una determinada base de datos o incluso una determinada tabla en una determinada base de datos.

¿Qué son el bloqueo optimista y el bloqueo pesimista?

El control de concurrencia en la base de datos garantiza que el aislamiento y la unidad de las transacciones y la unidad de la base de datos no se destruyan cuando varias transacciones acceden a los mismos datos en la base de datos al mismo tiempo. El bloqueo optimista y el bloqueo pesimista son los principales medios técnicos utilizados para el control de concurrencia.

  • Bloqueo pesimista: suponiendo que se producirá un conflicto de concurrencia, los datos operados se bloquearán y el bloqueo no se liberará hasta que se confirme la transacción y otras transacciones pueden modificarlo. Método de implementación: utilice el mecanismo de bloqueo en la base de datos.
  • Bloqueo optimista: suponga que no se producirán conflictos de concurrencia y solo verifique si los datos se han modificado al enviar la operación. Agregue un campo a la tabla y verifique si es igual al valor original versionantes de enviar la modificación. Si es igual, significa que los datos no han sido modificados y se pueden actualizar. De lo contrario, los datos son datos sucios y no pueden ser actualizado. Método de implementación: el bloqueo optimista generalmente se implementa mediante un mecanismo o algoritmo de número de versión.versionversionCAS

¿Has usado alguna vez la lista de procesos?

show processlistO show full processlistpuede verificar si MySQL está actualmente bajo presión, ejecutándose SQLy si se SQLestá ejecutando lentamente. Los parámetros de retorno son los siguientes:

  1. id : ID del hilo, se puede utilizar para kill idcerrar un hilo.
  2. base de datos : nombre de la base de datos
  3. usuario : usuario de la base de datos
  4. host : IP de la instancia de la base de datos
  5. comando : el comando actualmente ejecutado , como Sleep, Queryetc.Connect
  6. tiempo : tiempo de consumo, unidad de segundos
  7. estado : estado de ejecución, que incluye principalmente los siguientes estados:
    • Suspender, el hilo está esperando que el cliente envíe una nueva solicitud.
    • Bloqueado, el hilo está esperando el bloqueo.
    • Envío de datos, procesamiento SELECTde registros de consulta y envío de resultados al cliente al mismo tiempo.
    • Matar, ejecutar killla declaración, mata el hilo especificado
    • Conectar, un nodo esclavo está conectado al nodo maestro
    • Salir, el hilo está saliendo.
    • Ordenar por grupo, GROUP BYordenar por
    • Clasificar por orden, ORDER BYclasificar por
  8. informaciónSQL : declaración en ejecución

¿El límite de consultas MySQL 1000,10 es tan rápido como el límite 10?

Dos métodos de consulta. Corresponde limit offset, sizea dos formas de y limit size.

De hecho limit size, es equivalente a limit 0, size. Es decir, empezar a tomar datos de tamaño desde 0.

En otras palabras, la diferencia entre los dos métodos es si el desplazamiento es 0.

Primero veamos la lógica de ejecución interna de limit sql.

MySQL se divide internamente en capa de servidor y capa de motor de almacenamiento . En circunstancias normales, el motor de almacenamiento utiliza innodb.

Hay muchos módulos en la capa del servidor, lo que hay que prestar atención es que el ejecutor es el componente que se utiliza para manejar el motor de almacenamiento.

El ejecutor puede recuperar filas de datos llamando a la interfaz proporcionada por el motor de almacenamiento. Cuando los datos cumplan completamente con los requisitos (como cumplir con otras condiciones donde), se colocarán en el conjunto de resultados y finalmente se devolverán al cliente llamando a mysql .

Tome el proceso de ejecución límite del índice de clave principal como ejemplo:

Ejecución select * from xxx order by id limit 0, 10;, la selección va seguida de un asterisco , lo que significa que se requiere toda la información del campo de los datos de la fila.

La capa del servidor llamará a la interfaz de innodb, obtendrá los datos de fila completos del 0 al 10 en el índice de clave principal en innodb , los devolverá a la capa del servidor, los colocará en el conjunto de resultados de la capa del servidor y los devolverá. al cliente.

Haga que el desplazamiento sea mayor, por ejemplo, la ejecución es:select * from xxx order by id limit 500000, 10;

La capa del servidor llamará a la interfaz de innodb. Dado que este tiempo offset = 500000, los datos de fila completos de 0 a (500000 + 10) se obtendrán del índice de clave principal en innodb. Después de regresar a la capa del servidor , será se descarta uno por uno de acuerdo con el valor de desplazamiento, y finalmente solo los elementos del último tamaño , es decir, 10 datos, se dejan en el conjunto de resultados de la capa del servidor y se devuelven al cliente.

Se puede ver que cuando el desplazamiento no es 0, la capa del servidor obtendrá muchos datos inútiles de la capa del motor , y obtener estos datos inútiles lleva mucho tiempo.

Por lo tanto, el límite 1000,10 en la consulta MySQL será más lento que el límite 10. La razón es que el límite 1000,10 eliminará 1000+10 datos y descartará los primeros 1000, lo que lleva más tiempo.

¿Cuántos datos se pueden almacenar en un árbol B+ con una altura de 3?

El motor de almacenamiento InnoDB tiene su propia unidad de almacenamiento mínima: página.

El comando para consultar el tamaño de la página InnoDB es el siguiente:

mysql> show global status like 'innodb_page_size';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| Innodb_page_size | 16384 |
+------------------+-------+

Se puede ver que el tamaño de página predeterminado de innodb es 16384B = 16384/1024 = 16kb.

En MySQL, lo más apropiado es establecer el tamaño de un nodo en el árbol B+ en una página o en un múltiplo de una página. Porque si el tamaño de un nodo es <1 página, al leer este nodo, en realidad se lee una página, lo que provoca un desperdicio de recursos.

Los nodos que no son hoja en el árbol B+ almacenan claves + punteros ; los nodos hoja almacenan filas de datos .

Para los nodos hoja, si el tamaño de datos de una fila es 1k, entonces se pueden almacenar 16 datos en una página.

Para los nodos que no son hoja, si la clave usa bigint, es de 8 bytes y el puntero es de 6 bytes en MySQL. Son 14 bytes en total, por lo que 16k puede almacenar 16 * 1024/14 = 1170 punteros de índice.

Entonces se puede calcular que para un árbol B + con una altura de 2, el nodo raíz almacena el nodo puntero de índice, luego tiene 1170 nodos hoja para almacenar datos, y cada nodo hoja puede almacenar 16 datos, un total de 1170 x 16 = 18720 datos. Para un árbol B+ con una altura de 3, puede almacenar 1170 x 1170 x 16 = 21902400 datos ( más de 20 millones de datos ), es decir, para más de 20 millones de datos, solo necesitamos un B+. árbol con una altura de 3.

Por lo tanto, en InnoDB, cuando la altura del árbol B + es generalmente de 3 niveles, puede satisfacer las necesidades de almacenamiento de datos de decenas de millones.

¿Cómo optimizar la paginación profunda?

O tome el SQL anterior como vacío:select * from xxx order by id limit 500000, 10;

Método uno :

Como se puede ver en el análisis anterior, cuando el desplazamiento es muy grande, la capa del servidor obtendrá una gran cantidad de datos inútiles de la capa del motor. Cuando la selección va seguida del número *, es necesario copiar la información completa de la fila. En comparación con copiar los datos completos , copiar solo uno o dos campos de columna en los datos de la fila requiere más tiempo.

Debido a que los datos de compensación anteriores al final no son necesarios, no es necesario copiar los campos completos, por lo que la declaración SQL se puede modificar para:

select * from xxx  where id >=(select id from xxx order by id limit 500000, 1) order by id limit 10;

Primero ejecute la subconsulta select id from xxx by id limit 500000, 1. Esta operación en realidad obtendrá 500000+1fragmentos de datos del índice de clave principal en innodb. Luego, la capa del servidor descartará los primeros 500.000 fragmentos y solo conservará el ID del último fragmento de datos.

Pero la diferencia es que en el proceso de regreso a la capa del servidor, solo se copiará la columna de identificación en la fila de datos, pero no todas las columnas de la fila de datos. Cuando la cantidad de datos es grande, el consumo de tiempo de esta parte es bastante obvio..

Después de obtener la identificación anterior, suponiendo que esta identificación es exactamente igual a 500000, entonces el sql se convierte

select * from xxx  where id >=500000 order by id limit 10;

De esta manera, innodb vuelve a revisar el índice de clave principal , localiza rápidamente los datos de la fila con id = 500000 a través del árbol B +, la complejidad del tiempo es lg (n) y luego recupera 10 datos hacia atrás.

Método dos:

Ordene todos los datos según la clave principal de ID , luego recupérelos en lotes y use el ID máximo del lote actual como siguiente condición de filtrado para la consulta.

select * from xxx where id > start_id order by id limit 10;

A través del índice de clave principal, se localiza la posición de start_id cada vez y luego se atraviesan 10 datos, de esta manera, no importa cuán grandes sean los datos, el rendimiento de la consulta es relativamente estable.

¿Cómo optimizar la consulta de una tabla grande si es lenta?

Una determinada tabla tiene casi 10 millones de datos y la consulta es lenta, ¿cómo optimizarla?

Cuando la cantidad de registros en una sola tabla MySQL es demasiado grande, el rendimiento de la base de datos disminuirá significativamente. Algunas medidas de optimización comunes son las siguientes:

  • Correctamente indexado. Cree un índice en el campo apropiado, por ejemplo, cree un índice en las columnas involucradas en los comandos WHERE y ORDER BY. Puede usar EXPLAIN para verificar si se usa un índice o un escaneo completo de la tabla.
  • Optimización de índices, optimización de SQL. Principio de coincidencia más a la izquierda, etc., consulte: https://topjavaer.cn/database/mysql.html#%E4%BB%80%E4%B9%88%E6%98%AF%E8%A6%86%E7 %9B %96%E7%B4%A2%E5%BC%95
  • Crea particiones. Establezca particiones horizontales para campos clave, como campos de tiempo. Si las condiciones de consulta a menudo se consultan a través de rangos de tiempo, esto puede mejorar mucho el rendimiento.
  • Aprovecha el almacenamiento en caché. Utilice Redis y otros datos de puntos de acceso de caché para mejorar la eficiencia de las consultas
  • Limitar el alcance de los datos. Por ejemplo: cuando los usuarios consultan información histórica, pueden controlarla dentro del rango de tiempo de un mes.
  • Separación de lectura y escritura. Esquema clásico de división de bases de datos, la base de datos maestra es responsable de escribir y la base de datos esclava es responsable de leer
  • La optimización se lleva a cabo a través de subbases de datos y subtablas, incluyendo principalmente división vertical y división horizontal.
  • Correctamente indexado. Indexar en los campos apropiados, como la indexación en las columnas involucradas en los comandos WHERE y ORDERBY
  1. Heterogeneidad de datos para es
  2. Separación de datos fríos y calientes. Los datos que no se usaban comúnmente hace unos meses se colocan en el almacenamiento en frío y los datos más recientes se colocan en el almacenamiento en caliente.
  3. Actualice el tipo de base de datos a una base de datos compatible con MySQL (OceanBase, tidb)

¿Qué tamaño tiene una sola tabla en MySQL para dividir bases de datos y tablas?

Actualmente existen dos teorías principales:

  1. Si el volumen de datos de una sola tabla MySQL supera los 20 millones de filas, el rendimiento se reducirá significativamente. Considere dividir bases de datos y tablas.
  2. El "Manual de desarrollo de Java" de Alibaba establece que la fragmentación de bases de datos y tablas solo se recomienda cuando el número de filas en una sola tabla excede los 5 millones o la capacidad de una sola tabla excede los 2 GB.

De hecho, este valor no tiene nada que ver con el número real de registros, sino con la configuración de MySQL y el hardware de la máquina. Porque MySQL carga el índice de la tabla en la memoria para mejorar el rendimiento. Cuando el tamaño del búfer de InnoDB es suficiente, se puede cargar completamente en la memoria y no habrá problemas con las consultas. Sin embargo, cuando una base de datos de una sola tabla alcanza un límite superior de cierta magnitud, la memoria no puede almacenar su índice, lo que provoca que consultas SQL posteriores generen E/S de disco, lo que resulta en una degradación del rendimiento. Por supuesto, esto también está relacionado con el diseño de la estructura de tabla específica, y el problema final es la limitación de memoria.

Por lo tanto, para las subbases de datos y tablas, es necesario combinar las necesidades reales y no sobrediseñar. No utilizamos el diseño de subbases de datos y subtablas al comienzo del proyecto, sino que a medida que el negocio crece y se imposible seguir optimizando, considerar subbases de datos Mejorar el rendimiento del sistema con subtablas. A este respecto, el "Manual de desarrollo de Java" de Alibaba agrega: Si no se espera que el volumen de datos alcance este nivel en tres años, no divida la base de datos en tablas al crear la tabla.

En cuanto al tamaño de una única tabla MySQL que se va a dividir en bases de datos y tablas, debe evaluarse en función de los recursos de la máquina.

Hablemos de las diferencias entre contar(1), contar(*) y contar(nombre de campo)

Bueno, primero hablemos de la diferencia entre recuento (1) y recuento (nombre de campo).

La principal diferencia entre los dos es

  1. count(1) contará todos los registros de la tabla, incluidos los registros con campos nulos.
  2. count(nombre del campo) contará el número de veces que este campo aparece en la tabla, ignorando el caso en el que el campo sea nulo. Es decir, los registros con campos nulos no se cuentan.

A continuación, echemos un vistazo a las diferencias entre los tres.

En términos de efecto de ejecución:

  • count (*) incluye todas las columnas, lo que equivale al número de filas. Al calcular los resultados, los valores de columna NULL no se ignorarán.
  • count(1) incluye ignorar todas las columnas y usar 1 para representar la línea de código. Al contar los resultados, los valores de columna que sean NULL no se ignorarán.
  • count (nombre del campo) solo incluye el nombre de la columna. Al contar los resultados, se ignorará el recuento de valores de columnas vacías (el vacío aquí no significa solo una cadena vacía o 0, sino que significa nulo). Es decir, un cierto valor de campo es NULL, no se recopilarán estadísticas .

En términos de eficiencia de ejecución:

  • El nombre de la columna es la clave principal y el recuento (nombre del campo) será más rápido que el recuento (1).
  • El nombre de la columna no es la clave principal, el recuento (1) será más rápido que el recuento (nombre de la columna)
  • Si la tabla tiene varias columnas y no tiene una clave principal, count(1) funciona mejor que count(*)
  • Si hay una clave primaria, la eficiencia de ejecución del recuento de selección (clave primaria) es óptima
  • Si la tabla tiene solo un campo, seleccionar recuento (*) es óptimo.

¿Cuál es la diferencia entre DATETIME y TIMESTAMP en MySQL?

Bueno, ambos TIMESTAMPy DATETIMEse pueden utilizar para almacenar tiempo. Tienen las siguientes diferencias principales:

1. Rango de representación

  • FECHA HORA: 1000-01-01 00:00:00.000000 a 9999-12-31 23:59:59.999999
  • MARCA DE TIEMPO: '1970-01-01 00:00:01.000000' UTC y '2038-01-09 03:14:07.999999' UTC

TIMESTAMPEl intervalo de tiempo admitido es relativamente DATATIMEpequeño y puede superarse fácilmente.

2. Ocupación del espacio

  • MARCA DE TIEMPO: 4 bytes
  • DATETIME: Antes de MySQL 5.6.4, ocupaba 8 bytes y en versiones posteriores ocupaba 5 bytes.

3. ¿El tiempo de depósito se convertirá automáticamente?

TIMESTAMPDe forma predeterminada, al insertar o actualizar datos, TIMESTAMPla columna se completará/actualizará automáticamente con la hora actual ( CURRENT_TIMESTAMP). DATETIMENo realizará ninguna conversión ni detectará la zona horaria. Almacenará los datos que le proporciones.

4. TIMESTAMPSe ve más afectado por la zona horaria, la versión MYSQL y el MODO SQL del servidor. Debido a TIMESTAMPque almacena marcas de tiempo, las horas obtenidas en diferentes zonas horarias son inconsistentes.

5. Si se almacena NULL, los valores reales almacenados de los dos son diferentes.

  • MARCA DE TIEMPO: La hora actual ahora() se almacenará automáticamente.
  • DATETIME: La hora actual no se almacenará automáticamente, pero el valor NULL se almacenará directamente.

Dime por qué no se recomienda utilizar claves foráneas.

Una clave externa es una restricción, la existencia de esta restricción asegurará que la relación entre datos entre tablas sea siempre completa. La existencia de claves foráneas no está exenta de ventajas.

Las claves externas pueden garantizar la integridad y coherencia de los datos, y las operaciones en cascada son convenientes. Además, el uso de claves externas puede confiar la evaluación de la integridad de los datos a la base de datos, reduciendo la cantidad de código en el programa.

Aunque las claves externas pueden garantizar la integridad de los datos, pueden provocar muchos defectos en el sistema.

1. Problemas de concurrencia. Cuando se utilizan claves externas, cada vez que modifica los datos, debe verificar los datos en otra tabla y adquirir bloqueos adicionales. Si se encuentra en un escenario de transacciones de alta concurrencia y mucho tráfico, es más probable que el uso de claves externas provoque un punto muerto.

2. Problemas de escalabilidad. Por ejemplo, al MySQLmigrar a una nueva base de datos Oracle, las claves externas dependen de las características de la propia base de datos, por lo que la migración puede resultar inconveniente.

3. No es propicio para subbases de datos y subtablas. En el caso de división y fragmentación horizontal, las claves externas no pueden surtir efecto. Poner el mantenimiento de las relaciones entre los datos en la aplicación puede ahorrar muchos problemas para futuras subdivisiones de bases de datos y tablas.

¿Cuáles son los beneficios de utilizar claves primarias de incremento automático?

La clave primaria de aumento automático permite que el índice de clave primaria mantenga el orden de inserción incremental tanto como sea posible, evitando divisiones de página, por lo que el índice es más compacto y la eficiencia al realizar consultas.

¿Por qué no se puede reciclar el valor cada vez mayor de InnoDB?

Principalmente para mejorar la eficiencia y el paralelismo de la inserción de datos.

Supongamos que hay dos transacciones ejecutadas en paralelo. Al solicitar un valor de incremento automático, para evitar que las dos transacciones soliciten el mismo ID de incremento automático, los bloqueos deben bloquearse y luego aplicarse secuencialmente.

Supongamos que la transacción A aplica para id = 2 y la transacción B aplica para id = 3. Entonces el valor de incremento automático de la tabla t es 4 en este momento y la ejecución continúa a partir de entonces.

La transacción B se confirmó correctamente, pero la transacción A tuvo un conflicto de clave única.

Si a la transacción A se le permite revertir la identificación de incremento automático, es decir, cambiar el valor de incremento automático actual de la tabla t a 2, entonces habrá una situación como esta: ya hay una fila con id=3 en la tabla, y el valor de identificación de incremento automático actual es 2.

A continuación, se aplicarán otras transacciones que continúen ejecutándose para id = 2 y luego para id = 3. En este momento, aparecerá un error de instrucción de inserción "conflicto de clave principal".

Para resolver este conflicto de clave principal, existen dos métodos:

  • Antes de cada solicitud de una identificación, primero determine si la identificación ya existe en la tabla. Si existe, omita esta identificación. Sin embargo, este método es costoso. Porque originalmente solicitar una identificación era una operación rápida, pero ahora tenemos que ir al árbol de índice de clave principal para determinar si la identificación existe.
  • Para ampliar el rango de bloqueo de la ID de incremento automático, debe esperar hasta que se complete y envíe una transacción antes de que la siguiente transacción pueda solicitar la ID de incremento automático. El problema con este método es que la granularidad del bloqueo es demasiado grande y la capacidad de concurrencia del sistema se reduce considerablemente.

Se puede ver que ambos métodos causarán problemas de rendimiento.

Por lo tanto, InnoDB abandonó el diseño de "permitir que se revierta la ID de incremento automático", y la ID de incremento automático no se revertirá si la declaración no se ejecuta.

¿Dónde se almacena la clave primaria de incremento automático?

Diferentes motores tienen diferentes estrategias de almacenamiento para valores incrementados automáticamente:

  • El valor de incremento automático del motor MyISAM se guarda en el archivo de datos.
  • Antes de MySQL 8.0, el valor de incremento automático del motor InnoDB se almacenaba en la memoria. Este valor en la memoria se perderá después de que MySQL se reinicie. Cuando la tabla se abre por primera vez después de reiniciar, encontrará el valor máximo del autoincremento max (id) y luego agregará 1 al valor máximo como self. -incrementar el valor de la tabla; MySQL8 La versión .0 registrará los cambios que aumentan automáticamente en el registro de rehacer y confiará en el registro de rehacer para recuperarse al reiniciar.

¿La clave primaria de incremento automático tiene que ser continua?

No necesariamente, existen varias situaciones que pueden hacer que la clave primaria de incremento automático sea discontinua.

1. El conflicto de clave única hace que la clave primaria de incremento automático sea discontinua. Cuando insertamos datos en una tabla InnoDB con una clave primaria de incremento automático, si se viola la restricción única del índice único definido en la tabla, la inserción de datos fallará. En este momento, el valor clave de la clave primaria de incremento automático de la tabla se revertirá en 1. La próxima vez que inserte datos nuevamente, ya no podrá usar los valores clave generados por el último desplazamiento debido a que no se pudieron insertar datos. Debe usar los valores clave generados por el nuevo desplazamiento.

2. La reversión de transacciones hace que la clave primaria de incremento automático sea discontinua. Cuando insertamos datos en una tabla InnoDB con una clave primaria de incremento automático, si la transacción se habilita explícitamente y luego finalmente se revierte por algún motivo, el valor de incremento automático de la tabla también se revertirá en este momento. y los siguientes nuevos datos insertados no podrán usar el valor de incremento automático rodado, pero deberán volver a solicitar un nuevo valor de incremento automático.

3. La inserción por lotes da como resultado valores de autoincremento discontinuos. MySQL tiene una estrategia para la aplicación por lotes de ID que aumentan automáticamente:

  • Durante la ejecución de la declaración, la primera vez que solicite una ID de incremento automático, se asignará 1 ID de incremento automático.
  • Después de que se agote 1, si solicita por segunda vez, se asignarán 2 ID de aumento automático.
  • Después de que se agoten 2, si solicita por tercera vez, se asignarán 4 ID de aumento automático.
  • Y así sucesivamente, cada aplicación es el doble de la anterior (puede que no se utilice toda la última aplicación)

Si la siguiente transacción vuelve a insertar datos, se aplicarán en función del autoincremento posterior a la aplicación de la transacción anterior. En este momento, el valor que aumenta automáticamente es discontinuo.

4. Si el tamaño del paso de incremento automático no es 1, también hará que la clave primaria de incremento automático sea discontinua.

¿Cómo sincronizar datos de MySQL con la caché de Redis?

Referencia: https://cloud.tencent.com/developer/article/1805755

Hay dos opciones:

1. Redis se actualiza automáticamente y sincrónicamente a través de MySQL, implementado mediante el activador MySQL + función UDF .

El proceso es aproximadamente el siguiente:

  1. Establecer un disparador en MySQL para que los datos sean operados y monitorear la operación
  2. Cuando el cliente escribe datos en MySQL, se activará el disparador. Después del disparador, se llama a la función UDF de MySQL.
  3. La función UDF puede escribir datos en Redis para lograr el efecto de sincronización

2. Analice el binlog de MySQL para sincronizar los datos de la base de datos con Redis. Esto se puede lograr a través del canal. Canal es un proyecto de código abierto de Alibaba que proporciona suscripción y consumo de datos incrementales basados ​​en el análisis de registros incrementales de la base de datos.

El principio del canal es el siguiente:

  1. Canal simula el protocolo de interacción del esclavo mysql, se disfraza de esclavo mysql y envía el protocolo de volcado al maestro mysql.
  2. mysql master recibe la solicitud de volcado y comienza a enviar el registro binario al canal
  3. canal analiza el objeto de registro binario (originalmente un flujo de bytes) y escribe los datos en Redis de forma sincrónica.

¿Por qué el manual de Java de Alibaba prohíbe el uso de procedimientos almacenados?

Primero veamos qué es un procedimiento almacenado.

Un procedimiento almacenado es un conjunto de declaraciones SQL que se utilizan para completar funciones específicas en un sistema de base de datos grande. Se almacena en la base de datos y es válido permanentemente después de compilarse una vez. El usuario especifica el nombre del procedimiento almacenado y proporciona los parámetros. (si el procedimiento almacenado tiene parámetros) para ejecutarlo.

Los procedimientos almacenados tienen principalmente las siguientes desventajas.

  1. Los procedimientos almacenados son difíciles de depurar . El desarrollo de procedimientos almacenados siempre ha carecido de un entorno IDE eficaz. El SQL en sí suele ser muy largo y la depuración requiere dividir las oraciones y ejecutarlas de forma independiente, lo cual es muy problemático.
  2. Mala portabilidad . Es difícil trasplantar procedimientos almacenados. Generalmente, los sistemas comerciales inevitablemente utilizarán las características y sintaxis únicas de la base de datos. Al reemplazar la base de datos, es necesario reescribir esta parte del código, lo cual es costoso.
  3. Dificultades en la gestión . El directorio de procedimientos almacenados es plano, no una estructura de árbol como un sistema de archivos, es fácil de manejar cuando hay pocos scripts, pero una vez que hay demasiados, el directorio caerá en el caos.
  4. Los procedimientos almacenados solo se optimizan una vez . A veces, a medida que aumenta la cantidad de datos o cambia la estructura de datos, el plan de ejecución seleccionado por el procedimiento almacenado original puede no ser óptimo, por lo que se requiere intervención manual o recompilación en este momento.

Finalmente, me gustaría compartir con ustedes un repositorio de Github, que contiene más de 300 archivos PDF de libros informáticos clásicos compilados por Dabin, incluidos lenguaje C, C ++, Java, Python, front-end, bases de datos, sistemas operativos, redes informáticas y estructuras de datos. y algoritmo, y aprendizaje automático., Programming Life , etc. Puedes destacarlo y buscar directamente en él la próxima vez que busques libros. ¡El almacén se actualiza continuamente! dirección de github

Si no puede acceder a Github, puede acceder a la dirección de la nube de código. dirección de nube de código

Supongo que te gusta

Origin blog.csdn.net/Tyson0314/article/details/132159169
Recomendado
Clasificación