Tabla de contenidos
Este capítulo describe la sintaxis para los comandos SQL soportados en MySQL.
ALTER {DATABASE | SCHEMA} [db_name
]alter_specification
[,alter_specification
] ...alter_specification
: [DEFAULT] CHARACTER SETcharset_name
| [DEFAULT] COLLATEcollation_name
ALTER DATABASE
le permite cambiar las
características globales de una base de datos. Estas
características se almacenan en el fichero
db.opt
en el directorio de la base de
datos. Para usar ALTER DATABASE
, necesita el
permiso ALTER
en la base de datos.
La cláusula CHARACTER SET
cambia el conjunto
de carácteres por defecto de la base de datos. La cláusula
COLLATE
cambia la colación por defecto de la
base de datos. El conjunto de carácteres y la colación se
discuten en Capítulo 10, Soporte de conjuntos de caracteres.
En MySQL 5.0, el nombre de base de datos puede omitirse. El
comando se aplica a la base de datos por defecto. ALTER
SCHEMA
puede usarse desde MySQL 5.0.2.
ALTER [IGNORE] TABLEtbl_name
alter_specification
[,alter_specification
] ...alter_specification
: ADD [COLUMN]column_definition
[FIRST | AFTERcol_name
] | ADD [COLUMN] (column_definition
,...) | ADD INDEX [index_name
] [index_type
] (index_col_name
,...) | ADD [CONSTRAINT [symbol
]] PRIMARY KEY [index_type
] (index_col_name
,...) | ADD [CONSTRAINT [symbol
]] UNIQUE [index_name
] [index_type
] (index_col_name
,...) | ADD [FULLTEXT|SPATIAL] [index_name
] (index_col_name
,...) | ADD [CONSTRAINT [symbol
]] FOREIGN KEY [index_name
] (index_col_name
,...) [reference_definition
] | ALTER [COLUMN]col_name
{SET DEFAULTliteral
| DROP DEFAULT} | CHANGE [COLUMN]old_col_name
column_definition
[FIRST|AFTERcol_name
] | MODIFY [COLUMN]column_definition
[FIRST | AFTERcol_name
] | DROP [COLUMN]col_name
| DROP PRIMARY KEY | DROP INDEXindex_name
| DROP FOREIGN KEYfk_symbol
| DISABLE KEYS | ENABLE KEYS | RENAME [TO]new_tbl_name
| ORDER BYcol_name
| CONVERT TO CHARACTER SETcharset_name
[COLLATEcollation_name
] | [DEFAULT] CHARACTER SETcharset_name
[COLLATEcollation_name
] | DISCARD TABLESPACE | IMPORT TABLESPACE |table_options
ALTER TABLE
le permite cambiar la estructura
de una tabla existente. Por ejemplo, puede añadir o borrar
columnas, crear o destruir índices, cambiar el tipo de columnas
existentes, o renombrar columnas o la misma tabla. Puede cambiar
el comentario de la tabla y su tipo.
La sintaxis para varias de las alteraciones permitidas es
similar a cláusulas del comando CREATE
TABLE
. Esto incluye modificaciones
table_options
, para opciones tales
como ENGINE
,
AUTO_INCREMENT
, y
AVG_ROW_LENGTH
. Consulte
Sección 13.1.5, “Sintaxis de CREATE TABLE
”.
Algunas operaciones pueden producir advertencias si se intentan
en una tabla para que el motor de almacenamiento no soporte la
operación. Estas advertencias pueden mostrarse con
SHOW WARNINGS
. Consulte
Sección 13.5.4.22, “Sintaxis de SHOW WARNINGS
”.
Si usa ALTER TABLE
para cambiar la
especificación de una columna pero DESCRIBE
indica que la
columna no ha cambiado, es posible que MySQL haya ignorado las
modificaciones por alguna de las razones descritas en
Sección 13.1.5.1, “Cambios tácitos en la especificación de columnas”. Por ejemplo, si intenta
cambiar una columna tbl_name
VARCHAR
a
CHAR
, MySQL usa VARCHAR
si
la tabla contiene otras columnas de longitud variable.
ALTER TABLE
funciona creando una copia
temporal de la tabla original. La alteración se realiza en la
copia, luego la tabla original se borra y se renombra la nueva.
Mientras se ejecuta ALTER TABLE
la tabla
original es legible por otros clientes. Las actualizaciones y
escrituras en la tabla se esperan hasta que la nueva tabla esté
lista, luego se redirigen automáticamente a la nueva tabla sin
ninguna actualización fallida.
Tenga en cuenta que si usa cualquier otra opción en
ALTER TABLE
distinta a
RENAME
, MySQL siempre crea una tabla
temporal, incluso si los datos no necesitan ser copiados (tales
como cuando cambia el nombre de una columna). Planeamos arreglar
esto en el futuro, pero debido a que ALTER
TABLE
no es un comando que se use frecuentemente, no
es un tema demasiado urgente. Para tablas
MyISAM
puede incrementar la velocidad de la
operación de recrear índices (que es la parte más lenta del
proceso de alteración) mediante la variable de sistema
myisam_sort_buffer_size
poniendo un valor
alto.
Para usar ALTER TABLE
, necesita
ALTER
, INSERT
, y
permisos CREATE
para la tabla.
IGNORE
es una extensión MySQL a SQL
estándar. Controla cómo funciona ALTER
TABLE
si hay duplicados en las claves primarias en
la nueva tabla o si ocuren advertencias cuando está activo
el modo STRICT
. Si no se especifica
IGNORE
la copia se aborta y no se ejecuta
si hay errores de clave duplicada. Si se especifica
IGNORE
, entonces para duplicados con
clave única, sólo se usa el primer registro. El resto de
registros conflicitivos se borran. Los valores erróneos se
truncan al valor más cercano aceptable.
Puede ejecutar múltiples cláusulas ADD
,
ALTER
, DROP
, y
CHANGE
en un único comando
ALTER TABLE
. Esta es una extensión
MySQL al estándar SQL, que permite sólo una de cada
cláusula por comando ALTER TABLE
. Por
ejemplo, para borrar múltiples columnas en un único
comando:
mysql> ALTER TABLE t2 DROP COLUMN c, DROP COLUMN d;
CHANGE
, col_name
DROP
, y
col_name
DROP INDEX
son extensiones MySQL al
estándar SQL.
MODIFY
es una extensión de Oracle a
ALTER TABLE
.
La palabra COLUMN
es opcional y puede
omitirse.
Si usa ALTER TABLE
sin
ninguna otra opción, MySQL símplemente renombra cualquier
fichero que se corresponda a la tabla
tbl_name
RENAME TO
new_tbl_name
tbl_name
. No es necesario crear
una tabla temporal. (Puede usar el comando RENAME
TABLE
para renombrar tablas. Consulte
Sección 13.1.9, “Sintaxis de RENAME TABLE
”.)
Las cláusulas column_definition
usan la misma sintaxis para ADD
y
CHANGE
así como CREATE
TABLE
. Tenga en cuenta que esta sintaxis incluye
el nombre de la columna, no sólo el tipo. Consulte
Sección 13.1.5, “Sintaxis de CREATE TABLE
”.
Puede renombrar una columna usando CHANGE
. Para
ello, especifique el nombre de columna viejo y nuevo y el
tipo de la columna actual. Por ejemplo, para renombrar una
columna old_col_name
column_definition
INTEGER
de a
a
b
, puede hacer:
mysql> ALTER TABLE t1 CHANGE a b INTEGER;
Si quiere cambiar el tipo de una columna pero no el nombre,
la sintaxis CHANGE
necesita un nombre
viejo y nuevo de columna, incluso si son iguales. Por
ejemplo:
mysql> ALTER TABLE t1 CHANGE b b BIGINT NOT NULL;
Puede usar MODIFY
para cambiar el tipo de
una columna sin renombrarla:
mysql> ALTER TABLE t1 MODIFY b BIGINT NOT NULL;
Si usa CHANGE
o MODIFY
para acortar una columna para la que existe un índice en la
columna, y la longitud de la columna resultante es menor que
la del índice, MySQL reduce el índice automáticamente.
Cuando cambia un tipo de columna usando
CHANGE
o MODIFY
, MySQL
intenta convertir valores de columna existentes al nuevo
tipo lo mejor posible.
En MySQL 5.0, puede usar FIRST
o
AFTER
para añadir una columna a una posición específica sin un
registro de tabla. Por defecto se añade al final. Puede
usar col_name
FIRST
y AFTER
en
operaciones CHANGE
o
MODIFY
en MySQL 5.0.
ALTER COLUMN
especifica un nuevo valor
por defecto para una columna o borra el antiguo valor por
defecto. Si el antiguo valor por defecto se borra y la
columna puede ser NULL
, el nuevo valor
por defecto es NULL
. Si la columna no
puede ser NULL
, MySQL asigna un valor por
defecto, como se describe en Sección 13.1.5, “Sintaxis de CREATE TABLE
”.
DROP INDEX
borra un índice. Es una
extensión MySQL al estándar SQL. Consulte
Sección 13.1.7, “Sintaxis de DROP INDEX
”.
Si las columnas se borran de una tabla, las columnas también se borran de cualquier índice del que formaran parte. Si todas las columnas que crean un índice se borran, también se borra el índice.
Si una tabla contiene sólo una columna, la columna no puede
borrarse. Si lo que quiere es borrar la tabla, use
DROP TABLE
.
DROP PRIMARY KEY
borra el índice
primario. Nota: En versiones anteriores
de MySQL, si no existe clave primaria, entonces
DROP PRIMARY KEY
borraría el primer
índice UNIQUE
de la tabla. Esto ya no es
así en MySQL 5.0, cuando trata de usar DROP
PRIMARY KEY
en una tabla sin clave primaria daría
lugar a un error.
Si añade UNIQUE INDEX
o PRIMARY
KEY
a una tabla, se almacena antes que cualquier
índice no único para que MySQL pueda detactar claves
duplicadas tan rápido como sea posible.
ORDER BY
le permite crear la nueva tabla
con los registros en un orden específico. Tenga en cuenta
que la tabla no queda en este orden tras las inserciones y
borrados. Esta opción es útil cuando sabe que normalmente
consultará los registros en el mismo orden; usando esta
opción tras grandes cambios en la tabla, puede ser capaz de
obtener un mejor rendimiento. En algunos casos, puede hacer
la ordenación más fácil para MySQL si la tabla está en
el orden de la columna por la que quiere ordenar
posteriormente.
Si usa ALTER TABLE
en una tabla
MyISAM
, todos los índices no únicos se
crean en un batch separado (como para REPAIR
TABLE
). Esto debe hacer ALTER
TABLE
mucho más rápido cuando tiene muchos
índices.
En MySQL 5.0, esta característica puede activarse
explícitamente ALTER TABLE ... DISABLE
KEYS
le dice a MySQL que pare de actualizar
índices no únicos para una tabla MyISAM
. ALTER TABLE ... ENABLE KEYS
debe usarse
para recrear índices perdidos. MySQL lo hace con un
algoritmo especial que es mucho más rápido que insertar
claves una a una, así que deshabilitar claves antes de
realizar operaciones de inserción masivas debería dar una
mejora de velocidad. Usar ALTER TABLE ... DISABLE
KEYS
requiere del permiso INDEX
además de los permisos mencionados anteriormente.
Las cláusulas FOREIGN KEY
y
REFERENCES
son soportadas por el motor
InnoDB
, que implementa ADD
[CONSTRAINT [
. Consulte
Sección 15.6.4, “Restricciones (constraints) symbol
]] FOREIGN KEY
(...) REFERENCES ... (...)FOREIGN KEY
”. Para otros
motores de almacenamiento, las cláusulas se parsean pero se
ignoran. La cláusula CHECK
se parsea
pero se ignora por todos los motores de almacenamiento.
Consulte Sección 13.1.5, “Sintaxis de CREATE TABLE
”. La razón para
aceptar pero ignorar las cláusulas es para compatibilidad,
para hacer más fácil portar código de otros servidores
SQL, y para ejecutar aplicaciones que crean tablas con
referencias. Consulte
Sección 1.7.5, “Diferencias en MySQL del estándar SQL”.
En MySQL 5.0, InnoDB
soporta el uso de
ALTER TABLE
para borrar claves foranas:
ALTER TABLEyourtablename
DROP FOREIGN KEYfk_symbol
;
Para más información, consulte
Sección 15.6.4, “Restricciones (constraints) FOREIGN KEY
”.
ALTER TABLE
ignora las opciones
DATA DIRECTORY
y INDEX
DIRECTORY
.
Si quiere cambiar el conjunto de carácteres por defecto de
la tabla y todas las columnas de carácteres
(CHAR
, VARCHAR
,
TEXT
) a un nuevo conjunto de carácteres,
use un comando como:
ALTER TABLEtbl_name
CONVERT TO CHARACTER SETcharset_name
;
Atención: La operación
precedente convierte los valores de columnas entre conjuntos
de carácteres. Esto no es lo que
quiere hacer si tiene una columna en un conjunto de
carácteres (como latin1
) pero los
valores almacenados realmente usan otro conjunto de
carácteres incompatible (como utf8
). En
este caso, tiene que hacer lo siguiente para cada una de
tales columnas:
ALTER TABLE t1 CHANGE c1 c1 BLOB; ALTER TABLE t1 CHANGE c1 c1 TEXT CHARACTER SET utf8;
La razón de que esto funcione es que no hay conversión
cuando convierte desde o hacia columnas
BLOB
.
Si especifica CONVERT TO CHARACTER SET
binary
, las columnas CHAR
,
VARCHAR
, y TEXT
se
converten a sus cadenas de carácteres binarias
(BINARY
, VARBINARY
,
BLOB
). Esto significa que las columnas no
tendrán un conjunto de carácters y que siguientes
operaciones CONVERT TO
no se les
aplicarán.
Para sólo cambiar el conjunto de carácteres por defecto de una tabla, use este comando:
ALTER TABLEtbl_name
DEFAULT CHARACTER SETcharset_name
;
La palabra DEFAULT
es opcional. El
conjunto de carácteres por defecto es el que se usa si no
especifica uno para una nueva columna que añada a la tabla
(por ejemplo, con ALTER TABLE ... ADD
column
).
Atención: En MySQL 5.0,
ALTER TABLE ... DEFAULT CHARACTER SET
y
ALTER TABLE ... CHARACTER SET
son
equivalentes y cambian sólo el conjunto de carácteres por
defecto de la tabla.
Para una tabla InnoDB
creada con su
propio espacio de tablas en un fichero
.ibd
, este fichero puede descartarse e
importarse. Para descatar el fichero
.ibd
, use este comando:
ALTER TABLE tbl_name
DISCARD TABLESPACE;
Esto borra el fichero .ibd
actual, así
que asegúrese que tiene primero una copia de seguridad.
Tratar de acceder a la tabla mientras se descarta el fichero
provoca un error.
Para importar el fichero .ibd
de la
copia de seguridad de nuevo a la tabla, cópielo en el
directorio de la base de datos, luego realice el comando:
ALTER TABLE tbl_name
IMPORT TABLESPACE;
Consulte Sección 15.6.6, “Usar un espacio de tablas para cada tabla”.
Con la función mysql_info()
de la API de
C, puede consultar el número de registros copiados, y
(cuando se usa IGNORE
) cuántos
registros se borraron debido a duplicación de valores de
claves única. Consulte Sección 24.3.3.32, “mysql_info()
”.
Hay algunos ejemplos que muestran usos de ALTER
TABLE
. Comienza con una tabla t1
que se crea como se muestra:
mysql> CREATE TABLE t1 (a INTEGER,b CHAR(10));
Para renombrar la tabla de t1
a
t2
:
mysql> ALTER TABLE t1 RENAME t2;
Para cambiar la columna a
desde
INTEGER
a TINYINT NOT NULL
(dejando el mismo nombre), y para cambiar la columna
b
desde CHAR(10)
a
CHAR(20)
así como dejarla de
b
a c
:
mysql> ALTER TABLE t2 MODIFY a TINYINT NOT NULL, CHANGE b c CHAR(20);
Para añadir una nueva columna TIMESTAMP
llamada d
:
mysql> ALTER TABLE t2 ADD d TIMESTAMP;
Para añadir índices en las columnas d
y
a
:
mysql> ALTER TABLE t2 ADD INDEX (d), ADD INDEX (a);
Para borrar la columna c
:
mysql> ALTER TABLE t2 DROP COLUMN c;
Para añadir una nueva columna entera
AUTO_INCREMENT
llamada c
:
mysql> ALTER TABLE t2 ADD c INT UNSIGNED NOT NULL AUTO_INCREMENT, -> ADD PRIMARY KEY (c);
Tenga en cuenta que indexamos c
(como
PRIMARY KEY
), ya que las columnas
AUTO_INCREMENT
deben indexarse, y también
que declaramos c
como NOT
NULL
, ya que las columnas de clave primara no pueden
ser NULL
.
Cuando añade una columna AUTO_INCREMENT
los
valores se rellenan con números secuenciales automáticamente.
Para tablas MyISAM
puede asignar el primer
número de secuencia ejecutando SET
INSERT_ID=
antes de
value
ALTER TABLE
o usando la opción de tabla
AUTO_INCREMENT=
.
Consulte Sección 13.5.3, “Sintaxis de value
SET
”.
Desde MySQL 5.0.3, puede usar la opción de tabla ALTER
TABLE ...
AUTO_INCREMENT=
para
value
InnoDB
para asignar el número de secuencia
de nuevos registros si el valor es mayor que el máximo valor en
la columna AUTO_INCREMENT
. Si el
valor es menor que el máximo actual en la columna, no se da
ningún mensaje de error y el valor de secuencia actual no se
cambia.
Con tablas MyISAM
, si no cambia la columna
AUTO_INCREMENT
, el número de secuencia no
se ve afectado. Si elimina una columna
AUTO_INCREMENT
y luego añade otra columna
AUTO_INCREMENT
los números se resecuencian
comenzando en 1.
CREATE {DATABASE | SCHEMA} [IF NOT EXISTS]db_name
[create_specification
[,create_specification
] ...]create_specification
: [DEFAULT] CHARACTER SETcharset_name
| [DEFAULT] COLLATEcollation_name
CREATE DATABASE
crea una base de datos con el
nombre dado. Para usar CREATE DATABASE
,
necesita el permiso CREATE
en la base de
datos.
Las reglas para nombres de bases de datos permitidos se dan en
Sección 9.2, “Nombres de bases de datos, tablas, índices, columnas y alias”. Ocurre un error si la base de
datos existe y no especifica IF NOT EXISTS
.
En MySQL 5.0, las opciones
create_specification
pueden darse para
especificar característica de la base de datos. Las
características se almacenan en el fichero
db.opt
en el directorio de la base de
datos. La cláusula CHARACTER SET
especifica
el conjunto de carácteres por defecto de la base de datos. La
cláusula COLLATE
especifica la colación por
defecto de la base de datos. Los nombres de colación y de
conjunto de carácteres se discuten en
Capítulo 10, Soporte de conjuntos de caracteres.
Las bases de datos en MySQL se implementan como directorios que
contienen ficheros que se corresponden a tablas en la base de
datos. Como no hay tablas en la base de datos cuando se crean
inicialmente, el comando CREATE DATABASE
en
MySQL 5.0 crea sólo un directorio bajo el directorio de datos
de MySQL y el fichero db.opt
file.
Si crea manualmente un directorio bajo el directorio de datos
(por ejemplo, con mkdir), el servidor lo
considera como un directorio de base de datos y muestra la
salida de SHOW DATABASES
.
CREATE SCHEMA
puede usarse desde MySQL 5.0.2.
También puede usar el programa mysqladmin para crear bases de datos. Consulte Sección 8.4, “Administrar un servidor MySQL con mysqladmin”.
CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEXindex_name
[USINGindex_type
] ONtbl_name
(index_col_name
,...)index_col_name
:col_name
[(length
)] [ASC | DESC]
En MySQL 5.0, CREATE INDEX
se mapea a un
comando ALTER TABLE
para crear índices.
Consulte Sección 13.1.2, “Sintaxis de ALTER TABLE
”.
Normalmente, crea todos los índices en una tabla cuando se crea
la propia tabla con CREATE TABLE
. Consulte
Sección 13.1.5, “Sintaxis de CREATE TABLE
”. CREATE INDEX
le permite añadir índices a tablas existentes.
Una lista de columnas de la forma
(col1,col2,...)
crea un índice de múltiples
columnas. Los valores de índice se forman al concatenar los
valores de las columnas dadas.
Para columnas CHAR
y
VARCHAR
, los índices pueden crearse para que
usen sólo parte de una columna, usando
para indexar un prefijo consistente en los primeros
col_name
(length
)length
carácteres de cada valor de
la columna. BLOB
t TEXT
pueden indexarse, pero se debe dar una
longitud de prefijo.
El comando mostrado aquí crea un índice usando los primeros 10
carácteres de la columna name
:
CREATE INDEX part_of_name ON customer (name(10));
Como la mayoría de nombres usualmente difieren en los primeros
10 carácteres, este índice no debería ser mucho más lento
que un índice creado con la columna name
entera. Además, usar columnas parcialmente para índices puede
hacer un fichero índice mucho menor, que puede ahorrar mucho
espacio de disco y además acelarar las operaciones
INSERT
.
Los prefijos pueden tener una longitud de hasta 255 bytes. Para
tablas MyISAM
y InnoDB
en
MySQL 5.0, pueden tener una longitud de hasta 1000 bytes . Tenga
en cuenta que los límites de los prefijos se miden en bytes,
mientras que la longitud de prefijo en comandos CREATE
INDEX
se interpreta como el número de carácteres.
Tenga esto en cuenta cuando especifique una longitud de prefijo
para una columna que use un conjunto de carácteres de
múltiples bytes.
En MySQL 5.0:
Puede añadir un índice en una columna que puede tener
valores NULL
sólo si está usando
MyISAM
, InnoDB
, o
BDB
.
Puede añadir un índice en una columna
BLOB
o TEXT
sólo si
está usando el tipo de tabla MyISAM
,
BDB
, o InnoDB
.
Una especificación index_col_name
puede acabar con ASC
o
DESC
. Estas palabras se permiten para
extensiones futuras para especificar almacenamiento de índice
ascendente o descendente. Actualmente se parsean pero se
ignoran; los valores de índice siempre se almacenan en orden
ascendente.
En MySQL 5.0, algunos motores le permiten especificar un tipo de
índice cuando se crea un índice. La sintaxis para el
especificador index_type
es
USING
.
Los valores type_name
type_name
posibles
soportados por distintos motores se muestran en la siguiente
tabla. Donde se muestran múltiples tipos de índice , el
primero es el tipo por defecto cuando no se especifica
index_type
.
Motor de almacenamiento | Tipos de índice permitidos |
MyISAM | BTREE |
InnoDB | BTREE |
MEMORY/HEAP | HASH , BTREE |
Ejemplo:
CREATE TABLE lookup (id INT) ENGINE = MEMORY; CREATE INDEX id_index USING BTREE ON lookup (id);
TYPE
puede usarse como sinónimo de type_name
USING
para especificar
un tipo de índice. Sin embargo, type_name
USING
es la
forma preferida. Además, el nombre de índice que precede el
tipo de índice en la especificación de la sintaxis de índice
no es opcional con TYPE
. Esto es debido a
que, en contra de USING
,
TYPE
no es una palabra reservada y se
interpreta como nombre de índice.
Si especifica un tipo de índice que no es legal para un motor de almacenamiento, pero hay otro tipo de índice disponible que puede usar el motor sin afectar los resultados de la consulta, el motor usa el tipo disponible.
Para más información sobre cómo MySQL usa índices, consulte Sección 7.4.5, “Cómo utiliza MySQL los índices”.
Índices FULLTEXT
en MySQL 5.0 puede indexar
sólo columnas CHAR
,
VARCHAR
, y TEXT
, y sólo
en tablas MyISAM
. Consulte
Sección 12.7, “Funciones de búsqueda de texto completo (Full-Text)”.
Índices SPATIAL
en MySQL 5.0 puede indexar
sólo columnas espaciales, y sólo en tablas
MyISAM
. Los tipo de columna espaciales se
describen en Capítulo 18, Extensiones espaciales de MySQL.
CREATE [TEMPORARY] TABLE [IF NOT EXISTS]tbl_name
[(create_definition
,...)] [table_options
] [select_statement
]
O:
CREATE [TEMPORARY] TABLE [IF NOT EXISTS]tbl_name
[(] LIKEold_tbl_name
[)];create_definition
:column_definition
| [CONSTRAINT [symbol
]] PRIMARY KEY [index_type
] (index_col_name
,...) | KEY [index_name
] [index_type
] (index_col_name
,...) | INDEX [index_name
] [index_type
] (index_col_name
,...) | [CONSTRAINT [symbol
]] UNIQUE [INDEX] [index_name
] [index_type
] (index_col_name
,...) | [FULLTEXT|SPATIAL] [INDEX] [index_name
] (index_col_name
,...) | [CONSTRAINT [symbol
]] FOREIGN KEY [index_name
] (index_col_name
,...) [reference_definition
] | CHECK (expr
)column_definition
:col_name
type
[NOT NULL | NULL] [DEFAULTdefault_value
] [AUTO_INCREMENT] [UNIQUE [KEY] | [PRIMARY] KEY] [COMMENT 'string
'] [reference_definition
]type
: TINYINT[(length
)] [UNSIGNED] [ZEROFILL] | SMALLINT[(length
)] [UNSIGNED] [ZEROFILL] | MEDIUMINT[(length
)] [UNSIGNED] [ZEROFILL] | INT[(length
)] [UNSIGNED] [ZEROFILL] | INTEGER[(length
)] [UNSIGNED] [ZEROFILL] | BIGINT[(length
)] [UNSIGNED] [ZEROFILL] | REAL[(length
,decimals
)] [UNSIGNED] [ZEROFILL] | DOUBLE[(length
,decimals
)] [UNSIGNED] [ZEROFILL] | FLOAT[(length
,decimals
)] [UNSIGNED] [ZEROFILL] | DECIMAL(length
,decimals
) [UNSIGNED] [ZEROFILL] | NUMERIC(length
,decimals
) [UNSIGNED] [ZEROFILL] | DATE | TIME | TIMESTAMP | DATETIME | CHAR(length
) [BINARY | ASCII | UNICODE] | VARCHAR(length
) [BINARY] | TINYBLOB | BLOB | MEDIUMBLOB | LONGBLOB | TINYTEXT [BINARY] | TEXT [BINARY] | MEDIUMTEXT [BINARY] | LONGTEXT [BINARY] | ENUM(value1
,value2
,value3
,...) | SET(value1
,value2
,value3
,...) |spatial_type
index_col_name
:col_name
[(length
)] [ASC | DESC]reference_definition
: REFERENCEStbl_name
[(index_col_name
,...)] [MATCH FULL | MATCH PARTIAL | MATCH SIMPLE] [ON DELETEreference_option
] [ON UPDATEreference_option
]reference_option
: RESTRICT | CASCADE | SET NULL | NO ACTIONtable_options
:table_option
[table_option
] ...table_option
: {ENGINE|TYPE} =engine_name
| AUTO_INCREMENT =value
| AVG_ROW_LENGTH =value
| [DEFAULT] CHARACTER SETcharset_name
[COLLATEcollation_name
] | CHECKSUM = {0 | 1} | COMMENT = 'string
' | MAX_ROWS =value
| MIN_ROWS =value
| PACK_KEYS = {0 | 1 | DEFAULT} | PASSWORD = 'string
' | DELAY_KEY_WRITE = {0 | 1} | ROW_FORMAT = {DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNDANT|COMPACT} | RAID_TYPE = { 1 | STRIPED | RAID0 } RAID_CHUNKS =value
RAID_CHUNKSIZE =value
| UNION = (tbl_name
[,tbl_name
]...) | INSERT_METHOD = { NO | FIRST | LAST } | DATA DIRECTORY = 'absolute path to directory
' | INDEX DIRECTORY = 'absolute path to directory
'select_statement:
[IGNORE | REPLACE] [AS] SELECT ... (Some legal select statement
)
CREATE TABLE
crea una tabla con el nombre
dado. Debe tener el permiso CREATE
para la
tabla.
Las reglas para nombres de tabla permitidos se dan en Sección 9.2, “Nombres de bases de datos, tablas, índices, columnas y alias”. Por defecto, la tabla se crea en la base de datos actual. Ocurre un error si la tabla existe, si no hay base de datos actual o si la base de datos no existe.
En MySQL 5.0, el nombre de tabla puede especificarse como
db_name.tbl_name
para crear la tabla
en la base de datos específica. Esto funciona haya una base de
datos actual o no. Si usa identificadores entre comillas,
entrecomille el nombre de base de datos y de tabla por separado.
Por ejemplo, `mydb`.`mytbl`
es legal, pero
`mydb.mytbl`
no.
Puede usar la palabra TEMPORARY
al crear una
tabla. Una tabla TEMPORARY
es visible sólo
para la conexión actual, y se borra automáticamente cuando la
conexión se cierra. Esto significa que dos conexiones distintas
pueden usar el mismo nombre de tabla temporal sin entrar en
conflicto entre ellas ni con tablas no
TEMPORARY
con el mismo nombre. (La tabla
existente se oculta hasta que se borra la tabla temporal.) En
MySQL 5.0, debe tener el permiso CREATE TEMPORARY
TABLES
para crear tablas temporales.
MySQL 5.0 soporta las palabras IF NOT EXISTS
para que no ocurra un error si la tabla existe. Tenga en cuenta
que no hay verificación que la tabla existente tenga una
estructura idéntica a la indicada por el comando
CREATE TABLE
. Nota: Si
usa IF NOT EXISTS
en un comando
CREATE TABLE ... SELECT
,cualquier registro
seleccionado por la parte SELECT
se inserta
si la tabla existe o no.
MySQL representa cada tabla mediante un fichero
.frm
de formato de tabla (definición) en
el directorio de base de datos. El motor para la tabla puede
crear otros ficheros también. En el caso de tablas
MyISAM
, el motor crea ficheros índice y de
datos. Por lo tanto, para cada tabla MyISAM
tbl_name
, hay tres ficheros de disco:
Fichero | Propósito |
| Fichero de formato de tabla (definición) |
| Fichero de datos |
| Fichero índice |
Los ficheros creados por cada motor de almacenamiento para representar tablas se describen en Capítulo 14, Motores de almacenamiento de MySQL y tipos de tablas.
Para información general de las propiedades de los diversos tipos de columna, consulte Capítulo 11, Tipos de columna. Para información acerca de tipos de columna espaciales, consulte Capítulo 18, Extensiones espaciales de MySQL.
Si no se especifica NULL
ni NOT
NULL
, la columna se trata como si se especificara
NULL
.
Una columna entera puede tener el atributo adicional
AUTO_INCREMENT
. Cuando inserta un valor
de NULL
(recomendado) o
0
en una columna
AUTO_INCREMENT
autoindexada, la columna
se asigna al siguiente valor de secuencia. Típicamente esto
es
,
donde value
+1value
es el mayor valor
posible para la columna en la tabla. Secuencias
AUTO_INCREMENT
comienzan con
1
. Tales columnas deben definirse como
uno de los tipos enteros como se describe en
Sección 11.1.1, “Panorámica de tipos numéricos”. (El valor 1.0
no es un entero.) Consulte
Sección 24.3.3.34, “mysql_insert_id()
”.
En MySQL 5.0, especificar
NO_AUTO_VALUE_ON_ZERO
para la opción de
servidor --sql-mode
o la variable de
sistema sql_mode
le permite almacenar
0
en columnas
AUTO_INCREMENT
como 0
sin generar un nuevo valor de secuencia. Consulte
Sección 5.3.1, “Opciones del comando mysqld”.
Nota: Sólo puede haber una
columna AUTO_INCREMENT
por tabla, debe
estar indexada, y no puede tener un valor
DEFAULT
. Una columna
AUTO_INCREMENT
funciona correctamente
sólo si contiene sólo valores positivos. Insertar un
número negativo se trata como insertar un número positivo
muy grande. Esto se hace para evitar problemas de precisión
cuando los números “cambian” de positivos a
negativos y asegura que no obtiene accidentalmente una
columna AUTO_INCREMENT
que contenga
0
.
Para tablas MyISAM
y
BDB
, puede especificar una columna
AUTO_INCREMENT
secundaria en una clave de
múltiples columnas. Consulte
Sección 3.6.9, “Utilización de AUTO_INCREMENT
”.
Para hacer MySQL compatible con otras aplicaciones ODBC ,
puede encontrar el valor AUTO_INCREMENT
para el último registro insertado con la siguiente
consulta:
SELECT * FROMtbl_name
WHEREauto_col
IS NULL
En MySQL 5.0, las definiciones de columnas de carácteres
puede incluir un atributo CHARACTER SET
para especificar el conjunto de carácteres y,
opcionalmente, una colación para la columna. Para detalles,
consulte Capítulo 10, Soporte de conjuntos de caracteres.
CHARSET
es sinónimo de
CHARACTER SET
.
CREATE TABLE t (c CHAR(20) CHARACTER SET utf8 COLLATE utf8_bin);
MySQL 5.0 interpreta las especificaciones de longitud en definiciones de columna en carácteres. (Algunas versiones anteriores los interpretan en bytes.)
La cláusula DEFAULT
especifica el valor
por defecto para una columna. Con una excepción, el valor
por defecto debe ser constante; no puede ser una función o
una expresión. Esto significa , por ejemplo, que no puede
poner como valor por defecto de una columna el valor de una
función como NOW()
o
CURRENT_DATE
. La excepción es que pude
especificar CURRENT_TIMESTAMP
como
defecto para columnas TIMESTAMP
.
Consulte Sección 11.3.1.1, “Propiedades de TIMESTAMP
desde MySQL 4.1”.
Antes de MySQL 5.0.2, si una definición de columna no
incluye valor DEFAULT
explícito, MySQL
determina el valor por defecto como sigue:
Si la columna puede tener valores NULL
,
la columna se define como una cláusula DEFAULT
NULL
explícita.
Si la columna no puede tener valores NULL
, MySQL define la columna con una cláusula
DEFAULT
explícita, usando el valor por
defecto implícito para el tipo de datos de la columna . Los
valores por defecto implícitos se definen como sigue:
Para tipos numéricos distintos a los declarados con el
atributo AUTO_INCREMENT
, por defecto
es 0
. Para una columna
AUTO_INCREMENT
, el valor por defecto
es el siguiente valor de la secuencia.
Para tipos de fecha y hora distintos a
TIMESTAMP
, el valor por defecto es el
valor “cero” apropiado para el tipo. Para
la primera columna TIMESTAMP
en una
tabla, el valor por defecto es la fecha actual y la
hora. Consulte Sección 11.3, “Tipos de fecha y hora”.
Para tipos de cadenas distintos a
ENUM
, el valor por defecto es la
cadena vacía. Para ENUM
, el valor
por defecto es el primer valor de la enumeración.
Las columnas BLOB
y
TEXT
no pueden tener un valor por
defecto.
Desde MySQL 5.0.2, si una definición de columna no incluye
valor DEFAULT
explícito , MySQL
determina el valor por defecto como sigue:
Si la columna puede tener NULL
como
valor, la columna se define con una cláusula
DEFAULT NULL
explícita. Esto es lo mismo
que antes de 5.0.2.
Si la columna no puede tener valores NULL
, MySQL define la columna sin cláusula
DEFAULT
explícita. Para entradas de
datos, si un comando INSERT
o
REPLACE
no incluye valor para la columna,
MySQL trata la columna según el modo SQL activo en ese
momento:
Si el modo estricto no está activado, MySQL pone en la columna el valor por defecto implícito para el tipo de datos de la columna.
Si está activo el modo estricto, ocurre un error para tablas transaccionales y el comando se deshace. Para tablas no transaccionales, ocurre un error, pero si esto ocurre para el segundo registro o siguientes de un comando de múltiples registros, los registros precedentes se insertarán.
Suponga que una tabla t
se define como
sigue:
CREATE TABLE t (i INT NOT NULL);
En este caso, i
no tiene valor
explícito, así que en modo estricto todos los siguientes
comandos producen un error en modo estricto y no se inserta
ningún registro. Para modo no estricto, sólo el tercer
comando produce un error; el valor implícito por defecto se
inserta para las dos primeras, pero la tercera falla ya que
DEFAULT(i)
no puede producir un valor:
INSERT INTO t VALUES(); INSERT INTO t VALUES(DEFAULT); INSERT INTO t VALUES(DEFAULT(i));
Consulte Sección 5.3.2, “El modo SQL del servidor”.
Para una tabla dada, puede usar el comando SHOW
CREATE TABLE
para ver qué columnas puede tener
una cláusula explícita DEFAULT
.
Un comentario para una columna puede especificarse en MySQL
5.0 con la opción COMMENT
. El
comentario se muestra con los comandos SHOW CREATE
TABLE
y SHOW FULL COLUMNS
.
En MySQL 5.0, el atributo SERIAL
puede
usarse como un alias para BIGINT UNSIGNED NOT NULL
AUTO_INCREMENT UNIQUE
.
KEY
normalemente es sinónimo para
INDEX
. En MySQL 5.0, el atributo clave
PRIMARY KEY
puede especificarse como
KEY
cuando se da en una definición de
columna. Esto se implementó por compatibilidad con otros
sistemas de bases de datos.
En MySQL, un índice UNIQUE
es uno en que
todos los valores en el índice deben ser distintos. Ocurre
un error si intenta añadir un nuevo registro con una clave
que coincida con un registro existente. La excepción es que
una columna en el índice puede contener valores
NULL
, puede contener valores
NULL
múltiples. Esta excepción no se
aplica a tablas BDB
, en las que una
columna indexada le permita un único
NULL
.
Una PRIMARY KEY
es una
KEY
única donde todas las columnas de la
clave deben definirse como NOT NULL
. Si
no se declaran explícitamente como NOT
NULL
, MySQL las declara implícitamente ( y sin
decirlo ) . Una tabla puede tener sólo una PRIMARY
KEY
. Si no tiene una PRIMARY
KEY
y una aplicación pide una PRIMARY
KEY
en sus tablas, MySQL retorna el primer índice
UNIQUE
que no tenga columnas
NULL
como la PRIMARY
KEY
.
En la tabla creada, una PRIMARY KEY
se
guarda en primer lugar, seguida por todos los índices
UNIQUE
, y luego los índices no únicos.
Esto ayuda al optimizador MySQL a priorizar qué indice usar
y también detectar más rápido claves
UNIQUE
duplicadas.
Una PRIMARY KEY
puede ser un índice de
múltiples columnas. Sin embargo, no puede crear un índice
de múltiples columnas usando el atributo de clave
PRIMARY KEY
en una especificación de
columna. Hacerlo sólo marca la columna como primaria. Debe
usar una cláusula PRIMARY KEY(index_col_name,
...)
separada.
Si un índice PRIMARY KEY
o
UNIQUE
consite sólo de una columna que
tenga un tipo entero, puede referirse a la columna como
_rowid
en comandos
SELECT
.
En MySQL, el nombre de una PRIMARY KEY
es
PRIMARY
. Para otros índices, si no
asigna un nombre, el índice tieen el mismo nombre que la
primera columna indexada, con un sufijo opcional
(_2
, _3
,
...
) para hacerlo único. Puede ver los
nombres de índice para una tabla usando SHOW INDEX
FROM
. Consulte
Sección 13.5.4.11, “Sintaxis de tbl_name
SHOW INDEX
”.
A partir de MySQL 5.0, algunos motores de almacenamiento le
permiten especificar un tipo de índice al crear el índice.
Consulte Sección 13.1.4, “Sintaxis de CREATE INDEX
”.
Para más información acerca de cómo usa los índices MySQL, consulte Sección 7.4.5, “Cómo utiliza MySQL los índices”.
En MySQL 5.0, sólo los motores MyISAM
,
InnoDB
, BDB
, y
MEMORY
soporta índices en columnas que
pueden tener valores NULL
. En otros
casos, debe declarar columnas indexadas como NOT
NULL
u ocurre un error.
Con sintaxis
en una especificación de índice, puede crear un índice
que use sólo los primeros col_name
(length
)length
carácteres de una columna CHAR
o
VARCHAR
. Indexar sólo un prefijo de
valores de columna como este puede hacer el fichero de
índice mucho más pequeño. Consulte
Sección 7.4.3, “Índices de columna”.
En MySQL 5.0, los motores MyISAM
y
InnoDB
soportan indexación en columnas
BLOB
y TEXT
. Al
indexar columnas BLOB
o
TEXT
debe
especificar una longitud de prefijo para el índice. Por
ejemplo:
CREATE TABLE test (blob_col BLOB, INDEX(blob_col(10)));
En MySQL 5.0, los prefijos pueden tener hasta 1000 bytes de
longitud para tablas MyISAM
y
InnoDB
y 255 bytes para otros tipos de
tabla. Tenga en cuenta que los límites de prefijo se miden
en bytes, mientras que la longitud de prefijo en comandos
CREATE TABLE
se interpretan como el
número de carácteres. Asegúrese de tener esto en cuenta
al especificar una longitud de prefijo para una columna que
use un conjunto de carácteres multi-byte .
Una especificación
index_col_name
puede acabar con
ASC
o DESC
. Estas
palabras clave se permiten para extensiones futuras para
especificar almacenamiento de índices ascendente o
descendentemente. Actualmente se parsean pero se ignoran;
los valores de índice siempre se almacenan en orden
ascendente.
Cuando usa ORDER BY
o GROUP
BY
en una columna TEXT
o
BLOB
en un SELECT
, el
servidor ordena los valores usando sólo el número inicial
de bytes indicados por la variable de sistema
max_sort_length
. Consulte
Sección 11.4.3, “Los tipos BLOB
y TEXT
”.
En MySQL 5.0, puede crear índices especiales
FULLTEXT
, que se usan para índices
full-text . Sólo las tablas MyISAM
soportan índices FULLTEXT
. Pueden
crearse sólo desde columnas CHAR
,
VARCHAR
, y TEXT
. La
indexación siempre se hace sobre la columna entera; la
indexación parcial no se soporta y cualquier longitud de
prefijo se ignora. Consulte
Sección 12.7, “Funciones de búsqueda de texto completo (Full-Text)” para más detalles.
En MySQL 5.0, puede crear índices
SPATIAL
en tipos de columna espaciales.
Los tipos espaciales se soportan sólo para tablas
MyISAM
y las columnas indexadas deben
declararase como NOT NULL
. Consulte
Capítulo 18, Extensiones espaciales de MySQL.
En MySQL 5.0, las tablas InnoDB
soportan
el chequeo de restricciones de claves foráneas . Consulte
Capítulo 15, El motor de almacenamiento InnoDB
. Tenga en cuenta que la sintaxis
FOREIGN KEY
en InnoDB
es más restrictiva que la sintaxis presentada para el
comando CREATE TABLE
al inicio de esta
sección: las columnas en la tabla referenciada debe siempre
nombrarse explícitamente. InnoDB
soporta
tanto acciones ON DELETE
como ON
UPDATE
en MySQL 5.0. Para la sintaxis precisa,
consulte Sección 15.6.4, “Restricciones (constraints) FOREIGN KEY
”.
Para otros motores de almacenamiento, MySQL Server parsea la
sintaxis FOREIGN KEY
y
REFERENCES
en comandos CREATE
TABLE
, pero no hace nada. La cláusula
CHECK
se parsea paro se ignora en todos
los motores de almacenamiento. Consulte
Sección 1.7.5.5, “Claves foráneas (foreign keys)”.
Para tablas MyISAM
cada columna
NULL
ocupa un bit extra, redondeado al
byte más próximo. La máxima longitud de registro en bytes
puede calcularse como sigue:
row length = 1 + (sum of column lengths
) + (number of NULL columns
+delete_flag
+ 7)/8 + (number of variable-length columns
)
delete_flag
es 1 para tables con
formato de registro estático. Las tablas estáticas usan un
bit en el registro para un flag que indica si el registro se
ha borrado. delete_flag
es 0 para
tablas dinámicas ya que el flag se almacena en una cabecera
de registro dinámica.
Estos cálculos no se aplican en tablas
InnoDB
, en las que el tamaño de
almacenamiento no es distinto para columnas
NULL
y NOT NULL
.
La parte table_options
de la sintaxis
CREATE TABLE
puede usarse desde MySQL 3.23.
Las opciones ENGINE
y TYPE
especifican el motor de almacenamiento para la tabla.
ENGINE
es el nombre preferido para la opción
en MySQL 5.0, y TYPE
está obsoleto. El
soporte para la palabra TYPE
usada en este
contexto desaparecerá en MySQL 5.1.
Las opciones ENGINE
y TYPE
pueden tener los siguientes valores:
Motor de almacenamiento | Descripción |
ARCHIVE | El motor de almacenamiento para archivar. Consulte
Sección 14.7, “El motor de almacenamiento ARCHIVE ”. |
BDB | Tablas transaccionales con bloqueo de página. Conocidas como
BerkeleyDB . Consulte
Sección 14.4, “El motor de almacenamiento BDB (BerkeleyDB )”. |
CSV | Tablas que almacenan registros en valores separados por comas. Consulte
Sección 14.8, “El motor de almacenamiento CSV ”. |
EXAMPLE | Motor de ejemplo. Consulte Sección 14.5, “El motor de almacenamiento EXAMPLE ”. |
FEDERATED | Motor que accede a tablas remotas. Consulte
Sección 14.6, “El motor de almacenamiento FEDERATED ”. |
HEAP | Consulte Sección 14.3, “El motor de almacenamiento MEMORY (HEAP )”. |
(OBSOLETE) ISAM | No disponible en MySQL 5.0. Si está actualizando a MySQL 5.0 desde una
versión prévia, debe convertir cualquier tabla
ISAM existente a
MyISAM antes de
la actualización. Consulte
Capítulo 14, Motores de almacenamiento de MySQL y tipos de tablas. |
InnoDB | Tablas transaccionales con bloqueo de registro y claves foráneas.
Consulte Capítulo 15, El motor de almacenamiento InnoDB . |
MEMORY | Los datos de este tipo de tabla se almacenan sólo en memoria. (Conocido
anteriormente como HEAP .) |
MERGE | Colección de tablas MyISAM usadas como una sola
tabla. También conocido como
MRG_MyISAM . Consulte
Sección 14.2, “El motor de almacenamiento MERGE ”. |
MyISAM | Motor binario portable que es el motor por defecto usado en MySQL.
Consulte Sección 14.1, “El motor de almacenamiento MyISAM ”. |
NDBCLUSTER | Clusterizado, tolerante a errores, tablas en memoria. También conocido
como NDB . Consulte
Capítulo 16, MySQL Cluster. |
Para más información acerca de motores MySQL, consulte Capítulo 14, Motores de almacenamiento de MySQL y tipos de tablas.
Si un motor no está disponible, MySQL usa en su lugar
MyISAM
. Por ejemplo, si una definición de
tabla incluye la opción ENGINE=BDB
pero el
servidor MySQL no soporta tablas BDB
, la
tabla se crea como MyISAM
. Esto hace posible
tener un entorno de replicación donde tiene tablas
transaccionales en el maestro pero tablas no transaccionales en
el esclavo (para tener más velocidad). En MySQL 5.0, aparece
una advertencia si la especificación del motor no es correcta.
Las otras opciones de tabla se usan para optimizar el comportamiento de la tabla. En la mayoría de casos, no tiene que especificar ninguna de ellas. La opción funciona para todos los motores a no ser que se indique lo contrario:
AUTO_INCREMENT
El valor inicial para AUTO_INCREMENT
para
la tabla. En MySQL 5.0, sólo funciona para tablas
MyISAM
y MEMORY
.
También se soporta para InnoDB
desde
MySQL 5.0.3. Para inicializar el primer valor de auto
incremento para motores que no soporten esta opción,
inserte un registro de prueba con un valor que sea uno menor
al deseado tras crear la tabla, y luego borre este registro.
Para motores que soportan la opción de tabla
AUTO_INCREMENT
en comandos
CREATE TABLE
puede usar ALTER
TABLE
para resetear el
valor tbl_name
AUTO_INCREMENT =
n
AUTO_INCREMENT
.
AVG_ROW_LENGTH
Una aproximación de la longitud media de registro para su tabla. Necesita inicializarla sólo para tablas grandes con registros de longitud variable.
Cuando crea una tabla MyISAM
, MySQL usa
el producto de las opciones MAX_ROWS
y
AVG_ROW_LENGTH
para decidir el tamaño de
la tabla resultante. Si no las especifica, el tamaño
máximo para la tabla es 65,536TB de datos (4GB antes de
MySQL 5.0.6). (Si su sistema operativo no soporta ficheros
de este tamaño, los tamaños de fichero se restringen al
límite del sistema operativo.) Si quiere mantener bajos los
tamaños de los punteros para que el índice sea pequeño y
rápido y no necesita realmente ficheros grandes, puede
decrementar el tamaño de puntero por defecto mediante la
variable de sistema
myisam_data_pointer_size
que se añadió
en MySQL 4.1.2. (Consulte
Sección 5.3.3, “Variables de sistema del servidor”.) Si quiere que
todas sus tablas sean capaces de crecer por encima del
límite por defecto y quiere mantener sus tablas ligeramente
más lentas y más grandes de lo necesario, puede
incrementar el tamaño de punter por defecto cambiando esta
variable.
[DEFAULT] CHARACTER SET
Especifica el conjunto de carácteres para la tabla.
CHARSET
es un sinónimo.
para CHARACTER SET
.
COLLATE
Especifica la colación por defecto de la tabla.
CHECKSUM
Póngalo a 1 si quiere que MySQL mantenga un checksum para
todos los registros (un checksum que MySQL actualiza
automáticamente según cambia la tabla). Esto hace que la
tabla tenga actualizaciones más lentas, pero hace más
fácil encontrar tablas corruptas. El comando
CHECKSUM TABLE
muestra el checksum (sólo
para MyISAM
).
COMMENT
Un comentario para su tabla, hasta 60 carácteres.
MAX_ROWS
Máximo número de registros que planea almacenar en la tabla. No es un límite absoluto, sino un indicador que la tabla debe ser capaz de almacenar al menos estos registros.
MIN_ROWS
Mínimo número de registros que planea almacenar en la tabla.
PACK_KEYS
Ponga esta opción a 1 si quiere tener índices más
pequeños. Esto hace normalmente que las actualizaciones
sean más lentas y las lecturas más rápidas. Poner esta
opción a 0 deshabilita la compresión de claves. Ponerla a
DEFAULT
le dice al motor que comprima
sólo columnas
CHAR
/VARCHAR
largas
(MyISAM
y ISAM
sólo).
Si no usa PACK_KEYS
, por defecto se
comprimen sólo cadenas, no números. Si usa
PACK_KEYS=1
, también se empaquetan
números.
Al comprimir claves de números binarios, MySQL usa compresión de prefijo:
Cada clave necesita un byte extra para indicar cuántos bytes de la clave previa son los mismos para la siguiente clave.
El puntero al registro se almacena en orden de el-mayor-byte-primero directamente tras la clave, para mejorar la compresión.
Esto significa que si tiene muchas claves iguales en dos
registros consecutivos, todas las “mismas”
claves siguientes usualmente sólo ocupan dos bytes
(incluyendo el puntero al registro). Comparar esto con el
caso ordinario donde las siguente claves ocupan
storage_size_for_key + pointer_size
(donde el tamaño del puntero es usualmente 4). Obtiene un
gran beneficio a partir de la compresión de prefijos sñolo
si tiene muchos números que sean el mismo. Si todas las
claves son totalmente distintas, usa un byte más por clave,
si la clave no es una clave que pueda tener valores
NULL
. (En ese caso, el tamaño
empaquetado de la clave se almacena en el mismo byte que se
usa para marcar si una clave es NULL
.)
PASSWORD
Encripta el fichero .frm
con una
contraseña. Esta opción no hace nada en la versión
estándar de MySQL.
DELAY_KEY_WRITE
Póngalo a 1 si quiere retardar actualizaciones de clave
para la tabla hasta que la tabla se cierra (sólo en
MyISAM
).
ROW_FORMAT
Define cómo deben almacenarse los registros. Actualmente
esta opción sólo funciona con tablas
MyISAM
. El valor de la opción puede ser
FIXED
o DYNAMIC
para
formato de longitud estática o variable.
myisampack cambia el tipo a
COMPRESSED
. Consulte
Sección 14.1.3, “Formatos de almacenamiento de tablas MyISAM
”.
Desde MySQL/InnoDB-5.0.3, los registros de InnoDB se
almacenan de forma más compacta
(ROW_FORMAT=COMPACT
) por defecto. El
antiguo formato puede usarse espeficicando
ROW_FORMAT=REDUNDANT
.
Tenga en cuenta que el soporte para RAID
se ha eliminado desde MySQL 5.0. Para información sobre
RAID
, consulte Manual de referencia de MySQL 4.1.
UNION
UNION
se usa cuando quiere usar una
colección de tablas idénticas como una. Funciona sólo con
tablas MERGE
. Consulte
Sección 14.2, “El motor de almacenamiento MERGE
”.
En MySQL 5.0, debe tener permisos SELECT
,
UPDATE
, y DELETE
para
las tablas mapeadas en una tabla MERGE
.
(Nota: Originalmente, todas las tablas
usadas tenían que estar en la misma base de datos que la
tabla MERGE
. Esta restricción se ha
eliminado.)
INSERT_METHOD
Si quiere insertar datos en una tabla
MERGE
debe especificarlo con
INSERT_METHOD
en la tabla en que se debe
insertar el registro. INSERT_METHOD
es
una opción útil para tablas MERGE
sólo. Use un valor dee FIRST
o
LAST
para que las inserciones vayan a la
primera o última tabla, o un valor de NO
para evitar inserciones. Consulte
Sección 14.2, “El motor de almacenamiento MERGE
”.
DATA DIRECTORY
, INDEX
DIRECTORY
Usando DATA
DIRECTORY='
o
directory
'INDEX
DIRECTORY='
puede especificar dónde debe el moto
directory
'MyISAM
buardar un fichero de datos e
índice de una tabla. Tenga en cuenta que el directorio debe
ser una ruta completa al directorio (no una ruta relativa).
Estas opciones sólo funcionan cuando no usa la opción
--skip-symbolic-links
. Su sistema
operativo debe tener una llamada
realpath()
que funcione bien. Consulte
Sección 7.6.1.2, “Utilización de enlaces simbólicos para tablas en Unix” para más
información.
En MySQL 5.0, puede crear una tabla de otra añadiendo un
comando SELECT
al final del comando
CREATE TABLE
:
CREATE TABLEnew_tbl
SELECT * FROMorig_tbl
;
MySQL crea nuevas columnas para todos los elementos en un
SELECT
. Por ejemplo:
mysql> CREATE TABLE test (a INT NOT NULL AUTO_INCREMENT, -> PRIMARY KEY (a), KEY(b)) -> TYPE=MyISAM SELECT b,c FROM test2;
Esto crea una tabla MyISAM
con tres columnas,
a
, b
, y
c
. Tenga en cuenta que las columnas para el
comando SELECT
se añaden a la derecha de la
tabla, no se sobreescriben en la misma. Consulte el siguiente
ejemplo:
mysql> SELECT * FROM foo; +---+ | n | +---+ | 1 | +---+ mysql> CREATE TABLE bar (m INT) SELECT n FROM foo; Query OK, 1 row affected (0.02 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> SELECT * FROM bar; +------+---+ | m | n | +------+---+ | NULL | 1 | +------+---+ 1 row in set (0.00 sec)
Para cada registro en la tabla foo
, se
inserta un registro en bar
con los valores de
foo
y valores por defecto para las nuevas
columnas:
Si hay cualquier error al copiar los datos a la tabla, se borra automáticamente y no se crea.
CREATE TABLE ... SELECT
no crea ningún
índice automáticamente. Se hace a propósito para hacer el
comando lo más flexible posible. Si quiere tener índices en la
tabla creada, debe especificarlo antes del comando
SELECT
:
mysql> CREATE TABLE bar (UNIQUE (n)) SELECT n FROM foo;
Algunas conversiones de tipos de columnas pueden ocurrir. Por
ejemplo, el atributo AUTO_INCREMENT
no se
preserva, y las columnas VARCHAR
pueden ser
CHAR
.
Al crear una tabla con CREATE ... SELECT
,
asegurése de poner un alias para cualquier llamada a función o
expresión en la consulta. Si no lo hace, el comando
CREATE
puede fallar o crear nombres de
columnas no deseados.
CREATE TABLE artists_and_works SELECT artist.name, COUNT(work.artist_id) AS number_of_works FROM artist LEFT JOIN work ON artist.id = work.artist_id GROUP BY artist.id;
Puede especificar explícitamente el tipo de una columna generada:
CREATE TABLE foo (a TINYINT NOT NULL) SELECT b+1 AS a FROM bar;
En MySQL 5.0, use LIKE
para crear una tabla
vacía basada en la definición de otra tabla, incluyendo
cualquier atributo de columna e índice definido en la tabla
original:
CREATE TABLEnew_tbl
LIKEorig_tbl
;
CREATE TABLE ... LIKE
no copia ninguna
opción de tabla DATA DIRECTORY
o
INDEX DIRECTORY
especificadas en la tabla
original, ni ninguna definición de clave foránea.
Puede preceder SELECT
con
IGNORE
o REPLACE
para
indicar cómo tratar registros que dupliquen claves únicas. Con
IGNORE
, los nuevos registros que duplican un
registro único existente se descartan. Con
REPLACE
, los nuevos registros reemplazan a
los antiguos con el mismo valor. Si ni IGNORE
ni REPLACE
se indican, los valores únicos
duplicados dan un error.
Para asegurar que el log de update o binario puede usarse para
recrear tablas originales, MySQL no permite inserciones
concurrentes durante CREATE TABLE ... SELECT
.
En algunos casos, MySQL cambia especificaciones de columnas
silencioasmente de las dadas en un comando CREATE
TABLE
o ALTER TABLE
. Pueden ser
cambiso a un tipo de datos, a atributos asociados con un tipo
de datos o a una especificación de índice.
Los posibles cambios de tipos de datos se dan en la siguiente lista. Ocurren antes de MySQL 5.0.3. Desde 5.0.3, ocurre un error si no se puede crear una columna usando el tipo de datos especificado.
Columnas VARCHAR
con una longitudo
menor que cuatro se cambian a CHAR
.
Si cualquier columna en una tabla tiene una longitud
variable, el registro entero pasa a tener longitud
variable. Por lo tanto, si una tabla contiene cualquier
columna de longitud variable (VARCHAR
,
TEXT
, o BLOB
), toda
columna CHAR
con más de tres
carácteres se cambia a columna VARCHAR
. Esto no afecta cómo usa las columnas en ningún modo;
en MySQL, VARCHAR
es sólo un modo
distinto de almacenar carácteres. MySQL realiza esta
conversión porque ahorra espacio y hacer las operaciones
de tabla más rápidas. Consulte
Capítulo 14, Motores de almacenamiento de MySQL y tipos de tablas.
Antes de MySQL 5.0.3, una columna CHAR
o VARCHAR
con una longitud mayor a 255
se convierte al tipo TEXT
más pequeño
que puede contener valores de la longitud dada. Por
ejemplo, VARCHAR(500)
se convierte en
TEXT
, y
VARCHAR(200000)
se convierte en
MEDIUMTEXT
. Tenga en cuenta que esta
conversión resulta en un cambio de comportamiento del
tratamiento de espacios finales.
Conversiones similares ocurren para
BINARY
y VARBINARY
,
excepto que se convierten en tipo BLOB
.
Desde MySQL 5.0.3, una columna CHAR
o
BINARY
con una longitud mayor a 255 no
se convierte silenciosamente . En su lugar, ocurre un
error. Desde MySQL 5.0.6 , la conversión silenciosa de
columnas VARCHAR
y
VARBINARY
con una longitudo mayor a
65,535 no ocurre si el modo estricto SQL está activado.
En su lugar, ocurre un error.
Para una especificación de
DECIMAL(
,
si M
,D
)M
no es mayor que
D
, se ajusta por encima. Por
ejemplo DECIMAL(10,10)
pasa a ser
DECIMAL(11,10)
.
Otros cambios de columna incluyen cambios de atributos o especficación de índice:
Los tamaños de muestra de TIMESTAMP
se
descartan. Tenga en cuenta que columnas
TIMESTAMP
han cambiado considrablemente
en versiones recientes de MySQL anteriores a 5.0; para una
descripción, consulte Manual de referencia de MySQL 4.1.
Las columnas que son parte de PRIMARY
KEY
son NOT NULL
incluso si
no se declaran como tales.
Los espacios finales se borran automáticamente para
ENUM
y SET
cuando se
crea la tabla.
MySQL mapea ciertos tipos de columna usados por otras bases de datos SQL a tipos MySQL . Consulte Sección 11.7, “Usar tipos de columnas de otros motores de bases de datos”.
Si incluye una cláusula USING
para
especificar un tipo de índice que no sea legal para un
motor de almacenamiento dado, pero hay otro tipo de
índice disponible que puede usar el motor sin afectar el
resultado de la consulta, el motor usa el tipo disponible.
Para ver si MySQL usa un tipo de columna distinto al
especificado, realice un comando DESCRIBE
o
SHOW CREATE TABLE
tras crear o alterar la
tabla.
Otros cambios de tipo de columna pueden ocurrir si comprime una tabla usando myisampack. Consulte Sección 14.1.3.3, “Características de las tablas comprimidas”.
DROP {DATABASE | SCHEMA} [IF EXISTS] db_name
DROP DATABASE
borrar todas las tablas en la
base de datos y borrar la base de datos. Sea
muy cuidadoso con este comando! Para
usarDROP DATABASE
, necesita el permiso
DROP
en la base de datos.
IF EXISTS
se usa para evitar un error si la
base de datos no existe.
DROP SCHEMA
puede usarse desde MySQL 5.0.2.
Si usa DROP DATABASE
en una base de datos
enlazada simbólicamente, tanto el enlace como la base de datos
se borran.
DROP DATABASE
retorna el número de tablas
que se eliminan. Se corresponde con el número de ficheros
.frm
borrados.
El comando DROP DATABASE
borrar del
directorio de base de datos los ficheros y directorios que MySQL
puede crear durante operaciones normales:
Todos los ficheros con estas extensiones:
.BAK | .DAT | .HSH | |
.MRG | .MYD | .ISD | |
.MYI | .db | .frm |
Todos los subdirectorios con nombres que tienen dos dígitos
hexadecimales 00
-ff
.
Son subdirectorios usados por tablas RAID
. (Estos directorios no se borran desde MySQL 5.0, cuando se
eliminó el soporte para tablas RAID
.
Debe convertir las tablas RAID
y eliminar
estos directorios manualmente antes de actualizar a MySQL
5.0. Consulte Sección 2.10.1, “Aumentar la versión de 4.1 a 5.0”.)
El fichero db.opt
, si existe.
Si permanecen otros ficheros o directorios en el directorio de
la base de datos tras que MySQL borre los ficheros listados, el
directorio de base de datos no puede borrarse. En este caso,
debe borrar cualquier fichero restante manualmente y realizar el
comando DROP DATABASE
de nuevo.
Puede borrar bases de datos con mysqladmin. Consulte Sección 8.4, “Administrar un servidor MySQL con mysqladmin”.
DROP INDEXindex_name
ONtbl_name
DROP INDEX
borra el índice llamado
index_name
de la tabla
tbl_name
. En MySQL 5.0, DROP
INDEX
se mapea a comando ALTER
TABLE
para borrar el índice. Consulte
Sección 13.1.2, “Sintaxis de ALTER TABLE
”.
DROP [TEMPORARY] TABLE [IF EXISTS]tbl_name
[,tbl_name
] ... [RESTRICT | CASCADE]
DROP TABLE
borra una o más tablas. Debe
tener el permiso DROP
para cada tabla. Todos
los datos de la definición de tabla son
borrados, así que tenga
cuidado con este comando!
Use IF EXISTS
para evitar un error para
tablas que no existan. Un NOTE
se genera para
cada tabla no existente cuando se usa IF
EXISTS
. Consulte Sección 13.5.4.22, “Sintaxis de SHOW WARNINGS
”.
RESTRICT
y CASCADE
se
permiten para hacer la portabilidad más fácil. De momento, no
hacen nada.
Nota: DROP
TABLE
hace un commit automáticamente con la
transacción activa,a no ser que use la palabra
TEMPORARY
.
La palabra TEMPORARY
tiene el siguiente
efecto:
El comando sólo borra tablas TEMPORARY
.
El comando no acaba una transacción en marcha.
No se chequean derechos de acceso. (Una tabla
TEMPORARY
es visible sólo para el
cliente que la ha creado, así que no es necesario.)
Usar TEMPORARY
es una buena forma de asegurar
que no borra accidentalmente una tabla no
TEMPORARY
.
RENAME TABLEtbl_name
TOnew_tbl_name
[,tbl_name2
TOnew_tbl_name2
] ...
Este comando renombra una o más tablas.
La operación de renombrar se hace automáticamente, lo que
significa que ningún otro flujo puede acceder a ninguna de las
tablas mientras se ejecuta el renombrado. Por ejemplo, si tiene
una tabla existente old_table
, puede crear
otra tabla new_table
con la misma estructura
pero vacía, y luego reemplazar la tabla existente con la vacía
como sigue:
CREATE TABLEnew_table
(...); RENAME TABLEold_table
TObackup_table
,new_table
TOold_table
;
Si el comando renombra más de una tabla, las operaciones de
renombrado se realizan de izquierda a derecha. Si quiere
intercambiar dos nombres de tablas, puede hacerlo así
(asumiendo que no existe ninguna tabla llamada
tmp_table
):
RENAME TABLEold_table
TOtmp_table
,new_table
TOold_table
,tmp_table
TOnew_table
;
Mientras haya dos bases de datos en el mismo sistema de ficheros puede renombrar una tabla para moverla de una base de datos a otra:
RENAME TABLEcurrent_db.tbl_name
TOother_db.tbl_name;
Cuando ejecuta RENAME
, no puede tener ninguna
tabla bloqueada o transacciones activas. Debe tener los permisos
ALTER
y DROP
en la tabla
original, y los permisos CREATE
y
INSERT
en la nueva tabla.
Si MySQL encuentra cualquier error en un renombrado múltiple, hace un renombrado inverso para todas las tablas renombradas para devolver todo a su estado original.
Sintaxis para una tabla:
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROMtbl_name
[WHEREwhere_definition
] [ORDER BY ...] [LIMITrow_count
]
Sintaxis para múltiples tablas:
DELETE [LOW_PRIORITY] [QUICK] [IGNORE]tbl_name
[.*] [,tbl_name
[.*] ...] FROMtable_references
[WHEREwhere_definition
]
O:
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROMtbl_name
[.*] [,tbl_name
[.*] ...] USINGtable_references
[WHEREwhere_definition
]
DELETE
borra los registros de
tbl_name
que satisfacen la condición
dada por where_definition
, y retorna
el número de registros borrados.
Si realiza un comando DELETE
sin cláusula
WHERE
se borran todos los registros. Una
forma más rápida de hacerlo, cuando no quiere saber el número
de registros borrados, se usa TRUNCATE TABLE
.
Consulte Sección 13.2.9, “Sintaxis de TRUNCATE
”.
Si borra el registro conteniendo el máximo valor para una
columna AUTO_INCREMENT
, el valor se reúsa
para una tabla BDB
, pero no para tablas
MyISAM
o InnoDB
. Si borra
todos los registros en la tabla con DELETE FROM
(sin cláusula
tbl_name
WHERE
) en modo AUTOCOMMIT
, la secuencia comienza para todos los tipos de tabla excepto
para InnoDB
y MyISAM
. Hay
algunas excepciones para este comportamiento para tablas
InnoDB
, como se discute en
Sección 15.6.3, “Cómo funciona una columna AUTO_INCREMENT
en InnoDB
”.
Para tablas MyISAM
y BDB
,
puede especificar una columna AUTO_INCREMENT
secundaria en una clave de múltiples columnas. En este caso, el
reúso de valores borrados del inicio de la secuencia se realiza
incluso para tablas MyISAM
. Consulte
Sección 3.6.9, “Utilización de AUTO_INCREMENT
”.
El comando DELETE
soporta los siguientes
modificadores:
Si especifica LOW_PRIORITY
, la ejecución
de DELETE
se retarda hasta que no hay
más clientes leyendo de la tabla.
Para tablas MyISAM
, si usa la palabra
QUICK
, el motor de almacenamiento no
mezcla las hojas del índice durante el borrado, que puede
acelerar algunos tipos de operaciones de borrado.
En MySQL 5.0, la palabra clave IGNORE
hace que MySQL ignore todos los errores durante el proceso
de borrar registros. (Los errores encontrados durante la
etapa de parseo se procesan de la forma habitual.) Los
errores que se ignoran debido al uso de esta opción se
retornan como advertencias.
La velocidad de las operaciones de borrado pueden verse
afectadas por factores discutidos en
Sección 7.2.16, “Velocidad de sentencias DELETE
”.
En tablas MyISAM
, los registros borrados se
mantienen en una lista enlazada y las operaciones
INSERT
siguientes reúsan antiguas posiciones
de registro. Para reclamar espacio no usado y reducir tamaño de
fichero, use el comando OPTIMIZE TABLE
o la
utilidad myisamchk para reorganizar las
tablas. OPTIMIZE TABLE
es más sencillo, pero
myisamchk es más rápido. Consulte
Sección 13.5.2.5, “Sintaxis de OPTIMIZE TABLE
” y
Sección 5.8.3.10, “Optimización de tablas”.
El modificador QUICK
afecta si las hojas del
índice es mezclan en operaciones de borrado. DELETE
QUICK
es más útil para aplicaciones en que los
valores del índice para registros borrados se replazan con
valores similares de registros insertados posteriormente. En
este caso, los agujeros dejados por los valores borrados se
reúsan.
DELETE QUICK
no es útil cuando los valores
borrados conducen a bloques de índices no rellenos con un rango
de valores índice para el que vuelven a ocurrir nuevas
inserciones. En este caso, el uso de QUICK
puede conducir a un gasto de espacio que queda sin reclamar.
Aquí hay un ejemplo de este escenario:
Cree una tabla que contenga una columna
AUTO_INCREMENT
indexada.
Inserta varios registros en la tabla. Cada inserción resulta en un valor índice que se añade al final del índice.
Borra un bloque de registros al final del rango de la
columna usando DELETE QUICK
.
En este escenario, los bloques de índice asociados con los
valores de índice borrado quedan sin rellenar pero no se
mezclan con otros bloques de índice debido al uso de
QUICK
. Quedan sin rellenar cuando hay nuevas
inserciones, ya que los nuevos registros no tienen valores
índice en el rango borrado. Además, quedan sin rellenar
incluso si luego usa DELETE
sin
QUICK
, a no ser que algunos de los valores de
índice borrados estén en los bloques de índice dentro o
adyacentes a los bloques no rellenos. Para reclamar el espacio
de índice sin usar bajo estas circunstancias use
OPTIMIZE TABLE
.
Si va a borrar varios registros de una tabla, puede ser más
sencillo usar DELETE QUICK
seguido por
OPTIMIZE TABLE
. Esto reconstruye el índice
en lugar de realizar varias operaciones de mezcla de bloques de
índice.
La opción de MySQL LIMIT
para
row_count
DELETE
le dice al servidor el máximo número
de registros a borrar antes de retornar el control al cliente.
Esto puede usarse para asegurar que un comando
DELETE
específico no tarada demasiado
tiempo. Puede simplemente repetir el comando
DELETE
hasta que el número de registros
afectados sea menor que el valor LIMIT
.
Si el comando DELETE
incluye una cláusula
ORDER BY
, los registros se borran en el
orden especificado por la cláusula. Esto es muy útil sólo en
conjunción con LIMIT
. Por ejemplo, el
siguiente ejemplo encuentra registros coincidentes con la
cláusula WHERE
ordenados por
timestamp_column
, y borra el primero (el más
viejo).
DELETE FROM somelog WHERE user = 'jcole' ORDER BY timestamp_column LIMIT 1;
Puede especificar múltiples tablas en un comando
DELETE
para borrar registros de una o más
tablas dependiendo de una condición particular en múltiples
tablas. Sin embargo, no puede usar ORDER BY
o
LIMIT
en un DELETE
de
múltiples tablas.
La parte table_references
lista las
tablas involucradas en el join. Esta sintaxis se describe en
Sección 13.2.7.1, “Sintaxis de JOIN
”.
Para la primera sintaxis, sólo los registros coincidentes de
las tablas listadas antes de la cláusula
FROM
se borran. Para la segunda sintaxis,
sólo los registros coincidentes de las tablas listadas en la
cláusula FROM
(antes de la cláusula
USING
) se borran. El efecto es que puede
borrar registros para varias tablas al mismo tiempo y tienen
tablas adicionales que se usan para buscar:
DELETE t1, t2 FROM t1, t2, t3 WHERE t1.id=t2.id AND t2.id=t3.id;
O:
DELETE FROM t1, t2 USING t1, t2, t3 WHERE t1.id=t2.id AND t2.id=t3.id;
Estos comandos usan las tres tablas al buscar registros a
borrar, pero borrar los registros coincidentes sólo para las
tablas t1
y t2
.
Los ejemplos anteriores muestran inner joins usando el operador
coma, pero comandos DELETE
de varias tablas
pueden usar cualquier tipo de join permitido por comandos
SELECT
tales como LEFT
JOIN
.
La sintaxis permite .*
tras los nombres de
tabla para compatibilidad con Access
.
Si usa un comando DELETE
de varias tablas
incluyendo tablas InnoDB
para las que hay
restricciones de clave foránea, el optimizador MySQL puede
procesar tablas en un orden ditinto del de su relación
padre/hijo. En este caso, el comando falla y se deshace. En su
lugar, debe borrar de una tabla úncia y confiar en la capacidad
de ON DELETE
que proporciona
InnoDB
para hacer que las otras tablas se
modifiquen correctamente.
Nota: En MySQL 5.0, debe usar el alias (si se dió) al referirse a un nombre de tabla:
En MySQL 4.1:
DELETE t1 FROM test AS t1, test2 WHERE ...
Borrados cruzados entre bases de datos se soportan para borrados de varias tablas, pero en este caso, debe referirse a las tablas sin usar alias. Por ejemplo:
DELETE test1.tmp1, test2.tmp2 FROM test1.tmp1, test2.tmp2 WHERE ...
Actualmente, no puede borrar desde una tabla y seleccionar de la misma tabla en una subconsulta.
DOexpr
[,expr
] ...
DO
ejecuta la expresión pero no retorna
ningún resultado. Esto es una abreviación de SELECT
, pero tiene la
ventaja que es más rápido cuando no le importa el resultado.
expr
, ...
DO
es útil principalmente con funciones que
tienen efectos colaterales, tales como
RELEASE_LOCK()
.
HANDLERtbl_name
OPEN [ ASalias
] HANDLERtbl_name
READindex_name
{ = | >= | <= | < } (value1
,value2
,...) [ WHEREwhere_condition
] [LIMIT ... ] HANDLERtbl_name
READindex_name
{ FIRST | NEXT | PREV | LAST } [ WHEREwhere_condition
] [LIMIT ... ] HANDLERtbl_name
READ { FIRST | NEXT } [ WHEREwhere_condition
] [LIMIT ... ] HANDLERtbl_name
CLOSE
El comando HANDLER
proporciona acceso directo
a las interfaces del motor de la tabla. En MySQL 5.0, está
disponible para tablas MyISAM
y
InnoDB
.
El comando HANDLER ... OPEN
abre una tabla,
haciéndola accesible mediante posteriores comandos
HANDLER ... READ
. Este objeto de tabla no se
comparte con otros flujos y no se cierra hasta que el flujo
llama HANDLER ... CLOSE
o el flujo termina.
Si abre la tabla usando un alias, referencias posteriores a la
tabla con otros comandos HANDLER
deben usar
el alias en lugar del nombre de la tabla.
La primera sintaxis HANDLER ... READ
recibe
un registro donde el índice especificado satisface los valores
dados y la condición WHERE
se cumple. Si
tiene un índice de múltiples columnas, especifique los valores
de la columna índice como una lista separada por comas. Los
valores epecificados para todas las columnas en el índice, o
los valores específicos para un prefijo a la izquierda de las
columnas índice. Suponga que un índice incluye tres columnas
llamadas col_a
, col_b
, y
col_c
, en ese orden. El comando
HANDLER
puede especificar valores para las
tres columnas en el índice, o para las columnas en el prefijo a
la izquierda. Por ejemplo:
HANDLER ...index_name
= (col_a_val,col_b_val,col_c_val) ... HANDLER ...index_name
= (col_a_val,col_b_val) ... HANDLER ...index_name
= (col_a_val) ...
La segunda sintaxis HANDLER ... READ
recibe
un registro de la tabla en orden del índice que cumple la
condición WHERE
.
La tercera sintaxis HANDLER ... READ
recibe
un registro de la tabla en orden de registro natural que cumple
la condición WHERE
. Es más rápido que
HANDLER
cuando se desea un escaneo completo de
tabla. El orden de registro natural es el orden en que se
almacenan los registros en un fichero de datos de una tabla
tbl_name
READ
index_nameMyISAM
. Este comando funciona para tablas
InnoDB
también, pero no hay tal concepto
porque no hay un fichero de datos separado.
Sin una cláusula LIMIT
, todas las formas de
HANDLER ... READ
reciben un único registros
si una está disponible. Para retornar un número específico de
registros, incluya una cláusula LIMIT
.
Tiene la misma sintaxis que para el comando
SELECT
. Consulte Sección 13.2.7, “Sintaxis de SELECT
”.
HANDLER ... CLOSE
cierra una tabla que se
abrió con HANDLER ... OPEN
.
Nota: Para emplear la interfaz
HANDLER
para referirse a una tabla
PRIMARY KEY
, use el identificador
`PRIMARY`
entrecomillado:
HANDLER tbl_name
READ `PRIMARY` > (...);
HANDLER
es un comando de bajo nivel. Por
ejemplo, no proporciona consistencia. Esto es, HANDLER
... OPEN
no toma una muestra de
la tabla, y no bloquea la tabla. Esto
significa que tras un comando HANDLER ...
OPEN
realizado, los datos de la tabla pueden ser
modificados (por este o por otro flujo) y estas modificaciones
pueden aparecer sólo parcialmente en escaneos HANDLER
... NEXT
o HANDLER ... PREV
.
Hay varias razones para usar la interfaz
HANDLER
en lugar de comandos
SELECT
normales:
HANDLER
es más rápido que
SELECT
:
Un objeto de tratamiento de motor de almacenamiento
designado se reserva para HANDLER ...
OPEN
. El objeto se reúsa para posteriores
comandos HANDLER
para esa tabla; no
necesita reinicializarse para cada una.
Hay menos parseo.
No hay sobrecarga del chequeo de consultas ni optimizador.
La tabla no tiene que estar bloqueada entre peticiones.
La interfaz del handler no tiene que propocionar una
vista de los datos consistente (por ejemplo, se permiten
dirty reads), así que el motor puede usar optimización
que SELECT
no permite.
HANDLER
hace mucho más fácil portar
aplicaciones que usen una interfaz tipo
ISAM
a MySQL.
HANDLER
le permite consultar una base de
datos de forma difícil o imposible de realizar con
SELECT
. La interfaz de
HANDLER
es una forma más natural de
consultar los datos cuando se trabaja con aplicaciones que
proporcionan una interfaz de usuario interactiva a la base
de datos.
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE] [INTO]tbl_name
[(col_name
,...)] VALUES ({expr
| DEFAULT},...),(...),... [ ON DUPLICATE KEY UPDATEcol_name
=expr
, ... ]
O:
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE] [INTO]tbl_name
SETcol_name
={expr
| DEFAULT}, ... [ ON DUPLICATE KEY UPDATEcol_name
=expr
, ... ]
O:
INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE] [INTO]tbl_name
[(col_name
,...)] SELECT ... [ ON DUPLICATE KEY UPDATEcol_name
=expr
, ... ]
INSERT
inserta nuevos registros en una tabla
existente. Las formas INSERT ... VALUES
y
INSERT ... SET
del comando insertan registros
basados en valores explícitamente especificados. La forma
INSERT ... SELECT
inserta registros
seleccionados de otra tabla o tablas. INSERT ...
SELECT
se discute en Sección 13.2.4.1, “Sintaxis de INSERT ... SELECT
”.
tbl_name
es la tabla en que los
registros deben insertarse. Las columnas para las que el comando
proporciona valores pueden especificarse como sigue:
La lista de nombres de columna o la cláusula
SET
indican las columnas explícitamente.
Si no especifica la lista de columnas para INSERT
... VALUES
o INSERT ... SELECT
,
los valores para cada columna en la tabla deben
proporcionarse en la lista VALUES
o por
el SELECT
. Si no sabe el orden de las
columnas en la tabla, use DESCRIBE
para
encontrarlo.
tbl_name
Los valores de columna pueden darse de distintos modos:
Si no está ejecutando el modo estricto, cualquier columna
que no tenga un valor asignado explícitamente recibe su
valor por defecto (explícito o implícito). Por ejemplo, si
especifica una lista de columnas que no nombra todas las
columnas en la tabla, las no nombradas reciben sus valores
por defecto. Los valores por defecto asignados se describen
en Sección 13.1.5, “Sintaxis de CREATE TABLE
”. Consulte
Sección 1.7.6.2, “Restricciones (constraints) sobre datos inválidos”.
Si quiere que un comando INSERT
genere un
error a no ser que especifique explícitamente valores para
todas las columnas que no tienen un valor por defecto, debe
usar modo STRICT
. Consulte
Sección 5.3.2, “El modo SQL del servidor”.
Use DEFAULT
para asignar a una columna
explícitamente su valor por defecto. Esto hace más fácil
escribir comandos INSERT
que asignan
valores a todas las columnas excepto unas pocoas, ya que le
permite evitar la escritura de una lista de valores
VALUES
incompleta. De otro modo, tendría
que escribir la lista de los nombres de columna
correspondientes a cada valor en la lista
VALUES
.
En MySQL 5.0, puede usar
DEFAULT(
como forma más general que puede usarse en expresiones para
producir un valor por defecto de una columna.
col_name
)
Si la lista de columnas y la lista VALUES
están vacías, INSERT
crea un registro
con cada conjunto de columnas con sus valores por defecto:
mysql> INSERT INTO tbl_name
() VALUES();
En modo STRICT
obtendrá un error si una
columna no tiene un valor por defecto. De otro modo, MySQL
usará el valor implícito para cualquier columna sin un
valor explícito por defecto definido.
Puede especificar una expresión
expr
para proporcionar un valor
de columna. Esto puede involucar convesión de tipos si el
tipo de la expresión no coincide con el tipo de la columna,
y la conversión de un valor dado puede resultar en
distintos valores insertados dependiendo del tipo de
columna. Por ejmplo, insertar la cadena
'1999.0e-2'
en una columna
INT
, FLOAT
,
DECIMAL(10,6)
, o YEAR
resulta en los valores 1999
,
19.9921
, 19.992100
, y
1999
insertados, respectivamente. La
razón de que el valor almacenado en las columnas
INT
y YEAR
sea
1999
es que la conversión
cadena-a-entero consulta sólo el trozo de la parte inicial
de la cadena que se puede considerar como un entero válido
o año. Para las columnas de coma flotante o punto fijo, la
conversión cadena-a-coma-flotante considera la cadena
entera un valor válido.
Una expresión expr
puede
referirse a cualquier columna que se haya asignado antes en
una lista de valores. Por ejemplo, puede hacer esto porque
el valor para col2
se refiere a
col1
, que se ha asignado préviamente:
mysql> INSERT INTOtbl_name
(col1
,col2
) VALUES(15,col1
*2);
Pero lo siguiente no es legal, ya que el valor para
col1
se refiere a
col2
, que se asigna tras
col1
:
mysql> INSERT INTOtbl_name
(col1
,col2
) VALUES(col2
*2,15);
Una excepción involucra a columnas que contienen valores
AUTO_INCREMENT
. Como el valor
AUTO_INCREMENT
se genera tras otras
asignaciones de valores, cualquier referencia a una columna
AUTO_INCREMENT
en la asignación retorna
un 0.
El comando INSERT
soporta los siguientes
modificadores:
Si usa la palabra DELAYED
, el servidor
pone el registro o registros a ser insertados en un búffer,
y el cliente realizando el comando INSERT
DELAYED
puede continuar. Si la tabla está en uso,
el servidor trata los registros. Cuando la tabla se libera,
el servidor comienza a insertar registros, chequeando
periódicamente para ver si hay alguna petición de lectura
para la tabla. Si la hay, la cola de registros retardados se
suspende hasta que la tabla se libera de nuevo. Consulte
Sección 13.2.4.2, “Sintaxis de INSERT DELAYED
”.
Si usa la palabra LOW_PRIORITY
, la
ejecución de INSERT
se retrasa hasta que
no hay otros clientes leyendo de la tabla. Esto incluye a
otros clientes que comiencen a leer mientras que los
clientes existentes están leyendo, y meintras el comando
INSERT LOW_PRIORITY
está en espera. Es
posible, por lo tanto, para un cliente que realice un
comando INSERT LOW_PRIORITY
esperar
durante mucho tiempo (o incluso para siempre) en un entorno
de muchas lecturas. (Esto es un contraste de INSERT
DELAYED
, que deja al cliente continuar. Consulte
Sección 13.2.4.2, “Sintaxis de INSERT DELAYED
”.) Tenga en cuenta que
LOW_PRIORITY
no debe usarse normalmente
con tablas MyISAM
y que hacerlo
deshabilita inserciones concurrentes. Consulte
Sección 14.1, “El motor de almacenamiento MyISAM
”.
Si especifica HIGH_PRIORITY
, deshabilita
el efecto de la opción
--low-priority-updates
si el servidor se
arrancó con esa opción. Hace que las insecionces
concurrentes no se usen.
Los valores afectados por un INSERT
pueden usarse usando la función
mysql_affected_rows()
de la API de C.
Consulte Sección 24.3.3.1, “mysql_affected_rows()
”.
Si usa la palabra IGNORE
en un comando
INSERT
, los errores que ocurren mientras
se ejecuta el comando se tratan como advertencias. Por
ejemplo, sin IGNORE
, un registro que
duplique un índice UNIQUE
existente o
valor PRIMARY KEY
en la tabla hace que un
error de clave duplicada en el comando se aborte. Con
IGNORE
, el registro todavía no se
inserta, pero no se muestra error. Las conversionse de datos
dispararían errores y abortarían el comando si no se
sepecificara IGNORE
. Con
IGNORE
, los valores inválidaos se
ajustan al valor más cercano y se insertan; las
advertencias se producen pero el comando no se aborta. Puede
determinar con la función mysql_info()
de la API de C cuántos registros se insertan realmente en
la tabla.
Si especifica ON DUPLICATE KEY UPDATE
, y se inserta
un registro que duplicaría un valor en un
índice UNIQUE
o PRIMARY
KEY
, se realiza un UPDATE
del
antiguo registro. Por ejemplo, si la columna
a
se declara como UNIQUE
y
contiene el valor 1
, los siguientes dos
comandos tienen efectos idénticos:
mysql> INSERT INTO table (a,b,c) VALUES (1,2,3) -> ON DUPLICATE KEY UPDATE c=c+1; mysql> UPDATE table SET c=c+1 WHERE a=1;
El valor de registros afectados es 1 si el registros se inserta como un nuevo registro y 2 si un valor existente se actualiza.
Nota: Si la columna
b
es única, el INSERT
sería equivalente a este comando UPDATE
:
mysql> UPDATE table SET c=c+1 WHERE a=1 OR b=2 LIMIT 1;
Si a=1 OR b=2
se cumple para varios
registros, sólo un registro se actualiza.
En general, debería intentar evitar usar una cláusula
ON DUPLICATE KEY
en tablas con claves únicas
múltiples.
MySQL 5.0 permite el uso de la función
VALUES(col_name)
en la cláusula
UPDATE
que se refiere a los valores de
columna de la porción INSERT
del comando
INSERT ... UPDATE
. En otras palabras,
VALUES(col_name)
en la cláusula
UPDATE
se refiere al valor de
col_name
que se insertarían, no
ocurre conflicto de clave duplicada. Esta función es
especialmente útil en inserciones de múltiples registros. La
función VALUES()
tiene sentido sólo en
comandos INSERT ... UPDATE
y retorna
NULL
de otro modo.
Ejemplo:
mysql> INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6) -> ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);
Este comando es idéntico a los siguientes dos comandos:
mysql> INSERT INTO table (a,b,c) VALUES (1,2,3) -> ON DUPLICATE KEY UPDATE c=3; mysql> INSERT INTO table (a,b,c) VALUES (4,5,6) -> ON DUPLICATE KEY UPDATE c=9;
Cuando usa ON DUPLICATE KEY UPDATE
, la
opción DELAYED
se ignora.
Puede encontrar el valor usado para una columna
AUTO_INCREMENT
usando la función SQL
LAST_INSERT_ID()
. Desde la API C, use la
función mysql_insert_id()
. Sin embargo,
debe tener en cuenta que las dos funciones no siempre se
comportan idénticamente. El comportamiento de comandos
INSERT
respecto a columnas
AUTO_INCREMENT
se discute en
Sección 12.9.3, “Funciones de información” y
Sección 24.3.3.34, “mysql_insert_id()
”.
Si usa un comando INSERT ... VALUES
con
listas de múltiples valores o INSERT ...
SELECT
, el comando retorna una cadena de información
en este formato:
Records: 100 Duplicates: 0 Warnings: 0
Records
indica el número de registros
procesados por el comando. (Este no es necesariamente el número
de registros realmente insertados, ya que
Duplicates
puede ser distinto a cero.)
Duplicates
indica el número de registros que
no pueden insertarse ya que duplicarían algunos valores de
índice únicos existentes Warnings
indicata
el número de intentos para insertar valores de columna que
fueron problemáticos por algo. Las advertencias pueden ocurrir
bajo cualquiera de las siguientes condiciones:
Insertar NULL
en una columna que se ha
declarado NOT NULL
. Para comandos
INSERT
de múltiples columnas o comandos
INSERT INTO... SELECT
, la columna se
asigna con el valor por defecto para el tipo de datos de la
columna. Este es 0
para tipos numéricos,
la cadena vacía (''
) para tipos de
cadenas, y el valor “cero” para tipos de fecha
y hora. Los comandos INSERT INTO ...
SELECT
se tratan del mismo modo que inserciones de
múltiples registros porque el servidor no examina el
resultado del SELECT
para ver si retorna
o no un único registro. (para un único registro
INSERT
, no hay ninguna advertencia cuando
NULL
se inserta en una columna
NOT NULL
. En lugar de eso, el comando
falla con un error.)
Poner en una columna numérica un valor fuera del rango de la columna. El valor se redondea al punto final del rango más cercano.
Asigne un valor tal como '10.34 a'
a una
columna numérica. El texto final se elimina y la parte
numérica se inserta. Si el valor de cadena no tiene parte
inicial numérica, la columna se pone a
0
.
Insertar una cadena en una columna de cadena
(CHAR
, VARCHAR
,
TEXT
, o BLOB
) que
excede la maxima longitud de la columna. El valor se trunca
a la máxima longitud de la columna.
Insertar un valor en una columna de fecha u hora que es ilegal para el tipo de la columna. La columna se asigna con el valor cero apropiado para el tipo.
Si usa la API de C, la cadena de información puede obtenerse
invocando la función mysql_info()
Consulte
Sección 24.3.3.32, “mysql_info()
”.
INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE] [INTO]tbl_name
[(col_name
,...)] SELECT ... [ ON DUPLICATE KEY UPDATEcol_name
=expr
, ... ]
Con INSERT ... SELECT
, puede insertar
rápidamente varios registros en un atabla desde una o varias
tablas.
Por ejemplo:
INSERT INTO tbl_temp2 (fld_id) SELECT tbl_temp1.fld_order_id FROM tbl_temp1 WHERE tbl_temp1.fld_order_id > 100;
La siguiente condición sirve para un comando INSERT
... SELECT
:
En MySQL 5.0, especifique IGNORE
explícitamente para ignorar registros que causarían
violaciones de clave duplicada.
No use DELAYED
con INSERT ...
SELECT
.
En MySQL 5.0, la tabla objetivo del comando
INSERT
puede aparecer en la cláusula
FROM
de la parte
SELECT
de la consulta. (Esto no era
posible en algunas versiones antiguas de MySQL.)
Las columnas AUTO_INCREMENT
funcionan
normalmente.
Para asegurar que el log binario puede usarse para recrear
las tablas originales, MySQL no permite inserciones
concurrentes durante INSERT ... SELECT
.
Actualmente, no puede insertar en una tabla y seleccionar de la misma tabla en una subconsulta.
En las partes de valores de ON DUPLICATE KEY
UPDATE
puede referirse a una columna en otras
tablas, mientras no use GROUP BY
en la
parte SELECT
. Un efecto lateral es que
debe calificar los nombres de columna no únicos en la parte
de valores.
Puede usar REPLACE
en lugar de
INSERT
para sobreescribir registros
antiguos REPLACE
es la contraparte de
INSERT IGNORE
en el tratamiento de nuevos
registros que contienen valores de clave única que duplican
registros antiguos: Los nuevos registros se usan para
reemplazar los antiguos registros en lugar de descartarlos.
INSERT DELAYED ...
La opción DELAYED
para el comando
INSERT
es una extensión de MySQL del
estándar SQL muy útil si tiene clientes que no pueden
esperar a que se complete el INSERT
. Este
es un problema común cuando usa MySQL para loguear y
periódicamente ejecuta comandos SELECT
y
UPDATE
que tardan mucho tiempo en
completarse.
Cuando un cliente usa INSERT DELAYED
,
obtiene un ok del servidor una vez, y el registro se encola
para insertarse cuando la tabla no está en uso por otro
flujo.
Otro beneficio de usar INSERT DELAYED
es
que las inserciones desde varios clientes se tratan juntas y
se escriben en un bloque. Esto es mucho más rápido que
realizar inserciones separadas.
Hay algunas restricciones al uso de
DELAYED
:
En MySQL 5.0, INSERT DELAYED
funciona
sólo con tablas MyISAM
y
MEMORY
. Para tablas
MyISAM
, si no hay bloques libres en
medio del fichero de datos, se soportan comandos
SELECT
y INSERT
concurrentes. Bajo estas circunstáncias, muy raramente
necesitará usar INSERT DELAYED
con
MyISAM
. Consulte
Sección 14.1, “El motor de almacenamiento MyISAM
” y
Sección 14.3, “El motor de almacenamiento MEMORY
(HEAP
)”.
En MySQL 5.0, INSERT DELAYED
debe
usarse sólo para comandos INSERT
que
especifiquen una lista de valores. El servidor ignora
DELAYED
para comandos INSERT
DELAYED ... SELECT
.
El servidor ignora DELAYED
para
comandos INSERT DELAYED ... ON DUPLICATE
UPDATE
.
Debido a que el comando retorna inmediatamente antes que
los registros se inserten, no puede usar
LAST_INSERT_ID()
para obtener el valor
AUTO_INCREMENT
que el comando genera.
Los registros DELAYED
no son visibles
por los comandos SELECT
hasta que se
hayan insertado realmente.
DELAYED
se ignora en la replicación de
esclavos porque puede causar que el esclavo tenga
distintos datos que el maestro.
Tenga en cuenta que los registros encolados se tratan sólo en
memoria hasta que se insertan en la tabla. Esto significa que
si termina mysqld forzadamente (por
ejemplo, con kill -9
) o si
mysqld muere inesperadamente, cualquier
registro encolado que no se escriba en disco se pierde.
A continuación se describe en detalle qué ocurre cuando usa
la opción DELAYED
con
INSERT
o REPLACE
. En
esta descriión, el “flujo” es el flujo que
recibe un comando INSERT DELAYED
y
“handler” es el flujo que trata todos los
comandos INSERT DELAYED
para una tabla
particular.
Cuando un flujo ejecuta un comando
DELAYED
para una tabla, un flujo
handler se crea para procesar todos los comandos
DELAYED
para la tabla, si tal handler
no existía préviamente.
El flujo chequea si el handler ha adquirido préviamente
un bloqueo DELAYED
; si no, le dice al
flujo handler que lo haga. El bloqueo
DELAYED
puede obtenerse incluso si
otros flujos tienen el bloqueo READ
o
WRITE
en la tabla. Sin embargo, el
handler espera a todos los bloqueos ALTER
TABLE
o FLUSH TABLES
para
asegurar que la estructura de tabla está actualizada.
El flujo ejecuta el comando INSERT
,
pero en lugar de escribir el registro en la tabla, pone
una copia del registro final en una cola administrada por
el flujo handler. Cualquier error de sintaxis es detectado
por el flujo y se reporta al programa cliente.
El cliente no puede obtener del servidor el número de
registros duplicados o el valor
AUTO_INCREMENT
del registro resultante,
ya que INSERT
retorna antes que se
complete la operación de inserción. (Si usa la API C, la
función mysql_info()
no retorna nada
inteligible por la misma razón.)
El log binario se actualiza por parte del flujo handler cuando el registro se inserta en la tabla. En caso de inserciones de múltiples registros, el log binario se actualiza cuando el primer registro se inserta.
Tras cada delayed_insert_limit
los
registros se escriben, el handler chequea si algún
comando SELECT
todavía está
pendiente. Si es así, les permite ejecutarse antes de
continuar.
Cuando el handler no tiene más registros en su cola, la
tabla se desbloquea. Si no se reciben nuevos comandos
INSERT DELAYED
en
delayed_insert_timeout
segundos, el
handler termina.
Si más de delayed_queue_size
registros
están pendientes en una cola de handler específica, el
flujo que pida el INSERT DELAYED
espera
hasta que haya espacio en la cola. Esto se hace para
asegurar que mysqld no usa toda la
memoria para la cola de memoria retrasada.
El flujo handler se muestra en l lista de procesos MySQL
con delayed_insert
en la columna
Command
. Si muere si ejecuta un
comando FLUSH TABLES
o puede matarlo
con KILL thread_id
. Sin embargo, antes
de salir, primero almacena todos los registros encolados
en la tabla. Durante esta operación no acepta ningún
nuevo comando INSERT
de otros flujos.
Si ejecuta un comando INSERT DELAYED
a
continuación, se crea un nuevo flujo handler.
Tenga en cuenta que esto significa que comandos
INSERT DELAYED
tienen mayor prioridad
que comandos INSERT
normales si hay un
handler INSERT DELAYED
en ejecución.
Otros comandos de actualización tienen que esperar hast
que la cola INSERT DELAYED
está
vacía, alguien termine el flujo handler (con
KILL thread_id
), o alguien ejecute un
FLUSH TABLES
.
Las siguientes variables de estado proporcionan
información acerca de comandos INSERT
DELAYED
:
Variable de estado | Significado |
Delayed_insert_threads | Número de flujos handler |
Delayed_writes | Número de registros escritos con INSERT DELAYED |
Not_flushed_delayed_rows | Número de registros esperando a ser escritos |
Puede ver estas variables ejecutando un comando
SHOW STATUS
o mysqladmin
extended-status.
Tenga en cuenta que INSERT DELAYED
es más
lento que un INSERT
normal si la tabla no
está en uso. También hay una sobrecarga adicional para el
servidor debido a que tiene que tratar un flujo separado para
cada tabla en que haya registros retardados. Esto significa
que debe usar INSERT DELAYED
sólo cuando
esté realmente seguro que lo necesita.
LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name
.txt' [REPLACE | IGNORE] INTO TABLEtbl_name
[FIELDS [TERMINATED BY 'string
'] [[OPTIONALLY] ENCLOSED BY 'char
'] [ESCAPED BY 'char
' ] ] [LINES [STARTING BY 'string
'] [TERMINATED BY 'string
'] ] [IGNOREnumber
LINES] [(col_name_or_user_var
,...)] [SETcol_name
=expr
,...)]
El comando LOAD DATA INFILE
lee registros
desde un fichero de texto a una tabla a muy alta velocidad. El
nombre de fichero debe darse como una cadena literal.
Para más información acerca de la eficiencia de
INSERT
contra LOAD DATA
INFILE
y acelerar LOAD DATA INFILE
,
consulte Sección 7.2.14, “Velocidad de la sentencia INSERT
”.
En MySQL 5.0, el conjunto de carácteres indicado por la
variable de sistema character_set_database
se
usa para interpretar la información en el fichero. SET
NAMES
y el valor de
character_set_client
no afecta la
interpretación de la entrada.
Puede cargar ficheros de datos usando la utilidad
mysqlimport ; opera enviando un comando
LOAD DATA INFILE
al servidor. La opción
--local
hace que
mysqlimport lea ficheros de datos desde el
equipo cliente. Puede especificar la opción
--compress
para obtener un mejor rendimiento
en redes lentas si el cliente y el servidor soportan el
protocolo comprimido. Consulte Sección 8.9, “El programa para importar datos mysqlimport”.
Si usa LOW_PRIORITY
, la ejecución del
comando LOAD DATA
se retarda hasta que no
haya más clientes leyendo de la tabla.
Si especifica CONCURRENT
con una tabla
MyISAM
que satisfaga la condición para
inserciones concurrentes (esto es, no contiene bloques libres en
medio), entonces otros flujos pueden recibir datos desde la
tabla mientras se ejecuta LOAD DATA
. Usar
esta opción afecta al rendimiento de LOAD
DATA
ligeramente, incluso si no hay otro flujo usando
la tabla al mismo tiempo.
Si se especifica LOCAL
, se interpreta
respecto al cliente final de la conexión:
Si se especifica LOCAL
, el fichero se lee
por parte del programa cliente en el equipo cliente y se
envía al servidor. El fichero puede darse como una ruta
completa para especificar su localización exacta. Si se da
como ruta relativa, el nombre se interpreta relativo al
directorio en que el cliente se inició.
Si no se especifica LOCAL
, el fichero no
debe localizarse en el equipo sevidor y se lee directamente
por el servidor.
Al localizar ficheros en el equipo servidor, el servidor usa las siguientes reglas:
Si se da una ruta absoluta, el servidor usa la ruta como tal.
Si se da una ruta relativa con uno o más componentes el servidor busca este fichero relativo al directorio de datos del servidor.
Si se da un nombre de fichero sin componentes, el servidor busca el fichero en el directorio de base de datos de la base de datos por defecto.
Tenga en cuenta que estas reglas significan que un fichero
llamado ./myfile.txt
se lee del directorio
de datos del servidor, mientras que el mismo fichero llamado
como myfile.txt
se lee desde el directorio
de base de datos de la base de datos por defecto. Por ejemplo,
el siguiente comando LOAD DATA
lee el fichero
data.txt
del directorio de la base de datos
para db1
porque db1
es la
base de datos actual, incluso si el comando carga
explícitamente el fichero en una tabla en la base de datos
db2
:
mysql> USE db1; mysql> LOAD DATA INFILE 'data.txt' INTO TABLE db2.my_table;
Tenga en cuenta que las rutas de windows se especifican usando barras en lugar de antibarras. Si usa barras, debe doblarlas.
Por razones de seguridad, al leer ficheros de texto localizados
en el servidor, los ficheros deben residir en el directorio de
la base de datos o ser leíbles por todo el mundo. Además, para
usar LOAD DATA INFILE
en ficheros del
servidor, debe tener el permiso FILE
.
Consulte Sección 5.6.3, “Privilegios de los que provee MySQL”.
Usar LOCAL
es un poco más lento que dejar al
servidor acceder al fichero directamente, porque el contenido
del fichero debe enviarse por la conexión desde el cliente al
servidor . Por otra parte, no necesita el permiso
FILE
para cargar ficheros locales.
En MySQL 5.0, LOCAL
funciona sólo si su
servidor y su cliente lo tienen activado. Por ejemplo, si
mysqld se arranca con
--local-infile=0
, entonces
LOCAL
no funciona. Consulte
Sección 5.5.4, “Cuestiones relacionadas con la seguridad y LOAD DATA LOCAL
”.
Si necesita LOAD DATA
para leer desde un
pipe, puede usar la siguiente técnica (aquí cargamos el
listado del directorio /
en una tabla):
mkfifo /mysql/db/x/x chmod 666 /mysql/db/x/x find / -ls > /mysql/db/x/x mysql -e "LOAD DATA INFILE 'x' INTO TABLE x" x
Las palabaras REPLACE
y
IGNORE
controlan el tratamiento de registros
de entrada que duplican registros existentes en claves únicas.
Si especifica REPLACE
, los registros de
entrada reemplazan registros existentes (en otras palabras, los
registros que tienen el mismo valor para una clave primaria o
única que un registro existente). Consulte
Sección 13.2.6, “Sintaxis de REPLACE
”.
Si especifica IGNORE
, los registros de
entrada que dupliquen un registro existente en una clave única
se ignoran. Si no especifica ninguna opción, el comportamiento
depende de si la palabra LOCAL
se ha
especificado o no. Sin LOCAL
, ocurre un error
cuando se encuentra un valor de clave duplicado, y el resto del
fichero de texto se ignora. Con LOCAL
, el
comportamiento por defecto es el mismo que si se especifica
IGNORE
, esto es porque el servidor no tiene
forma de parar la transmisión del fichero en medio de la
operación.
Si quiere ignorar restricciones de clave foránea durante la
operación de carga, puede realizar un comando SET
FOREIGN_KEY_CHECKS=0
antes de ejecutar LOAD
DATA
.
Si usa LOAD DATA INFILE
en una tabla vacía
MyISAM
, todos los índices no únicos se
crean en batch separados (como para REPAIR
TABLE
). Esto hace LOAD DATA INFILE
mucho más rápido cuando tiene varios índices. Normalmente
esto es muy rápido, pero en algunos casos extromos, puede crear
los índices incluso más rápido desactivándolos con
ALTER TABLE ... DISABLE KEYS
antes de cargar
el fichero en la tabla y usar ALTER TABLE ... ENABLE
KEYS
para recrear los índices tras cargar el fichero.
Consulte Sección 7.2.14, “Velocidad de la sentencia INSERT
”.
LOAD DATA INFILE
es el complemento de
SELECT ... INTO OUTFILE
. (Consulte
Sección 13.2.7, “Sintaxis de SELECT
”.) Para escribir datos de una tabla en
un fichero use SELECT ... INTO OUTFILE
. Para
leer el fichero de nuevo en una tabla, use LOAD DATA
INFILE
. La sintaxis de las cláusulas
FIELDS
y LINES
es la misma
para ambos. Ambas son opcionales, pero FIELDS
debe preceder a LINES
si se especifican
ambas.
Si especifica una cláusula FIELDS
, cada una
de sus subcláusulas (TERMINATED BY
,
[OPTIONALLY] ENCLOSED BY
, y ESCAPED
BY
) también es opcional, excepto que debe especificar
al menos una de ellas.
Si no especifica una cláusula FIELDS
, por
defecto es como si hubiera escrito esto:
FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\'
Si no especifica una cláusula LINES
, por
defecto es como si hubiera escrito esto:
LINES TERMINATED BY '\n' STARTING BY ''
En otras palabras, por defecto LOAD DATA
INFILE
actúa como sigue al leer la entrada:
Busca delimitadores de línea como nuevas líneas.
No ignora ningún prefijo de línea.
Rompe las líneas en campos con los tabuladores.
No espera campos entrecomillados dentro de ningún carácter delimitador.
Interpreta las ocurrencias de tabuladores, nuevas líneas o
'\
' precedidas por '\
'
como carácteres literales que son parte de valores de
campos.
Por defecto SELECT ... INTO OUTFILE
actúa
como sigue al escribir la salida:
Escribe tabuladores entre campos.
No entrecomilla los campos.
Usa '\
' para escapar las instancias de
tabuladores, nuevas líneas o '\
' que
ocurren entre valores de campos.
Escribe nuevas líneas al final de las líneas.
Tenga en cuenta que para escribir FIELDS ESCAPED BY
'\\'
, debe escribir dos antibarras para que se
interprete como una única antibarra.
Nota: Si ha generado el fichero
de texto en un sistema Windows , puede tener que usar
LINES TERMINATED BY '\r\n'
para leer
correctamente el fichero, ya que los programas de Windows
típicamente usan dos carácteres como terminadores de línea .
Algunos programas como WordPad, pueden usar
\r
como terminador de línea al escribir
ficheros. Para leer tales ficheros, use LINES
TERMINATED BY '\r'
.
Si todas las líneas que quiere leer tienen un prefijo común
que quiere ignorar, puede usar LINES STARTING BY
'
para
ignorar el prefijo (y cualquier cosa antes del mismo). Si una
línea no incluye el prefijo, la línea entera se ignora.
Nota
prefix_string
'prefix_string
puede ocurrir en medio de una
línea.
Ejemplo:
mysql> LOAD DATA INFILE '/tmp/test.txt' -> INTO TABLE test LINES STARTING BY "xxx";
Con esto puede leer en un fichero que contenga algo como:
xxx"row",1 something xxx"row",2
Y obtener los datos ("row",1)
y
("row",2)
.
La opción IGNORE
puede usarse para ignorar líneas al inicio del
fichero. Por ejemplo, puede usar number
LINESIGNORE 1
LINES
para ignorar una cabecera inicial que contenga
los nombres de las columnas:
mysql> LOAD DATA INFILE '/tmp/test.txt' -> INTO TABLE test IGNORE 1 LINES;
Cuando usa SELECT ... INTO OUTFILE
junto con
LOAD DATA INFILE
para escribir datos desde
una base de datos en un fichero y luego lee datos del fichero de
nuevo en la base de datos, las opciones de tratamiento de
fichero y de línea para ambos comandos deben coincidir. De otro
modo, LOAD DATA INFILE
no interpreta los
contenidos del fichero correctamente. Suponga que usa
SELECT ... INTO OUTFILE
para escribir un
fichero con campos delimitados por comas:
mysql> SELECT * INTO OUTFILE 'data.txt' -> FIELDS TERMINATED BY ',' -> FROM table2;
Para leer el fichero delimitado por comas, el comando correcto sería:
mysql> LOAD DATA INFILE 'data.txt' INTO TABLE table2 -> FIELDS TERMINATED BY ',';
Si en lugar de esto trata de leer en el fichero con el comando
mostrado aquí, no funcionaría porque le dice a LOAD
DATA INFILE
que busque tabuladores entre campos:
mysql> LOAD DATA INFILE 'data.txt' INTO TABLE table2 -> FIELDS TERMINATED BY '\t';
El resultado esperado es que cada línea de entrada se interprete como un único campo.
LOAD DATA INFILE
puede usarse para leer
ficheros obtenidos de fuentes externas. Por ejemplo, un fichero
en formato dBASE tiene campos separados por comas y
entrecomillados por comillas dobles. Si las líneas en el
fichero se terminan con nuevas líneas, el comando mostrado
aquí ilustra las opciones de campo y línea que debería usar
para cargar el fichero:
mysql> LOAD DATA INFILE 'data.txt' INTO TABLE tbl_name
-> FIELDS TERMINATED BY ',' ENCLOSED BY '"'
-> LINES TERMINATED BY '\n';
Cualquiera de las opciones de tratamiento de campo o línea
pueden especificarse como una cadena vacía
(''
). Si no está vacía, los valores
FIELDS [OPTIONALLY] ENCLOSED BY
y
FIELDS ESCAPED BY
deben ser un único
carácter. Los valores FIELDS TERMINATED BY
,
LINES STARTING BY
, y LINES
TERMINATED BY
pueden tener más de un carácter . Por
ejemplo, para escribir líneas terminadas por parejas de retorno
de carro y nueva línea, o para leer un fichero conteniendo
tales líneas, especifique una cláusula LINES
TERMINATED BY '\r\n'
.
Para leer un fichero que contenga bromas separadas por líneas
consistentes de %%
, puede hacer lo siguiente
mysql> CREATE TABLE jokes -> (a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, -> joke TEXT NOT NULL); mysql> LOAD DATA INFILE '/tmp/jokes.txt' INTO TABLE jokes -> FIELDS TERMINATED BY '' -> LINES TERMINATED BY '\n%%\n' (joke);
FIELDS [OPTIONALLY] ENCLOSED BY
controla el
entrecomillado de los campos. Para la salida (SELECT
... INTO OUTFILE
), si omite la palabra
OPTIONALLY
, todos los campos se delimitan por
el carácter ENCLOSED BY
. Un ejemplo de tal
salida (usando coma como el delimitador de campo) se muestra
aquí:
"1","a string","100.20" "2","a string containing a , comma","102.20" "3","a string containing a \" quote","102.20" "4","a string containing a \", quote and comma","102.20"
Si especifica OPTIONALLY
, el carácter
ENCLOSED BY
se usa sólo para delimitar
valores en columnas que tienen datos de cadenas (tales como
CHAR
, BINARY
,
TEXT
, o ENUM
):
1,"a string",100.20 2,"a string containing a , comma",102.20 3,"a string containing a \" quote",102.20 4,"a string containing a \", quote and comma",102.20
Tenga en cuenta que la ocurrencias del carácter
ENCLOSED BY
dentro de un campo se escapan
mediante un prefijo del carácter ESCAPED BY
.
También tenta en cuenta que si especifica un valor
ESCAPED BY
vacío, es posible generar salida
que no puede leerse correctamente con LOAD DATA
INFILE
. Por ejemplo, la salida precedente tendría la
siguiente apariencia si el carácter de escape estuviera vacío.
Observe que el segundo campo en la cuarta línea contiene una
coma siguiendo la delimitación, que (erróneamente) parece que
termine el campo:
1,"a string",100.20 2,"a string containing a , comma",102.20 3,"a string containing a " quote",102.20 4,"a string containing a ", quote and comma",102.20
Para entrada, el carácter ENCLOSED BY
, si
está presente, se elimina del final de los valores de campos .
(Esto es cierto se especifique OPTIONALLY
o
no; OPTIONALLY
no tiene efecto en la
interpretación de la entrada.) Las ocurrencias del carácter
ENCLOSED BY
prececdidas por el carater
ESCAPED BY
se interpretan como parte del
campo actual.
Si el campo comienza con el carácter ENCLOSED
BY
, las instancias del mismo se reorganizan como
terminadores del campo sólo si van seguidas por el campo o la
secuencia TERMINATED BY
. Para evitar
ambigüedad, las ocurrencias del carácter ENCLOSED
BY
dentro de un campo se pueden doblar y se
interpretan como una única instancia del carácter. Por
ejemplo, si se especifica ENCLOSED BY '"'
,
la delimitación se trata como se muestra aquí:
"The ""BIG"" boss" -> The "BIG" boss The "BIG" boss -> The "BIG" boss The ""BIG"" boss -> The ""BIG"" boss
FIELDS ESCAPED BY
controla cómo escribir o
leer carácteres especiales. Si el carácter FIELDS
ESCAPED BY
no está vacío, se usa como prefijo para
los siguientes carácteres de salida:
El carácter FIELDS ESCAPED BY
El carácter FIELDS [OPTIONALLY] ENCLOSED
BY
El primer carácter de los valores FIELDS
TERMINATED BY
y LINES TERMINATED
BY
ASCII 0
(lo que realmente se escribe a
continuación del carácter de escape es
'0
' en ASCCI, no un byte con valor cero)
Si el carácter FIELDS ESCAPED BY
está
vacío, no se escapan carácteres y NULL
se
muestra como NULL
, no \N
.
Probablemente no es una buena idea especificar un carácter de
escape vacío, particularmente si los valores de campos en sus
datos contienen cualquiera de los carácteres en la lista dada.
Para entrada, si el carácter FIELDS ESCAPED
BY
no está vacío, las ocurrencias del mismo se
eliminan y el siguiente carácter se toma literalmente como
parte del campo. Las excepciones son un '0
'
escapado o 'N
' (por ejemplo,
\0
o \N
si el carácter de
escape es '\
'). Estas secuencias se
interpretan como ASCII NUL (un byte con valor cero) y
NULL
. Las reglas para tratamiento de
NULL
se describen posteriormente.
Para más infomación de la sintaxis de escape
'\
' consulte Sección 9.1, “Valores literales”.
En ciertos casos, las opciones de tratamiento de campos y línea interactúan:
Si LINES TERMINATED BY
es una cadena
vacío y FIELDS TERMINATED BY
no está
vacío, las líneas se terminan con FIELDS
TERMINATED BY
.
Si los valores FIELDS TERMINATED BY
y
FIELDS ENCLOSED BY
están vacíois
(''
), se usa un formato fijo de registro
(no delimitado). Con este formato, no se usan delimitadores
entre campos (pero puede tener un terminador de línea). En
su lugar, los valores de columna se escriben y leen usando
los anchos de muestra de las columnas. Por ejemplo, si una
columna se declara como INT(7)
, los
valores para la columna se escriben usando campos de siete
carácteres. En la entrada, los valores para la columna se
obtienen leyendo siete carácteres.
LINES TERMINATED BY
se usa para separar
líneas. Si una línea no contiene todos los campos, el
resto de columnas se asignan con sus valores por defecto. Si
no tiene un terminador de línea, debe asignarlo a
''
. En este caso, el fichero de texto
debe contener todos los campos para cada registro.
El formato fijo de registro también afecta al tratamiento
de valores NULL
, como se describe
posteriormente. Tenga en cuenta que el formato de tamaño
fijo no funciona si está usando un conjunto de carácteres
multi byte.
El tratamiento de valores NULL
varía en
función de las opciones FIELDS
y
LINES
en uso:
Para los valores FIELDS
y
LINES
por defecto,
NULL
se escribe como
\N
para la salida, y
\N
para la entrada se lee como
NULL
(considerando que el carácter
ESCAPED BY
es '\
').
Si FIELDS ENCLOSED BY
no está vacílo,
un campo que contenga el literal NULL
como valor se lee como el valor NULL
.
Esto difiere de la palabra NULL
delimitada por carácteres FIELDS ENCLOSED
BY
, que se lee como la cadena
'NULL'
.
Si FIELDS ESCAPED BY
está vacío,
NULL
se escribe como la palabra
NULL
.
Con formato fijo de registro (lo que ocurre cuando
FIELDS TERMINATED BY
y FIELDS
ENCLOSED BY
están vacíos),
NULL
se escribe como una cadena vacía.
Teng en cuenta que esto hace que ambos valores
NULL
y cadenas vacías en la tabla sean
indistinguibles cuando se escriben en el fichero ya que
ambos se escriben como cadenas vacías. Si necesita
distinguir entre ambos al leer del fichero, no debe usar el
formato de registro fijo.
Algunos casos no son soportados por LOAD DATA
INFILE
:
Registros de tamaño fijo (FIELDS TERMINATED
BY
y FIELDS ENCLOSED BY
ambos
vacíos) y columnas BLOB
o
TEXT
.
Si especifica un separador que es igual o prefijo de otro,
LOAD DATA INFILE
no será capaz de
interpretar la entrada correctamente. Por ejemplo, la
siguiente cláusula FIELDS
causaría
problemas:
FIELDS TERMINATED BY '"' ENCLOSED BY '"'
Si FIELDS ESCAPED BY
está vacío, un
valor que contenga una ocurrencia de FIELDS
ENCLOSED BY
o LINES TERMINATED
BY
seguido por el valor FIELDS TERMINATED
BY
causa que LOAD DATA INFILE
pare de leer un campo o línea demasiado rápido. Esto
ocurre porque LOAD DATA INFILE
no puede
determinar apropiadamente dónde acaba el campo o línea.
El siguiente ejemplo carga todas las columnas de la tabla
persondata
:
mysql> LOAD DATA INFILE 'persondata.txt' INTO TABLE persondata;
Por defecto, cuando no se proporciona una lista al final de un
comando LOAD DATA INFILE
, las líneas de
entrada se espera que contengan un campo para cada columna de la
tabla. Si quiere cargar sólo algunas columnas de una tabla,
especifique una lista de columnas:
mysql> LOAD DATA INFILE 'persondata.txt' -> INTO TABLE persondata (col1,col2,...);
Debe especificar una lista de columnas si el orden de los campos del fichero de entrada difiere del orden de las columnas en la tabla. De otro modo, MySQL no puede decir cómo hacer coincidir los campos de entrada con las columnas de la tabla.
Antes de MySQL 5.0.3, la lista de columnas debe contener sólo
nombres de columnas en la tabla que se carga, y la cláusula
SET
no se soporta. Desde MySQL 5.0.3, la
lista de columnas puede contener nombres de columna o variables
y la cláusula SET
se soporta. Esto le
permite asignar valores de entrada a variables de usuario, y
luego realizar transformaciones on estos valores antes de
asignar los resultados a las columnas.
Las variables de usuario en la cláusula SET
puede usarse de distintos modos. El siguiente ejemplo usa la
primera columna en el fichero de datos directamente para el
valor de t1.column1
, y asigna la segunda
columna a una variable de usuario que está sujeta a una
operación de división antes de ser usada por el valor de
t2.column2
:
LOAD DATA INFILE 'file.txt' INTO TABLE t1 (column1, @var1) SET column2 = @var1/100;
La cláusula SET
puede usarse para
proporcionar valores no derivados del fichero de entrada. Los
siguientes comandos actualizan column3
con la
fecha y hora actuales:
LOAD DATA INFILE 'file.txt' INTO TABLE t1 (column1, column2) SET column3 = CURRENT_TIMESTAMP;
También puede descartar un valor de entrada asignándolo a una variable de usuario y no asignando la variable a una columna de tabla:
LOAD DATA INFILE 'file.txt' INTO TABLE t1 (column1, @dummy, column2, @dummy, column3);
El uso de la lista de columnas/variables y la cláusula
SET
está sujeto a las siguientes
restricciones:
Las asignaciones en la cláusula SET
deben tener sólo nombres de columna en el lado izquierdo
del operador de asignación.
Puede usar subconsultas en la parte derecha de la
asignación de SET
. Una subconsulta que
retorne un valor a ser asignado a otra coluimna sólo puede
ser una subconsulta escalar. Además, no puede usar una
subconsulta para seleccionar desde la tabla que se está
cargando.
Las líneas ignoradas por un cláusula
IGNORE
no se procesan por parta de la
lista de columnas/variables o por la cláusula
SET
.
Las variables de usuario no pueden usarse al cargar datos con formato de registo ya que las variables de usuario no tienen un ancho de muestra.
Al procesar una línea de entrada, LOAD DATA
la divide en campos y usa los valores según la lista de
columnas/ variables y la cláusula SET
, si
están presentes. A continuación se inserta el registro
resultante en la tabla. Si hay disparadores BEFORE
INSERT
o AFTER INSERT
para la
tabla, se activan antes o después de insertar el registro,
respectivamente.
Si una línea de entrada tiene demasiados campos, los campos extra se ignoran y el número de advertencias se incrementa.
Si una línea de entrada no tiene suficientes campos, las
columnas de la tabla que no tienen entrada adquieren su valor
por defecto. Los valores por defecto se describen en
Sección 13.1.5, “Sintaxis de CREATE TABLE
”.
Un valor de campo vacío se interpreta de forma distinta que si el valor no está presente:
Para tipos de cadenas, la columna adquiere la cadena vacía.
Para tipos numéricos, la columna recibe el valor
0
.
Para tipos de fecha y hora, la columna obtiene el valor “cero” apropiado para el tipo. Consulte Sección 11.3, “Tipos de fecha y hora”.
Estos son los mismos valores que resultan si asigna una cadena
vacía explícitamente a un tipo de cadena de carácteres,
numérico o de fecha u hora en un comando
INSERT
o UPDATE
statement.
Las columnas TIMESTAMP
obtienen la fecha y
hora actuales sólo si hay un valor NULL
para
la columna (esto es, \N
), o (para la primera
columna TIMESTAMP
únicamente) si se omite
TIMESTAMP
de la lista de campos cuando se
especifica una.
LOAD DATA INFILE
trata todas las entradas
como cadenas, asi que no puede usar valores numéricos para
columnas ENUM
o SET
del
modo en que puede hacerlo con comandos INSERT
. Todos los valores ENUM
y
SET
deben especificarse como cadenas.
Cuando acaba el comando LOAD DATA INFILE
,
retorna una cadena de información con el siguiente formato:
Records: 1 Deleted: 0 Skipped: 0 Warnings: 0
Si usa la API de C, puede obtener información acerca del
comando mediante la función mysql_info()
.
Consulte Sección 24.3.3.32, “mysql_info()
”.
Las advertencias se producen bajo las mismas circunstancias que
cuando los valores se insertan mediante el comando
INSERT
(consulte Sección 13.2.4, “Sintaxis de INSERT
”),
excepto que LOAD DATA INFILE
también genera
advertencias cuando hay muy pocos o demasiados campos en el
registro de entrada. Las advertencias no se almacenan en ningún
lugar; el número de las mismas puede usarse sólo como
indicación de si todo ha ido bien.
En MySQL 5.0, puede usar SHOW WARNINGS
para
obtener una lista de las primeras
max_error_count
advertencias como
información acerca de qué ha fallado. Consulte
Sección 13.5.4.22, “Sintaxis de SHOW WARNINGS
”.
REPLACE [LOW_PRIORITY | DELAYED] [INTO]tbl_name
[(col_name
,...)] VALUES ({expr
| DEFAULT},...),(...),...
O:
REPLACE [LOW_PRIORITY | DELAYED] [INTO]tbl_name
SETcol_name
={expr
| DEFAULT}, ...
O:
REPLACE [LOW_PRIORITY | DELAYED] [INTO]tbl_name
[(col_name
,...)] SELECT ...
REPLACE
funciona exactamente como
INSERT
, excepto que si un valor de la tabla
tiene el mismo valor que un nuevo registro para un índice
PRIMARY KEY
o UNIQUE
, el
antiguo registro se borra antes de insertar el nuevo. Consulte
Sección 13.2.4, “Sintaxis de INSERT
”.
Tenga en cuenta que a menos que la tabla tenga un índice
PRIMARY KEY
, o UNIQUE
usar
un comando REPLACE
no tiene sentido. Es
equivalente a INSERT
, ya que no hay índice
para determinar si un nuevo registro duplica otro.
Los valores para todas las columnas se toman de los valores
especificados en el comando REPLACE
.
Cualquier columna no presente adquiere su valor por defecto,
como ocurre con INSERT
. No puede referirse a
valores del registro actual y usarlos en el nuevo registro. Si
usa un comando tal como SET
, la referencia
al nombre de columna en la parte derecha se trata como
col_name
=
col_name
+ 1DEFAULT(
,
así que es equivalente a col_name
)SET
.
col_name
=
DEFAULT(col_name
) + 1
Para ser capaz de usar REPLACE
, debe tener
los permisos INSERT
y
DELETE
para la tabla.
El comando REPLACE
retorna un contador con el
número de registros afectados. Esta es la suma de registros
borrados e insertados. Si el contador es 1 para
REPLACE
de un único registro, se inserta un
registro y no se borra ninguno. Si el contador es mayor que 1,
uno o más registros se borraron antes de insertar el nuevo. Es
posible para un único registro reemplazar más de un registro
antiguo si la tabla contiene múltiples índices únicos y el
nuevo registro duplica valores para distintos registros antiguos
en distintos índices únicos.
El contador de registros afectados hace fácil determinar si
REPLACE
sólo añadió un registro o si
también reemplazo alguno: Compruebe si el contador es 1
(añadido) o mayor (reemplazados).
Si usa la API de C, el contador de registros afectados puede
obtenerse usando la función
mysql_affected_rows()
.
Actualmente, no puede reemplzar en una tabla y seleccionar de la misma en una subconsulta.
Aquí sigue en más detalle el algoritmo usado (también se usa
con LOAD DATA ... REPLACE
):
Intenta insertar el nuevo registro en la tabla
Mientras falle la inserción debido a error de clave duplicada por clave única o primaria:
Borra de la tabla el registro conflictivo que tiene el valor de clave duplicada
Intenta insertar de nuevo el registro en la tabla
SELECT [ALL | DISTINCT | DISTINCTROW ] [HIGH_PRIORITY] [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT] [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]select_expr
, ... [INTO OUTFILE 'file_name
'export_options
| INTO DUMPFILE 'file_name
'] [FROMtable_references
[WHEREwhere_definition
] [GROUP BY {col_name
|expr
|position
} [ASC | DESC], ... [WITH ROLLUP]] [HAVINGwhere_definition
] [ORDER BY {col_name
|expr
|position
} [ASC | DESC] , ...] [LIMIT {[offset
,]row_count
|row_count
OFFSEToffset
}] [PROCEDUREprocedure_name
(argument_list
)] [FOR UPDATE | LOCK IN SHARE MODE]]
SELECT
se usa para recibir registros
seleccionados desde una o más tablas. MySQL 5.0 incluye soporte
para comandos UNION
y subconsultas. Consulte
Sección 13.2.7.2, “Sintaxis de UNION
” y Sección 13.2.8, “Sintaxis de subconsultas”.
Cada select_expr
indicata una
columna que quiere recibir.
table_references
indicata la
tabla o tablas desde la que recibir registros. Su sintaxis
se describe en Sección 13.2.7.1, “Sintaxis de JOIN
”.
where_definition
consiste en la
palabra clave WHERE
seguida por una
expresión que indica la condición o condiciones que deben
satisfacer los registros para ser seleccionados.
SELECT
también puede usarse para recuperar
registros computados sin referencia a ninguna tabla.
Por ejemplo:
mysql> SELECT 1 + 1; -> 2
Todas las cláusulas usadas deben darse exactamente en el orden
mostrado en la descripción de la sintaxis. Por ejemplo, una
cláusula HAVING
debe ir tras cualquier
cláusula GROUP BY
y antes de cualquier
cláusula ORDER BY
.
Una select_expr
puede tener un
alias usando AS alias_name
. El alias se
usa como el nombre de columna de la expresión y puede
usarse en cláusulas GROUP BY
,
ORDER BY
, o HAVING
.
Por ejemplo:
mysql> SELECT CONCAT(last_name,', ',first_name) AS full_name -> FROM mytable ORDER BY full_name;
La palabra clave AS
es opcional cuando se
usa un alias para select_expr
. El
ejemplo precedente podría haberse escrito como:
mysql> SELECT CONCAT(last_name,', ',first_name) full_name -> FROM mytable ORDER BY full_name;
Como AS
es opcional, puede ocurrir un
sutil problema si olvida la coma entre dos expresiones
select_expr
: MySQL interpreta el
segundo como un nombre de alias. Por ejemplo, en el
siguiente comando, columnb
se tata como
un nombre de alias:
mysql> SELECT columna columnb FROM mytable;
Por esta razón, es una buena práctica poner los alias de
columnas usando AS
.
No se permite usar un alias de columna en una cláusula
WHERE
, ya que el valor de columna puede
no estar determinado cuando se ejecuta la cláusula
WHERE
. Consulte
Sección A.5.4, “Problemas con alias de columnas”.
La cláusula FROM
indica
la tabla desde la que recibir registros. Si nombra más de
una tabla, está realizando un join, Para información sobre
la sintaxis de join, consulte Sección 13.2.7.1, “Sintaxis de table_references
JOIN
”. Para
cada tabla especificada, puede opcionalmente especificar un
alias.
tbl_name
[[AS]alias
] [[USE INDEX (key_list
)] | [IGNORE INDEX (key_list
)] | [FORCE INDEX (key_list
)]]
El uso de USE INDEX
, IGNORE
INDEX
, FORCE INDEX
para dar al
optimizador pistas acerca de cómo escoger los indices se
describe en Sección 13.2.7.1, “Sintaxis de JOIN
”.
En MySQL 5.0, puede usar SET
max_seeks_for_key=
como alternativa para forzar a MySQL a que realice escaneos
de claves en lugar de escaneos de tabla.
value
Puede referirse a una tabla dentro de la base de datos
actual como tbl_name
(dentro de
la base de datos actual) , o como
db_name.tbl_name
para referirse a
una base de datos explícitamente. Puede referirse a una
columna como col_name
,
tbl_name.col_name
, o
db_name.tbl_name.col_name
. No
necesita especificar un prefijo
tbl_name
o
db_name.tbl_name
para una
referencia de columna a no ser que la referencia fuese
ambígua. Consulte Sección 9.2, “Nombres de bases de datos, tablas, índices, columnas y alias” para
ejemplos de ambigüedad que requieran las formas de
referencia de columna más explícitas.
En MySQL 5.0, puede especificar DUAL
como
nombre de tabla falso en siguaciones donde no se referencian
tablas:
mysql> SELECT 1 + 1 FROM DUAL; -> 2
DUAL
es una característica puramente de
compatibilidad. Otros servidores requieren esta sintaxis.
Una referencia de tabla puede tener un alias usando
o
tbl_name
AS
alias_name
tbl_name alias_name
:
mysql> SELECT t1.name, t2.salary FROM employee AS t1, info AS t2 -> WHERE t1.name = t2.name; mysql> SELECT t1.name, t2.salary FROM employee t1, info t2 -> WHERE t1.name = t2.name;
En la cláusula WHERE
, puede usar
cualquiera de las funciones que soporta MySQL, escepto para
funciones agregadas (resumen). Consulte
Capítulo 12, Funciones y operadores.
Las columnas seleccionadas para la salida pueden ser
referidas en cláusulas ORDER BY
y
GROUP BY
usando nombres de columnas,
alias, o posiciones. Las posiciones de columnas son enteros
y comienzan con 1:
mysql> SELECT college, region, seed FROM tournament -> ORDER BY region, seed; mysql> SELECT college, region AS r, seed AS s FROM tournament -> ORDER BY r, s; mysql> SELECT college, region, seed FROM tournament -> ORDER BY 2, 3;
Para ordenar en orden inverso, añada la palabra clave
DESC
(descendiente) al nombre de la
columna en la cláusula ORDER BY
por la
que está ordenando. Por defecto es orden ascendente; puede
especificarse explícitamente usando la palabra clave
ASC
.
El uso de posiciones de columna está obsoleto ya que la sintaxis se ha eliminado del estándar SQL.
Si usa GROUP BY
, los registros de salida
se ordenan según las columnas GROUP BY
como si tuviera un ORDER BY
para las
mismas columnas. MySQL 5.0 extiende la cláusula
GROUP BY
para que pueda especificar
ASC
y DESC
tras las
columnas nombradas en la cláusula:
SELECT a, COUNT(b) FROM test_table GROUP BY a DESC
MySQL extiende el uso de GROUP BY
para
permitir seleccionar campos que no se mencionan en la
cláusula GROUP BY
. Si no obtiene los
resultados que espera de la consulta, por favor lea la
descripción de GROUP BY
en
Sección 12.10, “Funciones y modificadores para cláusulas GROUP BY
”.
En MySQL 5.0, GROUP BY
permite un
modificador WITH ROLLUP
. Consulte
Sección 12.10.2, “Modificadores de GROUP BY
”.
La cláusula HAVING
se aplica casi al
final, justo antes de que los elementos se envíen al
cliente, sin optimización. (LIMIT
se
aplica tras HAVING
.)
Antes de MySQL 5.0.2, una cláusula
HAVING
podía referirse a cualquier
columna o alias nombrado en una
select_expr
en la lista
SELECT
o en subconsultas externas, y para
funciones agregadas. Sin embargo, el estándar SQL requiere
que HAVING
debe referirse sólo a
columnas en la cláusula GROUP BY
o
columnas usadas en funciones agregadas. Para acomodar ambos
estándars SQL y el comportamiento específico de MySQL en
que es capaz de referirse a columnas en la lista
SELECT
, MySQL 5.0.2 y posteior permite a
HAVING
referirse a columnas en la lista
SELECT
, en la cláusula GROUP
BY
, en subconsultas externas y en funciones
agregadas.
Por ejemplo, el siguiente comando funciona en MySQL 5.0.2 pero produce un error en versiones aneriores:
mysql> SELECT COUNT(*) FROM t GROUP BY col1 HAVING col1 = 2;
Si la cláusula HAVING
se refiere a una
columna ambígua, se muestra una advertencia. En el
siguiente comando, col2
es ambíguo
porque se usa tanto para un alias como para un nombre de
columna:
mysql> SELECT COUNT(col1) AS col2 FROM t GROUP BY col2 HAVING col2 = 2;
Se da preferencia al comportamiento SQL estándar, así que
si un nombre de columna HAVING
se usa en
un GROUP BY
y como alias de columna en la
lista de columnas de salida, se da preferencia a la columna
en GROUP BY
.
No use HAVING
para elementos que deban
estar en la cláusula WHERE
. Por
ejemplo, no escriba lo siguiente:
mysql> SELECTcol_name
FROMtbl_name
HAVINGcol_name
> 0;
Escriba esto en su lugar:
mysql> SELECTcol_name
FROMtbl_name
WHEREcol_name
> 0;
La cláusula HAVING
puede referirse a
funciones de agregación, algo que no puede hacer la
cláusula WHERE
:
mysql> SELECT user, MAX(salary) FROM users -> GROUP BY user HAVING MAX(salary)>10;
(Esto no funciona en versiones antiguas de MySQL.)
La cláusula LIMIT
puede usarse para
restringir el número de registros retornados por el comando
SELECT
. LIMIT
tiene
uno o dos argumentos numéricos, que deben ser enteros
positivos (incluyendo cero).
Con dos argumentos, el primer argumento especifica el desplazamiento del primer registro a retornar. El desplazamiento del registro inicial es 0 (no 1):
mysql> SELECT * FROM table LIMIT 5,10; # Retrieve rows 6-15
Por compatibilidad con PostgreSQL, MySQL también soporta la
sintaxis LIMIT
.
row_count
OFFSET offset
Para recibir todos los registros de un desplazamiento hasta el final del conjunto de resultados, puede usar algún número grande para el segundo parámetro. Ete comando recibe todos los registros desde el 96th hasta el último:
mysql> SELECT * FROM table LIMIT 95,18446744073709551615;
Con un argumento, el valor especifica el número de registros a retornar desde el comienzo del conjunto de resultados:
mysql> SELECT * FROM table LIMIT 5; # Retrieve first 5 rows
En otras palabras, LIMIT n
es equivalente
a LIMIT 0,n
.
La forma SELECT ... INTO OUTFILE
'file_name'
de SELECT
escribe
los registros seleccionados en un fichero. El fichero se
crea en el equipo servidor, así que debe tener el permiso
FILE
para usar esta sintaxis. El fichero
no puede existir, que entre otras cosas evita destruir
ficheros cruciales tales como
/etc/passwd
y tablas de la base de
datos.
El comando SELECT ... INTO OUTFILE
existe
principalmente para dejarle volcar una tabla rápidamente en
la máquina servidor. Si quiere crear el fichero resultante
en un equipo cliente distinto al equipo servidor, no puede
usar SELECT ... INTO OUTFILE
. En tal
caso, debería usar algún comando como mysql -e
"SELECT ..." > file_name
en el equipo cliente
para generar el fichero.
SELECT ... INTO OUTFILE
es el complemento
de LOAD DATA INFILE
; la sintaxis para la
parte export_options
del comando consiste
en las mismas cláusulas FIELDS
y
LINES
usadas con el comando LOAD
DATA INFILE
. Consulte
Sección 13.2.5, “Sintaxis de LOAD DATA INFILE
”.
FIELDS ESCAPED BY
controla cómo escribir
carácteres especiales. Si el carácter FIELDS
ESCAPED BY
no está vacío, se usa como prefijo
para los siguientes carácteres en la salida:
El carácter FIELDS ESCAPED BY
El carácter FIELDS [OPTIONALLY] ENCLOSED
BY
El primer carácter de FIELDS TERMINATED
BY
y LINES TERMINATED BY
ASCII 0
(que se escribe siguiendo el
carácter de escape ASCII '0
', no un
byte con valor cero)
Si el carácter FIELDS ESCAPED BY
está
vacío, no hay ningún carácter de escape y
NULL
se muestra por salida como
NULL
, no \N
.
Probablemente no es buena idea especificar un carácter de
escape vacío, particularmente si los valores de los campos
de sus datos contienen cualqiuera de los carácteres en la
lista dada.
La razón de lo anterior es que debe
escapar cualquier carácter FIELDS TERMINATED
BY
, ENCLOSED BY
,
ESCAPED BY
, o LINES TERMINATED
BY
para ser capaz de volver a leer el fichero
correctamente. ASCII NUL
se escapa para
hacer más fácil visualizarlo con algunos visores.
El fichero resultante no tiene que estar conforme a la sintaxis SQL, así que nada más debe escaparse.
Este es un ejemplo que produce un fichero en formato de valores separados por comas usado por varios programas:
SELECT a,b,a+b INTO OUTFILE '/tmp/result.text' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n' FROM test_table;
Si usa INTO DUMPFILE
en lugar de
INTO OUTFILE
, MySQL escribe sólo un
registro en el fichero, sin ninguna terminación de línea o
columna y sin realizar ningún proceso de escape. Esto es
útil si quiere almacenar un valor BLOB
en un fichero.
Nota: Cualquier fichero
creado por INTO OUTFILE
o INTO
DUMPFILE
es modificable por todos los usuarios en
el equipo servidor. La razón es que el servidor MySQL no
puede crear un fichero con un propietario distinto al
usuario que está en ejecución (nunca debe ejecutar
mysqld como root
por
esta y otras razones). El fichero debe ser modificable por
todo el mundo para que pueda maminpular sus contenidos.
Una cláusula PROCEDURE
nombra a un
procedimiento que debe procesar los datos en el conjunto de
resultados. Para un ejemplo, consulte
Sección 27.3.1, “Procedimiento Analyse”.
Si usa FOR UPDATE
en un motor de
almacenamiento que usa bloqueo de páginas o registros, los
registros examinados por la consulta se bloquean para
escritura hasta el final de la transacción actual. Usar
LOCK IN SHARE MODE
crea un bloqueo
compartido que evita a otras transacciones actualizar o
borrar los registros examinados. Consulte
Sección 15.10.5, “Bloquear lecturas SELECT ... FOR UPDATE
y
SELECT ... LOCK IN SHARE MODE
”.
Tras la palabra clave SELECT
, puede usar un
número de opciones que afectan la operación del comando.
Las opciones ALL
,
DISTINCT
, and DISTINCTROW
especifican si deben retornarse los registros duplicados. Si no
se da ninguna de estas opciones, por defecto es
ALL
(se retornan todos los registros
coincidentes). DISTINCT
y
DISTINCTROW
son sinónimos y especifican que
los registros duplicados en el conjunto de resultados deben
borrarse.
HIGH_PRIORITY
,
STRAIGHT_JOIN
, y opciones que comiencen con
SQL_
son extensiones de MySQL al estándar
SQL.
HIGH_PRIORITY
da a
SELECT
prioridad más alta que un comando
que actualice una tabla. Debe usar esto sólo para consultas
que son muy rápidas y deben realizarse una vez. Una
consulta SELECT HIGH_PRIORITY
que se
realiza mientras la tabla está bloqueada para lectura se
ejectua incluso si hay un comando de actualización
esperando a que se libere la tabla.
HIGH_PRIORITY
no puede usarse con
comandos SELECT
que sean parte de una
UNION
.
STRAIGHT_JOIN
fuerza al optimizador a
hacer un join de las tablas en el orden en que se listan en
la cláusula FROM
. Puede usarlo para
acelerar una consulta si el optimizador hace un join con las
tablas en orden no óptimo. Consulte
Sección 7.2.1, “Sintaxis de EXPLAIN
(Obtener información acerca de un SELECT
)”. STRAIGHT_JOIN
también puede usarse en la lista
table_references
. Consulte
Sección 13.2.7.1, “Sintaxis de JOIN
”.
SQL_BIG_RESULT
puede usarse con
GROUP BY
o DISTINCT
para decir al optimizador que el conjunto de resultados
tiene muchos registros. En este caso, MySQL usa directamente
tablas temporales en disco si son necesarias con una clave
en los elementos GROUP BY
.
SQL_BUFFER_RESULT
fuerza a que el
resultado se ponga en una tabla temporal . Esto ayuda a
MySQL a liberar los bloqueos de tabla rápidamente y ayuda
en casos en que tarda mucho tiempo en enviar el resultado al
cliente.
SQL_SMALL_RESULT
puede usarse con
GROUP BY
o DISTINCT
para decir al optimizador que el conjunto de resultados es
pequeño. En este caso, MySQL usa tablas temporales rápidas
para almacenar la tabla resultante en lugar de usar
ordenación. En MySQL 5.0, esto no hará falta normalmente.
SQL_CALC_FOUND_ROWS
le dice a MySQL que
calcule cuántos registros habrán en el conjunto de
resultados, sin tener en cuenta ninguna cláusula
LIMIT
. El número de registros pueden
encontrarse con SELECT FOUND_ROWS()
.
Consulte Sección 12.9.3, “Funciones de información”.
SQL_CACHE
le dice a MySQL que almacene el
resultado de la consulta en la caché de consultas si está
usando un valor de query_cache_type
de
2
o DEMAND
. Para una
consulta que use UNION
o subconsultas,
esta opción afecta a cualquier SELECT
en
la consulta. Consulte Sección 5.12, “La caché de consultas de MySQL”.
SQL_NO_CACHE
le dice a MySQL que no
almacene los resultados de consulta en la caché de
consultas. Consulte Sección 5.12, “La caché de consultas de MySQL”. Para una
consulta que use UNION
o subconsultas
esta opción afecta a cualquier SELECT
en
la consulta.
MySQL soporta las siguientes sintaxis de
JOIN
para la parte
table_references
de comandos
SELECT
y DELETE
y
UPDATE
de múltiples tablas:
table_reference
,table_reference
table_reference
[INNER | CROSS] JOINtable_reference
[join_condition
]table_reference
STRAIGHT_JOINtable_reference
table_reference
LEFT [OUTER] JOINtable_reference
join_condition
table_reference
NATURAL [LEFT [OUTER]] JOINtable_reference
{ ONtable_reference
LEFT OUTER JOINtable_reference
ONconditional_expr
}table_reference
RIGHT [OUTER] JOINtable_reference
join_condition
table_reference
NATURAL [RIGHT [OUTER]] JOINtable_reference
table_reference
se define como:
tbl_name
[[AS]alias
] [[USE INDEX (key_list
)] | [IGNORE INDEX (key_list
)] | [FORCE INDEX (key_list
)]]
join_condition
se define como:
ONconditional_expr
| USING (column_list
)
Generalmente no debería tener ninguna condición en la parte
ON
que se usa para restringir qué
registros desea en el conjunto de resultados, pero en su lugar
especificar esas condiciones en la cláusula
WHERE
. Hay excepciones a esta regla.
La sintaxis { OJ ... LEFT OUTER JOIN ...}
mostrada en la lista precedente existe sólo por
compatibilidad con ODBC.
Puede oner un alias en una referencia de tabla usando
o
tbl_name
AS
alias_name
tbl_name alias_name
:
mysql> SELECT t1.name, t2.salary FROM employee AS t1, info AS t2 -> WHERE t1.name = t2.name; mysql> SELECT t1.name, t2.salary FROM employee t1, info t2 -> WHERE t1.name = t2.name;
El condicional ON
es cualquier
expresión condicional de la forma que puede usarse en una
cláusula WHERE
.
Si no hay ningún registro coincidiente para la tabla de
la derecha en la parte ON
o
USING
en un LEFT
JOIN
, se usa un registro con todos las columnas
a NULL
para la tabla de la derecha.
Puede usar este hecho para encontrar registros en una
tabla que no tengan contraparte en otra tabla:
mysql> SELECT table1.* FROM table1 -> LEFT JOIN table2 ON table1.id=table2.id -> WHERE table2.id IS NULL;
Este ejemplo encuentra todos los registros en
table1
con un valor
id
no presente en
table2
(esto es, todos los registros en
table1
sin registro correspondiente en
table2
). Esto asume que
table2.id
se declara NOT
NULL
. Consulte
Sección 7.2.9, “Cómo optimiza MySQL los LEFT JOIN
y RIGHT JOIN
”.
La cláusula USING
(
muestra
una lista de columnas que deben existir en ambas tablas.
Las siguientes dos cláusulas son semánticamente
idénticas:
column_list
)
a LEFT JOIN b USING (c1,c2,c3) a LEFT JOIN b ON a.c1=b.c1 AND a.c2=b.c2 AND a.c3=b.c3
El NATURAL [LEFT] JOIN
de dos tablas se
define semánticamente equivalente a un INNER
JOIN
o LEFT JOIN
con una
cláusula USING
que nombra todas las
columnas que existen en ambas tablas.
INNER JOIN
y ,
(coma) son semánticamente equivalentes en la ausencia de
una condicicón de join: ambos producen un producto
Cartesiano entre las tablas especificadas (esto es, cada
registro en la primera tabla se junta con cada registro en
la segunda tabla).
RIGHT JOIN
funciona análogamente a
LEFT JOIN
. Para mantener el código
portable entre bases de datos, se recomienda que use
LEFT JOIN
en lugar de RIGHT
JOIN
.
STRAIGHT_JOIN
es idéntico a
JOIN
, excepto que la tabla de la
izquierda se lee siempre antes que la de la derecha. Esto
puede usarse para aquéllos casos (escasos) en que el
optimizador de join pone las tablas en orden incorrecto.
Puede proporcionar pistas de qué índice debe usar MySQL
cuando recibe información de una tabla. Especificando
USE INDEX (key_list)
, puede decirle a MySQL
que use sólo uno de los posibles índices para encontrar
registros en la tabla. La sintaxis alternativa IGNORE
INDEX (key_list)
puede usarse para decir a MySQL que
no use algún índice particular. Estos trucos son útiles si
EXPLAIN
muestra que MySQL está usando el
índice incorrecto de la lista de posibles índices.
También puede usar FORCE INDEX
, que actúa
como USE INDEX
(
pero con la
adición que un escaneo de tabla se asume como operación
muy cara. En otras palabras, un escaneo
de tabla se usa sólo si no hay forma de usar uno de los
índices dados para encontrar registros en la tabla.
key_list
)
USE KEY
, IGNORE KEY
, y
FORCE KEY
son sinónimos de USE
INDEX
, IGNORE INDEX
, y
FORCE INDEX
.
Nota: USE
INDEX
, IGNORE INDEX
, y
FORCE INDEX
sólo afecta los índices
usados cuando MySQL decide cómo encontrar registros en la
tabla y cómo hacer el join. No afecta si un índice está en
uso cuando se resuelve unORDER BY
o
GROUP BY
.
Algunos ejemplos de join:
mysql> SELECT * FROM table1,table2 WHERE table1.id=table2.id; mysql> SELECT * FROM table1 LEFT JOIN table2 ON table1.id=table2.id; mysql> SELECT * FROM table1 LEFT JOIN table2 USING (id); mysql> SELECT * FROM table1 LEFT JOIN table2 ON table1.id=table2.id -> LEFT JOIN table3 ON table2.id=table3.id; mysql> SELECT * FROM table1 USE INDEX (key1,key2) -> WHERE key1=1 AND key2=2 AND key3=3; mysql> SELECT * FROM table1 IGNORE INDEX (key3) -> WHERE key1=1 AND key2=2 AND key3=3;
Consulte Sección 7.2.9, “Cómo optimiza MySQL los LEFT JOIN
y RIGHT JOIN
”.
SELECT ... UNION [ALL | DISTINCT] SELECT ... [UNION [ALL | DISTINCT] SELECT ...]
UNION
se usa para combinar el resultado de
un número de comandos SELECT
en un
conjunto de resultados.
Las columnas seleccionadas lisatadas en posiciones
correspondientes de cada comando SELECT
deben tener el mismo tipo. (Por ejemplo, la primera columna
seleccionada por el primer comando debe tener el mismo tipo
que la primer columna seleccionada por otros comandos.) Los
nombres de columna usados por el primer comando
SELECT
se usan como nombres de columna para
los resultados retornados.
Los comandos SELECT
son comandos select
normales, pero con las siguientes restricciones:
Sólo el último comando SELECT
puede
usar INTO OUTFILE
.
HIGH_PRIORITY
no puede usarse con
comandos SELECT
que sean parte de una
UNION
. Si lo especifica para el primer
SELECT
, no tiene efecto. Si lo
especifica para cualquier SELECT
posterior, aparece un error de sintaxis.
Si no usa la palabra clave ALL
para
UNION
, todos los registros retornados son
únicos, como si hubiera hecho un DISTINCT
para el conjunto de resultados total. Si especifica
ALL
, obtiene todos los registros
coincidentes de todos los comandos SELECT
usados.
La palabra clave DISTINCT
es una palabra
opcional que no tiene efecto, pero se permite en la sintaxis
como requiere el estándar SQL . (En MySQL,
DISTINCT
representa el comportamiento por
defecto de una union.)
En MySQL 5.0, puede mezclar UNION ALL
y
UNION DISTINCT
en la misma consulta. Tipos
de UNION
mezclados se tratan de forma que
una unión DISTINCT
sobreescribe cualquier
unión ALL
a su izquierda. Una unión
DISTINCT
puede producirse explícitamente
usando UNION DISTINCT
o implícitamente
usando UNION
sin palabra clave
DISTINCT
o ALL
a
continuación.
Si quiere usar una cláusula ORDER BY
o
LIMIT
para ordenar o limitar el resultado
UNION
entero, ponga entre paréntesis los
comandos SELECT
individuales y ponga el
ORDER BY
o LIMIT
tras el
último. El siguiente ejemplo usa ambas cláusulas:
(SELECT a FROMtbl_name
WHERE a=10 AND B=1) UNION (SELECT a FROMtbl_name
WHERE a=11 AND B=2) ORDER BY a LIMIT 10;
Este tipo de ORDER BY
no puede usar
referencias de columnas que incluyan un nombre de columna
(esto es, nombres en formato
tbl_name.col_name
). En su lugar,
proporcione un alias de columna al primer comando
SELECT
y refiérase al alias en el
ORDER BY
, o a la columna en el
ORDER BY
usando su posición de columna.
(Un alias es preferible porque el uso de la posición de la
columna está obsoleto.)
Para aplicar ORDER BY
o
LIMIT
a un SELECT
individual, ponga la cláusula dentro de los paréntesis
alrededor del SELECT
:
(SELECT a FROMtbl_name
WHERE a=10 AND B=1 ORDER BY a LIMIT 10) UNION (SELECT a FROMtbl_name
WHERE a=11 AND B=2 ORDER BY a LIMIT 10);
Los ORDER BY
para comandos
SELECT
individuales entre paréntesis
tienen efecto sólo al combinarlos con
LIMIT
. De otro modo, el ORDER
BY
se optimiza a parte.
En MySQL 5.0, los tipos y longitudes de las columnas en el
conjunto de resultados de una UNION
tienen
en cuenta los valores recibidos por todos los comandos
SELECT
. Por ejemplo, considere lo
siguiente:
mysql> SELECT REPEAT('a',1) UNION SELECT REPEAT('b',10); +---------------+ | REPEAT('a',1) | +---------------+ | a | | bbbbbbbbbb | +---------------+
(En alguna versión anterior de MySQL, el segundo registro se habría truncado a una longitud de 1.)
ANY
, IN
y SOME
ALL
EXISTS
y NOT EXISTS
FROM
Una subconsulta es un comando SELECT
dentro
de otro comando.
MySQL 5.0 soporta todas las formas de subconsultas y operaciones que requiere el estándar SQL, así como algunas características específicas de MySQL.
Aquí hay un ejemplo de subconsulta:
SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2);
En este ejemplo, SELECT * FROM t1 ...
es la
consulta externa (o comando
externo), y (SELECT column1 FROM
t2)
es la subconsulta. Decimos
que la subconsulta está anidada dentro de
la consulta exterior, y de hecho, es posible anidar subconsultas
dentro de otras subconsultas hasta una profundidad considerable.
Una subconsulta debe siempre aparecer entre paréntesis.
Las principales ventajas de subconsultas son:
Permiten consultas estructuradas de forma que es posible aislar cada parte de un comando.
Proporcionan un modo alternativo de realizar operaciones que de otro modo necesitarían joins y uniones complejos.
Son, en la opinión de mucha gente, leíbles. De hecho, fue la innovación de las subconsultas lo que dio a la gente la idea original de llamar a SQL “Structured Query Language.”
Aquí hay un comando de ejemplo que muestra los puntos principales de la sintaxis de subconsultas como especifica el estándar SQL y soporta MySQL:
DELETE FROM t1 WHERE s11 > ANY (SELECT COUNT(*) /* no hint */ FROM t2 WHERE NOT EXISTS (SELECT * FROM t3 WHERE ROW(5*t2.s1,77)= (SELECT 50,11*s1 FROM t4 UNION SELECT 50,77 FROM (SELECT * FROM t5) AS t5)));
Una subconsulta puede retornar un escalar (un valor único), un registro, una columna o una tabla (uno o más registros de una o más columnas). Éstas se llaman consultas de escalar, columna, registro y tabla. Las subconsultas que retornan una clase particular de resultado a menudo pueden usarse sólo en ciertos contextos, como se describe en las siguientes secciones.
Hay pocas restricciones sobre los tipos de comandos en que
pueden usarse las subconsultas. Una subconsulta puede contener
cualquiera de las palabras claves o cláusulas que puede
contener un SELECT
ordinario:
DISTINCT
, GROUP BY
,
ORDER BY
, LIMIT
, joins,
trucos de índices, constructores UNION
,
comentarios, funciones, y así.
Una restricción es que el comando exterior de una subconsulta
debe ser: SELECT
, INSERT
,
UPDATE
, DELETE
,
SET
, o DO
. Otra
restricción es que actualmente no puede modificar una tabla y
seleccionar de la misma tabla en la subconsulta. Esto se aplica
a comandos tales como DELETE
,
INSERT
, REPLACE
, y
UPDATE
. Una discusión más comprensible de
las restricciones en las subconsultas se da en
Apéndice H, Restricciones en características de MySQL.
En su forma más sencilla, una subconsulta es una subconsulta
escalar que retorna un único valor. Una subconsulta escalar
es un operando simple, y puede usarlo prácticamente en
cualquier sitio en que un valor de columna o literal sea
legal, y puede esperar que tenga las características que
tienen todos los operandos: un tipo de datos, una longitud,
una indicación de si puede ser NULL
,
etcétera. Por ejemplo:
CREATE TABLE t1 (s1 INT, s2 CHAR(5) NOT NULL); INSERT INTO t1 VALUES(100, 'abcde'); SELECT (SELECT s2 FROM t1);
La subconsulta en este SELECT
retorna un
valor único ('abcde'
) que tiene un tipo de
datos CHAR
, una longitud de 5, un conjunto
de carácteres y una colación iguales a la que había por
defecto cuando se realizó el CREATE TABLE
, y una indicación que el valor en la columna puede ser
NULL
. De hecho, casi todas las consultas
pueden ser NULL
. Si la tabla usada en este
ejemplo estuviese vacía, la tabla de la subconsulta sería
NULL
.
Hay algunos contextos en que una subconsulta escalar no se
puede usar. Si un comando permite sólo un valor literal, no
puede usar una subconsulta. Por ejemplo,
LIMIT
necesita argumentos enteros, y
LOAD DATA
necesita una cadena con un nombre
de fichero. No puede usar subconsultas para proporcionar estos
valores.
Cuando vea los ejemplos en las siguientes secciones que
contengan el constructor (SELECT column1 FROM
t1)
, imagine que su própio código contiene
construcciones mucho más diversas y complejas.
Por ejemplo, suponga que hacemos dos tablas:
CREATE TABLE t1 (s1 INT); INSERT INTO t1 VALUES (1); CREATE TABLE t2 (s1 INT); INSERT INTO t2 VALUES (2);
Luego realice SELECT
:
SELECT (SELECT s1 FROM t2) FROM t1;
El resultado es 2
ya que hay un registro en
t2
que contiene una columna
s1
con un valor de 2
.
Una subconsulta escalar puede ser parte de una expresión. No olvide los paréntesis, incluso si la subconsulta es un operando que proporciona un argumento para una función. Por ejemplo:
SELECT UPPER((SELECT s1 FROM t1)) FROM t2;
El uso más común de una subconsulta es de la forma:
non_subquery_operand
comparison_operator
(subquery
)
Donde comparison_operator
es uno de
estos operadores:
= > < >= <= <>
Por ejemplo:
... 'a' = (SELECT column1 FROM t1)
Tiempo atrás el único sitio legal para una subconsulta era la parte derecha de la comparación, y puede encontrar algunos SGBDs que insistan en ello.
He aquí un ejemplo de una comparación común de
subconsultas que no puede hacerse mediante un join. Encuentra
todos los valores en la tabla t1
que son
iguales a un valor máximo en la tabla t2
:
SELECT column1 FROM t1 WHERE column1 = (SELECT MAX(column2) FROM t2);
Aquí hay otro ejemplo, que de nuevo es imposible de hacer con
un join ya que involucra agregación para una de las tablas.
Encuentra todos los registros en la tabla
t1
que contengan un valor que ocurre dos
veces en una columna dada:
SELECT * FROM t1 AS t WHERE 2 = (SELECT COUNT(*) FROM t1 WHERE t1.id = t.id);
Para una comparación realizada con uno de estos operadores,
la subconsulta debe retornar un escalar, con la excepción que
=
puede usarse con subconsultas de
registro. Consulte Sección 13.2.8.5, “Subconsultas de registro”.
Sintaxis:
operand
comparison_operator
ANY (subquery
)operand
IN (subquery
)operand
comparison_operator
SOME (subquery
)
La palabra clave ANY
, que debe seguir a un
operador de comparación, significa “return
TRUE
si la comparación es
TRUE
para ANY
(cualquiera) de los valores en la columna que retorna la
subconsulta.” Por ejemplo:
SELECT s1 FROM t1 WHERE s1 > ANY (SELECT s1 FROM t2);
Suponga que hay un registro en una tabla t1
que contiene (10)
. La expresión es
TRUE
si la tabla t2
contiene (21,14,7)
ya que hay un valor
7
en t2
que es menor que
10
. La expresión es
FALSE
si la tabla t2
contiene (20,10)
, o si la tabla
t2
está vacía. La expresión es
UNKNOWN
si la tabla t2
contiene (NULL,NULL,NULL)
.
La palabra IN
es un alias para =
ANY
. Por lo tanto, estos dos comandos son lo mismo:
SELECT s1 FROM t1 WHERE s1 = ANY (SELECT s1 FROM t2); SELECT s1 FROM t1 WHERE s1 IN (SELECT s1 FROM t2);
Sin embargo, NOT IN
no es un alias para
<> ANY
, sino para <>
ALL
. Consulte Sección 13.2.8.4, “Subconsultas con ALL
”.
La palabra SOME
es un alias para
ANY
. Por lo tanto, estos dos comandos son
el mismo:
SELECT s1 FROM t1 WHERE s1 <> ANY (SELECT s1 FROM t2); SELECT s1 FROM t1 WHERE s1 <> SOME (SELECT s1 FROM t2);
El uso de la palabra SOME
es raro, pero
este ejemplo muestra cómo puede ser útil. Para la mayoría
de gente, la frase en inglés “a is not equal to any
b” significa “there is no b which is equal to
a,” pero eso no es lo que quiere decir la sintaxis SQL.
La sintaxis significa “there is some b to which a is not
equal.” Usando <> SOME
en su
lugar ayuda a asegurar que todo el mundo entiende el
significado de la consulta.
Sintaxis:
operand
comparison_operator
ALL (subquery
)
La palabra ALL
, que debe seguir a un
operador de comparación, significa “return
TRUE
si la comparación es
TRUE
para ALL
todos los
valores en la columna que retorna la subconsulta.” Por
ejemplo:
SELECT s1 FROM t1 WHERE s1 > ALL (SELECT s1 FROM t2);
Suponga que hay un registro en la tabla t1
que contiene (10)
. La expresión es
TRUE
si la tabla t2
contiene (-5,0,+5)
ya que
10
es mayor que los otros tres valores en
t2
. La expresión es
FALSE
si la tabla t2
contiene (12,6,NULL,-100)
ya que hay un
único valor 12
en la tabla
t2
mayor que 10
. La
expresión es UNKNOWN
si la tabla
t2
contiene (0,NULL,1)
.
Finalmente, si la tabla t2
está vacía, el
resultado es TRUE
. Puede pensar que el
resultado debería ser UNKNOWN
, pero lo
sentimos, es TRUE
. Así, aunque extraño,
el siguiente comando es TRUE
cuando la
tabla t2
está vacía:
SELECT * FROM t1 WHERE 1 > ALL (SELECT s1 FROM t2);
Pero este comando es UNKNOWN
cuando la
tabla t2
está vacía:
SELECT * FROM t1 WHERE 1 > (SELECT s1 FROM t2);
Además, el siguiente comando es UNKNOWN
cuando la tabla t2
está vacía:
SELECT * FROM t1 WHERE 1 > ALL (SELECT MAX(s1) FROM t2);
En general, las tablas con valores
NULL
y las tablas
vacías son casos extremos. Al
escribir código para subconsultas, siempre considere si ha
tenido en cuenta estas dos posibilidades.
NOT IN
es un alias para <>
ALL
. Por lo tanto, estos dos comandos son
equivalentes:
SELECT s1 FROM t1 WHERE s1 <> ALL (SELECT s1 FROM t2); SELECT s1 FROM t1 WHERE s1 NOT IN (SELECT s1 FROM t2);
La discusión en este punto ha sido entre subconsultas escalares o de columnas, esto es, subcolumnas que retornan un único valor o una columna de valores. Una subconsulta de registro es una variante de subconsulta que retorna un único registro y por lo tanto retorna más de un valor de columna. Aquí hay dos ejemplos:
SELECT * FROM t1 WHERE (1,2) = (SELECT column1, column2 FROM t2); SELECT * FROM t1 WHERE ROW(1,2) = (SELECT column1, column2 FROM t2);
Las consultas aquí son ambas TRUE
si la
tabla t2
tiene un registro en que
column1 = 1
y column2 =
2
.
Las expresiones (1,2)
y
ROW(1,2)
a veces se llaman
constructores de registros. Ambos son
equivalentes. También son legales en otros contextos. Por
ejemplo, los siguientes dos comandos son semánticamente
equivalentes (aunque actualmente sólo puede optimizarse el
segundo):
SELECT * FROM t1 WHERE (column1,column2) = (1,1); SELECT * FROM t1 WHERE column1 = 1 AND column2 = 1;
El uso normal de constructores de registros, sin embargo, es
para comparaciones con subconsultas que retornan dos o más
columnas. Por ejemplo, la siguiente consulta responde a la
petición, “encuentra todos los registros en la tabla
t1
que también existen en la tabla
t2
”:
SELECT column1,column2,column3 FROM t1 WHERE (column1,column2,column3) IN (SELECT column1,column2,column3 FROM t2);
Si una subconsulta no retorna ningún registro, entonces
EXISTS
es subquery
TRUE
, y NOT EXISTS
es
subquery
FALSE
. Por ejemplo:
SELECT column1 FROM t1 WHERE EXISTS (SELECT * FROM t2);
Tradicionalmente, una subconsulta EXISTS
comienza con SELECT *
, pero puede comenzar
con SELECT 5
o SELECT
col1
o nada. MySQL ignora la lista
SELECT
en tales subconsultas, así que no
hace distinción.
Para el ejemplo precedente, si t2
contiene
algún registro, incluso registros sólo con valores
NULL
entonces la condición
EXISTS
es TRUE
. Este es
un ejemplo poco probable, ya que prácticamente siempre una
subconsulta [NOT] EXISTS
contiene
correlaciones. Aquí hay algunos ejemplos más realistas:
¿Qué clase de tienda hay en una o más ciudades?
SELECT DISTINCT store_type FROM Stores WHERE EXISTS (SELECT * FROM Cities_Stores WHERE Cities_Stores.store_type = Stores.store_type);
¿Qué clase de tienda no hay en ninguna ciudad?
SELECT DISTINCT store_type FROM Stores WHERE NOT EXISTS (SELECT * FROM Cities_Stores WHERE Cities_Stores.store_type = Stores.store_type);
¿Qué clase de tienda hay en todas las ciudades?
SELECT DISTINCT store_type FROM Stores S1 WHERE NOT EXISTS ( SELECT * FROM Cities WHERE NOT EXISTS ( SELECT * FROM Cities_Stores WHERE Cities_Stores.city = Cities.city AND Cities_Stores.store_type = Stores.store_type));
El último ejemplo es un doblemente anidado NOT
EXISTS
. Esto es, tiene una cláusula NOT
EXISTS
dentro de otra NOT EXISTS
.
Formalmente, responde a la pregunta “¿existe una ciudad
con una tienda que no esté en
Stores
?” Sin embargo, es más fácil
decir que un NOT EXISTS
responde a la
pregunta “¿es x TRUE
para todo
y?”
Una subconsulta correlacionada es una subconsulta que contiene una referencia a una tabla que también aparece en la consulta exterior. Por ejemplo:
SELECT * FROM t1 WHERE column1 = ANY (SELECT column1 FROM t2 WHERE t2.column2 = t1.column2);
Tenga en cuenta que la subconsulta contiene una referencia a
una columna de t1
, incluso aunque la
cláusula FROM
de la subconsulta no
menciona una tabla t1
. Por lo tanto, MySQL
busca fuera de la subconsulta y encuentra
t1
en la consulta externa.
Suponga que la tabla t1
contiene un
registro en que column1 = 5
y
column2 = 6
; mientras, la tabla
t2
contiene un registro en que
column1 = 5
y column2 =
7
. La expresión ... WHERE column1 = ANY
(SELECT column1 FROM t2)
sería
TRUE
, pero en este ejemplo, la cláusula
WHERE
dentro de la subconsulta es
FALSE
(ya que (5,6)
no
es igual a (5,7)
), así que la subconsulta
como un todo es FALSE
.
Regla de visibilidad: MySQL evalúa desde dentro hacia fuera. Por ejemplo:
SELECT column1 FROM t1 AS x WHERE x.column1 = (SELECT column1 FROM t2 AS x WHERE x.column1 = (SELECT column1 FROM t3 WHERE x.column2 = t3.column1));
En este comando, x.column2
debe ser una
columna en la tabla t2
ya que
SELECT column1 FROM t2 AS x ...
renombra
t2
. No hay una columna en la tabla
t1
porque SELECT column1 FROM t1
...
es una consulta externa que está
demasiado afuera.
Para subconsultas en cláusulas HAVING
u
ORDER BY
, MySQL busca nombres de columna
en la lista de selección exterior.
Para ciertos casos, una subconsulta correlacionada es óptima. Por ejemplo:
val
IN (SELECTkey_val
FROMtbl_name
WHEREcorrelated_condition
)
De otro modo, son ineficientes y lentas. Reescribir la consulta como un join puede mejorar el rendimiento.
Las subconsultas correlacionadas no pueden referirse a los resultados de funciones agregadas de la consulta exterior.
Las subconsultas son legales en la cláusula
FROM
de un comando
SELECT
. La sintaxis que vería es:
SELECT ... FROM (subquery
) [AS]name
...
La cláusula [AS]
es obligatoria, ya
que cada tabla en la cláusula name
FROM
debe
tener un nombre. Cualquier columna en la lista selecta de la
subquery
debe tener nombre único.
Puede encontrar esta sintaxis descrita en este manual, dónde
se usa el término “tablas derivadas.”
Asuma que tiene la tabla:
CREATE TABLE t1 (s1 INT, s2 CHAR(5), s3 FLOAT);
Aquí se muestra cómo usar una subconsulta en la cláusula
FROM
usando la tabla de ejemplo:
INSERT INTO t1 VALUES (1,'1',1.0); INSERT INTO t1 VALUES (2,'2',2.0); SELECT sb1,sb2,sb3 FROM (SELECT s1 AS sb1, s2 AS sb2, s3*2 AS sb3 FROM t1) AS sb WHERE sb1 > 1;
Resultado: 2, '2', 4.0
.
Aquí hay otro ejemplo: suponga que quiere conocer la media de un conjunto de sumas para una tabla agrupada. Esto no funcionaría:
SELECT AVG(SUM(column1)) FROM t1 GROUP BY column1;
Sin embargo, esta consulta proporciona la información deseada:
SELECT AVG(sum_column1) FROM (SELECT SUM(column1) AS sum_column1 FROM t1 GROUP BY column1) AS t1;
Tenga en cuenta que el nombre de columna usado dentro de la
subconsultas (sum_column1)
se reconoce en
la consulta exterior.
Las subconsultas en la cláusula FROM
pueden retornar un escalar, columna, registro o tabla. De
momento, las subconsultas en la cláusula
FROM
no pueden ser subconsultas correladas.
Las subconsultas en la cláusula FROM
se
ejecutan incluso para el comando EXPLAIN
(esto es, se construyen las tablas temporales derivadas). Esto
ocurre porque las consultas de niveles superiores necesitan
información acerca de todas las tablas durante la fase de
optimización.
Hay algunos retornos de error nuevos que se aplican sólo a subconsultas. Esta sección los agrupa ya que revisarlos ayuda a recordar algunos puntos importantes.
Número incorrecto de columnas de la subconsulta:
ERROR 1241 (ER_OPERAND_COL) SQLSTATE = 21000 Message = "Operand should contain 1 column(s)"
Este error ocurre en casos como este:
SELECT (SELECT column1, column2 FROM t2) FROM t1;
Se permite usar una subconsulta que retorne múltiples columnas, si el propósito es la comparación. Consulte Sección 13.2.8.5, “Subconsultas de registro”. Sin embargo, en otros contextos, la subconsulta debe ser un operando escalar.
Número incorrecto de registros de la subconsulta:
ERROR 1242 (ER_SUBSELECT_NO_1_ROW) SQLSTATE = 21000 Message = "Subquery returns more than 1 row"
Este error ocurre de comandos en que la subconsulta retorna más de un registro. Considere el siguiente ejemplo:
SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2);
Si SELECT column1 FROM t2
retorna sólo
un registro la consulta anterior funcionará. Si la
subconsulta retorna más de un registro, ocurre el error
1242 . En ese caso, la consulta debe reescribirse como:
SELECT * FROM t1 WHERE column1 = ANY (SELECT column1 FROM t2);
Tabla usada incorrectamente en la subconsulta:
Error 1093 (ER_UPDATE_TABLE_USED) SQLSTATE = HY000 Message = "You can't specify target table 'x' for update in FROM clause"
Este error ocurre en casos como el siguiente:
UPDATE t1 SET column2 = (SELECT MAX(column1) FROM t1);
Puede usar una subconsulta para asignaciones dentro del
comando UPDATE
, ya que las subconsultas
son legales en los comandos UPDATE
y
DELETE
así como en los
SELECT
. Sin embargo, no puede usar la
misma tabla (en este caso la tabla t1
)
para la cláusula FROM
de la
subconsulta y el objetivo a actualizar.
Para motores transaccionales, el fallo de una subconsulta provoca que falle el comando entero. Para motores no transaccionales, las modificaciones de datos hechas antes de encontrar el error se preservan.
El desarrollo está en marcha, por lo que no hay trucos de optimización fiables a largo plazo. Algunos trucos interesantes que puede usar son:
Use cláusulas de subconsulta que afecten al número u orden de los registros en la subconsulta. Por ejemplo:
SELECT * FROM t1 WHERE t1.column1 IN (SELECT column1 FROM t2 ORDER BY column1); SELECT * FROM t1 WHERE t1.column1 IN (SELECT DISTINCT column1 FROM t2); SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t2 LIMIT 1);
Reemplace un join con una subconsulta. Por ejemplo, pruebe:
SELECT DISTINCT column1 FROM t1 WHERE t1.column1 IN ( SELECT column1 FROM t2);
En lugar de:
SELECT DISTINCT t1.column1 FROM t1, t2 WHERE t1.column1 = t2.column1;
Algunas subconsultas pueden transformarse en joins por compatibilidad con versiones anteriores de MySQL que no soportan subconsultas. Sin embargo, en algunos casos, incluso en MySQL 5.0, convertir una subconsulta en un join puede mejorar el rendimiento. Consulte Sección 13.2.8.11, “Re-escribir subconsultas como joins en versiones de MySQL anteriores”.
Mueva las cláusulas desde fuera hacia dentro en la subconsulta. Por ejemplo , use esta consulta:
SELECT * FROM t1 WHERE s1 IN (SELECT s1 FROM t1 UNION ALL SELECT s1 FROM t2);
En lugar de:
SELECT * FROM t1 WHERE s1 IN (SELECT s1 FROM t1) OR s1 IN (SELECT s1 FROM t2);
Otro ejemplo. Use esta consulta:
SELECT (SELECT column1 + 5 FROM t1) FROM t2;
En lugar de:
SELECT (SELECT column1 FROM t1) + 5 FROM t2;
Use una subconsulta de registro en lugar de una subconsulta correlacionada . Por ejemplo, use:
SELECT * FROM t1 WHERE (column1,column2) IN (SELECT column1,column2 FROM t2);
En lugar de:
SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t2 WHERE t2.column1=t1.column1 AND t2.column2=t1.column2);
Use NOT (a = ANY (...))
en lugar de
a <> ALL (...)
.
Use x = ANY (table containing (1,2))
en
lugar de x=1 OR x=2
.
Use = ANY
en lugar de
EXISTS
.
Para subconsultas no correlacionadas que siempre retornan
un registro, IN
siempre es más lento
que =
. Por ejemplo, use esta consulta:
SELECT * FROM t1 WHERE t1.col_name
= (SELECT a FROM t2 WHERE b =some_const
);
En lugar de:
SELECT * FROM t1 WHERE t1.col_name
IN (SELECT a FROM t2 WHERE b =some_const
);
Estos trucos pueden hacer que los programas vayan más
rápidos o lentos. Usar recursos MySQL como la función
BENCHMARK()
es una buena idea para ver
cuáles funcionan.
Algunas optimizaciones que realiza MySQL son:
MySQL ejecuta subconsultas no correlacionadas sólo una
vez. Use EXPLAIN
para asegurar que una
subconsulta dada realmente no está correlacionada.
MySQL reescribe subconsultas IN
,
ALL
, ANY
, y
SOME
para aprovechar que las columnas
de la lista de select de la subconsulta está indexada.
MySQL reemplaza subconsultas de la siguiente forma con una
función de búsqueda de índice, que
EXPLAIN
describe como tipo especial de
join (unique_subquery
o
index_subquery
):
... IN (SELECTindexed_column
FROMsingle_table
...)
MySQL mejora expresiones de la siguiente forma con una
expresión que involucre MIN()
o
MAX()
, a no ser que hayan involucrados
valores NULL
o conjuntos vacíos:
value
{ALL|ANY|SOME} {> | < | >= | <=} (non-correlated subquery
)
Por ejemplo, esta cláusula WHERE
:
WHERE 5 > ALL (SELECT x FROM t)
puede tratarse por el optimizador como:
WHERE 5 > (SELECT MAX(x) FROM t)
Hay un capítulo titulado “Cómo transforma las
subconsultas MySQL” en el manual MySQL Internals
Manual. Puede obtener este documento descargando el paquete
fuente MySQL y buscando un fichero llamado
internals.texi
en el directorio
Docs
.
En versiones prévias de MySQL (anteriores a la MySQL 4.1),
sólo se soportaban consultas anidadas de la forma
INSERT ... SELECT ...
y REPLACE
... SELECT ...
. Este no es el caso en MySQL 5.0,
pero es cierto que hay a veces otras formas de testear la
pertenencia a un grupo de valores. También es cierto que en
algunas ocasiones, no es sólo posible reescribir una consulta
sin una subconsulta, sino que puede ser más eficiente hacerlo
que usar subconsultas. Una de las técnicas disponibles es
usar el constructor IN()
:
Por ejemplo, esta consulta:
SELECT * FROM t1 WHERE id IN (SELECT id FROM t2);
Puede reescribirse como:
SELECT DISTINCT t1.* FROM t1, t2 WHERE t1.id=t2.id;
Las consultas:
SELECT * FROM t1 WHERE id NOT IN (SELECT id FROM t2); SELECT * FROM t1 WHERE NOT EXISTS (SELECT id FROM t2 WHERE t1.id=t2.id);
Pueden reescribirse usando IN()
:
SELECT table1.* FROM table1 LEFT JOIN table2 ON table1.id=table2.id WHERE table2.id IS NULL;
Un LEFT [OUTER] JOIN
puede ser más rápido
que la subconsulta equivalente ya que el servidor puede ser
capaz de optimizarlo mejor — este es un hecho no
específico de MySQL Server . Antes de SQL-92, los outer joins
no existían, así que las subconsultas eran el único modo de
hacer ciertas cosas. Hoy, MySQL Server y otros sistemas de
bases de datos ofrecen un ámplio rango de tipos de outer
join.
MySQL Server soporta comandos DELETE
para
múltiples tablas que pueden usarse para borrar registros
basándose en la información de una tabla o de varias al
mismo tiempo. Los comandos UPDATE
para
múltiples tablas también se soportan en MySQL 5.0.
TRUNCATE TABLE tbl_name
TRUNCATE TABLE
vacía una tabla
completamente. Lógicamente, esto es equivalente a un comando
DELETE
que borre todos los registros, pero
hay diferencias prácticas bajo ciertas circunstáncias.
Para InnoDB
antes de la versión 5.0.3,
TRUNCATE TABLE
se mapea a
DELETE
, así que no hay diferencia. A partir
de MySQL/InnoDB-5.0.3, está disponible TRUNCATE
TABLE
muy rápido. La operación se mapea a
DELETE
si hay restricciones de clave foránea
que referencien la tabla.
Para otros motores, TRUNCATE TABLE
difiere de
DELETE FROM
en los siguientes puntos en MySQL
5.0:
Las operaciones de truncado destruyen y recrean la tabla, que es mucho más rápido que borrar registros uno a uno.
Las operaciones de truncado no son transaccionales; ocurre un error al intentar un truncado durante una transacción o un bloqueo de tabla.
No se retorna el número de registros borrados.
Mientras el fichero de definición de la tabla
sea válido, la tabla puede recrearse como una vacía con
tbl_name
.frmTRUNCATE TABLE
, incluso si los ficheros
de datos o de índice se han corrompido.
El tratador de tablas no recuerda el último valor
AUTO_INCREMENT
usado, pero empieza a
contar desde el principio. Esto es cierto incluso para
MyISAM
y InnoDB
, que
normalmente no reúsan valores de secuencia.
TRUNCATE TABLE
es una extensión de Oracle
SQL adoptada en MySQL.
Sintaxis para una tabla:
UPDATE [LOW_PRIORITY] [IGNORE]tbl_name
SETcol_name1
=expr1
[,col_name2
=expr2
...] [WHEREwhere_definition
] [ORDER BY ...] [LIMITrow_count
]
Sintaxis para múltiples tablas:
UPDATE [LOW_PRIORITY] [IGNORE]table_references
SETcol_name1
=expr1
[,col_name2
=expr2
...] [WHEREwhere_definition
]
El comando UPDATE
actualiza columnas en
registros de tabla existentes con nuevos valores. La cláusula
SET
indica qué columna modificar y los
valores que puede recibir. La cláusula WHERE
, si se da, especifica qué registros deben actualizarse. De
otro modo, se actualizan todos los registros. Si la cláusula
ORDER BY
se especifica, los registros se
actualizan en el orden que se especifica. La cláusula
LIMIT
es el límite de registros a
actualizar.
El comando UPDATE
soporta los siguientes
modificadores:
Si usa la palabra clave LOW_PRIORITY
, la
ejecución de UPDATE
se retrasa hasta que
no haya otros clientes leyendo de la tabla.
Si usa la palabra clave IGNORE
, el
comando de actualización no aborta incluso si ocurren
errores durante la actualización. Los registros que
presenten conflictos de clave duplicada no se actualizan.
Los registros cuyas columnas se actualizan a valores que
provocarían errores de conversión de datos se actualizan
al valor válido más próximo.
Si accede a una columna de tbl_name
en una expresión, UPDATE
usa el valora ctual
de la columna. Por ejemplo, el siguiente comando pone la columna
age
a uno más que su valor actual:
mysql> UPDATE persondata SET age=age+1;
Las asignaciones UPDATE
se avalúna de
izquierda a derecha. Por ejemplo, el siguiente comando dobla la
columna age
y luego la incrementa:
mysql> UPDATE persondata SET age=age*2, age=age+1;
Si pone en una columna el valor que tiene actualmente, MySQL se da cuenta y no la actualiza.
Si actualiza una columna declarada como NOT
NULL
con un valor NULL
, la columna
recibe el valor por defecto apropiado para el tipo de la columna
y se incrementa el contador de advertencias. El valor por
defecto es 0
para tipos numéricos, la cadena
vacía (''
) para tipos de cadena, y el valor
“cero” para valores de fecha y hora.
UPDATE
retorna el número de registros que se
cambian. En MySQL 5.0, la función
mysql_info()
de la API de C retorna el
número de registros coincidentes actualizados y el número de
advertencias que ocurren durante el UPDATE
.
Puede usar LIMIT
para restringir
el alcance del row_count
UPDATE
. Una cláusula
LIMIT
es una restricción de registros
coincidentes. El comando para en cuanto encuentra
row_count
registos que satisfagan la
cláusula WHERE
, tanto si han sido cambiados
como si no.
Si un comando UPDATE
incluye una cláusula
ORDER BY
, los registros se actualizan en el
orden especificado por la cláusula.
Puede realizar operaciones UPDATE
que cubran
varias tablas. La parte
table_references
lista las tablas
involucradas en el join. Su sintaxis se describe ámpliamente en
Sección 13.2.7.1, “Sintaxis de JOIN
”. Aquí hay un ejemplo:
UPDATE items,month SET items.price=month.price WHERE items.id=month.id;
Este ejemplo muestra un inner join usando el operador coma, pero
los comandos UPDATE
de múltiples tablas
pueden usar cualquier tipo de join permitido en comandos
SELECT
tales como LEFT
JOIN
.
Nota: No
puede usar ORDER BY
o
LIMIT
con un UPDATE
de
múltiples tablas.
En MySQL 5.0, necesita el permiso UPDATE
sólo para columnas referenciadas en un
UPDATE
de múltiples tablas que se actualizan
realmente. Necesita sólo el permiso SELECT
para algunas columnas que se leen pero no se modifican.
Si usa un comando UPDATE
de múltiples tablas
que involucren tablas InnoDB
con
restricciones de claves foráneas, el optimizador de MySQL puede
procesar tablas en un orden distinto al de la relación
padre/hijo. En este caso, el comando fall y hace un roll back.
En su lugar, actualice una única tabla y confíen en las
capacidades de ON UPDATE
que proporciona
InnoDB
para que el resto de tablas se
modifiquen acórdemente. Consulte
Sección 15.6.4, “Restricciones (constraints) FOREIGN KEY
”.
Actualmente, no puede actualizar una tabla y seleccionar de la misma en una subconsulta.
{DESCRIBE | DESC}tbl_name
[col_name
|wild
]
DESCRIBE
proporciona información acerca de
columnas en una tabla. Es una abreviación de SHOW
COLUMNS FROM
. Desde MySQL 5.0.1, estos comandos
también muestran información para vistas.
Consulte Sección 13.5.4.3, “Sintaxis de SHOW COLUMNS
”.
col_name
puede ser un nombre de
columna, o una cadena con los carácteres de SQL
'%
' y '_
' para obtener
salida sólo para las columnas con nombres que coincidan con la
cadena. No hay necesidad de delimitar la cadena con comillas a
no ser que contenga espacios u otros carácteres especiales.
mysql> DESCRIBE city; +------------+----------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+----------+------+-----+---------+----------------+ | Id | int(11) | | PRI | NULL | auto_increment | | Name | char(35) | | | | | | Country | char(3) | | UNI | | | | District | char(20) | YES | MUL | | | | Population | int(11) | | | 0 | | +------------+----------+------+-----+---------+----------------+ 5 rows in set (0.00 sec)
La columna Null
indica si pueden almacenarse
los valores NULL
, mostrando
YES
cuando se permiten valores
NULL
.
La columna Key
indica si el campo está
indexado. Un valor de PRI
indica que el campo
es parte de una clave primaria de tabla. UNI
indica que el campo es parte de un índice
UNIQUE
. El valor MUL
indica que se permiten múltiples ocurrencias de un valor dado
dentro del campo.
Un campo puede designarse como MUL
incluso si
se usa un índice UNIQUE
si se permiten
valores NULL
, ya que múltiples registros en
un índice UNIQUE
pueden tener un valor
NULL
si la columna no se declara NOT
NULL
. Otra causa para MUL
en un
índice UNIQUE
es cuando dos columnas de un
índice UNIQUE
compuesto; mientras la
combinación de las columnas sea única, cada columna puede
tener múltiples ocurrencias de un valor dado. Tenga en cuenta
que en un índice compuesto sólo el campo de más a la
izquierda del índice tiene una entrada en la columna
Key
.
La columna Default
indica el valor por
defecto asignado al campo.
La columna Extra
contiene cualquier
información adicional disponible acerca de un campo dado. En
nuestro ejemplo la columna Extra
indica que
la columna Id
se creó con la palabra clave
AUTO_INCREMENT
.
Si los tipos de columna son distintos a los esperados según el
comando CREATE TABLE
, tenga en cuenta que a
veces MySQL cambia los tipos de columa. Consulte
Sección 13.1.5.1, “Cambios tácitos en la especificación de columnas”.
El comando DESCRIBE
se proporciona por
compatibilidad con Oracle.
Los comandos SHOW CREATE TABLE
y
SHOW TABLE STATUS
proporcionan información
acerca de tablas . Consulte Sección 13.5.4, “Sintaxis de SHOW
”.
USE db_name
El comando USE
le dice a MySQL que
use la base de datos db_name
db_name
como la
base de datos por defecto para los comandos siguientes. Sigue
siendo la base de datos por defecto hasta el final de la sesión
o hasta que se realiza otro comando USE
:
mysql> USE db1; mysql> SELECT COUNT(*) FROM mytable; # selects from db1.mytable mysql> USE db2; mysql> SELECT COUNT(*) FROM mytable; # selects from db2.mytable
Hacer una base de datos particular la actual signfica que el
comando USE
no le imposibilita a acceder a
tablas en otras bases de datos. El siguiente ejemplo accede a la
tabla author
desde la base de datos
db1
y a la tabla editor
desde la base de datos db2
:
mysql> USE db1; mysql> SELECT author_name,editor_name FROM author,db2.editor -> WHERE author.editor_id = db2.editor.editor_id;
El comando USE
se proporciona por
compatibilidad con Sybase.
Por defecto, MySQL se ejecuta con el modo autocommit activado. Esto significa que en cuanto ejecute un comando que actualice (modifique) una tabla, MySQL almacena la actualización en disco.
Si usa tablas transaccionales (como InnoDB
o
BDB
), puede desactivar el modo autocommit con
el siguiente comando:
SET AUTOCOMMIT=0;
Tras deshabilitar el modo autocommit poniendo la variable
AUTOCOMMIT
a cero, debe usar
COMMIT
para almacenar los cambios en disco o
ROLLBACK
si quiere ignorar los cambios hechos
desde el comienzo de la transacción.
Si quiere deshabilitar el modo autocommit para una serie única
de comandos, puede usar el comando START
TRANSACTION
:
START TRANSACTION; SELECT @A:=SUM(salary) FROM table1 WHERE type=1; UPDATE table2 SET summary=@A WHERE type=1; COMMIT;
Con START TRANSACTION
, autocommit permanece
deshabilitado hasta el final de la transacción con
COMMIT
o ROLLBACK
. El modo
autocommit vuelve a su estado prévio.
BEGIN
y BEGIN WORK
se
soportan como alias para START TRANSACTION
para iniciar una transacción. START
TRANSACTION
es sintaxis SQL estándar y es la forma
recomendada para iniciar una transacción ad-hoc . El comando
BEGIN
difiere del uso de la palabra clave
BEGIN
que comienza un comando compuesto
BEGIN ... END
. El último no comienza una
transacción. Consulte Sección 19.2.7, “Sentencia compuesta BEGIN ... END
”.
Puede comenzar una transacción así:
START TRANSACTION WITH CONSISTENT SNAPSHOT;
La cláusula WITH CONSISTENT SNAPSHOT
comienza una lectura consistente para motores de almacenamiento
capaces de ello. Actualmente, esto se aplica sólo a
InnoDB
. El efecto es el mismo que realizar un
START TRANSACTION
seguido por un
SELECT
desde cualquier tabla
InnoDB
. Consulte
Sección 15.10.4, “Lecturas consistentes que no bloquean”.
Comenzar una transacción provoca que se realice un
UNLOCK TABLES
implícito.
Tenga en cuenta que si no usa tablas transaccionales, cualquier cambio se almacena de golpe, a pesar del estado del modo autocommit .
Si realiza un comando ROLLBACK
tras
actualizar una tabla no transaccional dentro de una
transacción, ocurre una advertencia
ER_WARNING_NOT_COMPLETE_ROLLBACK
. Los cambios
en tablas transaccionales se deshacen, pero no los cambios en
tablas no transaccionales.
Cada transacción se almacena en el log binario en un trozo,
hasta COMMIT
. Las transacciones que se
deshacen no se loguean. (Exceción: Las
modificaciones a tablas no transaccionales no pueden deshacerse.
Si una transacción que se deshace incluye modificaciones a
tablas no transaccionales, la transacción entera se loguea con
un comando ROLLBACK
al final para asegurar
que las modificaciones a estas tablas se replican.) Consulte
Sección 5.10.3, “El registro binario (Binary Log)”.
Puede cambiar el nivel de aislamiento para transacciones con
SET TRANSACTION ISOLATION LEVEL
. Consulte
Sección 13.4.6, “Sintaxis de SET TRANSACTION
”.
Deshacer puede ser una operación lenta que puede ocurrir sin
que el usuario lo haya pedido explícitamente (por ejemplo,
cuando ocurre un error). Debido a ello, SHOW
PROCESSLIST
en MySQL 5.0 muestra Rolling
back
en la columna State
para la
conexión durante rollbacks implícitos y explícitos (comando
SQL ROLLBACK
).
Algunos comandos no pueden deshacerse. En general, esto incluye comandos del lenguaje de definición de datos (DDL), tales como los que crean y borran bases de datos, los que crean, borran o alteran tablas o rutinas almacenadas.
Debe designar que sus transacciones no incluyan tales comandos.
Si realiza un comando pronto en una transacción que no puede
deshacerse, y luego un comando posterior falla, el efecto global
de la transacción no puede deshacerse mediante un comando
ROLLBACK
.
Cada uno de los comandos siguientes (y cualquier sinónimo de
los mismos) terminan una transacción implícitamente, como si
hubiera realizado un COMMIT
antes de ejecutar
el comando:
ALTER TABLE | BEGIN | CREATE INDEX |
CREATE TABLE | | CREATE DATABASE |
DROP DATABASE | DROP INDEX | DROP TABLE |
LOAD MASTER DATA | LOCK TABLES | RENAME TABLE |
SET AUTOCOMMIT=1 | START TRANSACTION | TRUNCATE TABLE |
UNLOCK TABLES
también realiza un commit de
una transacción si hay cualquier tabla bloqueada.
Las transacciones no pueden anidarse. Esto es una consecuencia
del COMMIT
implícito realizado por cualquier
transacción actual cuando realiza un comando START
TRANSACTION
o uno de sus sinónimos.
SAVEPOINT identifier ROLLBACK TO SAVEPOINT identifier
En MySQL 5.0, InnoDB
soporta los comandos SQL
SAVEPOINT
y ROLLBACK TO
SAVEPOINT
.
El comando SAVEPOINT
crea un punto dentro de
una transacción con un nombre identifier
. Si
la transacción actual tiene un punto con el mismo nombre, el
antiguo se borra y se crea el nuevo.
El comando ROLLBACK TO SAVEPOINT
deshace una
transacción hasta el punto nombrado. Las modificaciones que la
transacción actual hace al registro tras el punto se deshacen
en el rollback, pero InnoDB
no libera los bloqueos de registro que se
almacenaron en memoria tras el punto . (Tenga en cuenta que para
un nuevo registro insertado, la información de bloqueo se
realiza a partir del ID de transacción almacenado en el
registro; el bloqueo no se almacena separadamente en memoria. En
este caso, el bloqueo de registro se libera al deshacerse todo.)
Los puntos creados tras el punto nombrado se borran.
Si un comando retorna el siguiente error, significa que no existe ningún punto con el nombre especificado:
ERROR 1181: Got error 153 during ROLLBACK
Todos los puntos de la transacción actual se borran si ejecuta
un COMMIT
, o un ROLLBACK
que no nombre ningún punto.
LOCK TABLEStbl_name
[ASalias
] {READ [LOCAL] | [LOW_PRIORITY] WRITE} [,tbl_name
[ASalias
] {READ [LOCAL] | [LOW_PRIORITY] WRITE}] ... UNLOCK TABLES
LOCK TABLES
bloquea tablas para el flujo
actual. Si alguna de las tablas la bloquea otro flujo, bloquea
hasta que pueden adquirirse todos los bloqueos. UNLOCK
TABLES
libera cualquier bloqueo realizado por el flujo
actual. Todas las tablas bloqueadas por el flujo actual se
liberan implícitamente cuando el flujo reliza otro
LOCK TABLES
, o cuando la conexión con el
servidor se cierra.
Un bloqueo de tabla protege sólo contra lecturtas inapropoadas
o escrituras de otros clientes. El cliente que tenga el bloqueo,
incluso un bloqueo de lectura, puede realizar operaciones a
nivel de tabla tales como DROP TABLE
.
Tenga en cuenta lo siguiente a pesar del uso de LOCK
TABLES
con tablas transaccionales:
LOCK TABLES
no es una operación
transaccional y hace un commit implícito de cualquier
transacción activa antes de tratar de bloquear las tablas.
También, comenzar una transacción (por ejemplo, con
START TRANSACTION
) realiza un
UNLOCK TABLES
implícito. (Consulte
Sección 13.4.3, “Sentencias que causan una ejecución (commit) implícita”.)
La forma correcta de usar LOCK TABLES
con
tablas transaccionales,como InnoDB
, es
poner AUTOCOMMIT = 0
y no llamar a
UNLOCK TABLES
hasta que hace un commit de
la transacción explícitamente. Cuando llama a
LOCK TABLES
, InnoDB
internamente realiza su propio bloqueo de tabla, y MySQL
realiza su propio bloqueo de tabla.
InnoDB
libera su bloqueo de tabla en el
siguiente commit, pero para que MySQL libere su bloqueo de
tabla, debe llamar a UNLOCK TABLES
. No
debe tener AUTOCOMMIT = 1
, porque
entonces InnoDB
libera su bloqueo de
tabla inmediatamente tras la llamada de LOCK
TABLES
, y los deadlocks pueden ocurrir
fácilmente. (Tenga en cuenta que en MySQL 5.0, no
adquirimos el bloqueo de tabla InnoDB
en
absoluto si AUTOCOMMIT=1
, para ayudar a
aplicaciones antiguas a envitar deadlocks.)
ROLLBACK
no libera bloqueos de tablas no
transaccionales de MySQL.
Para usar LOCK TABLES
en MySQL 5.0, debe
tener el permiso LOCK TABLES
y el permiso
SELECT
para las tablas involucradas.
La razón principal para usar LOCK TABLES
es
para emular transacciones o para obtener más velocidad al
actualizar tablas. Esto se explica con más detalle
posteriormente.
Si un flujo obtiene un bloqueo READ
en una
tabla, ese flujo (y todos los otros) sólo pueden leer de la
tabla. Si un flujo obtiene un bloqueo WRITE
en una tabla, sólo el flujo con el bloqueo puede escribir a la
tabla. El resto de flujos se bloquean hasta que se libera el
bloqueo.
La diferencia entre READ LOCAL
y
READ
es que READ LOCAL
permite comandos INSERT
no conflictivos
(inserciones concurrentes) se ejecuten mientras se mantiene el
bloqueo. Sin embargo, esto no puede usarse si va a manipular los
ficheros de base de datos fuera de MySQL mientras mantiene el
bloqueo. Para tablas InnoDB
, READ
LOCAL
esencialmente no hace nada: No bloquea la tabla.
Para tablas InnoDB
, el uso de READ
LOCAL
está obsoleto ya que una
SELECT
consistente hace lo mismo, y no se
necesitan bloqueos.
Cuando usa LOCK TABLES
, debe bloquear todas
las tablas que va a usar en sus consultas. Mientras los bloqueos
obtenidos con un comando LOCK TABLES
están
en efecto, no puede acceder a ninguna tabla que no estuviera
bloqueada por el comando. Además, no puede usar una tabla
bloqueada varias veces en una consulta --- use alias para ello.
Tenga en cuenta que en este caso, debe tener un bloqueo separado
para cada alias.
mysql> LOCK TABLE t WRITE, t AS t1 WRITE; mysql> INSERT INTO t SELECT * FROM t; ERROR 1100: Table 't' was not locked with LOCK TABLES mysql> INSERT INTO t SELECT * FROM t AS t1;
Si sus consultas se refieren a una tabla que use un alias, debe bloquear la tabla que usa el mismo alias. No funciona bloquear la tabla sin especificar el alias:
mysql> LOCK TABLE t READ; mysql> SELECT * FROM t AS myalias; ERROR 1100: Table 'myalias' was not locked with LOCK TABLES
Si bloquea una tabla usando un alias, debe referirse a ella en sus consultas usando este alias:
mysql> LOCK TABLE t AS myalias READ; mysql> SELECT * FROM t; ERROR 1100: Table 't' was not locked with LOCK TABLES mysql> SELECT * FROM t AS myalias;
WRITE
bloquea normalmente teniendo una
prioridad superior que READ
al bloquear para
asegurar que las actualizaciones se procesan en cuanto se puede.
Esto significa que si un flujo obtiene un bloqueo
READ
y luego otro flujo pide un bloqueo
WRITE
, las peticiones de bloqueo
READ
posteriores esperan hasta que el flujo
WRITE
quita el bloqueo. Puede usar bloqueos
LOW_PRIORITY WRITE
para permitir a otros
flujos que obtengan bloqueos READ
mientras el
flujo está en espera para el bloqueo WRITE
.
Debe usar bloqueos LOW_PRIORITY WRITE
sólo
si está seguro que habrá un momento sin flujos con bloqueos
READ
.
LOCK TABLES
funciona como sigue:
Ordena todas las tablas a ser bloqueadas en un orden definido internamente. Desde el punto de vista del usuario, este orden es indefinido.
Si una tabla se bloquea con bloqueo de escritura y lectura, pone el bloqueo de lectura antes del de escritura.
Bloquea una tabla cada vez hasta que el flujo obtiene todos los bloqueos.
Esta política asegura un bloqueo de tablas libre de deadlocks. Sin embargo hay otros puntos que debe tener en cuenta respecto a esta política:
Si está usando un bloqueo LOW_PRIORITY WRITE
para una tabla, sólo significa que MySQL espera para este
bloqueo particular hasta que no hay flujos que quieren un
bloqueo READ
. Cuando el flujo ha obtenido el
bloqueo WRITE
y está esperando para obtener
un bloqueo para la siguiente tabla en la lista, todos los otros
flujos esperan hasta que el bloqueo WRITE
se
libera. Si esto es un problema con su aplicación, debe
considerar convertir algunas de sus tablas a transaccionales.
Puede usar KILL
para terminar un flujo que
está esperando para un bloqueo de tabla. Consulte
Sección 13.5.5.3, “Sintaxis de KILL
”.
Tenga en cuenta que no debe bloquear
ninguna tabla que esté usando con INSERT
DELAYED
ya que en tal caso el
INSERT
lo realiza un flujo separado.
Normalmente, no tiene que bloquear tablas, ya que todos los
comandos UPDATE
son atómicos, ningún otro
flujo puede interferir con ningún otro que está ejecutando
comandos SQL . Hay algunos casos en que no debe bloquear tablas
de ningún modo:
Si va a ejecutar varias operaciones en un conjunto de tablas
MyISAM
, es mucho más rápido bloquear
las tablas que va a usar. Bloquear tablas
MyISAM
acelera la inserción, las
actualizaciones, y los borrados. Por contra, ningún flujo
puede actualizar una tabla con un bloqueo
READ
(incluyendo el que tiene el bloqueo)
y ningún flujo puede acceder a una tabla con un bloqueo
WRITE
distinto al que tiene el bloqueo.
La razón que algunas operaciones MyISAM
sean más rápidas bajo LOCK TABLES
es
que MySQL no vuelca la caché de claves para la tabla
bloqueada hasta que se llama a UNLOCK
TABLES
. Normalmente, la caché de claves se vuelca
tras cada comando SQL.
Si usa un motor de almacenamiento en MySQL que no soporta
transacciones, debe usar LOCK TABLES
si
quiere asegurarse que ningún otro flujo se ejecute entre un
SELECT
y un UPDATE
. El
ejemplo mostrado necesita LOCK TABLES
para ejecutarse sin problemas:
mysql> LOCK TABLES trans READ, customer WRITE; mysql> SELECT SUM(value) FROM trans WHERE customer_id=some_id
; mysql> UPDATE customer -> SET total_value=sum_from_previous_statement
-> WHERE customer_id=some_id
; mysql> UNLOCK TABLES;
Sin LOCK TABLES
, es posible que otro
flujo pueda insertar un nuevo registro en la tabla
trans
entre la ejecución del comando
SELECT
y UPDATE
.
Puede evitar usar LOCK TABLES
en varios casos
usando actualizaciones relativas (UPDATE customer SET
)
o la función value
=value
+new_value
LAST_INSERT_ID()
, Consulte
Sección 1.7.5.3, “Transacciones y operaciones atómicas”.
Puede evitar bloquear tablas en algunos casos usando las
funciones de bloqueo de nivel de usuario
GET_LOCK()
y
RELEASE_LOCK()
. Estos bloqueos se guardan en
una tabla hash en el servidor e implementa
pthread_mutex_lock()
y
pthread_mutex_unlock()
para alta velocidad.
Consulte Sección 12.9.4, “Funciones varias”.
Consulte Sección 7.3.1, “Métodos de bloqueo”, para más información acerca de la política de bloqueo.
Puede bloquear todas las tablas en todas las bases de datos con
bloqueos de lectura con el comando FLUSH TABLES WITH
READ LOCK
. Consulte Sección 13.5.5.2, “Sintaxis de FLUSH
”. Esta es
una forma muy conveniente para obtener copias de seguridad si
tiene un sistema de ficheros como Veritas que puede obtener el
estado en un punto temporal.
Nota: Si usa ALTER
TABLE
en una tabla bloqueada, puede desbloquearse.
Consulte Sección A.7.1, “Problemas con ALTER TABLE
”.
SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE }
Este comando prepara el nivel de aislamiento de transacción para la siguiente transacción, globalmente, o para la sesión actual.
El comportamiento por defecto de SET
TRANSACTION
es poner el nivel de aislammiento para la
siguiente transacción (que no ha empezado todavía). Si usa lka
palabra clave GLOBAL
el comando pone el nivel
de aislamiento de transacción por defecto globalmente para
todas las transacciones creadas desde ese momento. Las
conexiones existentes no se ven afectadas. Necesita el permiso
SUPER
para hacerlo. Usar la palabra clave
SESSION
determina el nivel de transacción
para todas las transacciones futuras realizadas en la conexión
actual.
Para descripciones del nivel de aislamiento de cada transacción
InnoDB
, consulte
Sección 15.10.3, “InnoDB
y TRANSACTION ISOLATION LEVEL
”.
InnoDB
soporta cada uno de estos niveles en
MySQL 5.0. El nivel por defecto es REPEATABLE
READ
.
Puede inicializar el nivel de aislamiento global por defecto
para mysqld con la opción
--transaction-isolation
. Consulte
Sección 5.3.1, “Opciones del comando mysqld”.
CREATE USERuser
[IDENTIFIED BY [PASSWORD] 'password
'] [,user
[IDENTIFIED BY [PASSWORD] 'password
']] ...
El comando CREATE USER
se añadió en MySQL
5.0.2. Este comando crea nuevas cuentas MySQL. Para usarlas,
debe tener el permiso global CREATE USER
o
el permiso INSERT
para la base de datos
mysql
. Para cada cuenta, CREATE
USER
crea un nuevo registro en la tabla
mysql.user
que no tiene permisos. Un error
ocurre si la cuenta ya existe.
La cuenta puede tener una contraseña con la cláusula
opcional IDENTIFIED BY
. El valor
user
y la contraseña se dan del
mismo modo que para el comando GRANT
. En
particular, para especificar la contraseña en texto plano,
omita la palabra clave PASSWORD
. Para
especificar la contraseña como el valor hasheado retornado
por la función PASSWORD()
, incluya la
palabra clave PASSWORD
. Consulte
Sección 13.5.1.3, “Sintaxis de GRANT
y REVOKE
”.
DROP USERuser
[,user
] ...
El comando DROP USER
borra una o más
cuentas MySQL . Para usarlo, debe tener el permiso global
CREATE USER
o el permiso
DELETE
para la base de datos
mysql
. Cada cuenta se nombra usando el
mismo formato que para GRANT
o
REVOKE
; por ejemplo,
'jeffrey'@'localhost'
. Las partes de
usuario y equipo del nombre de cuenta se corresponden a las
columnas User
y Host
del
registro de la tabla user
para la cuenta.
DROP USER
como está en MySQL 5.0.0 borra
sólo cuentas que no tienen permisos. En MySQL 5.0.2, se
modificó para eliminar permisos de cuenta también. Esto
significa que el procedimiento para borrar una cuenta depende
en su versión de MySQL.
Desde MySQL 5.0.2, puede borrar una cuenta y sus permisos como sigue:
DROP USER user
;
El comando borra registros de permisos para la cuenta de todas las tablas de permisos.
En MySQL 5.0.0 y 5.0.1, DROP USER
borra
sólo cuentas MySQL que no tienen permisos. En estas versiones
MySQL sólo sirve para borrar cada registro de cuenta de la
tabla user
. Para borrar una cuenta MySQL
completamente (incluyendo todos sus permisos), debe usar el
siguiente procedimiento, realizando estos pasos en el orden
mostrado:
Use SHOW GRANTS
para determinar los
permisos que tiene la cuenta. Consulte
Sección 13.5.4.10, “Sintaxis de SHOW GRANTS
”.
Use REVOKE
para revocar los permisos
mostrados por SHOW GRANTS
. Esto borra
registros para la cuenta de todas las tablas de permisos
excepto la tabla user
, y revoca
cualquier permiso global listado en la tabla
user
. Consulte
Sección 13.5.1.3, “Sintaxis de GRANT
y REVOKE
”.
Borre la cuenta usando DROP USER
para
borrar el registro de la tabla user
.
DROP USER
no cierra automáticamente
ninguna sesión de usuario. En lugar de ello, en el evento que
un usuario con una sesión abierta se elimina, el comando no
tiene efecto hasta que se cierra la sesión de usuario. Una
vez se ha cerrado, el usuario se borra, y el próximo usuario
de logueo del usuario fallará. Esto es por diseño.
GRANTpriv_type
[(column_list
)] [,priv_type
[(column_list
)]] ... ON [object_type
] {tbl_name
| * | *.* |db_name
.*} TOuser
[IDENTIFIED BY [PASSWORD] 'password
'] [,user
[IDENTIFIED BY [PASSWORD] 'password
']] ... [REQUIRE NONE | [{SSL| X509}] [CIPHER 'cipher
' [AND]] [ISSUER 'issuer
' [AND]] [SUBJECT 'subject
']] [WITHwith_option
[with_option
] ...]object_type
= TABLE | FUNCTION | PROCEDUREwith_option
= GRANT OPTION | MAX_QUERIES_PER_HOURcount
| MAX_UPDATES_PER_HOURcount
| MAX_CONNECTIONS_PER_HOURcount
| MAX_USER_CONNECTIONScount
REVOKEpriv_type
[(column_list
)] [,priv_type
[(column_list
)]] ... ON [object_type
] {tbl_name
| * | *.* |db_name
.*} FROMuser
[,user
] ... REVOKE ALL PRIVILEGES, GRANT OPTION FROMuser
[,user
] ...
Los comandos GRANT
y
REVOKE
permiten a los adminitradores de
sistemas crear cuentas de usuario MySQL y darles permisos y
quitarlos de las cuentas.
La información de cuenta de MySQL se almacena en las tablas
de la base de datos mysql
. Esta base de
datos y el sistema de control de acceso se discuten
extensivamente en
Capítulo 5, Administración de bases de datos, que puede
consultar para más detalles.
Si las tablas de permisos tienen registros de permisos que
contienen nombres de tablas o bases de datos con mayúsculas y
minúsculas y la variable de sistema
lower_case_table_names
está activa,
REVOKE
no puede usarse para quitar los
permisos. Es necesario manipular las tablas de permisos
directamente. (GRANT
no creará estos
registros cuando está activo
lower_case_table_names
, pero tales
registros pueden haberse creado préviamente a activar la
variable.)
Los permisos pueden darse en varios niveles:
Nivel global
Los permisos globales se aplican a todas las bases de
datos de un servidor dado. Estos permisos se almacenan en
la tabla mysql.user
. GRANT ALL
ON *.*
y REVOKE ALL ON *.*
otorgan y quitan sólo permisos globales.
Nivel de base de datos
Los permisos de base de datos se aplican a todos los
objetos en una base de datos dada. Estos permisos se
almacenan en las tablas mysql.db
y
mysql.host
. GRANT ALL ON
y
db_name
.*REVOKE ALL ON
otorgan y
quitan sólo permisos de bases de datos.
db_name
.*
Nivel de tabla
Los permisos de tabla se aplican a todas las columnas en
una tabla dada. Estos permisos se almacenan en la tabla
mysql.tables_priv
. GRANT ALL
ON
y
db_name.tbl_name
REVOKE ALL ON
otorgan y quian permisos sólo de tabla.
db_name.tbl_name
Nivel de columna
Los permisos de columna se aplican a columnas en una tabla
dada. Estos permisos se almacenan en la tabla
mysql.columns_priv
. Usando
REVOKE
, debe especificar las mismas
columnas que se otorgaron los permisos.
Nivel de rutina
Los permisos CREATE ROUTINE
,
ALTER ROUTINE
,
EXECUTE
, y GRANT
se
aplican a rutinas almacenadas. Pueden darse a niveles
global y de base de datos. Además, excepto para
CREATE ROUTINE
, estos permisos pueden
darse en nivel de rutinas para rutinas individuales y se
almacenan en la tabla mysql.procs_priv
.
La cláusula object_type
se
añadió en MySQL 5.0.6. Debe especificarse como
TABLE
, FUNCTION
, o
PROCEDURE
cuando el siguiente objeto es una
tabla, una función almacenada, o un procedimiento almacenado.
Para usar esta cláusula cuando actualice de una versión
anterior de MySQL a la 5.0.6, debe actualizar las tablas de
permisos. Consulte Sección 2.10.2, “Aumentar la versión de las tablas de privilegios”.
Para usar GRANT
o
REVOKE
, debe tener el permiso
GRANT OPTION
, y debe tener los permisos
que está dando o quitando.
Para hacer fácil de quitar todos los permisos, MySQL 5.0 tiene la siguiente sintaxis, que borra todos los permisos globales, de nivel de base de datos y de nivel de tabla para los usuarios nombrados:
REVOKE ALL PRIVILEGES, GRANT OPTION FROMuser
[,user
] ...
Para usar esta sintaxis REVOKE
, debe tener
el permiso CREATE USER
global o el permiso
UPDATE
para la base de datos
mysql
.
Para los comandos GRANT
y
REVOKE
, priv_type
pueden especificarse como cualquiera de los siguientes:
Permiso | Significado |
ALL [PRIVILEGES] | Da todos los permisos simples excepto GRANT OPTION |
ALTER | Permite el uso de ALTER TABLE |
ALTER ROUTINE | Modifica o borra rutinas almacenadas |
CREATE | Permite el uso de CREATE TABLE |
CREATE ROUTINE | Crea rutinas almacenadas |
CREATE TEMPORARY TABLES | Permite el uso de CREATE TEMPORARY TABLE |
CREATE USER | Permite el uso de CREATE USER , DROP
USER , RENAME USER , y
REVOKE ALL PRIVILEGES . |
CREATE VIEW | Permite el uso de CREATE VIEW |
DELETE | Permite el uso de DELETE |
DROP | Permite el uso de DROP TABLE |
EXECUTE | Permite al usuario ejecutar rutinas almacenadas |
FILE | Permite el uso de SELECT ... INTO OUTFILE y
LOAD DATA INFILE |
INDEX | Permite el uso de CREATE INDEX y DROP
INDEX |
INSERT | Permite el uso de INSERT |
LOCK TABLES | Permite el uso de LOCK TABLES en tablas para las que
tenga el permiso SELECT |
PROCESS | Permite el uso de SHOW FULL PROCESSLIST |
REFERENCES | No implementado |
RELOAD | Permite el uso de FLUSH |
REPLICATION CLIENT | Permite al usuario preguntar dónde están los servidores maestro o esclavo |
REPLICATION SLAVE | Necesario para los esclavos de replicación (para leer eventos del log binario desde el maestro) |
SELECT | Permite el uso de SELECT |
SHOW DATABASES | SHOW DATABASES muestra todas las bases de datos |
SHOW VIEW | Permite el uso de SHOW CREATE VIEW |
SHUTDOWN | Permite el uso de mysqladmin shutdown |
SUPER | Permite el uso de comandos CHANGE MASTER ,
KILL , PURGE MASTER
LOGS , and SET GLOBAL , el
comando mysqladmin debug le permite
conectar (una vez) incluso si se llega a
max_connections |
UPDATE | Permite el uso de UPDATE |
USAGE | Sinónimo de “no privileges” |
GRANT OPTION | Permite dar permisos |
El permiso EXECUTE
no es operacional hasta
MySQL 5.0.3. CREATE VIEW
y SHOW
VIEW
se añadieron en MySQL 5.0.1. CREATE
USER
, CREATE ROUTINE
, y
ALTER ROUTINE
se añadieron en MySQL 5.0.3.
Para usar estos permisos al actualizar desde una versión
anterior de MySQL que no los tenga, debe actualizar primero
las tablas de permisos, como se describe en
Sección 2.10.2, “Aumentar la versión de las tablas de privilegios”.
El permiso REFERENCES
actualmente no se
usa.
USAGE
puede especificarse cuando quiere
crear un usuario sin permisos.
Use SHOW GRANTS
para determinar qué
permisos tiene la cuenta. Consulte
Sección 13.5.4.10, “Sintaxis de SHOW GRANTS
”.
Puede asignar permisos globales usando sintaxis ON
*.*
o permisos a nivel de base de datos usando la
sintaxis ON
. Si especifica
db_name
.*ON *
y tiene seleccionada una base de datos
por defecto, los permisos se dan en esa base de datos.
(Atención: Si especifica
ON *
y no ha
seleccionado una base de datos por defecto, los permisos dados
son globales.)
Los permisos FILE
,
PROCESS
, RELOAD
,
REPLICATION CLIENT
, REPLICATION
SLAVE
, SHOW DATABASES
,
SHUTDOWN
, y SUPER
son
permisos administrativos que sólo pueden darse globalmente
(usando sintaxis ON *.*
).
Otros permisos pueden darse globalmente o a niveles más específicos.
Los únicos valores priv_type
que puede
especificar para una tabla son SELECT
,
INSERT
, UPDATE
,
DELETE
, CREATE
,
DROP
, GRANT OPTION
,
INDEX
, y ALTER
.
Los únicos valores priv_type
que puede
especificar para una columna (cuando usa la cláusula
column_list
) son
SELECT
, INSERT
, y
UPDATE
.
Los únicos valores priv_type
que puede
especificar a nivel de rutina son ALTER
ROUTINE
, EXECUTE
, y
GRANT OPTION
. CREATE
ROUTINE
no es un permiso de nivel de rutina porque
debe tener este permiso para ser capaz de crear una rutina en
primer lugar.
Para los niveles global, base de datos, tabla y rutina,
GRANT ALL
asigna sólo los permisos que
existen en el nivel que está otorgándolos. Por ejemplo, si
usa GRANT ALL ON
, este es un
comando de nivel de base de datos, así que ninguno de los
permisos únicamente globales tales como
db_name
.*FILE
se otorgan.
MySQL le permite dar permisos incluso en objetos de bases de
datos que no existen. En tales casos, los permisos a dar deben
incluir el permiso CREATE
. Este
es el comportamiento diseñado, y se pretende
permitir al administrador de la base de datos perparar cuentas
de usuario y permisos para objetos de base de datos que se
crearán posteriormente.
MySQL no elimina automáticamente nigún permiso si borra una tabla o base de datos . Si borra un rutina, se quita cualquier permiso dado a nivel de rutina para la misma.
Nota: los carácters comodín
'_
' y '%
' se permiten al
especificar nombres de base de datos en comandos
GRANT
que otorgan permisos a nivel global o
de base de datos. Esto significa, por ejemplo, que si quiere
usar un carácter '_
' como parte de un
nombre de base de datos, debe especificarlo como
'\_
' en el comando GRANT
, para evitar que el usuario sea capaz de acceder a bases de
datos adicionales que coincidan con el patrón de los
comodines, por ejemplo GRANT ... ON `foo\_bar`.* TO
...
.
Para acomodar los permisos a los usuarios de equipos
arbitrários, MySQL soporta especificar el valor
user
con la forma
.
Si un valor user_name
@host_name
user_name
o
host_name
es legal como
identificador sin poner entre comillas, no necesita hacerlo.
Sin embargo, las comillas son necesarias para especificar una
cadena user_name
conteniendo
carácteres especiales (tales como '-
'), o
una cadena host_name
conteniendo
carácteres especiales o comodín (tales como
'%
'); por ejemplo,
'test-user'@'test-hostname'
. Entrecomille
el nombre de usuario y de equipo separadamente.
Puede especificar carácteres comodín en el nombre de equipo.
Por ejemplo,
se aplica a user_name
@'%.loc.gov'user_name
para
cualquier equipo en el dominio loc.gov
, y
se aplica a user_name
@'144.155.166.%'user_name
para
cualquier equipo en la clase subred clase C
144.155.166
.
La forma simple user_name
es
sinónimo de
.
user_name
@'%'
MySQL no soporta comodines en el nombre de usuario. Los
usuarios anónimos se definien insertando entradas con
User=''
en la tabla
mysql.user
o creando un usuario con un
nombre vacío con el comando GRANT
:
mysql> GRANT ALL ON test.* TO ''@'localhost' ...
Al especificar valores delimitados, use comillas simples para
delimitar los nombres de bases de datos, tabla, columna y de
rutina ('`
'). Para los nombres de equipo,
nombres de usuario, y contraseñas como cadenas, use
apóstrofes (''
').
Advertencia: Si permite
conectar con el servidor a usuarios anónimos, debe dar
permisos a todos los usuarios locales como
.
De otro modo, la cuenta de usuario anónimo para
user_name
@localhostlocalhost
en la tabla
mysql.user
(creada durante la instalación
de MySQL) se usa cuando los usuarioa con nombre intentan
loguear con el servidor MySQL desde la máquina local.
Puede determinar si esto se aplica a su sistema ejecutando la siguiente consulta, que lista cualquier usuario anónimo:
mysql> SELECT Host, User FROM mysql.user WHERE User='';
Si quiere borrar la cuenta anónima local para evitar el problema descrito, use estos comandos:
mysql> DELETE FROM mysql.user WHERE Host='localhost' AND User=''; mysql> FLUSH PRIVILEGES;
GRANT
soporta nombres de equipo de hasta 60
carácteres. Los nombres de bases de datos, tablas, columnas y
rutinas pueden tener hasta 64 carácteres. Los nombres de
usuario pueden tener hasta 16 carácteres. Los nombres de
usuario pueden tener hasta 16 carácteres. Estos
límites están harcodeados en el software MySQL y no pueden
cambiarse alterando las tablas de permisos .
Los permisos para una tabla o columna se forman de forma
aditiva como una OR
lógica de los permisos
en cada uno de los cuatro niveles de permisos. Por ejemplo, si
la tabla mysql.user
especifica que un
usuario tiene un permiso SELECT
global, el
permiso no puede denegarse mediante una entrada en el nivel de
base de datos, tabla o columna.
Los permisos de una columna pueden calcularse como sigue:
global privileges OR (database privileges AND host privileges) OR table privileges OR column privileges
En la mayoría de casos, puede dar derechoa a un usuario en sólo uno de los niveles de permisos, así que la vida normalmente no es tan complicada. Los detalles de este procedimiento de chequeo de permisos se presentan en Sección 5.6, “El sistema de privilegios de acceso de MySQL”.
Si otorga permisos para una combinación usuario/equipo que no
existe en la tabla mysql.user
se añade una
entrada que permite allí hasta que se borra con un comando
DELETE
. En otras palabras,
GRANT
puede crear entradas
user
pero REVOKE
no los
borra; debe hacerlo explícitamente usando DROP
USER
o DELETE
.
Si se crea un nuevo usuario o si tiene permisos globales para
otorgar permisos, la contraseña de usuario se cambia con la
contraseña especificada por la cláusula IDENTIFIED
BY
, si se da una. Si el usuario ya tiene una
contraseña, esta se reemplaza por la nueva.
Atención: Si crea un nuevo
usuario pero no especifica una cláusula IDENTIFIED
BY
, el usuario no tiene contraseña. Esto es muy
poco seguro. Desde MySQL 5.0.2, puede activar el modo SQL
NO_AUTO_CREATE_USER
para evitar que
GRANT
cree un nuevo usuario si lo hiciese
de otro modo, a no ser que IDENTIFIED BY
se
de para proporcionar la nueva contraseña de usuario.
Las contraseñas pueden ponerse con el comando SET
PASSWORD
. Consulte Sección 13.5.1.5, “Sintaxis de SET PASSWORD
”.
En la cláusula IDENTIFIED BY
, la
contraseña debe darse como el valor de contraseña literal.
No es necesario usar la función PASSWORD()
como lo es para el comando SET PASSWORD
.
Por ejemplo:
GRANT ... IDENTIFIED BY 'mypass';
Si no quiere enviar la contraseña en texto plano y conoce el
valor haseado que PASSWORD()
retornaría
para la contraseña, puede especificar el valor hasheado
precedido por la palabra clave PASSWORD
:
GRANT ... IDENTIFIED BY PASSWORD '*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4';
En un programa C , puede obtener el valor haseado usando la
función make_scrambled_password()
de la
API de C.
Si da permisos para una base de datos, se crea una entrada en
la tabla mysql.db
si es necesario. Si todos
los permisos para la base de datos se eliminan con
REVOKE
, esta entrada se borra.
Si un usuario no tiene permisos para una tabla, el nombre de
tabla no se muestra cuando el usuario pide una lista de talbas
(por ejemplo, con el comando SHOW TABLES
).
El permiso SHOW DATABASES
le permite a la
cuenta ver nombres de bases de datos realizando el comando
SHOW DATABASE
. Las cuentas que no tienen
este permiso sólo ven las bases de datos para las que tienen
algún permiso, y no pueden usar el comando para nada si el
servidor se arranca con la opción
--skip-show-database
.
La cláusula WITH GRANT OPTION
le da al
usuario la habilidad para dar a otros usuarios cualquier
permiso que tenga el usuario en el nivel de permiso
especificado. Debe tener cuidado de a quién da el permiso
GRANT OPTION
, ya que dos usuarios con
permisos distintos pueden ser capaces de juntar permisos!
No puede dar a otro usuario un permiso que no tenga usted
mismo; el permiso GRANT OPTION
le permite
asignar sólo los permisos que tenga usted.
Tenga en cuenta que cuando le da a un usuario el permiso
GRANT OPTION
a un nivel de permisos
particular, cualquier permiso que tenga el usuario (o que se
de en el futuro!) a este nivel también son otorgables por
este usuario. Suponga que le da a un usuario el permisos
INSERT
en una base de datos. Si otorga el
permiso SELECT
en la base de datos y
especifica WITH GRANT OPTION
, el usuario
puede quitar no sólo el permiso SELECT
sino también INSERT
. Si luego otorga el
permiso UPDATE
al usuario en la base de
datos, el usuario puede quitar INSERT
,
SELECT
, y UPDATE
.
No debe otorgar permisos ALTER
a un usuario
normal. Si lo hace, el usuario puede intentar engañar al
sistema de permisos renombrando tablas!
Las opciones MAX_QUERIES_PER_HOUR
,
count
MAX_UPDATES_PER_HOUR
, y
count
MAX_CONNECTIONS_PER_HOUR
limitan el número
de consultas, actualizaciones, y logueos que puede realizar un
usuario durante cualquier perído de una hora. Si
count
count
es 0 (por defecto), esto
significa que no hay limitación para ese usuario.
La MAX_USER_CONNECTIONS
opción,
implementada en MySQL 5.0.3, limita el máximo número de
conexiones simultáneas que la cuenta puede hacer. Si
count
count
es 0 (por defecto), la
max_user_connections
variable de sistema
determina el número de conexiones simultáneas para la
cuenta.
Nota: para especificar cualquiera de estas opciones de
limitación de recursos para un usuario existente sin afectar
a los permisos existentes, use GRANT USAGE ON *.* ...
WITH MAX_...
.
Consulte Sección 5.7.4, “Limitar recursos de cuentas”.
MySQL puede chequear atributos certificados X509 además que
la autenticación usual que se basa en el nombre de usuario y
contraseña. Para especificar opciones relacionadas con SSL
para la cuenta MySQL, use la cláusula
REQUIRE
del comando
GRANT
. (Para información de transfondo
sobre el uso de SSL con MySQL, consulte
Sección 5.7.7, “Usar conexiones seguras”.)
Hay distintas posibilidades para limitar tipos de conexión para una cuenta:
Si una cuenta no tiene requerimientos de SSL o X509, se permiten conexiones sin encriptar si la contraseña y nombre de usuario son válidos. Sin embargo, las conexiones no encriptadas pueden usarse en las opciones de cliente, si el cliente tiene los ficheros clave y de certificado apropiados.
La opción REQUIRE SSL
le dice al
servidor que permita sólo conexiones SSL encriptadas para
la cuenta. Tenga en cuenta que esta opción puede omitirse
si hay algunos registros de control de acceso que permitan
conexiones no SSL.
mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost' -> IDENTIFIED BY 'goodsecret' REQUIRE SSL;
REQUIRE X509
significa que el cliente
debe tener un certificado válido pero que el certificador
exacto y el asunto no importan. El único requerimiento
que debe ser posible de verificar es la firma con uno de
las AC certificadas.
mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost' -> IDENTIFIED BY 'goodsecret' REQUIRE X509;
REQUIRE ISSUER
'
crea una
restricción de intentos de conexión en que el cliente
debe presentar un certificado X509 válido presentado por
la AC issuer
'issuer
. Si el cliente
presenta un certificado válido pero de otra AC, el
servidor rehúsa la conexión. El uso de certificados X509
siempre implica encripción, por lo que la opción
SSL
no es necesaria.
mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost' -> IDENTIFIED BY 'goodsecret' -> REQUIRE ISSUER '/C=FI/ST=Some-State/L=Helsinki/ O=MySQL Finland AB/CN=Tonu Samuel/Email=tonu@example.com';
Tenga en cuenta que el valor ISSUER
debe entrarse como una cadena única.
REQUIRE SUBJECT
'
crea la
restricción en los intentos de conexión de que el
cliente debe presentar un certificado X509 válido con el
asunto subject
'subject
. Si el cliente
presenta un certificado válido pero con un asunto
distinto, el servidor rehúsa la conexión.
mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost' -> IDENTIFIED BY 'goodsecret' -> REQUIRE SUBJECT '/C=EE/ST=Some-State/L=Tallinn/ O=MySQL demo client certificate/ CN=Tonu Samuel/Email=tonu@example.com';
Tenga en cuenta que el valor SUBJECT
debe entrarse como una única cadena.
REQUIRE CIPHER
'
se necesita
para asegurar que se usan cifradores suficientemente
fuertes y longitudes de claves acordes. SSL por sí mismo
puede ser débil si se usan algoritmos antiguos con claves
de encriptación cortas. Con esta opción, puede
especificar el método de cifrado exacto para permitir una
conexión.
cipher
'
mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost' -> IDENTIFIED BY 'goodsecret' -> REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA';
Las opciones SUBJECT
,
ISSUER
, y CIPHER
pueden
combinarse en la cláusula REQUIRE
así:
mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost' -> IDENTIFIED BY 'goodsecret' -> REQUIRE SUBJECT '/C=EE/ST=Some-State/L=Tallinn/ O=MySQL demo client certificate/ CN=Tonu Samuel/Email=tonu@example.com' -> AND ISSUER '/C=FI/ST=Some-State/L=Helsinki/ O=MySQL Finland AB/CN=Tonu Samuel/Email=tonu@example.com' -> AND CIPHER 'EDH-RSA-DES-CBC3-SHA';
Tenga en cuenta que los valores SUBJECT
y
ISSUER
deben entrarse como una única
cadena.
En MySQL 5.0, la palabra clave AND
es
opcional entre las opciones REQUIRE
.
El orden de las opciones no importa, pero no puede especificarse ninguna opción dos veces.
Cuando mysqld arranca, todos los permisos se leen en memoria. Para más detalles, consulte Sección 5.6.7, “Cuándo tienen efecto los camios de privilegios”.
Tenga en cuenta que si usa permisos de tablas o de columnas para un usuario, el servidor examina los permisos de tablas y usuarios para todos los usuarios y esto ralentiza MySQL ligeramente. De forma similar, si limita el número de consultas, actualizaciones o conexiones para cualquier usuario, el servidor debe monitorizar estos valores.
Las mayores diferencias entre las versiones de
GRANT
de MySQL y SQL estándar son:
En MySQL, los permisos se asocian con una combinación de nombre de usuario/equipo y no sólo con el usuario.
SQL estándar no tienen permisos globales o a nivel de base de datos, ni soporta todos los tipos de permisos que soporta MySQL .
MySQL no soporta los permisos de SQL estándar
TRIGGER
o UNDER
.
Los permisos de SQL estándar se estructuran de forma
jerárquica. Si borra un usuario, todos los permisos que
tuviera el usuario se eliminan. Esto es cierto a partir de
MySQL 5.0.2 y si usa DROP USER
. Antes
de 5.0.2, los permisos otorgados no se eliminaban
automáticamente; debía hacerlo a mano. Consulte
Sección 13.5.1.2, “Sintaxis de DROP USER
”.
En SQL estándar, cuando borra una tabla, todos los
permisos para la tabla se eliminan. Con SQL estándar,
cuando quita un permiso, todos los permisos otorgados
basados en ese permiso también se eliminaban. En MySQL,
los permisos sólo pueden borrarse con comandos
REVOKE
explícitos o manipulando las
tablas de permisos de MySQL.
En MySQL, es posible tener el permiso
INSERT
sólo para algunas de las
columnas en la tabla. En este caso, todavía puede
ejecutar comandos INSERT
en la tabla
mientras omita esas columnas para las que no tiene el
permiso INSERT
. Las columnas omitidas
obtienen su valor por defecto implícito si no está
activado el modo SQL estricto. En modo estricto, el
comando se rehúsa si algunas de las columnas omitidas no
tienen valor por defecto.
Sección 5.3.2, “El modo SQL del servidor” discute acerca del modo
estricto. Sección 13.1.5, “Sintaxis de CREATE TABLE
” disctue acerca de
los valores por defecto implícitos.
Las columnas para las que no tiene el permiso
INSERT
se ponen a su valor por defecto.
SQL estándar requiere que tenga el permiso
INSERT
en todas las columnas.
En MySQL, si tiene el permiso INSERT sólo en alguna de las columnas de la tabla, puede ejecutar comandos INSERT — mientras omita las columnas para las que no tiene el permiso de su comando INSERT; tales columnas obtendrán su valor por defecto. En modo estricto (cuando sql_mode="traditional"), si alguna de las columnas omitidas no tiene valor por defecto, el comando INSERT se rehúsa.
RENAME USERold_user
TOnew_user
[,old_user
TOnew_user
] ...
El comando RENAME USER
renombra cuentas de
usuario MySQL existentes. Para usarlo, debe tener el permiso
CREATE USER
global o el permiso
UPDATE
para la base de datos
mysql
. Ocurre un error si cualquier de las
antiguas cuentas no existe o cualquiera de las nuevas ya
existe. Los valores old_user
y
new_user
se dan igual que para el
comando GRANT
.
El comando RENAME USER
se añadió en MySQL
5.0.2.
SET PASSWORD = PASSWORD('some password
') SET PASSWORD FORuser
= PASSWORD('some password
')
El comando SET PASSWORD
asigna una
contraseña a una cuenta de usuario MySQL existente.
La primera sintaxis asigna la contraseña para el usuario actual. Cualquier cliente que se conecte al servidor usando una cuenta no anónima puede cambiar la contraseña para la misma.
La segunda sintaxis asigna una contraseña para una cuenta
específica en el servidor actual. Sólo los clientes con el
permiso UPDATE
para la base de datos
mysql
pueden hacerlo. El valor
user
debe darse en formato
donde user_name
@host_name
user_name
y
host_name
son exactamente los
mismos que cuando se listan en las columnas
User
y Host
de la tabla
mysql.user
. Por ejemplo, si tiene una
entrada en las columnas User
y
Host
con los valores
'bob'
y '%.loc.gov'
,
escribiría el comando así:
mysql> SET PASSWORD FOR 'bob'@'%.loc.gov' = PASSWORD('newpass
');
Esto es equivalente al siguiente comando:
mysql> UPDATE mysql.user SET Password=PASSWORD('newpass
')
-> WHERE User='bob' AND Host='%.loc.gov';
mysql> FLUSH PRIVILEGES;
Nota: Si se está conectando
a un servidor MySQL 4.1 o posterior usando programas clientes
anteriores a la 4.1, no use los comandos SET
PASSWORD
o UPDATE
precedentes sin
leer Sección 5.6.9, “Hashing de contraseñas en MySQL 4.1” primero. El formato de
contraseña cambió en MySQL 4.1, y bajo ciertas
circunstáncias, puede que no sea capaz de conectar al
servidor.
En MySQL 5.0, puede ver su entrada de autenticación
user@host
ejecutando SELECT
CURRENT_USER()
.
ANALYZE [LOCAL | NO_WRITE_TO_BINLOG] TABLEtbl_name
[,tbl_name
] ...
Este comando analiza y almacena la distribución de clave para
una tabla. Durante el análisis, la tabla se bloquea con un
bloqueo de lectura. En MySQL 5.0, funciona en tablas
MyISAM
, BDB
, y
InnoDB
. Para tablas
MyISAM
, este comando es equivalente a usar
myisamchk -a.
MySQL usa la distribución de claves almacenada para decidir el orden en que las tablas deben hacer los joins cuando realiza uno en algo que no sea una constante.
El comando retorna una tabla con las siguientes columnas:
Columna | Valor |
Tabla | Nombre de tabla |
Op | Siempre analyze |
Msg_type | Es status , error ,
info , o warning |
Msg_text | Mensaje |
Puede chequear la distribución de claves almacenada con el
comando SHOW INDEX
. Consulte
Sección 13.5.4.11, “Sintaxis de SHOW INDEX
”.
Si la tabla no ha cambiado desde el último comando
ANALYZE TABLE
, la tabla no se vuelve a
analizar.
En MySQL 5.0, los comandos ANALYZE TABLE
se
escriben en el log binario a no ser que la palabra clave
NO_WRITE_TO_BINLOG
opcional (o su alias
LOCAL
) se use.
BACKUP TABLEtbl_name
[,tbl_name
] ... TO '/path/to/backup/directory
'
Nota: Este comando está obsoleto. Estamos trabajano en un mejor sustituto para este que proporcionará capacidades de copia de seguridad en línea. De momento, el script mysqlhotcopy puede usarse.
BACKUP TABLE
copia al directorio de base de
datos el mínimo número de ficheros de tablas necesarias para
restaurar la tabla, tras volcar cualquier cambios almacenados
en el buffer a disco. El comando funciona sólo para tablas
MyISAM
. Copia los ficheros de definición
.frm
y de datos .MYD
. El fichero índice .MYI
puede
reconstruirse desde estos otros. El directorio debe
especificarse con la ruta entera.
Antes de usar este comando consulte Sección 5.8.1, “Copias de seguridad de bases de datos”.
Durante la copia de seguridad, se realiza un bloqueo de
lectura para cada tabla, uno cada vez, mientras se hace la
copia. Si quier hacer una copia de seguridad de varias tablas
como una muestra (evitando que ninguna de ellas se cambie
durante la operación de la copia de seguridad), debe realizar
un comando LOCK TABLES
para obtener un
bloqueo de lectura para cada tabla en el grupo.
El comando retorna una tabla con las siguientes columnas:
Columna | Valor |
Tabla | Nombre de tabla |
Op | Siempre backup |
Msg_type | Es status , error ,
info , o warning |
Msg_text | Mensaje |
CHECK TABLEtbl_name
[,tbl_name
] ... [option
] ...option
= {QUICK | FAST | MEDIUM | EXTENDED | CHANGED}
Chequea una tabla o tablas para errores. CHECK
TABLE
funciona para tablas MyISAM
y InnoDB
. Para tablas
MyISAM
, la estadística de clave se
actualiza.
Desde MySQL 5.0.2, CHECK TABLE
puede
comprobar las vistas en busca de problemas tales como tablas que se
referencian en la definición de la vista que ya no existe.
El comando CHECK TABLE
retorna una tabla
con las siguientes columnas:
Columna | Valor |
Tabla | Nombre de tabla |
Op | Siempre check |
Msg_type | Es status , error ,
info , o warning |
Msg_text | Mensaje |
Tenga en cuenta que el comando puede producir varios registros
para información de cada tabla chequeada. El último registro
tiene un valor Msg_type
de
status
y Msg_text
normalmente debe ser OK
. Si no obtiene
OK
, o Table is already up to
date
debe realizar una reparación de la tabla.
Consulte Sección 5.8.3, “Mantenimiento de tablas y recuperación de un fallo catastrófico (crash)”. Table
is already up to date
significa que el motor de
almacenamiento para la tabla indicada indica que no hay
necesidad de chequear la tabla.
Las distintas opciones de chequeo que pueden darse se muestran
en la siguiente tabla. Estas opciones se aplican sólo para
tablas MyISAM
y se ignoran en tablas
InnoDB
y vistas.
Tipo | Significado |
QUICK | No escanea los registros para chequear enlaces incorrectos. |
FAST | Sólo chequea tablas que no se han cerrado correctamente. |
CHANGED | Sólo las tablas chequeadas que se han cambiado desde el úlitmo chequeo o no se han cerrado correctamente. |
MEDIUM | Escanea registros para verificar que los enlaces borrados están bien. También calcula el checksum de la clave para los registros y lo verifica con el checksum calculado para las claves. |
EXTENDED | Realiza una búsqueda completa para todas las claves para cada registro. Se asegura que la tabla es consistente 100%, pero tarda mucho tiempo! |
Si ninguna de las opciones QUICK
,
MEDIUM
, o EXTENDED
se
especifica, el tipo de chequeo por defecto para tablas de
formato dinámico MyISAM
es
MEDIUM
. Esto es lo mismo que ejecutar
myisamchk --medium-check
tbl_name
en la tabla. El
tipo de chequeo por defecto también es
MEDIUM
para tablas
MyISAM
de formato estático, a no ser que
se especifique CHANGED
o
FAST
. En tal caso, por defecto es
QUICK
. El escaneo de registro se evita para
CHANGED
y FAST
porque
los registros están corruptos muy raramente.
Puede combinar opciones de chequeo, como en el siguiente ejemplo, que realiza un chequeo rápido de la tabla para ver si se cerró correctamente:
CHECK TABLE test_table FAST QUICK;
Nota: En algunos casos,
CHECK TABLE
cambia la tabla. Esto ocurre si
la tabla se marca como “corrupted” o “not
closed properly” pero CHECK TABLE
no
encuentra ningún problema en la tabla. En este caso,
CHECK TABLE
marca la tabla como correcta.
Si una tabla está corrupta, es más probable que el problema esté en el índice y no en la parte de datos. Todos los tipos de chequeo chequean los índices profundamente y deberían encontrar la mayoría de errores.
Si quiere chequear una tabla que asume como correcta, no debe
usar opciones de chequeo o la opción
QUICK
. Ésta debe usarse cuando tiene prisa
y puede permitirse el pequeño riesgo que
QUICK
no encuentre un error en el fichero
de datos. (En la mayoría de casos, MySQL debería encontrar,
bajo uso normal, cualquier error en el fichero de datos. Si
esto ocurre, la tabla se marca como “corrupted” y
no puede usarse hasta que se repare.)
FAST
y CHANGED
están
pensados para usar desde un script (por ejemplo, para
ejecutarse desde cron) si quiere chequear
sus tablas de vez en cuando. En la mayoría de casos,
FAST
se prefiere en lugar de
CHANGED
. (El único caso en que no es el
método preferido es cuando sospecha que ha encontrado un bug
en el código MyISAM
.)
EXTENDED
debe usarse sólo después de
ejecutar un chequeo normal pero todavía obtiene errores
extraños de la tabla cuando MySQL intenta actualizar un
registro o encuentra un registro mediante la clave. (Esto es
muy improbable si un chequeo normal ha tenido éxito.)
Algunos problemas reportados por CHECK
TABLE
no pueden corregirse automáticamente:
Found row where the auto_increment column has the
value 0
.
Esto significa que tiene un registro en la tabla donde la
columna AUTO_INCREMENT
contiene un
valor de índice de 0. (Es posible crear un registro donde
la columna AUTO_INCREMENT
es 0 poneindo
la columna explícitamente a 0 con un comando
UPDATE
.)
Esto no es un error por si mismo, pero puede causar
problemas si decide volcar la tabla y restaurarla o
realizar un ALTER TABLE
en la tabla. En
este caso, la columna AUTO_INCREMENT
cambia los valores según las reglas de las columnas
AUTO_INCREMENT
, que pueden causar
problemas tales como errores de clave duplicada.
Para evitar las advertencias, símplemente ejecute un
comando UPDATE
para poner en la columna
un valor distinto a 0.
CHECKSUM TABLEtbl_name
[,tbl_name
] ... [ QUICK | EXTENDED ]
Reporta un checksum de tabla.
Si QUICK
se especifica, el checksum de la
tabla se reporta si está disponible, o
NULL
en otro caso. Esto es muy rápido. Un
checksum en vivo está permitido especificando la opción de
tabla CHECKSUM=1
, actualmente sólo
soportado por tablas MyISAM
. Consulte
Sección 13.1.5, “Sintaxis de CREATE TABLE
”.
En modo EXTENDED
la tabla completa se lee
registro a registro y se calcula el checksum. Esto puede ser
muy lento para tablas grandes.
Por defecto, si no se especifica ni QUICK
ni EXTENDED
, MySQL retorna un checksum en
vivo si el motor de tabla lo soporta y escanea la tabla de
otro modo.
CHECKSUM TABLE
retorna
NULL
para tablas no existentes. Desde MySQL
5.0.3, se genera una advertencia para esta condición.
OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLEtbl_name
[,tbl_name
] ...
OPTIMIZE TABLE
debe usarse si ha borrado
una gran parte de la tabla o si ha hecho varios cambios en una
tabla con registros de longitud variable (tablas que tienen
columnas VARCHAR
, BLOB
,
o TEXT
). Los registros borrados se
mantienen en una lista enlazada y operaciones
INSERT
posteriores reúsan posiciones de
antiguos registros. Puede usar OPTIMIZE
TABLE
para reclamar el usuario no usado y para
defragmentar el fichero de datos.
En la mayoría de inicializaciones, no necesita ejecutar
OPTIMIZE TABLE
para nada. Incluso si hace
muchas actualizaciones a registros de longitud variables, no
es probable que necesite hacerlo más de una vez a la semana o
mes y sólo en ciertas tablas.
Actualmente, OPTIMIZE TABLE
funciona sólo
en tablas MyISAM
, BDB
y
InnoDB
.
Para tablas MyISAM
, OPTIMIZE
TABLE
funciona como sigue:
Si la tabla ha borrado o dividido registros, repare la tabla.
Si las páginas índice no están ordenadas, ordénelas.
Si las estadísticas no están actualizadas (y la reparación no puede hacerse ordenando el índice), actualícelas.
Para tablas BDB
, OPTIMIZE
TABLE
es mapea como ANALYZE
TABLE
. Para tablas InnoDB
, se
mapea con ALTER TABLE
, que reconstruye la
tabla. Reconstruye las estadísticas actualizadas de índice y
libera espacio no usado en el índice clusterizado. Consulte
Sección 13.5.2.1, “Sintaxis de ANALYZE TABLE
”.
Puede hacer que OPTIMIZE TABLE
funcione con
otros tipos de tabla arrancando mysqld con
la opción --skip-new
o
--safe-mode
; en este caso
OPTIMIZE TABLE
se mapea con ALTER
TABLE
.
Tenga en ceunta que MySQL bloquea la tabla mientras se ejecuta
OPTIMIZE TABLE
.
En MySQL 5.0, los comandos OPTIMIZE TABLE
se escriben en el log binario a no ser que la palabra
NO_WRITE_TO_BINLOG
opcional(o su alias
LOCAL
) se use. Esto se hace para que los
comandos OPTIMIZE TABLE
se usen en MySQL
server actuando como maestro de replicación se replique por
defecto en el esclavo de replicación.
REPAIR [LOCAL | NO_WRITE_TO_BINLOG] TABLEtbl_name
[,tbl_name
] ... [QUICK] [EXTENDED] [USE_FRM]
REPAIR TABLE
repara una tabla posiblemente
corrupta. Por defecto, tiene el mismo efecto que
myisamchk --recover
tbl_name
. REPAIR
TABLE
funciona sólo en tablas
MyISAM
.
Normalmente nunca debe ejecutar este comando. Sin embargo, si
hay un desastre, REPAIR TABLE
puede
recuperar todos los datos de una tabla
MyISAM
. Si sus tablas se corrompen a
menudo, debe intentar encontrar la razón de lo que lo causa,
para eliminar la necesidad de usar REPAIR
TABLE
. Consulte Sección A.4.2, “Qué hacer si MySQL sigue fallando (crashing)”. Consulte
Sección 14.1.4, “Problemas en tablas MyISAM
”.
El comando retorna una tabla con las siguientes columnas:
Columna | Valor |
Tabla | Nombre de tabla |
Op | Siempre es repair |
Msg_type | Es status , error ,
info , o warning |
Msg_text | Mensaje |
El comando REPAIR TABLE
puede producir
muchos registros de información para cada tabla reparada. El
último registro tiene un valor Msg_type
de
status
y Msg_test
normalmente debe ser OK
. Si no obtiene
OK
, debe intentar reparar la tabla con
myisamchk --safe-recover, ya que
REPAIR TABLE
no implementa todas las
opciones de myisamchk. Plaenamos hacerlo
más flexible en el futuro.
Si se da QUICK
, REPAIR
TABLE
intenta reparar sólo el árbol índice. Este
tipo de reparación es como lo que hace myisamchk
--recover --quick.
Si usa EXTENDED
, MySQL crea el índice
registro a registro en lugar de crear un índice a la vez
ordenando. Este tipo de reparación es como el hecho por
myisamchk --safe-recover.
También hay un modo USE_FRM
disponible en
MySQL 5.0 para REPAIR TABLE
. Use esto si el
fichero índice .MYI
no existe o su
cabecera está corrupta. En este modo, MySQL recrea el fichero
.MYI
usando información desde el fichero
.frm
. Este tipo de reparación no puede
hacerse con myisamchk.
Nota: Use este modo
sólo si no puede usar modos
REPAIR
normalmente. La cabecera
.MYI
contiene información importante de
metadatos (en particular, los valores actuales
AUTO_INCREMENT
y Delete
link
) que se pierden en REPAIR ...
USE_FRM
. No use USE_FRM
si la
tabla está comprimida, ya que esta información se almacena
en el fichero .MYI
.
En MySQL 5.0, los comandos REPAIR TABLE
se
escriben en el log binario a no ser que la palabra opcional
NO_WRITE_TO_BINLOG
(o su alias
LOCAL
) se use.
Atención: Si el servidor
muere durante una operación REPAIR TABLE
,
es esencial tras restaurarla que inmediatamente ejecute otro
comando REPAIR TABLE
para la tabla antes de
realizar cualquier otra operación en ella. (Siempre es una
buena idea empezar haciendo una copia de seguridad.) En el
peor caso, puede tener un nuevo fichero índice limpio sin
información acerca del fichero de datos, y luego la siguiente
operación que realice puede sobreescribir el fichero de
datos. Este es un escenario improbable pero posible.
RESTORE TABLEtbl_name
[,tbl_name
] ... FROM '/path/to/backup/directory
'
Restaura la tabla o tablas de una copia de seguridad que se
hizo con BACKUP TABLE
. Las tablas
existentes no se sobreescriben; si trata restaurar una tabla
existente, obtiene un error. Pero como BACKUP
TABLE
, RESTORE TABLE
actualmente
funciona sólo para tablas MyISAM
. El
directorio debe especificarse como una ruta completa.
La copia de seguridad para cada tabla consiste en su fichero
de formato .frm
y fichero de datos
.MYD
. La operación de restauración
restaura aquellos ficheros, luego los usa para reconstruir el
fichero índice .MYI
. La restauración
tarda más tiempo que la copia de seguridad debido a la
necesidad de reescribir los índices. Mientras más índices
tenga la tabla, más tarda.
El comando retorna una tabla con las siguientes columnas:
Columna | Valor |
Tabla | Nombre de tabla |
Op | Siempre restore |
Msg_type | Es status , error ,
info , o warning |
Msg_text | Mensaje |
SETvariable_assignment
[,variable_assignment
] ...variable_assignment
:user_var_name
=expr
| [GLOBAL | SESSION]system_var_name
=expr
| @@[global. | session.]system_var_name
=expr
SET
inicializa distintos tipos de variables
que afectan la operación del servidor o de su cliente. Puede
usarse para asignar valores a las variables de usuario o de
sistema.
El comando SET PASSWORD
para asignar
contraseñas de cuenta se describen en
Sección 13.5.1.5, “Sintaxis de SET PASSWORD
”.
La mayoría del sistema puede cambiarse en tiempo de ejecución. Las variables de sistema que pueden describirse dinámicamente se describen en Sección 5.3.3.1, “Variables de sistema dinámicas”.
Nota: Las versiones antiguas de MySQL
empleaban SET OPTION
para este comando, pero
su uso está obsoleto en favor de SET
.
El siguiente ejemplo muestra las distintas sintaxis que puede usar para cambiar las variables.
Una variable de usuario se escribe como
@
y puede
cambiarse como sigue:
var_name
SET @var_name
=expr
;
Más información sobre variables de usuario se da en Sección 9.3, “Variables de usuario”.
Se puede referir a las variables de sistema en comandos
SET
como var_name
.
El nombre puede ir precedido opcionalmente por
GLOBAL
o @@global.
para
indicar explícitamente que la variable es global, o por
SESSION
, @@session.
, o
@@
para indicar que es una variable de
sesión. LOCAL
y @@local.
son sinónimos para SESSION
y
@@session.
. Si no hay modificador presente,
SET
asigna un valor a la variable de sesión.
La sintaxis
@@
para
variables de sistema se soporta para hacer la sintaxis de MySQL
compatible con otros sistemas de base de datos.
var_name
Si cambia varias variables de sistema en el mismo comando, la
última opción GLOBAL
o
SESSION
usada se usa para variables que no
tienen modo especificado.
SET sort_buffer_size=10000; SET @@local.sort_buffer_size=10000; SET GLOBAL sort_buffer_size=1000000, SESSION sort_buffer_size=1000000; SET @@sort_buffer_size=1000000; SET @@global.sort_buffer_size=1000000, @@local.sort_buffer_size=1000000;
Si cambia una variable de sistema usando
SESSION
(por defecto), el valor queda en
efecto hasta que la sesión actual finaliza o hasta que cambia
la variable con un valor distinto. Si cambia la variable de
sistema usando GLOBAL
, que requiere el
permiso SUPER
, el valor se recuerda y se usa
para nuevas conexiones hasta que el servidor se reinicia. Si
quiere hacer un cambio de variable permanente, debe ponerlo en
un fichero de opciones. Consulte Sección 4.3.2, “Usar ficheros de opciones”.
Para evitar uso incorrecto, MySQL produce un error si usa
SET GLOBAL
con una variable que sólo puede
ser usada con SET SESSION
o si no especifica
GLOBAL
(o @@
) cuando
cambie una variable global.
Si quiere cambiar una variable SESSION
al
valor GLOBAL
o un valor
GLOBAL
al valor de compilación de MySQL por
defecto, puede hacerlo con DEFAULT
. Por
ejemplo, los siguientes dos comandos son idénticos en cambiar
los valores de sesión o max_join_size
al
valor global:
SET max_join_size=DEFAULT; SET @@session.max_join_size=@@global.max_join_size;
Puede obtener una lista de la mayoría de variables de sistema
con SHOW VARIABLES
. (Consulte
Sección 13.5.4.21, “Sintaxis de SHOW VARIABLES
”.) Para obtener un nombre de
variable específico, use una cláusula LIKE
commo se muestra:
SHOW VARIABLES LIKE 'max_join_size'; SHOW GLOBAL VARIABLES LIKE 'max_join_size';
Para obtener una lista de variables cuyos nombres coinciden con
un patrón, use el comodín '%
':
SHOW VARIABLES LIKE 'have%'; SHOW GLOBAL VARIABLES LIKE 'have%';
El comodín puede usarse en cualquier posición dentro del patrón para coincidir.
Puede obtener el valor de un valor específico usando la
sintaxis @@[global.|local.]var_name
con
SELECT
:
SELECT @@max_join_size, @@global.max_join_size;
Cuando recibe una variable con SELECT
@@var_name
(esto es,no especifica
global.
, session.
, o
local.
), MySQL retorna el valor
SESSION
si existe y el valor
GLOBAL
en otro caso.
La siguiente lista describe variables que tienen sintaxis no
estándar o que no se describe en la lista de variables de
sistema que se encuentra en
Sección 5.3.3, “Variables de sistema del servidor”. Aunque estas
variables no se muestran con SHOW VARIABLES
,
puede obtener sus valores con SELECT
(con la
excepción de CHARACTER SET
y SET
NAMES
). Por ejemplo:
mysql> SELECT @@AUTOCOMMIT; +--------------+ | @@autocommit | +--------------+ | 1 | +--------------+
AUTOCOMMIT = {0 | 1}
Pone el modo autocommit . Con valor 1
,
todos los cambios de una tabla toman efecto inmediatamente.
Si se pone a 0
, debe usar
COMMIT
para aceptar una transacción o
ROLLBACK
para cancelarla. Si cambia el
modo AUTOCOMMIT
de 0
a
1
, MySQL realiza un
COMMIT
automático de cualquier
transacción abierta . Otra forma de comenzar una
transacción es usar un comando START
TRANSACTION
o BEGIN
. Consulte
Sección 13.4.1, “Sintaxis de START TRANSACTION
, COMMIT
y ROLLBACK
”.
Si se pone a 1
, todas las tablas
temporales se almacenan en disco en lugar que en memoria.
Esto es un poco lento, pero el error The table
no
ocurre para operaciones tbl_name
is fullSELECT
que
requieran una tabla temporal grande. El valor por defecto
para una nueva conexión es 0
(use tablas
temporales en memoria). Normalmente, nunca debería
necesitar usar esta variable, ya que MySQL 5.0 convierte
automáticamente tablas en memoria a tablas en disco como se
requiere. (Nota: Esta variable se
llamaba préviamente SQL_BIG_TABLES
.)
CHARACTER SET
{
charset_name
|
DEFAULT}
Esto mapea todas las cadenas desde y hacia el cliente con el
mapeo dado. Puede añadir nuevos mapeos editando
sql/convert.cc
en la distribución
fuente MySQL. En MySQL 5.0, SET CHARACTER
SET
cambia tres variables de sistema
character_set_client
y
character_set_results
se actualizan con
el conjunto de carácteres dado, y
character_set_connection
al valor de
character_set_database
.
El mapeo por defecto puede restaurarse usando el valor
DEFAULT
.
Tenga en cuenta que la sintaxis para SET CHARACTER
SET
difiere de la de la mayoría de otras
opciones.
FOREIGN_KEY_CHECKS = {0 | 1}
Con valor de 1
(por defecto), las claves
foráneas para tablas InnoDB
se chequean.
Si se pone a 0
, se ignoran. Deshabilitar
el chequeo de clave foránea puede ser útil para recargar
tablas InnoDB
en un orden distinto que el
requerido por sus relaciones padre/hijo, Consulte
Sección 15.6.4, “Restricciones (constraints) FOREIGN KEY
”.
IDENTITY =
value
La variable es un sinónimo para la variable
LAST_INSERT_ID
. Existe por
compatibilidad con otras bases de datos. Puede leer su valor
con SELECT @@IDENTITY
, y cambiarlo
mediante SET IDENTITY
.
INSERT_ID =
value
Cambia el valor a ser usado por los comandos
INSERT
o ALTER TABLE
al insertar un valor AUTO_INCREMENT
.
Esto se usa principalmente con el lob binario.
LAST_INSERT_ID =
value
Cambia el valor a ser retornado de
LAST_INSERT_ID()
. Esto se almacena en el
log binario cuando usa LAST_INSERT_ID()
en un comando que actualice una tabla. Cambiar esta variable
no actualiza el valor retornado por la función de la
mysql_insert_id()
API de C.
NAMES {'
charset_name
' |
DEFAULT}
SET NAMES
cambia tres variables de
sesión de sistema character_set_client
,
character_set_connection
, y
character_set_results
al conjunto de
carácteres dado. Cambiar
character_set_connection
a
charset_name
también cambia
collation_connection
a la colación por
defecto para charset_name
.
El mapeo por defecto puede restaurarse usando un valor de
DEFAULT
.
Tenga en cuenta que la sintaxis para SET
NAMES
difiere de la usada para la mayoría de
otras opciones.
SQL_NOTES = {0 | 1}
Con el valor 1 (por defecto), advertencias del nivel
Note
se registran. Con valor 0, las
advertencias Note
se suprimen.
mysqldump incluye la salida para cambiar
esta variable a 0 así que recargar el fichero volcado no
produce advertencias para eventos que no afectan a la
integridad de la operación de recarga.
SQL_NOTES
se añadió en MySQL 5.0.3.
SQL_AUTO_IS_NULL = {0 | 1}
Con valor 1
(por defecto), puede
encontrar el último registro insertado para una tabla que
contiene una columna AUTO_INCREMENT
usando el siguiente constructor:
WHERE auto_increment_column
IS NULL
Este comportamiento lo usan algunos programas ODBC, como Access.
SQL_BIG_SELECTS = {0 | 1}
Con valor 0
, MySQL aborta los comandos
SELECT
que probablemente tardarán mucho
tiempo (esto es, comandos para los que el optimizador estima
que el número de registros examinados excede el valor de
max_join_size
). Esto es útil cuando un
comando WHERE
no aconsejable se ejecuta.
El valor por defecto para una nueva conexión es
1
, que permite todos los comandos
SELECT
.
Si cambia la variable de sistema
max_join_size
a un valor distinto a
DEFAULT
,
SQL_BIG_SELECTS
se pone a
0
.
SQL_BUFFER_RESULT = {0 | 1}
SQL_BUFFER_RESULT
fuerza los resultados
de los comandos SELECT
a poner en tablas
temporales. Esto ayuda a MySQL a liberar los bloqueos de
tabla rápidamente y pueden ser beneficioso en caso que
tarde un largo tiempo para enviar resultados al cliente.
SQL_LOG_BIN = {0 | 1}
Con valor 0
, no se realiza logueo en el
log binario para el cliente. El cliente debe tener el
permiso SUPER
para cambiar esta opción.
SQL_LOG_OFF = {0 | 1}
Con valor 1
, no se realiza logueo en el
log de consultas generales para el cliente. El cliente debe
tener el permiso SUPER
para cambiar esta
opción.
SQL_LOG_UPDATE = {0 | 1}
Esta variable está obsoleta, y es mapea a
SQL_LOG_BIN
.
SQL_QUOTE_SHOW_CREATE = {0 | 1}
Con valor 1
, SHOW CREATE
TABLE
entrecomilla los nombres de tabla y
columnas. Si se pone a 0
, se desactiva el
entrecomillado. Esta opción está activada por defecto,
así que la replicación funciona para tablas con nombres de
tabla y columna que no lo requieren. Consulte
Sección 13.5.4.5, “Sintaxis de SHOW CREATE TABLE
”.
SQL_SAFE_UPDATES = {0 | 1}
Con valor 1
, MySQL aborta comandos
UPDATE
o DELETE
que no
usan una clave en la cláusula WHERE
o
LIMIT
. Esto hace posible cazar los
comandos UPDATE
o
DELETE
donde las claves no se usan
apropiadamente y que probablemente cambiarían o borrarían
un gran número de registros.
SQL_SELECT_LIMIT =
{
value
| DEFAULT}
El máximo número de registros a retornar desde comandos
SELECT
. El valor por defecto para una
nueva conexión es “unlimited.” Si cambia este
límite, el valor por defecto puede restaurarse usando un
valor SQL_SELECT_LIMIT
de
DEFAULT
.
Si un SELECT
tiene una cláusula
LIMIT
el LIMIT
tiene
preferencia sobre el valor de
SQL_SELECT_LIMIT
.
SQL_SELECT_LIMIT
no se aplica a comandos
SELECT
ejecutados en rutinas almacenadas.
Tampoco se aplica a comandos SELECT
que
no producen un conjunto de resultados a ser retornado al
cliente. Esto incluye comandos SELECT
en
subconsultas, CREATE TABLE ... SELECT
, y
INSERT INTO ... SELECT
.
SQL_WARNINGS = {0 | 1}
Esta variable controla si comandos INSERT
de un registro producen una cadena de información si hay
una advertencia. Por defecto es 0. Cambie el valor a 1 para
producir una cadena de información.
TIMESTAMP =
{
timestamp_value
|
DEFAULT}
Cambia la hora del cliente. Se usar para obtener la fecha y
hora original si usa el log binario para restaurar
registros. timestamp_value
debe ser un
Unix epoch timestamp, no un timestamp de MySQL.
UNIQUE_CHECKS = {0 | 1}
Con valor 1
(por defecto), se realizan
chequeos en tablas InnoDB
para índices
secundarios. Con valor 0
, no se hacen
chequeos de valores únicos para entradas de índices
insertados en el búffer de inserción de InnoDB. Si sabe
con certeza que sus datos no contienen violaciones de
valores únicos, puede ponerlo a 0 para acelerar
importaciones de tablas grandes a InnoDB.
SHOW CHARACTER SET
SHOW COLLATION
SHOW COLUMNS
SHOW CREATE DATABASE
SHOW CREATE TABLE
SHOW DATABASES
SHOW ENGINE
SHOW ENGINES
SHOW ERRORS
SHOW GRANTS
SHOW INDEX
SHOW INNODB STATUS
SHOW LOGS
SHOW OPEN TABLES
SHOW PRIVILEGES
SHOW PROCESSLIST
SHOW STATUS
SHOW TABLE STATUS
SHOW TABLES
SHOW TRIGGERS
SHOW VARIABLES
SHOW WARNINGS
SHOW
tiene varias formas que proporcionan
información acerca de bases de datos, tablas, columnas o
información de estado acerca del servidor. Esta sección
describe estos puntos:
SHOW [FULL] COLUMNS FROMtbl_name
[FROMdb_name
] [LIKE 'pattern
'] SHOW CREATE DATABASEdb_name
SHOW CREATE TABLEtbl_name
SHOW DATABASES [LIKE 'pattern
'] SHOW ENGINEengine_name
{LOGS | STATUS } SHOW [STORAGE] ENGINES SHOW ERRORS [LIMIT [offset
,]row_count
] SHOW GRANTS FORuser
SHOW INDEX FROMtbl_name
[FROMdb_name
] SHOW INNODB STATUS SHOW [BDB] LOGS SHOW PRIVILEGES SHOW [FULL] PROCESSLIST SHOW [GLOBAL | SESSION] STATUS [LIKE 'pattern
'] SHOW TABLE STATUS [FROMdb_name
] [LIKE 'pattern
'] SHOW [OPEN] TABLES [FROMdb_name
] [LIKE 'pattern
'] SHOW TRIGGERS SHOW [GLOBAL | SESSION] VARIABLES [LIKE 'pattern
'] SHOW WARNINGS [LIMIT [offset
,]row_count
]
El comando SHOW
también tiene formas que
proporcionan información acerca de servidores de replicación
maestros y esclavos y se describen en
Sección 13.6, “Sentencias de replicación”:
SHOW BINLOG EVENTS SHOW MASTER LOGS SHOW MASTER STATUS SHOW SLAVE HOSTS SHOW SLAVE STATUS
En la sintaxis para un comando SHOW
dado
incluye una parte LIKE
'
,
pattern
''
es una
cadena que puede contener los carácteres de SQL
'pattern
'%
' y '_
' . El patrón es
útil para restringir la salida del comando para valores
coincidentes.
SHOW CHARACTER SET [LIKE 'pattern
']
El comando SHOW CHARACTER SET
muestra todos
los conjuntos de carácteres disponibles. Esto tiene una
cláusula LIKE
opcional que indica qué
nombres de conjuntos de carácteres hay coincidentes. Por
ejemplo:
mysql> SHOW CHARACTER SET LIKE 'latin%'; +---------+-----------------------------+-------------------+--------+ | Charset | Description | Default collation | Maxlen | +---------+-----------------------------+-------------------+--------+ | latin1 | ISO 8859-1 West European | latin1_swedish_ci | 1 | | latin2 | ISO 8859-2 Central European | latin2_general_ci | 1 | | latin5 | ISO 8859-9 Turkish | latin5_turkish_ci | 1 | | latin7 | ISO 8859-13 Baltic | latin7_general_ci | 1 | +---------+-----------------------------+-------------------+--------+
La columna Maxlen
muestra el máximo
número de bytes usados para almacenar un carácter.
SHOW COLLATION [LIKE 'pattern
']
La salida de SHOW COLLATION
incluye todos
los conjuntos de carácteres disponibles. Tiene una cláusula
LIKE
opcional cuyo
pattern
indica qué nombres de
colación coinciden. Por ejemplo:
mysql> SHOW COLLATION LIKE 'latin1%'; +-------------------+---------+----+---------+----------+---------+ | Collation | Charset | Id | Default | Compiled | Sortlen | +-------------------+---------+----+---------+----------+---------+ | latin1_german1_ci | latin1 | 5 | | | 0 | | latin1_swedish_ci | latin1 | 8 | Yes | Yes | 0 | | latin1_danish_ci | latin1 | 15 | | | 0 | | latin1_german2_ci | latin1 | 31 | | Yes | 2 | | latin1_bin | latin1 | 47 | | Yes | 0 | | latin1_general_ci | latin1 | 48 | | | 0 | | latin1_general_cs | latin1 | 49 | | | 0 | | latin1_spanish_ci | latin1 | 94 | | | 0 | +-------------------+---------+----+---------+----------+---------+
La columna Default
indica si una colación
está por defecto para su conjunto de carácteres.
Compiled
indica si el conjunto de
carácteres está compilado en el servidor.
Sortlen
está relacionado con la cantidad
de memoria requerida para ordenar cadenas expresadas en el
conjunto de carácteres.
SHOW [FULL] COLUMNS FROMtbl_name
[FROMdb_name
] [LIKE 'pattern
']
SHOW COLUMNS
muestra información acerca de
las columnas en una tabla dada. También funciona para vistas
desde MySQL 5.0.1.
Si los tipos de columnas difieren de los que espera basados en
su comando CREATE TABLE
, tenga en cuenta
que MySQL a veces cambia tipos de columnas cuando crea o
altera una tabla. Las condiciones en que esto ocurre se
describen en Sección 13.1.5.1, “Cambios tácitos en la especificación de columnas”.
La palabra clave FULL
hace que la salida
incluya los permisos que tiene así como cualquier comentario
por columna para cada columna.
Puede usar db_name.tbl_name
como
alternativa a la sintaxis
. En otras
palabras, estos dos comandos son equivalentes:
tbl_name
FROM
db_name
mysql> SHOW COLUMNS FROM mytable FROM mydb; mysql> SHOW COLUMNS FROM mydb.mytable;
SHOW FIELDS
es un sinónimo para
SHOW COLUMNS
. Puede listar las columnas de
una tabla con el comando mysqlshow
db_name
tbl_name
.
El comando DESCRIBE
proporciona
información similar a SHOW COLUMNS
.
Consulte Sección 13.3.1, “Sintaxis de DESCRIBE
(Información acerca de las columnas)”.
SHOW CREATE {DATABASE | SCHEMA} db_name
Muestra un comando CREATE DATABASE
que crea
la base de datos dada. SHOW CREATE SCHEMA
puede usarse desde MySQL 5.0.2.
mysql> SHOW CREATE DATABASE test\G *************************** 1. row *************************** Database: test Create Database: CREATE DATABASE `test` /*!40100 DEFAULT CHARACTER SET latin1 */
SHOW CREATE TABLE tbl_name
Muestra un comando CREATE TABLE
que crea la
tabla dada. Desde MySQL 5.0.1, este comando funciona con
vistas.
mysql> SHOW CREATE TABLE t\G *************************** 1. row *************************** Table: t Create Table: CREATE TABLE t ( id INT(11) default NULL auto_increment, s char(60) default NULL, PRIMARY KEY (id) ) ENGINE=MyISAM
SHOW CREATE TABLE
entrecomilla los nombres
de tabla y columna según el valor de la opción
SQL_QUOTE_SHOW_CREATE
.
Sección 13.5.3, “Sintaxis de SET
”.
SHOW {DATABASES | SCHEMAS} [LIKE 'pattern
']
SHOW DATABASES
lista la base de datos en el
servidor MySQL . Puede obtener esta lista usando el comando
mysqlshow . En MySQL 5.0, ve sólo las
bases de datos para las que tiene alguna clase de permiso, si
no tiene el permiso SHOW DATABASES
.
Si el servidor se arrancó con la opción
--skip-show-database
, no puede usar este
comando a no ser que tenga el permiso SHOW
DATABASES
.
SHOW SCHEMAS
puede usarse desde MySQL 5.0.2
SHOW ENGINE engine_name
{LOGS | STATUS }
SHOW ENGINE
muestra información de log o
estado acerca de motores de almacenamiento. Los siguientes
comandos se soportan actualmente:
SHOW ENGINE BDB LOGS SHOW ENGINE INNODB STATUS
SHOW ENGINE BDB LOGS
muestra información
de estado acerca de ficheros de log BDB
existentes. Retorna los siguientes campos:
File
Ruta completa al fichero de log.
Type
Tipo del fichero de log (BDB
para
ficheros de log Berkeley DB).
Status
Estado del fichero de log (FREE
si el
fichero puede borrarse, o IN USE
si el
fichero se necesita en el subsistema de transacción)
SHOW ENGINE INNODB STATUS
muestra
información extendida acerca del estado del comando
InnoDB
.
Sinónimos antiguos (ahora obsoletos) para estos comandos son
SHOW [BDB] LOGS
y SHOW INNODB
STATUS
.
SHOW ENGINE
puede usarse desde MySQL 4.1.2.
SHOW [STORAGE] ENGINES
SHOW ENGINES
muestra su información de
estado acerca del motor de almacenamiento. Esto es
particularmente útil para chequear si un motor de
almacenamiento se soporta, o para ver si el motr es.
SHOW TABLE TYPES
es un sinónimo obsoleto.
mysql> SHOW ENGINES\G *************************** 1. row *************************** Engine: MyISAM Support: DEFAULT Comment: Default engine as of MySQL 3.23 with great performance *************************** 2. row *************************** Engine: MEMORY Support: YES Comment: Hash based, stored in memory, useful for temporary tables *************************** 3. row *************************** Engine: HEAP Support: YES Comment: Alias for MEMORY *************************** 4. row *************************** Engine: MERGE Support: YES Comment: Collection of identical MyISAM tables *************************** 5. row *************************** Engine: MRG_MYISAM Support: YES Comment: Alias for MERGE *************************** 6. row *************************** Engine: ISAM Support: NO Comment: Obsolete storage engine, now replaced by MyISAM *************************** 7. row *************************** Engine: MRG_ISAM Support: NO Comment: Obsolete storage engine, now replaced by MERGE *************************** 8. row *************************** Engine: InnoDB Support: YES Comment: Supports transactions, row-level locking, and foreign keys *************************** 9. row *************************** Engine: INNOBASE Support: YES Comment: Alias for INNODB *************************** 10. row *************************** Engine: BDB Support: YES Comment: Supports transactions and page-level locking *************************** 11. row *************************** Engine: BERKELEYDB Support: YES Comment: Alias for BDB *************************** 12. row *************************** Engine: NDBCLUSTER Support: NO Comment: Clustered, fault-tolerant, memory-based tables *************************** 13. row *************************** Engine: NDB Support: NO Comment: Alias for NDBCLUSTER *************************** 14. row *************************** Engine: EXAMPLE Support: NO Comment: Example storage engine *************************** 15. row *************************** Engine: ARCHIVE Support: YES Comment: Archive storage engine *************************** 16. row *************************** Engine: CSV Support: NO Comment: CSV storage engine *************************** 17. row *************************** Engine: FEDERATED Support: YES Comment: Federated MySQL storage engine *************************** 18. row *************************** Engine: BLACKHOLE Support: YES Comment: /dev/null storage engine (anything you write to it disappears)
Un valor Support
indica si el motor se
soporta, y cuál está activo por defecto. Por ejemplo, si el
servidor se arranca con la opción
--default-table-type=InnoDB
, el valor
Support
para el registro
InnoDB
tiene el valor
DEFAULT
.
SHOW ERRORS [LIMIT [offset
,]row_count
] SHOW COUNT(*) ERRORS
Este comando es similar a SHOW WARNINGS
,
excepto que en lugar de mostrar errores, advertencias, y notas
sólo muestra errores.
La cláusula LIMIT
tiene la misma sintaxis
que para el comando SELECT
. Consulte
Sección 13.2.7, “Sintaxis de SELECT
”.
El comando SHOW COUNT(*) ERRORS
muestra el
número de errores. Puede recibir este número de la variable
error_count
:
SHOW COUNT(*) ERRORS; SELECT @@error_count;
Para más información consulte
Sección 13.5.4.22, “Sintaxis de SHOW WARNINGS
”.
SHOW GRANTS FOR user
Este comando lista el comando GRANT
que
debe realizarse para duplicar los permisos para una cuenta de
usuario MySQL.
mysql> SHOW GRANTS FOR 'root'@'localhost'; +---------------------------------------------------------------------+ | Grants for root@localhost | +---------------------------------------------------------------------+ | GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION | +---------------------------------------------------------------------+
Para listar los permisos de la sesión actual, puede usar cualquiera de los siguientes comandos:
SHOW GRANTS; SHOW GRANTS FOR CURRENT_USER; SHOW GRANTS FOR CURRENT_USER();
SHOW INDEX FROMtbl_name
[FROMdb_name
]
SHOW INDEX
retorna información de índice
de tabla en un formato que recuerda la llamada
SQLStatistics
en ODBC.
SHOW INDEX
returna los siguientes campso:
Table
Nombre de tabla.
Non_unique
0 si el índice no puede contener duplicados, 1 si puede.
Key_name
Nombre del índice
Seq_in_index
Número de secuencia de columna en el índice, comenzando con 1.
Column_name
Nombre de columna.
Collation
Cómo se ordena la columna en el índice. En MySQL, puede
tener valores 'A
' (Ascendente) o
NULL
(No ordenado).
Cardinality
Número de valores únicos en el índice. Se actualiza
ejecutando ANALYZE TABLE
o
myisamchk -a.
Cardinality
se cuenta basándose en las
estadísticas almacenadas como enteros, así que no es
necesariamente precisa para tablas pequeñas. Mientras
más grande sea, más grande es la probabilidad que MySQL
use el índice al hacer joins.
Sub_part
Número de carácteres indexados si la columna sólo está
indexada parcialmente. NULL
si la
columna entera está indexada.
Packed
Indica cómo está empaquetada la clave.
NULL
si no lo está.
Null
Contiene YES
si la columna puede
contener NULL
. Si no, la columna
contiene NO
desde MySQL 5.0.3, y
''
antes.
Index_type
Método de índice usado (BTREE
,
FULLTEXT
, HASH
,
RTREE
).
Comment
Comentarios varios.
Puede usar db_name.tbl_name
como
alternativa para la sintaxis
. Estos dos
comandos son equivalentes:
tbl_name
FROM
db_name
mysql> SHOW INDEX FROM mytable FROM mydb; mysql> SHOW INDEX FROM mydb.mytable;
SHOW KEYS
es sinónimo para SHOW
INDEX
. Puede listar los índices de una tabla con el
comando mysqlshow -k
db_name
tbl_name
.
SHOW INNODB STATUS
En MySQL 5.0, este es un sinónimo obsoleto para SHOW
ENGINE INNODB STATUS
. Consulte
Sección 13.5.4.7, “Sintaxis de SHOW ENGINE
”.
SHOW [BDB] LOGS
En MySQL 5.0, este es un sinónimo obsoleto para SHOW
ENGINE BDB LOGS
. Consulte
Sección 13.5.4.7, “Sintaxis de SHOW ENGINE
”.
SHOW OPEN TABLES
SHOW OPEN TABLES
lista las tablas no
TEMPORARY
abiertas actualmente en la caché
de tablas. Consulte Sección 7.4.8, “Cómo abre y cierra tablas MySQL”.
SHOW OPEN TABLES
returna los siguientes
campos:
Database
La base de datos que contiene la tabla.
Table
Nombre de tabla.
In_use
Número de veces que la tabla está en uso para consultas. Si el contador es cero, la tabla está abierta, pero no está siendo usada.
Name_locked
Si un nombre de tabla está bloqueado. El bloqueo de nombres se usa para operaciones tales como borrar o renombrar tablas.
SHOW OPEN TABLES
se añadió en MySQL
3.23.33.
SHOW PRIVILEGES
SHOW PRIVILEGES
muestra la lista de
permisos de sistema que soporta MySQL server. La salida exacta
depende de la versión de su servidor.
mysql> SHOW PRIVILEGES\G *************************** 1. row *************************** Privilege: Alter Context: Tables Comment: To alter the table *************************** 2. row *************************** Privilege: Alter routine Context: Functions,Procedures Comment: To alter or drop stored functions/procedures *************************** 3. row *************************** Privilege: Create Context: Databases,Tables,Indexes Comment: To create new databases and tables *************************** 4. row *************************** Privilege: Create routine Context: Functions,Procedures Comment: To use CREATE FUNCTION/PROCEDURE *************************** 5. row *************************** Privilege: Create temporary tables Context: Databases Comment: To use CREATE TEMPORARY TABLE *************************** 6. row *************************** Privilege: Create view Context: Tables Comment: To create new views *************************** 7. row *************************** Privilege: Create user Context: Server Admin Comment: To create new users *************************** 8. row *************************** Privilege: Delete Context: Tables Comment: To delete existing rows *************************** 9. row *************************** Privilege: Drop Context: Databases,Tables Comment: To drop databases, tables, and views *************************** 10. row *************************** Privilege: Execute Context: Functions,Procedures Comment: To execute stored routines *************************** 11. row *************************** Privilege: File Context: File access on server Comment: To read and write files on the server *************************** 12. row *************************** Privilege: Grant option Context: Databases,Tables,Functions,Procedures Comment: To give to other users those privileges you possess *************************** 13. row *************************** Privilege: Index Context: Tables Comment: To create or drop indexes *************************** 14. row *************************** Privilege: Insert Context: Tables Comment: To insert data into tables *************************** 15. row *************************** Privilege: Lock tables Context: Databases Comment: To use LOCK TABLES (together with SELECT privilege) *************************** 16. row *************************** Privilege: Process Context: Server Admin Comment: To view the plain text of currently executing queries *************************** 17. row *************************** Privilege: References Context: Databases,Tables Comment: To have references on tables *************************** 18. row *************************** Privilege: Reload Context: Server Admin Comment: To reload or refresh tables, logs and privileges *************************** 19. row *************************** Privilege: Replication client Context: Server Admin Comment: To ask where the slave or master servers are *************************** 20. row *************************** Privilege: Replication slave Context: Server Admin Comment: To read binary log events from the master *************************** 21. row *************************** Privilege: Select Context: Tables Comment: To retrieve rows from table *************************** 22. row *************************** Privilege: Show databases Context: Server Admin Comment: To see all databases with SHOW DATABASES *************************** 23. row *************************** Privilege: Show view Context: Tables Comment: To see views with SHOW CREATE VIEW *************************** 24. row *************************** Privilege: Shutdown Context: Server Admin Comment: To shut down the server *************************** 25. row *************************** Privilege: Super Context: Server Admin Comment: To use KILL thread, SET GLOBAL, CHANGE MASTER, etc. *************************** 26. row *************************** Privilege: Update Context: Tables Comment: To update existing rows *************************** 27. row *************************** Privilege: Usage Context: Server Admin Comment: No privileges - allow connect only
SHOW [FULL] PROCESSLIST
SHOW PROCESSLIST
le muestra qué flujos
están en ejecución. Puede obtener esta información usando
el comando mysqladmin processlist . Si
tiene el permiso SUPER
, puede ver todos
los flujos. De otro modo, puede ver sólo los propios (esto
es, flujos asociados con la cuenta MySQL que está usando).
Consulte Sección 13.5.5.3, “Sintaxis de KILL
”. Si no usa la palabra clave
FULL
, sólo los primeros 100 carácteres
de cada consulta se muestran.
En MySQL 5.0, el comando reporta el nombre de equipo ara
conexiones TCP/IP en formato
para hacer más fácil determinar qué hace cada cliente.
host_name
:client_port
Este comando es útil si obtiene el mensaje de error
"demasiadas conexiones" para encontrar qué ocurre. MySQL
reserva una conexión extra para usar por cuentas con el
permiso SUPER
, para asegurar que el
administrador siempre es capaz de conectar y comprobar el
sistema (asumiendo que no da este permiso a todos los
usuarios).
Algunos estados vistos comúnmente en la salida de
SHOW PROCESSLIST
:
Checking table
El flujo está realizando un chequeo (automático) de la tabla.
Closing tables
Significa que el flujo está volcando los datos que han cambiado de la tabla a disco y cerrando las tablas usadas. Esto debe ser una operación rápido. Si no lo es, debe verificar que no tiene el disco lleno y que el disco no tiene un uso muy pesado.
Connect Out
Esclavo conectando con el maestro.
Copying to tmp table on disk
El conjunto de resultados temporal era mayor que
tmp_table_size
y el flujo está
cambiando la tabla temporal de memoria a disco para
ahorrar memoria.
Creating tmp table
El flujo está creando una tabla temporal para guardar parte del resultado de una consulta.
deleting from main table
El servidor está ejecutando la primera parte de un borrado de tablas múltiple y borrando sólo la primera tabla.
deleting from reference tables
El servidor está ejecutando la segunda parte de un borrado de tablas múltiples y borrando los registros coincidentes de las otras tablas.
Flushing tables
El flujo está ejecutando FLUSH TABLES
y espera a que todos los flujos cierren sus tablas.
Killed
Alguien ha enviado un comando KILL
al
flujo y debería abortar en cuanto chequee el flag kill.
El flag se chequea en cada vuelta al bucle principal de
MySQL, pero en algunos casos puede tardar algo de tiempo
en que muera el flujo. Si el flujo está bloqueado por
algún otro flujo, el kill tiene efecto en cuanto el otro
flujo libera el bloqueo.
Locked
La consulta está bloqueada por otra consulta.
Sending data
El flujo está procesando registros para un comando
SELECT
y también enviando datos al
cliente.
Sorting for group
El flujo está ordenando para un GROUP
BY
.
Sorting for order
El flujo está ordenando para un ORDER
BY
.
Opening tables
El flujo está intentando abrir una tabla. Esto debería
ser un proceso muy rápido, a no ser que algo importante
evite la abertura. Por ejemplo, un comando ALTER
TABLE
o LOCK TABLE
puede
evitar abrir una tabla hasta que el comando acabe.
Removing duplicates
La consulta usaba SELECT DISTINCT
de
forma que MySQL no podía optimizar las distintas
operaciones en una fase temprana. Debido a ello, MySQL
necesita una fase extra para borrar todos los registros
duplicados antes de enviar el resultado al cliente.
Reopen table
El flujo obtivo un bloqueo para la tabla, pero se dio cuenta tras obtenerlo que la estructura de la tabla cambió. Se libera el bloqueo, cierra la tabla y trata de reabrirla.
Repair by sorting
El código de reparación está usando una ordenación para crear índices.
Repair with keycache
El código de reparación está usando creación de claves
una a una en la caché de claves. Esto es mucho más lento
que Repair by sorting
.
Searching rows for update
El flujo hace una primera fase para encontrar todos los
registro coincidentes antes de actualizarlos. Esto debe
hacerse si UPDATE
está cambiando el
índice que se usa para encontrar los registros
implicados.
Sleeping
El flujo espera que el cliente envíe un nuevo comando .
System lock
El flujo espera obtener un bloqueo de sistema externo para
la tabla. Si no está usando múltiples servidors
mysqld accediendo a las mismas tablas,
puede deshabilitar los bloqueos de sistema con la opción
--skip-external-locking
.
Upgrading lock
El handler INSERT DELAYED
trata de
obtener un bloqueo para la tabla para insertar registros.
Updating
El flujo está buscando registros para actualizar.
User Lock
El flujo espera un GET_LOCK()
.
Waiting for tables
El flujo obtuvo una notificación que la estructura de la tabla cambió y necesita reabrirla. Sin embargo, para ello, debe esperar a que el resto de flujos cierren la tabla en cuestión.
Esta notificación tiene lugar si otro flujo ha usado
FLUSH TABLES
o uno de los siguientes
comandos en la tabla en cuestión: FLUSH TABLES
,
tbl_name
ALTER TABLE
, RENAME
TABLE
, REPAIR TABLE
,
ANALYZE TABLE
, o OPTIMIZE
TABLE
.
waiting for handler insert
El handler INSERT DELAYED
ha procesado
las inserciones pendientes y espera nuevas.
La mayoría de estados se corresponden a operaciones rápidas. Si un flujo está en alguno de ellos varios segundos, puede existir un problema que necesite investigar.
Hay algunos estdos que no se mencionan en la lista precedente, pero varios de ellos son útiles sólo para encontrar fallos en el servidor.
SHOW [GLOBAL | SESSION] STATUS [LIKE 'pattern
']
SHOW STATUS
proporciona información de
estado del servidor. Esta información puede obtenerse usando
el comando mysqladmin extended-status .
Aquí se muestra una salida parcial. La lista de variables y sus vallires pueden ser distintos para su servidor. El significado de cada variable se da en Sección 5.3.4, “Variables de estado del servidor”.
mysql> SHOW STATUS; +--------------------------+------------+ | Variable_name | Value | +--------------------------+------------+ | Aborted_clients | 0 | | Aborted_connects | 0 | | Bytes_received | 155372598 | | Bytes_sent | 1176560426 | | Connections | 30023 | | Created_tmp_disk_tables | 0 | | Created_tmp_tables | 8340 | | Created_tmp_files | 60 | ... ... ... | Open_tables | 1 | | Open_files | 2 | | Open_streams | 0 | | Opened_tables | 44600 | | Questions | 2026873 | ... ... ... | Table_locks_immediate | 1920382 | | Table_locks_waited | 0 | | Threads_cached | 0 | | Threads_created | 30022 | | Threads_connected | 1 | | Threads_running | 1 | | Uptime | 80380 | +--------------------------+------------+
Con una cláusula LIKE
, el comando muestra
sólo las variables que coinciden con el patrón:
mysql> SHOW STATUS LIKE 'Key%'; +--------------------+----------+ | Variable_name | Value | +--------------------+----------+ | Key_blocks_used | 14955 | | Key_read_requests | 96854827 | | Key_reads | 162040 | | Key_write_requests | 7589728 | | Key_writes | 3813196 | +--------------------+----------+
Las opciones GLOBAL
y
SESSION
son nuevas en MySQL 5.0.2 Con
GLOBAL
, obtiene los valores de estado para
todas las conexiones a MySQL. Con SESSION
,
obtiene los valores de estado para la conexión actual. Si no
usa estas opciones, por defecto es SESSION
.
LOCAL
es sinónimo de
SESSION
.
Tenga en cuenta que algunas variables de estado sólo tienen
un valor global. Para ellas obtiene el mismo valor para
GLOBAL
y SESSION
.
SHOW TABLE STATUS [FROMdb_name
] [LIKE 'pattern
']
SHOW TABLE STATUS
funciona como
SHOW TABLE
, pero proporciona mucha más
información acerca de cada tabla. Puede obtener esta lista
usando el comando mysqlshow --status
db_name
. Desde MySQL
5.0.1, este comando también muestra información sobre
vistas.
SHOW TABLE STATUS
returna los siguientes
campos:
Name
Nombre de tabla.
Engine
Motor para la tabla. Antes de MySQL 4.1.2, este valor se
llama Type
. Consulte
Capítulo 14, Motores de almacenamiento de MySQL y tipos de tablas.
Version
Número de versión del fichero .frm
de la tabla.
Row_format
Formato de almacenamiento de registros
(Fixed
, Dynamic
,
Compressed
,
Redundant
, Compact
).
Desde MySQL/InnoDB 5.0.3, el formato de tablas InnoDB se
reporta como Redundant
o
Compact
. Antes de 5.0.3, las tablas
InnoDB siempre están en formato
Redundant
.
Rows
Número de registros. Algunos motores como
MyISAM
, guardan el número exacto.
Para otros motores, como InnoDB
, este
valor es una aproximación y puede variar del valor real
hasta de un 40 a 50%. En tales casos, use SELECT
COUNT(*)
para obtener el número real de
registros.
El valor Rows
es
NULL
para tablas en la base de datos
INFORMATION_SCHEMA
.
Avg_row_length
Longitud de registro media.
Data_length
Tamaño del fichero de datos.
Max_data_length
Máxima longitud del fichero d edatos. Este es el número total de bytes de datos que pueden almacenarse en la tabla dado el tamaño de puntero de datos usado.
Index_length
Tamaño de fichero índice.
Data_free
Número de bytes reservados no usados.
Auto_increment
Siguiente valor AUTO_INCREMENT
.
Create_time
Cuándo se creó la tabla .
Update_time
Cuándo se actualizó por última vez el fichero de datos.
Check_time
Cuándo se chequeó la tabla por última vez.
Collation
Conjunto de carácteres y colación de la tabla.
Checksum
Valor de checksum en vivo (si hay).
Create_options
Opciones extra usadas con CREATE TABLE
.
Comment
Comentario usado al crear la tabla (o información de porqué MySQL no puede acceder a la información de tabla).
En el comentario de tabla, las tablas
InnoDB
reportan el espacio libre del
espacio de tabla al que pertenece la tabla. Para una tabla
localizada en el espacio compartido, este es el espacio libre
del espacio de tabla compartido. Si usa múltiples espacios y
la tabla tiene el suyo, el espacio libre es sólo para esa
tabla.
Para tablas MEMORY
(HEAP
) los valores
Data_length
,
Max_data_length
, y
Index_length
aproximan la cantidad real de
memoria reservada. El algoritmo de reserva reserva grandes
cantidades de memoria para reducir el número de operaciones
de reserva.
Para vistas, todos los campos mostrados por SHOW
TABLE STATUS
son NULL
excepto que
Name
indicata el nombre de vista y
Comment
dice view
.
SHOW [FULL] TABLES [FROMdb_name
] [LIKE 'pattern
']
SHOW TABLES
lista las tablas no
TEMPORARY
en una base de datos dada. Puede
obtener esta lista usando el comando mysqlshow
db_name
.
Antes de MySQL 5.0.1, la salida de SHOW
TABLES
contiene una única columna de nombres de
tabla. Desde MySQL 5.0.1, este comando lista cualquier vista
en la base de datos. Desde MySQL 5.0.2, se soporta el
modificador FULL
de forma que SHOW
FULL TABLES
muestra una segunda columna de salida.
Los valores para la segunda columna son BASE
TABLE
para una tabla VIEW
para
una vista.
Nota: Si no tiene permisos
para una tabla, la tabla no se muestra en la salida de
SHOW TABLES
o mysqlshow
db_name.
SHOW TRIGGERS [FROMdb_name
] [LIKEexpr
]
SHOW TRIGGERS
lista los disparadores
definidos en el MySQL server. Se implementó en MySQL 5.0.10.
Para el disparadores ins_sum
como se define
en Sección 20.3, “Utilización de disparadores”, la salida de este comando
es la que se muestra:
mysql> SHOW TRIGGERS LIKE 'acc%'; +---------+--------+---------+-------------------------------+--------+---------+ | Trigger | Event | Table | Statement | Timing | Created | +---------+--------+---------+-------------------------------+--------+---------+ | ins_sum | INSERT | account | SET @sum = @sum + NEW.amount | BEFORE | NULL | +---------+--------+---------+-------------------------------+--------+---------+
Nota: Cuando use una
cláusula LIKE
con SHOW
TRIGGERS
, la expresión a cumplir
(expr
) se compara con el nombre de
la tabla en que se declara el disparador, y no con el nombre
del disparador:
mysql> SHOW TRIGGERS LIKE 'ins%'; Empty set (0.01 sec)
Aquí se muestra una breve explicación de las columnas de la salida de este comando:
Trigger
: Nombre del disparador.
Event
: Evento que invoca el
disparador. Debe ser 'INSERT'
,
'UPDATE'
, o
'DELETE'
.
Table
: La tabla para la que se define
el disparador.
Statement
: Comando a ejecutar cuando
se invoca el disparador. Es lo mismo que el texto
mostrado en la columna
ACTION_STATEMENT
de
INFORMATION_SCHEMA.TRIGGERS
.
Timing
: Puede ser
'BEFORE'
o
'AFTER'
.
Created
: Actualmente el valor de esta
columna siempre es NULL
.
Debe tener el permiso SUPER
para ejecutar
SHOW TRIGGERS
.
Consulte Sección 22.1.16, “La tabla INFORMATION_SCHEMA TRIGGERS
”.
SHOW [GLOBAL | SESSION] VARIABLES [LIKE 'pattern
']
SHOW VARIABLES
muestra los valores de
algunas variables de sistema de MySQL. Esta información puede
obtenerse usando el comando mysqladmin
variables .
Con la opción GLOBAL
, obtiene los valores
que se usan para nuevas conexiones de MySQL. Con
SESSION
, obtiene los valores que hay en
efecto para la conexión actual. Si no usa estas opciones, por
defecto es SESSION
.
LOCAL
es sinónimo de
SESSION
.
Si los valores por defecto no son adecuados, puede cambiar la
mayoría de variables usando opciones de línea de comandos
cuando mysqld arranca o en tiempo de
ejecución con el comando SET
. Consulte
Sección 5.3.1, “Opciones del comando mysqld” y
Sección 13.5.3, “Sintaxis de SET
”.
La salida parcial se muestra aquí. La lista de variables y sus valores pueden ser distintos para su servidor. El significado de cada variable se da en Sección 5.3.3, “Variables de sistema del servidor”. Información acerca de cómo adecuarlos se proporciona en Sección 7.5.2, “Afinar parámetros del servidor”.
mysql> SHOW VARIABLES; +---------------------------------+---------------------------------------------------------+ | Variable_name | Value | +---------------------------------+---------------------------------------------------------+ | auto_increment_increment | 1 | | auto_increment_offset | 1 | | automatic_sp_privileges | ON | | back_log | 50 | | basedir | / | | bdb_cache_size | 8388600 | | bdb_home | /var/lib/mysql/ | | bdb_log_buffer_size | 32768 | ... ... ... | max_connections | 100 | | max_connect_errors | 10 | | max_delayed_threads | 20 | | max_error_count | 64 | | max_heap_table_size | 16777216 | | max_join_size | 4294967295 | | max_relay_log_size | 0 | | max_sort_length | 1024 | ... ... ... | time_zone | SYSTEM | | timed_mutexes | OFF | | tmp_table_size | 33554432 | | tmpdir | | | transaction_alloc_block_size | 8192 | | transaction_prealloc_size | 4096 | | tx_isolation | REPEATABLE-READ | | updatable_views_with_limit | YES | | version | 5.0.7-beta-Max | | version_bdb | Sleepycat Software: Berkeley DB 4.1.24: (June 11, 2005) | | version_comment | MySQL Community Edition - Max (GPL) | | version_compile_machine | i686 | | version_compile_os | pc-linux-gnu | | wait_timeout | 28800 | +---------------------------------+---------------------------------------------------------+
Con una cláusula LIKE
, el comando muestra
sólo las variables que coinciden con el patrón:
mysql> SHOW VARIABLES LIKE 'have%'; +-----------------------+----------+ | Variable_name | Value | +-----------------------+----------+ | have_archive | NO | | have_bdb | YES | | have_blackhole_engine | YES | | have_compress | YES | | have_crypt | YES | | have_csv | YES | | have_example_engine | YES | | have_federated_engine | YES | | have_geometry | YES | | have_innodb | YES | | have_isam | NO | | have_ndbcluster | DISABLED | | have_openssl | NO | | have_query_cache | YES | | have_raid | NO | | have_rtree_keys | YES | | have_symlink | YES | +-----------------------+----------+
SHOW WARNINGS [LIMIT [offset
,]row_count
] SHOW COUNT(*) WARNINGS
SHOW WARNINGS
muestra los mensajes de
error, advertencia y notas retornadas por el último comando
que haya generado algún mensaje, o nada si el último mensaje
que haya usado una tabla no haya generado mensajes. Un comando
relacionado, SHOW ERRORS
, sólo muestra los
errores. Consulte Sección 13.5.4.9, “Sintaxis de SHOW ERRORS
”.
La lista de mensajes se resetea para cada nuevo comando que use una tabla.
El comando SHOW COUNT(*) WARNINGS
muestra
el número total de errores, advertencias y notas. Puede
recibir este número de la variable
warning_count
:
SHOW COUNT(*) WARNINGS; SELECT @@warning_count;
El valor de warning_count
puede ser mayor
que el número de mensajes mostrados por SHOW
WARNINGS
si la variable de sistema
max_error_count
tiene un valor tan pequeño
que no se almacenen todos los mensajes. Se muestra
posteriormente un ejemplo de cómo puede pasar esto.
La cláusula LIMIT
tiene la misma sintaxis
que para el comando SELECT
. Consulte
Sección 13.2.7, “Sintaxis de SELECT
”.
El servidor MySQL devuelve el número total de errores,
advertencias, y notas que hayan resultado desde el último
comando. Si usa la API de C, este valor puede obtenerse
llamando a mysql_warning_count()
. Consulte
Sección 24.3.3.63, “mysql_warning_count()
”.
Las advertencias se generan para comandos tales como
LOAD DATA INFILE
y comandos DML tales como
INSERT
, UPDATE
,
CREATE TABLE
, y ALTER
TABLE
.
El siguiente comando DROP TABLE
provoca una
nota:
mysql> DROP TABLE IF EXISTS no_such_table; mysql> SHOW WARNINGS; +-------+------+-------------------------------+ | Level | Code | Message | +-------+------+-------------------------------+ | Note | 1051 | Unknown table 'no_such_table' | +-------+------+-------------------------------+
Aquí hay un ejemplo simple que muesta una advertencia de
sintaxis para CREATE TABLE
y advertencias
de conversiones para INSERT
:
mysql> CREATE TABLE t1 (a TINYINT NOT NULL, b CHAR(4)) TYPE=MyISAM; Query OK, 0 rows affected, 1 warning (0.00 sec) mysql> SHOW WARNINGS\G *************************** 1. row *************************** Level: Warning Code: 1287 Message: 'TYPE=storage_engine' is deprecated, use 'ENGINE=storage_engine' instead 1 row in set (0.00 sec) mysql> INSERT INTO t1 VALUES(10,'mysql'),(NULL,'test'), -> (300,'Open Source'); Query OK, 3 rows affected, 4 warnings (0.01 sec) Records: 3 Duplicates: 0 Warnings: 4 mysql> SHOW WARNINGS\G *************************** 1. row *************************** Level: Warning Code: 1265 Message: Data truncated for column 'b' at row 1 *************************** 2. row *************************** Level: Warning Code: 1263 Message: Data truncated, NULL supplied to NOT NULL column 'a' at row 2 *************************** 3. row *************************** Level: Warning Code: 1264 Message: Data truncated, out of range for column 'a' at row 3 *************************** 4. row *************************** Level: Warning Code: 1265 Message: Data truncated for column 'b' at row 3 4 rows in set (0.00 sec)
El máximo número de errores, advertencias y notas a
almacenar se controla mediante la variable de sistema
max_error_count
. Por defecto, su valor es
64. Para cambiar el número de mensajes que quiere almacenar,
cambie el valor de max_error_count
. En el
siguiente ejemplo, el comando ALTER TABLE
produce tres mensajes de advertencia, pero sólo se almacena
uno porque max_error_count
vale 1:
mysql> SHOW VARIABLES LIKE 'max_error_count'; +-----------------+-------+ | Variable_name | Value | +-----------------+-------+ | max_error_count | 64 | +-----------------+-------+ 1 row in set (0.00 sec) mysql> SET max_error_count=1; Query OK, 0 rows affected (0.00 sec) mysql> ALTER TABLE t1 MODIFY b CHAR; Query OK, 3 rows affected, 3 warnings (0.00 sec) Records: 3 Duplicates: 0 Warnings: 3 mysql> SELECT @@warning_count; +-----------------+ | @@warning_count | +-----------------+ | 3 | +-----------------+ 1 row in set (0.01 sec) mysql> SHOW WARNINGS; +---------+------+----------------------------------------+ | Level | Code | Message | +---------+------+----------------------------------------+ | Warning | 1263 | Data truncated for column 'b' at row 1 | +---------+------+----------------------------------------+ 1 row in set (0.00 sec)
Para deshabilitar las advertencias, ponga
max_error_count
a 0. En este caso,
warning_count
indica cuántas advertencias
ocurren, pero ninguno de los mensajes se almacenan.
Desde MySQL 5.0.3, puede poner la variable de sesión
SQL_NOTES
a 0 para que las advertencias del
nivel Note
no se guarden.
CACHE INDEXtbl_index_list
[,tbl_index_list
] ... INkey_cache_name
tbl_index_list
:tbl_name
[[INDEX|KEY] (index_name
[,index_name
] ...)]
El comando CACHE INDEX
asigna índices de
tabla a una caché de clave específica. Se usa sólo para
tablas MyISAM
.
El siguiente comando asigna índices de las tablas
t1
, t2
, y
t3
a la caché de claves llamada
hot_cache
:
mysql> CACHE INDEX t1, t2, t3 IN hot_cache; +---------+--------------------+----------+----------+ | Table | Op | Msg_type | Msg_text | +---------+--------------------+----------+----------+ | test.t1 | assign_to_keycache | status | OK | | test.t2 | assign_to_keycache | status | OK | | test.t3 | assign_to_keycache | status | OK | +---------+--------------------+----------+----------+
La sintaxis de CACHE INDEX
le permite
especifcar que sólo deben asignarse índicess particulares de
una tabla a la caché. Sin embargo, la implementación actual
asigna todos los índices de la tabla a la caché, así que no
hay razón para especificar nada más que el nombre de tabla.
La caché de clave referenciada en un comando CACHE
INDEX
puede crearse cambiando su tamaño con un
comando que asigne un valor al parámetro o en la
configuración del parámetro del servidor. Por ejemplo:
mysql> SET GLOBAL keycache1.key_buffer_size=128*1024;
Puede accederse a los parámetros de la caché de claves como miembros de una variable de sistema estructurada. Consulte Sección 9.4.1, “Variables estructuradas de sistema”.
Una caché de claves debe existir antes de asignarle índices:
mysql> CACHE INDEX t1 IN non_existent_cache; ERROR 1284 (HY000): Unknown key cache 'non_existent_cache'
Por defecto, los índices de tabla se asignan a la caché de claves principal (por defecto) creada en el arranque del servidor. Cuando se destruye una caché de índices, todos los índices asignados a la misma se asignan de nuevo a la caché por defecto.
Las asignaciones de índices afectan al servidor globalmente: Si un cliente asigna un índice a una caché dada, esta caché se usa para todas las consultas que tengan que ver con el índice, sin importar qué cliente realiza las consultas.
FLUSH [LOCAL | NO_WRITE_TO_BINLOG]flush_option
[,flush_option
] ...
Debe usar el comando FLUSH
si quiere
limpiar algunas de las cachés internas que usa MySQL . Para
ejecutar FLUSH
, debe tener el permiso
RELOAD
.
flush_option
puede ser cualquiera
de los siguientes valores:
HOSTS
Vacía las tablas de la caché de equipos. Debe volcar las
tablas de equipos si algunos de sus equipos cambia el
número IP o si obtiene el mensaje de error Host
... is blocked
. Cuando ocurren sucesivamente
más de max_connect_errors
errores para
un equipo dado mientras conecta con el servidor MySQL ,
MySQL asume que hay algo incorrecto y bloquea el equipo de
más peticiones de conexión. Volcar las tablas de equipos
le permite al equipo intentar conectar de nuevo. Consulte
Sección A.2.5, “La máquina '
”. Puede arrancar
mysqld con
host_name
' está bloqueada--max_connect_errors=999999999
para
evitar este mensaje de error.
DES_KEY_FILE
Recarga las claves DES del fichero que se especifica con
la opción --des-key-file
en tiempo de
arranque del servidor.
LOGS
Cierra y reabre todos los ficheros de log. Si ha
especificado un fichero de log de actualizaciones o un
fichero de log binario sin una extensión, el número de
extensión del fichero de log se incrementa en uno
respecto al fichero anterior. Si ha usado una extensión
del nombre de fichero, MySQL cierra y reabre el fichero de
log. En Unix, esto es lo mismo que enviar una señal
SIGHUP
al servidor
mysqld (excepto en algunas versiones
Mac OS X 10.3 donde mysqld ignora
SIGHUP
y SIGQUIT
).
PRIVILEGES
Recarga los permisos de las tablas de permisos en la base
de datos mysql
.
QUERY CACHE
Defragmenta caché de consulta para utilizar mejor su
memoria. Este comando no borra ninguna consulta de la
caché, no como RESET QUERY CACHE
.
STATUS
Resetea la mayoría de variables de estado a cero. Esto es algo que debe usar sólo al debugar una consulta. Consulte Sección 1.6.1.3, “Cómo informar de bugs y problemas”.
{TABLE | TABLES}
[
tbl_name
[,
tbl_name
] ...]
Cuando no se nombran tablas, cierra todas las tablas
abiertas y fuerza a todas las tablas en uso a que se
cierren. Esto también vuelca la caché de consultas. Con
uno o más nombres de tabla, vuelca sólo las tablas
dadas. FLUSH TABLES
también borra
todos los resultados de consultas de la caché de
consultas, como el comando RESET QUERY
CACHE
.
TABLES WITH READ LOCK
Cierra todas las tablas abiertas y bloquea todas las
tablas para todas las bases de datos con una bloqueo de
lectura hasta que ejecute UNLOCK
TABLES
. Esto es una forma muy conveniente de
obtener copias de seguridad si tiene un sistema de
ficheros como Veritas que puede tomas muestras en puntos
de tiempo concretos.
USER_RESOURCES
Resetea todos los recursos por hora de usuario a cero.
Esto le permite a los clientes que hayan alcanzado el
límite de su conexión de hora, de consulta o de
actualización para reanudar las actividades
inmediatamente. FLUSH USER_RESOURCES
no
se aplica al límite en conexiones máximas simultáneas.
Consulte Sección 13.5.1.3, “Sintaxis de GRANT
y REVOKE
”.
En MySQL 5.0, los comandos FLUSH
se
escriben en el lob binario a no ser que la plabra
NO_WRITE_TO_BINLOG
(o su alias
LOCAL
) se use.
Nota: FLUSH
LOGS
, FLUSH MASTER
,
FLUSH SLAVE
, y FLUSH TABLES WITH
READ LOCK
no se loguean en ningún caso porque
causarían problemas si se replicasen en un esclavo.
Puede acceder a algunos de estos comandos con la utilidad
mysqladmin usando los comandos
flush-hosts
, flush-logs
,
flush-privileges
,
flush-status
, o
flush-tables
.
Consulte Sección 13.5.5.5, “Sintaxis de RESET
” para información acerca
cómo se usa el comando RESET
para
replicación.
KILL [CONNECTION | QUERY] thread_id
Cada conexión a mysqld se ejecuta en un
flujo separado. Puede ver los flujos en ejecución con el
comando SHOW PROCESSLIST
y matar un flujo
con el comando KILL
.
thread_id
En MySQL 5.0.0, KILL
permite los
modificadores opcionales CONNECTION
o
QUERY
:
KILL CONNECTION
es lo mismo que
KILL
sin modificadores: termina la
conexión asociada con el
thread_id
dado.
KILL QUERY
termina el comando que la
conexión está ejecutando actualmente, pero deja a la
conexión intacta.
Si tiene el permiso PROCESS
, puede ver
todos los flujos, puede matar todos los flujos y comandos. De
otro modo, puede ver y matar sólo sus propios flujos y
comandos.
Puede usar los comandos mysqladmin processlist y mysqladmin kill para examinar y matar flujos.
Nota: No puede usar
KILL
con la biblioteca Embedded MySQL
Server porque el servidor empotrado se ejecuta dentro del
flujo de la aplicación que lo aloja. No crea ningún flujo de
conexión por sí solo.
Cuando hace un KILL
, se activa un flag
específico para el flujo. En la mayoría de casos, puede que
el flujo tarde algo de tiempo en morir, porque el flag kill se
chequea sólo cada ciertos intervalos:
En SELECT
, ORDER BY
y GROUP BY
, el flag se chequea tras
leer un bloque de registros. Si el flag kill está
activado, el comando se aborta.
Durante ALTER TABLE
, el flag kill se
chequea antes de que se lea cada bloque de registros de la
tabla original. Si el flag kill está activado, el comando
se aborta y la tabla temporal se borra.
Durante operaciones UPDATE
o
DELETE
, el flag kill se chequea tras
cada lectura de bloque y tras cada registro borrado o
actualizado. Si el flag kill está activado, el comando se
aborta. Tenga en cuenta que si no está usando
transacciones, los cambios no se deshacen.
GET_LOCK()
aborta y retorna
NULL
.
Un flujo INSERT DELAYED
rápidamente
vuelca (inserta) todos los registros que tiene en memoria
y luego termina.
Si el flujo está en el handler de bloqueo (estado:
Locked
), el bloqueo de tabla se aborta
rápidamente.
Si el flujo está esperando a espacio libre en disco en una llamada de lectura, la escritura se aborta con un mensaje de error "disco lleno".
Advertencia: Matar una
operación REPAIR TABLE
o
OPTIMIZE TABLE
en una tabla
MyISAM
resulta en una tabla que
corrupta y no usable. Cualquier lectura o escritura en una
tabla así falla hasta que la optimiza o repara de nuevo
(sin interrupción).
LOAD INDEX INTO CACHEtbl_index_list
[,tbl_index_list
] ...tbl_index_list
:tbl_name
[[INDEX|KEY] (index_name
[,index_name
] ...)] [IGNORE LEAVES]
El comando LOAD INDEX INTO CACHE
en MySQL
5.0 precarga un índice de tabla en la caché de clave para la
que se ha asignado por un comando CACHE
INDEX
, o en la caché de claves por defecto en otro
caso. LOAD INDEX INTO CACHE
se usa sólo
para tablas MyISAM
.
El modificador IGNORE LEAVES
hace que se
carguen sólo los bloques para los nodos que no sean hojas del
índice.
El siguiente comando precarga nodos (bloques índice) de
índices para las tablas t1
y
t2
:
mysql> LOAD INDEX INTO CACHE t1, t2 IGNORE LEAVES; +---------+--------------+----------+----------+ | Table | Op | Msg_type | Msg_text | +---------+--------------+----------+----------+ | test.t1 | preload_keys | status | OK | | test.t2 | preload_keys | status | OK | +---------+--------------+----------+----------+
Este comando precarga todos los bloques índice de
t1
. Sólo precarga bloques para los nodos
que no sean hojas de t2
.
La sintaxis de LOAD INDEX INTO CACHE
le
permite especificar que sólo índices particulares de una
tabla deben precargarse. Sin embargo, la implementación
actual precarga todos los índices de tabla en la caché, así
que no hay razón para especificar nada distinto al nombre de
tabla.
RESETreset_option
[,reset_option
] ...
El comando RESET
se usa para limpiar el
estado de varias operaciones de servidor. Actúa como una
versión más fuerte del comando FLUSH
.
Consulte Sección 13.5.5.2, “Sintaxis de FLUSH
”.
Debe tener el permiso RELOAD
para ejecutar
RESET
,
reset_option
puede ser cualquiera
de las siguientes:
MASTER
Borra todos los logs binarios listados en el fichero
índice, resetea el fichero de índice de log binario para
vaciarlo, y crea un nuevo fichero de log binario.
(Conocido como FLUSH MASTER
en
versiones prévias de MySQL.) Consulte
Sección 13.6.1, “Sentencias SQL para el control de servidores maestros”.
QUERY CACHE
Borra todos los resultados de consulta de la caché de consulta.
SLAVE
Hace que el esclavo olvide su posición de replicación en
los logs binarios del maestro. También resetea el log
retardado borrando cualquier fichero de log retardado y
comenzando uno nuevo. Conocido como FLUSH
SLAVE
en versiones prévias MySQL.) Consulte
Sección 13.6.2, “Sentencias SQL para el control de servidores esclavos”.
Esta sección describe comandos SQL relacionados con replicación. Un grupo de comandos se usa para controlar los servidores maestros. El otro se usa para controlar servidores esclavos.
La replicación puede controlarse mediante la interfaz SQL. Esta sección discute los comandos para administrar los maestros de replicación. Sección 13.6.2, “Sentencias SQL para el control de servidores esclavos” discute comandos para administrar servidores esclavos.
PURGE {MASTER | BINARY} LOGS TO 'log_name
' PURGE {MASTER | BINARY} LOGS BEFORE 'date
'
Borra todos los logs binarios listados en el índice de log prévio al log especificado o fecha. Los logs se borran de la lista guardada en el fichero de índice de log, así que el log dado pasa a ser el primero.
Ejemplo:
PURGE MASTER LOGS TO 'mysql-bin.010'; PURGE MASTER LOGS BEFORE '2003-04-02 22:46:26';
El argumento de BEFORE
date
puede estar en formato
'YYYY-MM-DD hh:mm:ss'
.
MASTER
y BINARY
son
sinónimos en MySQL 5.0.
Si tiene un esclavo activo que actualmente esté leyendo uno de los logs que está intentando borrar, este comando no hace nada y falla con un error. Sin embargo, si un esclavo está dormido y purga los logs que quiere leer, el esclavo no es capaz de replicar cuando se despierta. El comando puede ejecutarse mientras los esclavos se replican. No necesita pararlos.
Para purgar logs, siga este procedimiento:
En cada servidor esclavo, use SHOW SLAVE
STATUS
para chequear qué log está leyendo.
Obtinga una lista de los logs en el servidor maestro con
SHOW MASTER LOGS
.
Determine el primer log entre todos los esclavos. Este es el log objetivo. Si todos los esclavos están actualizados, este es el último log de la lista.
Haga una copia de seguridad de todos los logs que vaya a borrar. (Este paso es opcional, pero siempre recomendable.)
Purgue todos los logs hasta el log objetivo, pero no lo incluya.
RESET MASTER
Borra todos los logs binarios listados en el fichero índice, resetea el fichero índice de lob binario a vaciar, y recrea un nuevo fichero de log binario.
SET SQL_LOG_BIN = {0|1}
Activa o desactiva el logueo binario para la conexión actual
(SQL_LOG_BIN
es una variable de sesión) si
el cliente conecta usando una cuenta que tenga el permiso
SUPER
. En MySQL 5.0, el comando se rechaza
con un error si el cliente no tiene este permiso.
SHOW BINLOG EVENTS [IN 'log_name
'] [FROMpos
] [LIMIT [offset
,]row_count
]
Muestra los eventos en el log binario. Si no especifica
'log_name'
, se muestra el primer log
binario.
La cláusula LIMIT
tiene la misma sintaxis
que para el comando SELECT
. Consulte
Sección 13.2.7, “Sintaxis de SELECT
”.
Nota: Realizar SHOW
BINLOG EVENTS
sin cláusula LIMIT
puede iniciar un proceso muy largo y que consume muchos
recursos mientras el servidor vuelca los contenidos completos
del log binario (lo que incluye la mayoría de las consultas
ejecutadas por MySQL) a stdout. Para guardar el log binario en
un fichero de texto para analizar posteriormente, use la
utilidad mysqlbinlog . Consulte
Sección 8.5, “La utilidad mysqlbinlog para registros binarios”.
SHOW MASTER LOGS SHOW BINARY LOGS
Lista los ficheros del log binario en el servidor. Este
comando se usa como parte del procedimiento descrito en
Sección 13.6.1.1, “Sintaxis de PURGE MASTER LOGS
” para determinar qué logs
pueden purgarse.
mysql> SHOW BINARY LOGS; +---------------+-----------+ | Log_name | File_size | +---------------+-----------+ | binlog.000015 | 724935 | | binlog.000016 | 733481 | +---------------+-----------+
En MySQL 5.0, SHOW BINARY LOGS
, es
equivalente a SHOW MASTER LOGS
. La columna
File_size
se muestra desde MySQL 5.0.7.
CHANGE MASTER TO
LOAD DATA FROM MASTER
LOAD TABLE nombre_de_tabla
FROM MASTER
MASTER_POS_WAIT()
RESET SLAVE
SET GLOBAL SQL_SLAVE_SKIP_COUNTER
SHOW SLAVE STATUS
START SLAVE
STOP SLAVE
La replicación puede controlarse con la interfaz SQL. Esta sección discute comandos para administrar servidores de replicación esclavos. Sección 13.6.1, “Sentencias SQL para el control de servidores maestros” discute comandos para administrar servidores maestros.
CHANGE MASTER TOmaster_def
[,master_def
] ... master_def: MASTER_HOST = 'host_name
' | MASTER_USER = 'user_name
' | MASTER_PASSWORD = 'password
' | MASTER_PORT =port_num
| MASTER_CONNECT_RETRY =count
| MASTER_LOG_FILE = 'master_log_name
' | MASTER_LOG_POS =master_log_pos
| RELAY_LOG_FILE = 'relay_log_name
' | RELAY_LOG_POS =relay_log_pos
| MASTER_SSL = {0|1} | MASTER_SSL_CA = 'ca_file_name
' | MASTER_SSL_CAPATH = 'ca_directory_name
' | MASTER_SSL_CERT = 'cert_file_name
' | MASTER_SSL_KEY = 'key_file_name
' | MASTER_SSL_CIPHER = 'cipher_list
'
Cambia los parámetros que usa el servidor esclavo para conectar y comunicar con el servidor maestro.
MASTER_USER
,
MASTER_PASSWORD
,
MASTER_SSL
,
MASTER_SSL_CA
,
MASTER_SSL_CAPATH
,
MASTER_SSL_CERT
, y
MASTER_SSL_CIPHER
proporciona información
para el esclavo acerca de cómo conectar con su maestro.
Las opciones SSL (MASTER_SSL
,
MASTER_SSL_CA
,
MASTER_SSL_CAPATH
,
MASTER_SSL_CERT
,
MASTER_SSL_KEY
, y
MASTER_SSL_CIPHER
) pueden cambiarse incluso
en esclavos que se compilan sin soporte SSL. Se guardan en el
fichero master.info
, pero se ignorarn
hasta que use un servidor que tenga soporte SSL activado.
Si no especifica un parámetro dado, mantiene su valor antiguo, excepto cuando se indica en la siguiente discusión. Por ejemplo, si la contraseña para conectar a su maestro MySQL ha cambiado, necesita ejecutar este comando para decir al esclavo la nueva contraseña:
mysql> STOP SLAVE; -- if replication was running mysql> CHANGE MASTER TO MASTER_PASSWORD='new3cret'; mysql> START SLAVE; -- if you want to restart replication
Aquí no hay necesidad de especificar los parámetros que no cambian (equipo, puerto, usuario, y así).
MASTER_HOST
y
MASTER_PORT
son el nombre de equipo (o
dirección IP) del equipo maestro y su puerto TCP/IP. Tenga en
cuenta que si MASTER_HOST
es igual a
localhost
, entonces, como en otras partes
de MySQL, el puerto puede ignorarse (si los ficheros socket
Unix pueden usarse, por ejemplo).
Si especifica MASTER_HOST
o
MASTER_PORT
, el esclavo asume que el
servidor maestro es distinto que antes (incluso si especifica
un valor de equipo o de puerto igual que el anterior.) En este
caso, los antiguos valores para el log binario del servidor
maestro y su posición no se consideran aplicables por más
tiempo, así que si no especifica
MASTER_LOG_FILE
y
MASTER_LOG_POS
en el comando
MASTER_LOG_FILE=''
y
MASTER_LOG_POS=4
se añaden al final.
MASTER_LOG_FILE
y
MASTER_LOG_POS
son las coordinadas en que
flujo esclavo de entradea/salida debe empezar a leer del
maestro la siguiente vez que el flujo arranque. Si especifica
alguna de ellas, no puede especificar
RELAY_LOG_FILE
o
RELAY_LOG_POS
. Si no se especifica
MASTER_LOG_FILE
ni
MASTER_LOG_POS
, el esclavo usa las
últimas coordenadas del flujo SQL del esclavo
antes de realizar CHANGE
MASTER
. Esto asegura que no hay discontinuidad en la
replicación, incluso si el flujo SQL esclavo se comparó
posteriormente con el flujo esclavo de entrada/salida, cuando
símplemente quiere cambiar, digamos, la contraseña a usar.
CHANGE MASTER
borra todos los
ficheros de log retardados y arranca uno nuevo, a
no ser que especifique RELAY_LOG_FILE
o
RELAY_LOG_POS
. En tal caso, los logs
retardados se guardan; en MySQL 5.0, la variable global
relay_log_purge
se pone a 0.
CHANGE MASTER TO
actualiza los contenidos
de los ficheros master.info
y
relay-log.info
.
CHANGE MASTER
es útil para inicializar un
esclavo cuando tiene una imagen del maestro y ha guardado el
log y el desplazamiento correspondientes a la misma. Tras
cargar la imagen en el esclavo, puede ejecutar CHANGE
MASTER TO
MASTER_LOG_FILE='
en el esclavo.
log_name_on_master
',
MASTER_LOG_POS=log_offset_on_master
Ejemplos:
mysql> CHANGE MASTER TO -> MASTER_HOST='master2.mycompany.com', -> MASTER_USER='replication', -> MASTER_PASSWORD='bigs3cret', -> MASTER_PORT=3306, -> MASTER_LOG_FILE='master2-bin.001', -> MASTER_LOG_POS=4, -> MASTER_CONNECT_RETRY=10; mysql> CHANGE MASTER TO -> RELAY_LOG_FILE='slave-relay-bin.006', -> RELAY_LOG_POS=4025;
El primer ejemplo cambia el maestro y las coordenadas del log binario del maestro. Esto se usa cuando quiere preparar el esclavo para replicar el maestro.
El segundo ejemplo muestra una operación que se emplea menos
frecuentemente. Si se usa cuando el esclavo tiene logs
retardados que quiere ejecutar de nuevo por alguna razón.
Para ello, el maestro no necesita ser accesible. Sólo
necesita usar CHANGE MASTER TO
y arrancar
el flujo SQL (START SLAVE SQL_THREAD
).
Incluso puede usar la segunda operación en una configuración
de no replicación con un servidor aislado, no esclavo, para
recuperación de fallos posteriores. Suponga que su servidor
ha fallado y ha restaurado una copia de seguridad. Quiere
volver a ejecutar los logs binarios del servidor (no los logs
retardados, sino los logs binarios regulares), llamados (por
ejemplo) myhost-bin.*
. En primer lugar,
haga una copia de seguridad de los logs binarios en un sitio
seguro, en caso que no siga exactamente el procedimiento
posterior y accidentalmente haga que el servidor purgue los
logs binarios. En MySQL 5.0, use SET GLOBAL
relay_log_purge=0
para seguridad adicional. Cuando
arranca el servidor sin la opción
--log-bin
, En su lugar, use las opciones
--replicate-same-server-id
,
--relay-log=myhost-bin
(para que el
servidor crea que los logs binarios regulares son los logs
retardados), --skip-slave-start
. Cuando el
servidor arranca, ejecute estos comandos:
mysql> CHANGE MASTER TO -> RELAY_LOG_FILE='myhost-bin.153', -> RELAY_LOG_POS=410, -> MASTER_HOST='some_dummy_string'; mysql> START SLAVE SQL_THREAD;
El servidor lee y ejecuta sus propios logs binarios,
permitiendo recuperación de fallos. Una vez que finaliza la
recuperación, ejecute STOP SLAVE
, pare el
servidor, borre master.info
y
relay-log.info
, y reinicie el servidor
con sus opciones originales.
Actualmente, especificar MASTER_HOST
(incluso con un valor de prueba) se necesita para hacer que el
servidor piense que es un esclavo. En el futuro, planeamos
añadir opciones para evitar estas restricciones menores.
LOAD DATA FROM MASTER
Este comando toma una muesta del maestro y la copia en el
esclavo. Actualiza los valores de
MASTER_LOG_FILE
y
MASTER_LOG_POS
para que el esclavo comience
la replicación desde la posición correcta. Cualquier regla
de exclusión de tabla y base de datos especificada con las
opciones --replicate-*-do-*
y
--replicate-*-ignore-*
se tienen en cuenta.
--replicate-rewrite-db
no se tienen en cuenta. Esto es porque un
usuario puede, con esta opción, configurar un mapeo no único
tal como --replicate-rewrite-db=db1->db3
y --replicate-rewrite-db=db2->db3
, que
puede confundir al esclavo al cargar tablas del maestro.
El uso de este comando está sujeto a las siguientes condiciones:
Esto sólo funciona con tablas MyISAM
.
Intentos de cargar de una tabla no
MyISAM
provoca el siguiente error:
ERROR 1189 (08S01): Net error reading from master
Adquiere un bloqueo de lectura global del maestro al tomar la muesta, que evita actualizaciones en el maestro durante la operación de carga.
En el futuro, planeamos hacer este comando compatible con
tablas InnoDB
y eliminar la necesidad de
bloqueo de lectura global usando una copia de seguridad no
bloqueante en línea.
Si está cargando tablas grandes, puede tener que incrementar
los valores de net_read_timeout
y
net_write_timeout
en los servidores
esclavos y maestros. Consulte
Sección 5.3.3, “Variables de sistema del servidor”.
Tenga en cuenta que LOAD DATA FROM MASTER
no copia ninguna tabla de la base de
datos mysql
. Esto hace fácil tener
distintos usuarios y permisos en el maestro y el esclavo.
El comando LOAD DATA FROM MASTER
necesita
la cuenta de replicación que se usa para conectar con el
maesto para tener los permisos RELOAD
y
SUPER
en el maestro y el permiso
SELECT
para todas las tablas maestras que
quiera cargar. Todas las tablas del maestro para las que el
usuario no tiene el permiso SELECT
se
ignoran por LOAD DATA FROM MASTER
. Esto es
porque el maestro las oculta del usuario: LOAD DATA
FROM MASTER
llama SHOW DATABASES
para conocer las bases de datos a cargar por parte del
maestro, pero SHOW DATABASES
retorna sólo
bases de datos para las que el usuario tenga algunos permisos.
Consulte Sección 13.5.4.6, “Sintaxis de SHOW DATABASES
”. En la parte del
esclavo, el usuario que ejecuta LOAD DATA FROM
MASTER
debe tener permisos para crear y borrar bases
de datos y tablas que se copien.
LOAD TABLE tbl_name
FROM MASTER
Transfiere una copia de la tabla desde el maestro al esclavo.
Este comando se implementa principalmente para depurar
LOAD DATA FROM MASTER
. Requiere que la
cuenta usada para conectar con el servidor maestro tenga los
permisos RELOAD
y SUPER
en el maestro y el permiso SELECT
en la
tabla maestra a cargar. En la parte del esclavo, el usuario
que ejecuta LOAD TABLE FROM MASTER
debe
tener permisos para borrar y crear la tabla.
Las condiciones para LOAD DATA FROM MASTER
se aplican aquí. Por ejemplo, LOAD TABLE FROM
MASTER
funciona sólo en tablas
MyISAM
. También se aplican las notas sobre
timeouts para LOAD DATA FROM MASTER
.
SELECT MASTER_POS_WAIT('master_log_file
',master_log_pos
)
Esto es una función, no un comando. Se usa para asegurar que el esclavo ha leído y ejecutado eventos hasta la posición dada en el log binario del maestro. Consulte Sección 12.9.4, “Funciones varias” para una descripción completa.
RESET SLAVE
Hace que el esclavo olvide su posición de replicación en el
log binario del maestro. Este comando se debe usar para un
inicio limpio: borra los ficheros
master.info
y
relay-log.info
, todos los logs
retardados, y arranca un nuevo log retardado.
Nota: Todos los logs
retardados se borran, incluso si no se han ejecutado
completamente por parte del flujo SQL esclavo . (Esta es una
condición que es probable que exista en un esclavo de
replicación si ha ejecutado un comando STOP
SLAVE
o si el esclavo está muy cargado.)
La información de conexión almacenada en el fichero
master.info
se resetea inmediatamente
usando cualquier valor especificado en las opciones de
arranque correspondientes. Esta información incluye valores
tales como el equipo maestro, puerto, usuario y contraseña
del maestro. Si el flujo SQL esclavo está en medio de una
operación de replicar tablas temporales cuando se paró, y se
ejecuta RESET SLAVE
, estas tablas
temporales replicadas se borran en el esclavo.
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = n
Ignora los siguientes n
eventos del
maestro. Esto es útil para recuperarse de paradas de
replicación provocadas por un comando.
Este comando es válido sólo cuando el flujo esclavo no está en ejecución. De otro modo, produce un error.
SHOW SLAVE STATUS
Proporciona información de estado de parámetros esenciales
de los flujos esclavos. Si ejecuta este comando usando el
cliente mysql puede usar un terminador de
comando \G
en lugar de punto y coma para
obtener una salida vertical más legible:
mysql> SHOW SLAVE STATUS\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: localhost Master_User: root Master_Port: 3306 Connect_Retry: 3 Master_Log_File: gbichot-bin.005 Read_Master_Log_Pos: 79 Relay_Log_File: gbichot-relay-bin.005 Relay_Log_Pos: 548 Relay_Master_Log_File: gbichot-bin.005 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 79 Relay_Log_Space: 552 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 8
SHOW SLAVE STATUS
retorna los siguientes
campos:
Slave_IO_State
Una copia del campo State
se la salida
de SHOW PROCESSLIST
para el flujo
esclavo de entrada/salida. Le dice si el flujo está
tratando de conectar con el maestro, esperando eventos del
maestro, reconectando con el maestro, etc. Los estados
posibles se listan en
Sección 6.3, “Detalles de la implementación de la replicación”.
Consultar este campo es necesario porque, por ejemplo, el
flujo puede estar en ejecución pero intentando conectar
con el maestro sin éxito; sólo este campo le muestra el
problema de conexión. El estado del flujo SQL no se copia
porque es más simple. Si está en ejecución, no hay
problema; si no es así, puede encontrar el error en el
campo Last_Error
(descrito
posteriormente).
Master_Host
Equipo maestro actual
Master_User
Usuario actual usado para conectar con el maestro.
Master_Port
Puerto maestro actual.
Connect_Retry
Valor actual de la opción
--master-connect-retry
.
Master_Log_File
Nombre del fichero de log binario desde el que está leyendo actualmente el flujo de entrada/salida.
Read_Master_Log_Pos
La posición hasta la que el flujo de entrada/salida ha leído en el log binario del maestro.
Relay_Log_File
Nombre del fichero de log retardado desde el que el flujo SQL está leyendo y ejecutando actualmente.
Relay_Log_Pos
La posición hasta la que el flujo SQL ha leído y ejecutado en el flujo en el log retardado actual.
Relay_Master_Log_File
Nombre del log binario maestro que contiene la mayoría de los eventos recientes ejecutados por el flujo SQL.
Slave_IO_Running
Si el flujo de entrada/salida está activo.
Slave_SQL_Running
Si el flujo SQL está activo.
Replicate_Do_DB, Replicate_Ignore_DB
La lista de bases de datos especificadas con las opciones
--replicate-do-db
y
--replicate-ignore-db
, si se dió
alguna.
Replicate_Do_Table, Replicate_Ignore_Table,
Replicate_Wild_Do_Table,
Replicate_Wild_Ignore_Table
Lista de tablas especificadas con las opciones
--replicate-do-table
,
--replicate-ignore-table
,
--replicate-wild-do-table
, y
--replicate-wild-ignore_table
, si se
dió alguna.
Last_Errno, Last_Error
Número y mensaje de error retornados por la última
consulta ejecutada. Un número de error 0 y mensaje vacío
significa “no error.” Si el valor
Last_Error
no está vacío, también
aparece como mensaje en el log de errores del esclavo.
Por ejemplo:
Last_Errno: 1051 Last_Error: error 'Unknown table 'z'' on query 'drop table z'
El mensaje indica que la tabla z
existió en el maestro y se borró allí, pero no existió
en el esclavo, así que DROP TABLE
falló en el esclavo. (Esto puede ocurrir, por ejemplo, si
olvidó copiar la tabla en el esclavo al configurar la
replicación.)
Skip_Counter
El último valor usado para
SQL_SLAVE_SKIP_COUNTER
.
Exec_Master_Log_Pos
La posición del último evento ejecutado por el flujo SQL
del log binario del maestro
(Relay_Master_Log_File
).
(Relay_Master_Log_File
,
Exec_Master_Log_Pos
) en el log binario
del maestro correspondiente a
(Relay_Log_File
,
Relay_Log_Pos
) en el log retardado.
Relay_Log_Space
Tamaño total combinado de todos los logs retardados existentes.
Until_Condition, Until_Log_File,
Until_Log_Pos
Valores especificados en la cláusula
UNTIL
del comando START
SLAVE
.
Until_Condition
tiene estos valores:
None
si no se especificó
UNTIL
Master
si el esclavo está leyendo
hasta una posición dada en el log binario del maestro
Relay
si el esclavo está leyendo
hasta una posición dada en su log retardado
Until_Log_File
y
Until_Log_Pos
indica los valors del
nombre de fichero y posición que definen el punto en que
el flujo SQL para su ejecución.
Master_SSL_Allowed, Master_SSL_CA_File,
Master_SSL_CA_Path, Master_SSL_Cert, Master_SSL_Cipher,
Master_SSL_Key
Estos campos muestran los parámetros SSL usados por el esclavo para conectar con el maestro, si hay algo.
Master_SSL_Allowed
tiene estos valores:
Yes
si se permite conexión SSL con
el maestro
No
si no se permite una conexión
SSL con el maestro
Ignored
se se permite una conexión
SSL pero el servidor esclavo no tiene soporte SSL
activdo
Los valores de los otros campos relacionados con SSL se
corresponden con los valores de las opciones
--master-ca
,
--master-capath
,
--master-cert
,
--master-cipher
, y
--master-key
.
Seconds_Behind_Master
Este campo indica el “retardo” del esclavo. Cuando el flujo SQL esclavo está en ejecución (procesando actualizaciones), este campo es el número de segundos que han pasado desde el momento del evento más reciente del maestro ejecutado por este flujo. Cuando ese flujo lo atrapa el flujo de entrada/salida esclavo y pasa a espera de más eventos del flujo de entrada/salida este campo es cero. En resumen, este campo mide en segundos la diferencia temporal entre el flujo SQL esclavo y el flujo de entrada/salida esclavo.
Si la conexión de red entre maestro y esclavo es rápida,
el flujo de entrada/salida esclavo es muy cercano al
maestro, así que este campo es una buena aproximación de
cuanto tarda el flujo SQL esclavo en compararse con el
maestro. Si la red es lenta, esta
no es una buena
aproximación, el flujo SQL esclavo puede verse atrapado a
menudo por un flujo de entrada/salida esclavo lento , así
que Seconds_Behind_Master
a menudo
muestra un valor de 0, incluso si el flujo de
entrada/salida se compara posteriormente con el maestro.
En otras palabras, esta columna es
útil sólo para redes rápidas.
Esta computación de diferencia temporal funciona incluso
si el esclavo y maestro no tienen relojes idénticos ( la
diferencia de tiempo se computa cuando el flujo de
entrada/ salida del esclavo arranca, y se asume como que
permance constante desde ese momento).
Seconds_Behind_Master
es
NULL
(que significa
“desconocido”) si el flujo SQL esclavo no
está en ejecución, o si el flujo de entrada/salida
esclavo no está en ejecución o no conectado con el
maestro. Por ejemplo si el flujo de entrada/salida esclavo
está durmiendo durante
master-connect-retry
segundos antes de
reconectar, NULL
se muestra, ya que el
esclavo no puede saber lo que hace el maestro, y así no
puede asegurar el retardo.
Este campo tiene una limitación. El timestamp se preserva
a través de la replicación, lo que significa que, si un
maestr M1 es un esclavo de M0, cualquier evento desde el
log binario de M1 que se origine al replicar un evento del
log binario M0 tiene el timestamp del evento. Esto permite
a MySQL replicar TIMESTAMP
con éxito.
Sin embargo, la desventaja para
Seconds_Behind_Master
es que si M1
también recibe actualizaciones directas de los clientes,
el valor se desvía aleatoriamente, ya que a veces el
último evento de M1 es de M0 y otras de actualización
directa, y por lo tanto es el timestampo más reciente.
START SLAVE [thread_type
[,thread_type
] ... ] START SLAVE [SQL_THREAD] UNTIL MASTER_LOG_FILE = 'log_name
', MASTER_LOG_POS =log_pos
START SLAVE [SQL_THREAD] UNTIL RELAY_LOG_FILE = 'log_name
', RELAY_LOG_POS =log_pos
thread_type: IO_THREAD | SQL_THREAD
START SLAVE
sin opciones arranca los flujos
esclavos. El flujo de entrada/salida lee consultas del
servidor maestro y las almacena en el log retardado. El flujo
SQL lee el log retardado y ejecuta las consultas.
START SLAVE
require el permiso
SUPER
.
Si START SLAVE
tiene éxito al arrancar los
flujos esclavos, retorna sin ningún error. Sin emgargo,
incluso en tal caso, puede ser que el flujo esclavo arranqu y
luego pare (por ejemplo, porque no puede conectar con el
maestro o leer sus logs binarios, o algún otro problema).
START SLAVE
no le advierte acerca de esto.
Debe chequear el log de errores esclavo para mensajes de error
generados por los flujos esclavos, o chequear que estén
ejecutándos correctamente con SHOW SLAVE
STATUS
.
En MySQL 5.0, puede añadir las opciones
IO_THREAD
y SQL_THREAD
al comando para decir qué flujo arrancar.
Una cláusula UNTIL
puede añadirse para
especificar que el esclavo debe arrancar y ejecutar hasta que
el flujo SQL llegue a un punto dado en los logs binarios del
maestro o en los logs retardados del esclavo. Cuando el flujo
SQL llega a ese punto, para. Si la opción
SQL_THREAD
se especifica en el comando,
arranca sólo el flujo SQL. De otro modo, arranca ambos flujos
esclavos. Si el flujo SQL está en ejecución, la cláusula
UNTIL
se ignora y se muestra una
advertencia.
Para una cláusula UNTIL
, debe especificar
nombre de fichero de log y posición. No mezcle opciones de
maestro y log retardado.
Cualquier condición UNTIL
se resetea
mediante un comando STOP SLAVE
, un comando
START SLAVE
que no incluya cláusula
UNTIL
, o reinicio de servidor.
La cláusula UNTIL
puede ser útil para
depurar replicación, o para que la replicación proceda justo
antes del punto en que quiera evitar tener un esclavo
replicando un comando. Por ejemplo, si se ejecuta un comando
DROP TABLE
no deseado, puede usar
UNTIL
para decir al esclavo que ejecute
hasta ese punto pero no más. Para encontrar el evento, use
mysqlbinlog con los logs maestros o los
logs retardados del esclavo, o usando un comando SHOW
BINLOG EVENTS
.
Si está usando UNTIL
para tener las
consultas replicadas por el proceso esclavo en secciones, se
recomienda que arranque el esclavo con la opción
--skip-slave-start
para evitar que el flujo
SQL se ejecute cuando arranque el servidor. Es probablemente
mejor usar esta opción con un fichero de opciones en lugar
que en la línea de comandos, así que un reinicio inesperado
del servidor no hace que se olvide.
El comando SHOW SLAVE STATUS
incluye campos
de salida que muestran los valores actuales de la condición
UNTIL
.
En versiones prévias de MySQL, este comando se llamó
SLAVE START
cuyo uso todavía se acepta en
MySQL 5.0 por compatibilidad con versiones anteriores, pero
ahora está obsoleto.
STOP SLAVE [thread_type
[,thread_type
] ... ] thread_type: IO_THREAD | SQL_THREAD
Para el flujo esclavo. STOP SLAVE
necesita
el permiso SUPER
.
Como START SLAVE
, este comando puede usarse
con las opciones IO_THREAD
y
SQL_THREAD
para nombrar el flujo o flujos a
parar.
En versiones prévias de MySQL, este comando se llamó
SLAVE STOP
. Su uso se acepta en MySQL 5.0
por compatibilidad con versiones anteriores, pero ahora está
obsoleto.
MySQL 5.0 proporciona soporte para comandos preparados en la parte del servidor. Este soporte aprovecha del protocolo binario cliente-servidor implementado en MySQL 4.1, dado que use una interfaz de programación cliente apropiada. Las interfaces candidatas incluyen la biblioteca de la API de C de MySQL y MySQL Connector/NET. Por ejemplo, la API C proporciona un conjunto de llamadas de funciones que prepararn su API de comandos preparados. Consulte Sección 24.3.4, “Sentencias preparadas de la API C”. Otras interfaces de lenguajes pueden proporcionar soporte para comandos preparados que usen el protocolo binario enlazando la biblioteca cliente C, un ejemplo es la extensión mysqli extension in PHP 5.0.
Una interfaz SQL alternativa para comandos preparados está disponible Su intefaz no es tan eficiente como usar el protocolo binario mediante una API de comandos preparados, pero no necesita programación porque está disponible directamente a nivel SQL:
Puede usarlo cuando no haya interfaz programable diponible
Puede usarlo desde cualquier programa que le permita enviar comandos SQL al servidor, tales como el programa cliente mysql .
Puede usarlo incluso si el cliente está usando una antigua versión de la biblioteca cliente. El único requerimiento es que sea capaz de conectar a un servidor lo suficientemente reciente para soporta sintaxis SQL para comandos preparados.
La sintaxis SQL para comandos preparados está pensada para usar en situaciones como la siguiente:
Puede querer testear cómo fucionan los comandos preparados en su aplicación antes de codificar la aplicación. O quizás una aplicación tenga un problema ejecutando comandos preparados y quiera determinar interactivamente cuál es el problema.
Quiere crear un test de uso que describa un problema que está teniendo con comandos preparados, así que puede perparar un reporte de error.
Necesita usar comandos preparados pero no tiene acceso a la API de programación que los soporta.
La sintaxis SQL para comandos preparados se abasa en tres comandos SQL:
PREPAREstmt_name
FROMpreparable_stmt
; EXECUTEstmt_name
[USING @var_name
[, @var_name
] ...]; {DEALLOCATE | DROP} PREPAREstmt_name
;
El comando PREPARE
prepara un comando y le
asigna un nombre, stmt_name
, con el que
referirse al comando posteriormente. Los nombres de comando no son
sensibles a mayúsculas.
preparable_stmt
es una cadena literal o
una variable de usuario que contenga el texto del comando. El
texto debe representar un comando SQL único, no varios. Dentro
del comando, pueden usarse carácteres '?
' como
marcadores de parámetros para indicar dónde estarán los valores
en la consulta posterior cuando la ejecute. Los carácteres
'?
' no deben delimitarse con comillas, incluso
si pretende ligarlos con valores de cadenas.
Si un comando preparado con ese nombre existe, se elimina implícitamente antes que se prepare el nuevo comando. Esto significa que si el nuevo comando contiene un error y no puede preparase, se retorna un error y no existe un comando con el nombre dado.
El alcance de los comandos preparados es la sesión de cliente dentro de la que se crea. Otros clintes no pueden verlos.
Tras preparar un comando, lo ejecuta con un comando
EXECUTE
que se refiere al nombre de comando
preparado. Si el comando preparado contiene cualquier marcador de
parámetro, debe añadir una cláusula USING
que liste las variables de usuario conteniendo los valores a ligar
con los parámetros. Los valores de parámetros pueden
proporcionarse sólo por variables de usuario, y la cláusula
USING
debe nombrar exactamente tantas variables
como el número de marcadores de parámetros en el comando.
Puede ejecutar un comando preparado dado varias veces, pasando distintas variables al mismo o configurando las variables con distintos valores para cada ejecución.
Para eliminar un comando preparado, use el comando
DEALLOCATE PREPARE
. Tratar de ejecutar un
comando preparado tras borrarlo provoca un error.
Si termina una sesión de cliente sin borrar un comando preparado préviamente, el servidor lo borra automáticamente.
Los siguientes comandos SQL pueden usarse en comandos preparados:
CREATE TABLE
, DELETE
,
DO
, INSERT
,
REPLACE
, SELECT
,
SET
, UPDATE
, y la mayoría
de comandos SHOW
. Otros comandos no se
soportan todavía.
Los siguientes ejemplos muestran dos formas equivalentes de preparar un comando que calcula la hipotenusa de un triángulo dadas las longitudes de los dos catetos.
El primer ejemplo muestra cómo crear un comando preparado usando una cadena literal para proporcionar el texto del comando:
mysql> PREPARE stmt1 FROM 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse'; mysql> SET @a = 3; mysql> SET @b = 4; mysql> EXECUTE stmt1 USING @a, @b; +------------+ | hypotenuse | +------------+ | 5 | +------------+ mysql> DEALLOCATE PREPARE stmt1;
El segundo ejemplo es similar, pero proporciona el texto del comando como variable de usuario:
mysql> SET @s = 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse'; mysql> PREPARE stmt2 FROM @s; mysql> SET @a = 6; mysql> SET @b = 8; mysql> EXECUTE stmt2 USING @a, @b; +------------+ | hypotenuse | +------------+ | 10 | +------------+ mysql> DEALLOCATE PREPARE stmt2;
La sintaxis SQL para comandos preparados no puede usarse anidada.
Esto es, un comando pasado a PREPARE
no puede
ser el mismo un comando PREPARE
,
EXECUTE
, o DEALLOCATE
PREPARE
.
Además, la sintaxis SQL para comandos preparados es distinta de
la usada en llamadas a la API de comandos preparados. Por ejemplo,
use la función mysql_stmt_prepare()
de la API
C para preparar un comando PREPARE
,
EXECUTE
, o DEALLOCATE
PREPARE
.
La sintaxis SQL para comandos preparados no puede usarse dentro de procedimientos almacenados y funciones.
Ésta es una traducción del manual de referencia de MySQL, que puede encontrarse en dev.mysql.com. El manual de referencia original de MySQL está escrito en inglés, y esta traducción no necesariamente está tan actualizada como la versión original. Para cualquier sugerencia sobre la traducción y para señalar errores de cualquier tipo, no dude en dirigirse a mysql-es@vespito.com.