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

ALTER TABLE en MySQL:¿Amigo o enemigo?

La declaración ALTER TABLE es una de las declaraciones más utilizadas en el mundo de MySQL:la declaración le permite agregar, eliminar o modificar columnas en una tabla. En esta publicación de blog, intentaremos profundizar en qué es, qué hace y cuándo debe usarse.

¿Qué es ALTER TABLE y qué hace?

Como ya se mencionó anteriormente, la declaración ALTER TABLE permite a los DBA y desarrolladores agregar, eliminar o modificar columnas en una tabla. En pocas palabras, ALTER TABLE cambia la estructura de una tabla:le permite agregar, eliminar columnas, agregar o eliminar índices, cambiar el nombre de las columnas o cambiar su tipo.

¿Cuándo y cómo uso ALTER TABLE?

Para usar ALTER TABLE, generalmente necesita los privilegios ALTER, CREATE e INSERT. Para cambiar el nombre de una tabla, los privilegios requeridos son ALTER y DROP para la tabla anterior, luego los privilegios CREATE, ALTER e INSERT para la nueva tabla que se creará. Para asignar los privilegios necesarios a un determinado usuario, puede utilizar la siguiente consulta:

GRANT ALTER, CREATE, INSERT ON database.* TO 'demo_user';

Reemplace base de datos con el nombre de su base de datos, el comodín con el nombre de la tabla si desea que los privilegios solo se apliquen a ciertas tablas (el comodín hace que el privilegio se aplique en todas las tablas) y demo_user con el nombre de tu usuario Si desea que los privilegios se utilicen en todas las bases de datos y todas las tablas dentro de ellas, simplemente reemplace la base de datos con un comodín:

GRANT ALTER, CREATE, INSERT ON *.* TO 'demo_user';

Para hacer uso de la declaración ALTER TABLE, ejecute una consulta que cambie la estructura de una tabla - ALTER TABLE se usa para agregar, eliminar o modificar columnas en una tabla:la consulta también puede ser usado para agregar índices a las columnas. Estos son algunos ejemplos básicos de las consultas más utilizadas:

ALTER TABLE demo_table ADD column_name VARCHAR(255) NOT NULL DEFAULT ‘’; T

su consulta agregaría una columna column_name a una tabla demo_table. Agregue FIRST al final de la consulta para que la columna sea la primera columna de la tabla.

ALTER TABLE demo_table ADD column_2 VARCHAR(255) NOT NULL DEFAULT ‘’ AFTER column_1; T

su consulta agregaría una columna column_2 después de la columna column_1 en una tabla demo_table.

ALTER TABLE demo_table ADD COLUMN column_2 INT GENERATED ALWAYS AS (column_1 + 1) STORED; 

Esta consulta agregaría una columna generada a la tabla.

ALTER TABLE demo_table DROP COLUMN demo_column; 

Esta consulta colocaría la columna demo_column en una tabla demo_table.

ALTER TABLE demo_table ADD INDEX demo_index(demo_column); 

Esta consulta agregaría un índice llamado demo_index (se pueden elegir nombres) en una columna llamada demo_column en una tabla llamada demo_table.

ALTER TABLE demo_table ADD INDEX (demo_column), ADD UNIQUE (demo_unique); 

Esta consulta agregaría un índice en una columna demo_column y un índice único en la columna demo_unique.

ALTER TABLE demo_table MODIFY column_name VARCHAR(255) CHARACTER SET utf8mb4; 

Esta consulta cambiaría el conjunto de caracteres predeterminado de una columna específica.

ALTER TABLE demo_table CONVERT TO CHARACTER SET charset_name; 

Esta consulta cambiaría el conjunto de caracteres predeterminado de la tabla y todas las columnas de caracteres (CHAR, VARCHAR y TEXT).

ALTER TABLE demo_table PARTITION BY HASH(demo_column) PARTITIONS 8; 

Esta consulta dividiría la columna demo_column en 8 particiones por hash.

ALTER TABLE demo_table TABLESPACE tablespace_1 STORAGE DISK; 

Esta consulta convertiría la tabla demo_table en almacenamiento basado en disco.

Si está agregando índices, tenga en cuenta que puede agregar diferentes tipos de índices (por ejemplo, un índice BTREE o un índice FULLTEXT), también puede agregar un índice que cubra solo una cierta cantidad de caracteres en una columna con una consulta como esta:

ALTER TABLE demo_table ADD INDEX demo_index(column_name(10));

La consulta anterior agregaría un índice llamado demo_index en los primeros 10 caracteres de la columna llamada column_name en una tabla llamada demo_table.

Los índices en MySQL son una bestia compleja y realmente merecen un tema propio, por lo que no entraremos en detalles aquí, pero si desea obtener más información, nuestra publicación anterior sobre los índices de MySQL debería proporcionar algunos más información.

¿Cómo funciona ALTER TABLE?

ALTER TABLE en MySQL tiene sus propias sutilezas. A partir de la versión más actual de MySQL, es decir, MySQL 8.0. Hay 3 algoritmos que afectan el rendimiento de ALTER TABLE para tales alteraciones. Estos son:

  • COPIAR

    • Las operaciones se realizan en una copia de la tabla original y los datos de la tabla se copian de la tabla original a la nueva tabla fila por fila. En la mayoría de los casos, este algoritmo puede ser muy costoso en términos de uso de recursos, especialmente para tablas grandes y grandes. Cuando se elige o selecciona este algoritmo, no se permiten todos los DML simultáneos, por lo que cualquier consulta posterior que haga referencia a la tabla afectada tendrá que esperar o ponerse en cola en la lista de procesos. Lo más probable es que su base de datos se atasque si las conexiones están al máximo.

  • INSTALAR

    • Las operaciones evitan copiar los datos de la tabla, pero pueden reconstruir la tabla en su lugar. Un bloqueo exclusivo de metadatos en la tabla puede tomarse brevemente durante las fases de preparación y ejecución de la operación. Por lo general, se admite DML concurrente.

  • INSTANTE

    • Las operaciones solo modifican metadatos en el diccionario de datos. No se realizan bloqueos de metadatos exclusivos en la tabla durante la preparación y la ejecución, y los datos de la tabla no se ven afectados, lo que hace que las operaciones sean instantáneas. Se permite DML concurrente. (Introducido en MySQL 8.0.12)

El proceso ALTER TABLE de MySQL puede no ser un problema con tablas más pequeñas, pero si su conjunto de datos es más grande, puede tener problemas:muchas personas han experimentado consultas ALTER TABLE que han tardado horas, días o incluso semanas. completar. En la mayoría de los casos, eso sucede debido al proceso de alteración de tablas de MySQL descrito anteriormente. Sin embargo, hay una manera de reducir al menos ligeramente el tiempo que tarda en completarse la consulta:

  1. Cree una nueva tabla como su tabla de origen con la estructura deseada ejecutando
    CREATE TABLE demo_table_new LIKE demo_table;
    luego ajustando su estructura. En este caso, demo_table es la tabla de origen y demo_table_new es la nueva tabla.
  2. Insertar datos en la nueva tabla.
  3. Cambie el nombre de la tabla anterior a demo_table_old (ajuste el nombre según sus necesidades).
  4. Cambie el nombre de la nueva tabla al nombre anterior de la tabla anterior.
  5. Finalmente, copie las filas de la tabla anterior a la tabla nueva y, si es necesario, cree índices.

Aunque los pasos anteriores funcionan bien. Sin embargo, en escenarios de casos del mundo real, los administradores de bases de datos o los desarrolladores se inclinan por usar pt-online-schema-change de Percona o usar gh-ost de Github. Puede echar un vistazo a nuestra publicación anterior Principales herramientas de código abierto para migraciones de MySQL y MariaDB, que ofrece una descripción general de estas herramientas de cambio de esquema.

De todos modos, lo que hemos descrito anteriormente se conoce con frecuencia como el enfoque de "instantánea":en esencia, crea una nueva tabla con la estructura deseada, luego realiza un cambio de nombre y suelta para intercambiar las dos tablas. . También hay otra forma:también puede intercambiar servidores y ejecutar ALTER TABLE en servidores que no están en producción. Para MyISAM, puede DESHABILITAR CLAVES, cargar datos y luego HABILITAR CLAVES.

ALTER TABLE Problemas

Si está utilizando la sentencia ALTER TABLE para crear índices (también puede usar la sentencia CREATE INDEX), se recomienda crear índices después de insertar los datos porque es una forma bastante conocida de acelerar procesamiento no solo en MySQL, sino también en otros sistemas de gestión de bases de datos, como Oracle. Sin embargo, en general, tenga en cuenta que se espera que la mayoría de las operaciones ALTER TABLE causen algunos problemas (interrupción del servicio) a MySQL.

También hay otra forma de acelerar todo el proceso, aunque es un poco más avanzada:si puede convencer a MySQL de que solo modifique el archivo .frm de la tabla (los archivos .frm describen la definición de la mesa) y deja la mesa en paz, el proceso será más rápido:

  1. Cree una tabla vacía con el mismo diseño que la tabla anterior sin modificarla.
  2. Cierre todas las tablas en uso y evite que se abran todas las tablas nuevas ejecutando 
    FLUSH TABLES WITH READ LOCK.
  3. Intercambie los archivos .frm.
  4. Libere el bloqueo de lectura ejecutando UNLOCK TABLES.

También tenga en cuenta que si desea modificar una columna y la sintaxis parece correcta pero aún recibe un error, podría ser el momento de buscar una sintaxis diferente. Por ejemplo:

ALTER TABLE demo_table ADD long VARCHAR(255); 

Una consulta como esta generaría un error porque largo es una palabra reservada. Para evitar tal error, escape la palabra con acentos graves:

ALTER TABLE demo_table ADD `long` VARCHAR(255);

También vale la pena señalar que los nombres de las columnas solo se pueden escapar usando acentos graves y no con comillas simples o dobles. Por ejemplo, una consulta como esa también generaría un error:

ALTER TABLE demo_table CHANGE COLUMN ‘demo_column’ ‘demo_column_2’ VARCHAR(255);

Resumen

MySQL usa la declaración ALTER TABLE para agregar, eliminar o modificar columnas en una tabla. Para que la declaración se ejecute con éxito, debe tener los privilegios ALTER, CREATE e INSERT para la tabla. La declaración también tiene algunas sutilezas únicas en sí misma:su rendimiento puede verse afectado cuando se ejecuta en tablas muy grandes debido a la forma en que funciona, pero mientras sepa cómo funciona la declaración y qué hace, debería estar bien.