Está en la página 1de 107

Administracin de bases de datos: MySQL 5.

1
Indice
1. Introduccin......................................................................................................................3
1.1 Bases de datos relacionales.......................................................................................3
1.2 Conceptos bsicos.....................................................................................................3
1.3 MySQL........................................................................................................................4
1.3.1 Sistema de ersiones...........................................................................................!
1.3.2 Licencia................................................................................................................"
1.4 #r$uitectura L#M%......................................................................................................"
2. #r$uitectura......................................................................................................................&
3. SQL y MySQL................................................................................................................11
3.1 'ipos de instrucciones..............................................................................................11
3.2 Instrucciones bsicas...............................................................................................11
3.2.1 Consultas (S)L)C'*..........................................................................................11
3.2.2 Seleccionar re+istros (,-).)*.........................................................................13
3.2.3 )nla/ar tablas (01I2*.........................................................................................13
3.2.4 Modi3icar datos (I2S).'4 5%6#')4 y 6)L)')*...............................................1!
3.2.! Crear bases de datos4 tablas e 7ndices..............................................................1&
3.2." Cambiar dise8o de tablas...................................................................................19
3.2.: Borrar bases de datos y tablas..........................................................................19
3.3 Cambios de dise8o automticos..............................................................................2;
3.4 Inspeccionar meta datos (S-1,*............................................................................2;
3.! 'ablas I2<1.M#'I12=SC-)M#...........................................................................22
4. Caracter7sticas espec73icas de MySQL..........................................................................2!
4.1 'ipos de tablas.........................................................................................................2!
4.1.1 MyIS#M..............................................................................................................2"
4.1.2 Inno6B................................................................................................................2&
4.1.3 MyIS#M s Inno6B............................................................................................3;
4.1.4 M)M1.>...........................................................................................................31
4.1.! 2B6CL5S')....................................................................................................32
4.2 'ipos de datos..........................................................................................................33
4.2.1 )nteros (???I2'*.................................................................................................33
4.2.2 )nteros #5'1=I2C.)M)2'.............................................................................34
4.2.3 6atos binarios (BI' y B11L*..............................................................................3!
4.2.4 2@meros en coma 3lotante (<L1#' y 615BL)*...............................................3!
4.2.! 2@meros de coma 3iAa (6)CIM#L*.....................................................................3"
4.2." <ecBa y Bora (6#')4 'IM)4 6#')'IM)4 'IM)S'#M%*...................................3"
4.2.: Cadenas de caracteres (C-#.4 C#.C-#.4 ???')D'*....................................3:
4.2.& 6atos binarios (???BL1B y BI'*........................................................................4;
4.2.9 1tros tipos..........................................................................................................4;
4.2.1; 1pciones y atributos.........................................................................................41
4.2.11 6atos EIS.........................................................................................................41
!. Modos SQL.....................................................................................................................44
". 6ise8o de bases de datos..............................................................................................!;
".1 2ormali/acin...........................................................................................................!1
".2 Inte+ridad re3erencial................................................................................................!4
:. Fndices............................................................................................................................!&
:.1 Conceptos bsicos...................................................................................................!&
:.2 )structuras de datos................................................................................................."2
:.3 Fndices y tipos de tablas..........................................................................................."4
:.3.1 'ablas MyIS#M.................................................................................................."4
:.3.2 'ablas -)#%......................................................................................................"!
:.3.3 'ablas Inno6B...................................................................................................."!
:.4 Fndices <ullGte?t........................................................................................................."!
&. 1ptimi/acin de consultas.............................................................................................":
&.1 Eestin interna de las consultas..............................................................................":
&.1.1 CacBe de consultas............................................................................................":
&.1.2 #nlisis sintctico y optimi/acin.......................................................................":
&.2 )D%L#I2 S)L)C'...................................................................................................."&
&.3 Caracter7sticas del optimi/ador................................................................................:"
&.4 Identi3icar consultas lentas.......................................................................................:&
&.! Modi3icar el comportamiento de MySQL..................................................................:9
9. Cistas..............................................................................................................................&2
1;. %rocedimientos #lmacenados......................................................................................&4
1;.1 Sinta?is...................................................................................................................&:
1;.2 Llamadas................................................................................................................&&
1;.3 %armetros y alores de retorno............................................................................&9
1;.4 Cariables................................................................................................................9;
1;.! )ncapsulacin de instrucciones.............................................................................91
1;." Control de 3luAo........................................................................................................91
1;.: Bucles.....................................................................................................................92
1;.& Eestin de errores (Bandlers*.................................................................................93
1;.9 Cursores.................................................................................................................94
11. 'ri++ers........................................................................................................................9"
12. 'ransacciones............................................................................................................1;;
13. .espaldos (bacHups*..................................................................................................1;2
14. #dministracin de accesos y se+uridad.....................................................................1;!
14.1 'ipos de cone?iones.............................................................................................1;!
14.2 #dministracin de accesos...................................................................................1;!
14.3 Creacin de bases de datos4 usuarios y sus priile+ios......................................1;"
14.4 Base de datos Imys$lI...........................................................................................1;:
1. Introduccin
1.1 Bases de datos relacionales
5na base de datos relacional es un conAunto ordenado de datos4 los cuales normalmente
estn almacenados en uno o ms 3icBeros. Los datos estn estructurados en tablas4 y
estas pueden tener re3erencias cru/adas. La e?istencia de estas re3erencias o relaciones
es lo $ue da el nombre de relacional a este tipo de bases de datos.
%or eAemplo4 una base de datos puede almacenar in3ormacin a cerca de los clientes de
una compa87a. La bases de datos estar7a compuesta de una tabla de clientes (nombre4
direccin4 ...etc*4 una tabla con los productos $ue la empresa o3rece4 y 3inalmente4 una
tabla con los pedidos de la empresa. # traJs de la tabla de pedidos ser7a posible acceder
a los datos de las otras dos tablas (por eAemplo4 a traJs de los identi3icadores de cliente y
producto*.
Como eAemplos de sistemas de bases de datos relacionales tenemos MySQL4 1racle4
%ost+reSQL4 Microso3t SQL Serer4 IBM 6B24 ... etc. )stos sistemas proporcionan
Berramientas $ue permiten almacenar los datos de manera e3iciente4 procesar las
queries, anali/ar y ordenar los datos4 ... etc. #dems4 todo esto Ba de ser posible $ue
3uncione sobre una red4 por lo $ue normalmente Bablaremos de un seridor de bases de
datos.
Como contraposicin a las bases de datos relacionales tenemos las bases de datos
orientadas a obAetos. )stas pueden almacenar obAetos indiiduales sin estar estructurados
en tablas. )stas bases de datos permiten acceder directamente a obAetos de3inidos en el
entorno de un len+uaAe de pro+ramacin (%-%4 CKK4 0aa4 ...*. # pesar de $ue Ban Babido
una serie de tendencias Bacia bases de datos relacionales en los @ltimos a8os4 estas solo
Ban encontrado pe$ue8os nicBos de mercado.
1.2 Conceptos bsicos
>a Bemos mencionado $ue las tablas son las estructuras donde se +uardan los datos.
Cada l7nea de una tabla se llama re+istro (data record*4 y su estructura iene determinada
por la de3inicin de la tabla. %or eAemplo4 en una tabla de direcciones de usuarios cada
re+istro contendr campos (fields* para el nombre4 apellido4 calle4 ... %ara cada campo Bay
una serie de tipos de datos prede3inidos $ue determinan con e?actitud la in3ormacin $ue
puede ser almacenada.
La descripcin de una base de datos consistente en arias tablas con todos sus campos4
relaciones e 7ndices se llama un modelo de base de datos (database model*. )ste modelo
de3ine como se tienen $ue construir las estructuras de datos y al mismo tiempo especi3ica
el 3ormato en $ue los datos deben ser almacenados.
2ormalmente4 las tablas almacenan los datos sin un orden concreto4 y de BecBo el orden
suele ser en el $ue Ban sido introducidos. Sin embar+o4 para poder usar los datos de una
manera @til se necesita $ue estos puedan ser ordenados si+uiendo uno o ms criterios.
%or eAemplo4 si disponemos de una tabla de clientes4 podemos $uerer obtener la lista de
clientes $ue Ban comprado un determinado producto en los @ltimos 12 meses4 ordenados
por el cdi+o postal.
%ara crear una lista as7 se debe eAecutar una consulta (query* en la base de datos. )l
resultado es a su e/ una tabla $ue se aloAa en memoria .#M. )stas consultas se
reali/an en el len+uaAe SQL (Structured Query Language*. # pesar de ser un estandard
para los sistemas de bases de datos relacionales4 cada 3abricante o3rece sus
es?rtensiones particulares SQL4 con lo $ue el obAetio de la compatibilidad no siempre se
alcan/a.
Cuando las tablas crecen Basta un tama8o considerable4 la elocidad de las consultas
depende si+ni3icatiamente de si e?iste un 7ndice (index* $ue proporciona el orden de los
datos de un determinado campo. Concretamente4 un 7ndice es una tabla $ue @nicamente
almacena in3ormacin sobre el orden de los re+istros de una tabla. 5n 7ndice corresponde
a un campo clae (key*.
Los 7ndices aceleran las consultas4 pero a un coste. %rimero4 re$uieren un espacio de
almacenamiento e?tra4 y se+undo4 deben ser actuali/ados cada e/ $ue la tabla es
modi3icada.
Las claes y los 7ndices pueden ser primarios4 y en ese caso se tienen $ue cumplir la
condicin de $ue Baya una @nica re3erencia para cada re+istro de la tabla. 2ormalmente
las claes primarias se representan con un n@mero cuyo alor es asi+nado
automticamente por la base de datos cada e/ se crea un re+istro (autoincrement*
1.! MySQL
5n poco de BistoriaL
)l len+uaAe SQL 3ue creado por IBM en 19&1. )s un estndar de los sistemas
relacionales. )st aprobado como estndar #2SIMIS1 desde 19&:.N
MySQL nace como un proyecto para crear un sistema de bases de datos de
so3tOare libre por parte de la empresa sueca MySQL #B en 199!
MySQL Ba sido ad$uirida por Sun Microsystems en enero de 2;;&.
6e a$u7 en adelante se entiende $ue toda le in3ormacin correspondiente a MySQL se
re3iere a la ersin !.;. 6e todas maneras4 la mayor7a de las caracter7sticas se pueden
aplicar a otras ersiones4 especialmente a la pr?ima ersin !.1.
MySQL es un sistema de bases de datos relacional. # pesar de su popularidad4 este
sistema toda7a no tiene al+unas de las caracter7sticas $ue poseen otros sistemas
comerciales. Sin embar+o4 estas di3erencias son cada e/ ms pe$ue8as. #l+unas de las
compa8ias $ue usan MySQL son >aBooP4 BBC 2eOs4 C2)'4 2oHia4 >ou'ube4 <licHr4
Eoo+le4 ...
Las principales caracter7stica de MySQL sonL
Sistema de base de datos relacionales
#r$uitectura clienteMseridor
Compatibilidad con SQL. )n este momento soporta SQLL2;;34 aun$ue tiene mucBas
e?tensiones
SubS)L)C'S. )s capa/ de procesar consultas del tipoL
SELECT * FROM table1 WHERE x IN (SELECT y FROM table2)
Cistas (Views*. Son consultas SQL cuyos resultados son tratados como si 3ueran una
tabla di3erente4 permitiendo tener di3erentes istas de una misma tabla.
Stored %rocedures. Son consultas SQL $ue estn almacenadas en la base de datos.
Como olas istas4 pueden incrementar la e3iciencia y simpli3icar la administracin de la
base de datos.
'ri++ers. Son comandos SQL $ue se eAecutan automticamente en ciertas
operaciones (I2S).'4 5%6#') y 6)L)')*.
5nicode. #dems4 MySQL soporta casi cual$uier tipo de codi3icacin de caracteres4
como LatinG1 y LatinG2.
<ullGte?t searcB. )sta caracter7stica acelera y simpli3ica la b@s$ueda de palabras $ue
se encuentran almacenadas en campos de tipo te?to.
.eplicacin. %ermite copiar el contenido de una base de datos a m@ltiples
ordenadores. )sta caracter7stica se usa para meAorar la proteccin contra 3allos4 y
parta acelerar las consultas.
'ransacciones. 5na transaccin es un conAunto de operaciones sobre una base de
datos $ue 3uncionan como un blo$ue. )s sistema ase+ura $ue o bien se Ban eAecutado
todas las operaciones4 o nin+una. )s to es lido incluso si Bay una ca7da del sistema4
un 3allo elJctrico4 o cual$uier otro desastre.
.estricciones sobre claes e?ternas (foreign keys*. Son re+las con las $ue se ase+ura
la inte+ridad de las relaciones entre tablas.
Len+uaAes de pro+ramacin. -ay un +ran n@mero de #%Is y librer7as para desarrollar
aplicaciones MySQL. %or eAemplo4 se pueden usar len+uaAes como C4 CKK4 0aa4 %erl4
%-%4 %ytBon y 'cl.
16BC. %ermite $ue MySQL sea usada con la inter37cie 16BC de Microso3t4 lo $ue
Bace $ue pueda ser usada por len+uaAes como 6epBi4 CisualBasic4 ...
Independiente de plata3orma. )l seridor MySQL puede 3uncionar sobre una ariedad
de sistemas operatios como Mac 1S D4 Linu?4 Microso3t ,indoOs4 y todas las
ariastes 5ni? (#ID4 BS6I4 <reeBS64 -%G5D4 1penBS64 SEI4 Sun Solaris*
Sin embar+o4 a pesar de esta importante lista de caracter7sticas4 MySQl tiene una serie de
limitacionesL
Cuando MySQL usa las tablas del tipo MyIS#M4 el sistema de blo$ueo (locking* de
datos solo 3unciona para tablas enteras. )so si+ni3ica $ue si $ueremos modi3icar una
tabla y no $ueremos $ue nadie ms pueda inter3erir en la operacin4 la @nica maneras
es blo$uear totalmente el acceso a la tabla entera. )ste problema se puede resoler
usando tablas del tipo Inno6B $ue soportan blo$ueo por re+istro.
MySQL no permite a8adir tipos de datos de3inidos por el usuario.
MySQL no soporta DML.
MySQL no o3rece 3uncionalidad para aplicaciones en tiempo real.
)l sistema de tri++ers a@n no est maduro.
1.!.1 Sistema de "ersiones
Las ersiones de MySQL se identi3ican con los si+uientes atributosL
#lpBa. )stas ersiones estn en pleno desarrollo y por lo tanto se pueden esperar
nueas 3uncionalidades4 y cambios $ue las Ba+an incompatibles con ersiones
anteriores. 'ambiJn es probable $ue ten+an errores seeros.
Beta. La ersin est casi completa4 pero no Ba sido probada e?tensiamente. >a no
se introducirn +randes cambios.
Eamma. La ersin Beta Ba alcan/ado cierta estabilidad. Se resolern los errores
$ue apare/can. 'ambiJn denominada Release Candidate (RC).
enerally !"ailable (E#*. )sta ersin ya puede ser usada en produccin y en
entornos donde la 3iabilidad es cr7tica. )n estos momentos corresponde a la ersin
!.;.
La Bistoria de MySQL desde el punto de sus ersiones Ba sido la si+uiente (actuali/ada a
24M;4M2;;&*L
3.23L )nero de 2;;1
4.;L Mar/o de 2;;3
4.1L 1ctubre de 2;;4
!.;L 1ctubre 2;;!
)sta ersin es actualmente la enerally !"ailable4 y por lo tanto la
recomendada para entornos de produccin.
)n esta ersin se incorporaron caracter7sticas tan importantes como tri++ers y
stored procedures.
!.1L Boy (!.1.24*
)sta ersin est en estado de Release Candidate
".;L Boy (".;.4*
)sta ersin est en estado #lpBa y por lo tanto leAos de poder usada.
Incluir el nueo motor de almacenamiento <alcon
1.!.2 Licencia
5na de las caracter7sticas ms atractias de MySQL es su licencia. MySQL es un
proyecto de so3tOare libre. 6esde 0unio de 2;;; se libera baAo la licencia E%L (#$
%ublic License*. Sin embar+o4 si se $uiere usar MySQL para un 3in comercial sin la
necesidad de proporcionar el cdi+o 3uente de nuestra aplicacin4 entonces se puede
comprar una licencia comercial.
1.# Ar$uitectura LAM%
5na de las ra/ones de la popularidad de MySQL reside en $ue es una pie/a 3undamental
de la ar$uitectura L#M% (Linu? K ApacBe K MySQL K %-%*. )sta ar$uitectura puede
erse resumida en la <i+ura 1.
)sta ar$uitectura es muy utili/ada para seridores de aplicaciones Oeb. Consiste en
ordenadores 3uncionando con el sistema operatio E25MLinu? $ue eAecutan el seridor
Oeb #pacBe y el seridor MySQL. Sobre estos dos 3uncionan aplicaciones Oeb escritas
en el len+uaAe %-%. Su +ran di3usin se debe a $ue todos los componentes son so3tOare
libre y adems a su e3iciencia. La parte central de esta ar$uitectura se podr7a denominar
L#M ya $ue Linu?K#pacBeKMySQL es el denominador com@n sobre el $ue pueden
3uncionar no solo aplicaciones en %-% sino en multitud de len+uaAes como %ytBon o 0aa.
&igura '( !rquitectura L!)%
2. Ar$uitectura
MySQL es un sistema de bases de datos relacional. )so si+ni3ica $ue la in3ormacin est
or+ani/ada en bases de datos4 $ue estn compuestas por tablas4 $ue estn compuestas
por re+istros4 $ue estn compuestos por columnas. )n la <i+ura 2 podemos er dicBa
estructura.
Cada base de datos est compuesta por tablas. Las tablas a su e/ se de3inen con
columnas4 cada una de un tipo de datos di3erente4 $ue con3orman los re+istros. #dems
de los datos $ue almacenamos4 las tablas pueden contener 7ndices4 y al+unas de sus
columnas tienen propiedades especiales como claes primarias y claes 3orneas $ue
permiten establecer relaciones entre las tablas.
Los sistemas $ue maneAan estas estructuras se pueden describir en capas. )n +eneral4
un sistema de bases de datos relacional tienen tres capasL
*lustraci+n ,( -squema de una base de datos relacional
.e+istro
&abla1
Base de datos 1
col1 col3 col2
?
.
.
.
.
.
.
Clae primaria
Fndice
Clae 3ornea
.e+istro
&abla2
col1 col3 col2
.
.
.
.
.
.
Clae primaria
?
&*gura .( las tres ca/as de un
sistema de bases de datos
relacional
La capa de aplicacin es la parte ms e?terna del sistema y es la inter3ice a traJs de la
$ue los usuarios se comunican con el sistema.
La 3uncionalidad central del sistema est en la capa l+ica. )s donde se reali/an todas las
operaciones del sistema. )sta capa se puede re3inar de la si+uiente maneraL
)n esta capa se reali/an arias operaciones. La primera y $ue sire de inter3icie con la
capa de aplicacin es el procesamiento de las instrucciones SQL. 6espuJs Bay dos
mdulosL el maneAo de transacciones4 y la recuperacin despuJs de errores. <inalmente
est la parte $ue se encar+a de traducir las instrucciones SQL en acciones sobre el
almacenamiento de datos.
<inalmente4 la capa 37sica es donde estn almacenados los datos.
&igura 0( 1escri/ci+n de la ca/a l+gica
&igura 2( !rquitectura de )ySQL
)sta ar$uitectura +eneral sire para MySQL4 y en la <i+ura ! podemos er con ms
detalle los aspectos particulares del sistema.
)n esta 3i+ura4 los Connectors representan la #%I $ue MySQL e?pone al usuario4 por lo
$ue representar7a la parte ms cercana al sistema de la capa aplicacin. MySQL dispone
de #%Is para mucBos len+uaAes de pro+ramacin. )n la parte ms baAa podemos er los
elementos &ile system y &iles 3 Logs $ue representan la capa 37sica.
Lo $ue $ueda entre medio es la capa l+ica4 donde reside la 3uncionalidad del seridor. La
<i+ura " muestra como es el 3luAo de eAecucin de una sentencia SQL dentro del seridor.
Bsicamente4 las consultas entran a traJs de un protocolo clienteMseridor proenientes
de las aplicaciones. Las consultas4 pueden ser almacenas en una cacBe para su posterior
reutili/acin. 6espuJs4 si la consulta $ue Ba entrado no se encuentra en la cacBe4 se
procede a su anlisis sintctico4 $ue produce una serie de estructuras de datos $ue se
almacenan en memoria. )n esta 3ase4 puede Bacerse uso de las sentencias preparadas
(%re/ared statements* $ue siren para aumentar la e3iciencia de determinadas consultas.
5na e/ la consulta est preparada4 su eAecucin puede ser directa (no es un S)L)C'* o
bien pasar por el optimi/ador si es de tipo S)L)C'. )sto es as7 ya $ue las instrucciones
S)L)C' suelen ser las potencialmente ms costosas ya $ue pueden necesitar acceder a
tablas enteras o +randes porciones de la base de datos.
5na e/ la sentencia est lista para eAecutarse4 el acceso a los datos se Bace a traJs de
una inter37cie +enJrica de acceso a los datos 37sicos $ue es independiente del tipo de tabla
$ue usemos. > por @ltimo4 la consulta se eAecuta en el subsistema correspondiente al tipo
de tabla $ue estamos accediendo.
&igura 4( &lu5o de e5ecuci+n del ser"idor )ySQL
!. SQL y MySQL
)n esta seccin daremos un bree repaso al len+uaAe SQL. )ste len+uaAe se usa para
3ormular instrucciones al sistema de bases de datos4 incluyendo consultas e instrucciones
para cambiar o borrar obAetos de la base de datos.
!.1 &ipos de instrucciones
Las instrucciones principales de SQL se pueden clasi3icar en tres +ruposL
Data Manipulation Language '(ML): S)L)C'4 I2S).'4 5%6#') y 6)L)')4 y
arias instrucciones ms siren para leer datos de las tablas4 y para almacenar y
modi3icarlos. Son la parte central del len+uaAe.
Data Definition Language (((L*L son las instrucciones $ue siren para dise8ar la
base de datosL C.)#') '#BL)4 #L'). '#BL)4 ...
Data Control Language ((CL*L son las instrucciones usadas para de3inir los
mecanismos de se+uridad de las base de datosL E.#2'4 .)C1Q).
!.2 Instrucciones bsicas
!.2.1 Consultas 'S*L*C&)
)l comando S)L)C' se utili/a para e?traer in3ormacin de las tablas. %or eAemploL
mysql> SELECT * FROM editoriales;
+--------+-------------------+---------------------+
| editID | nomreEdit | ts |
+--------+-------------------+---------------------+
| ! | "r#$o %naya | &''(-!&-'& !)*+,*-) |
| & | "r#$o .laneta | &''(-!&-'& !)*+,*-) |
| + | Crisol | &''(-!&-'& !)*+,*-) |
| ( | Edi/iones Destino | &''(-!&-'& !)*+,*-) |
| - | Editorial Ci0itas | &''(-!&-'& !)*+,*-) |
| 1 | 2l#me | &''(-!&-'& !)*+,*-) |
| !, | .arado3 Liros | &''(-!&-'& !)*+,*-) |
| !4 | Dia5 de Santos | &''(-!&-'& !)*+,*-) |
| !1 | %na6rama | &''(-!&-'& !)*+,*-) |
| &' | Edite/ni/as | &''(-!&-'& !)*+,*-) |
| &! | Desni0el | &''(-!&-'& !)*+,*-) |
| &+ | "redos | &''(-!&-'& !)*+,*-) |
| &( | 7erder | &''(-!&-'& !)*+,*-) |
+--------+-------------------+---------------------+
!+ ro8s in set 9':'' se/;
Se puede usar para contar el n@mero de re+istrosL
mysql> SELECT COUNT(editID) FROM editoriales;
+---------------+
| COUNT(editID) |
+---------------+
| 13 |
+---------------+
1 row in set (0.00 sec)
1 el n@mero de re+istros @nicos (6IS'I2C'*L
mysql> SELECT COUNT(DISTINCT editID) FROM titulos;
+------------------------+
| COUNT(DISTINCT editID) |
+------------------------+
| 7 |
+------------------------+
1 row in set (0.00 sec)
Se puede restrin+ir las columnas $ue se seleccionanL
mysql> SELECT nombreEdit FROM editoriales;
+-------------------+
| nombreEdit |
+-------------------+
| Grupo Anaya |
| Grupo Planeta |
| Crisol |
| Ediciones Destino |
| Editorial Civitas |
| Blume |
| Paradox Libros |
| Diaz de Santos |
| Anagrama |
| Editecnicas |
| Desnivel |
| Gredos |
| Herder |
+-------------------+
13 rows in set (0.00 sec)
Se puede limitar el n@mero de re+istros le7dosL
mysql> SELECT nombreEdit FROM editoriales LIMIT 3;
+---------------+
| nombreEdit |
+---------------+
| Grupo Anaya |
| Grupo Planeta |
| Crisol |
+---------------+
3 rows in set (0.00 sec)
Se pueden ordenar los resultadosL
mysql> SELECT * FROM editoriales ORDER BY nombreEdit;
+--------+-------------------+---------------------+
| editID | nombreEdit | ts |
+--------+-------------------+---------------------+
| 19 | Anagrama | 2004-12-02 18:36:58 |
| 9 | Blume | 2004-12-02 18:36:58 |
| 3 | Crisol | 2004-12-02 18:36:58 |
| 21 | Desnivel | 2004-12-02 18:36:58 |
| 17 | Diaz de Santos | 2004-12-02 18:36:58 |
| 4 | Ediciones Destino | 2004-12-02 18:36:58 |
| 20 | Editecnicas | 2004-12-02 18:36:58 |
| 5 | Editorial Civitas | 2004-12-02 18:36:58 |
| 23 | Gredos | 2004-12-02 18:36:58 |
| 1 | Grupo Anaya | 2004-12-02 18:36:58 |
| 2 | Grupo Planeta | 2004-12-02 18:36:58 |
| 24 | Herder | 2004-12-02 18:36:58 |
| 16 | Paradox Libros | 2004-12-02 18:36:58 |
+--------+-------------------+---------------------+
13 rows in set (0.00 sec)1
!.2.2 Seleccionar re+istros ',-*.*)
Si $ueremos 3iltrar los resultados de un S)L)C' podemos poner condicionesL
mysql> SELECT nombreAutor FROM autores WHERE nombreAutor >= 'M';
+----------------+
| nombreAutor |
+----------------+
| Martin Josep |
| Molina Ana |
| Molina Marc |
| Montilla Belen |
| Muntal Carmen |
| Ortega Narcis |
| Perez Miquel |
| Puig David |
| Reig Tomas |
| Ruiz Sebastian |
| Vila Robert |
+----------------+
11 rows in set (0.01 sec)
mysql> SELECT nombreAutor FROM autores WHERE nombreAutor LIKE '%ar%';
+----------------+
| nombreAutor |
+----------------+
| Martin Josep |
| Alvarez Tobias |
| Gil Carles |
| Garcia Jordi |
| Ortega Narcis |
| Molina Marc |
| Colomer Gerard |
| Garcia Simon |
| Duarte Pablo |
| Muntal Carmen |
+----------------+
10 rows in set (0.00 sec)
mysql> SELECT nombreAutor FROM autores WHERE IDautor IN (1, 7, 37);
+----------------+
| nombreAutor |
+----------------+
| Perez Miquel |
| Costa Pau |
| Fontanella Teo |
+----------------+
3 rows in set (0.00 sec)
!.2.! *nla/ar tablas '01I2)
%or eAemplo4 si $ueremos obtener una lista de libros con su editorial correspondienteL
mysql> SELECT titulo, nombreEdit FROM titulos, editoriales WHERE
titulos.editID = editoriales.editID;
+----------------------------------------------+-------------------+
| titulo | nombreEdit |
+----------------------------------------------+-------------------+
| Linux | Grupo Anaya |
| Client/Server Survival Guide | Grupo Anaya |
| A Guide to the SQL Standard | Grupo Anaya |
| Visual Basic 6 | Grupo Anaya |
| Excel 2000 programmieren | Grupo Anaya |
| LaTeX | Grupo Anaya |
| Mathematica | Grupo Anaya |
| Maple | Grupo Anaya |
| VBA-Programacin con Excel 7 | Grupo Anaya |
| Visual Basic: programacin de bases de datos | Grupo Anaya |
| MySQL | Grupo Anaya |
| LaTeX en la web | Grupo Anaya |
| Linux | Grupo Anaya |
| PostgreSQL | Grupo Anaya |
| Java | Grupo Anaya |
| The Definitive Guide to Excel VBA | Grupo Planeta |
| MySQL | Grupo Planeta |
| A Programmer's Introduction to PHP 4.0 | Grupo Planeta |
| Web Application Development with PHP 4.0 | Crisol |
| MySQL | Crisol |
| MySQL & mSQL | Ediciones Destino |
| Practical UNIX & Internet Security | Ediciones Destino |
| MySQL Cookbook | Ediciones Destino |
| PHP - Introduccion | Editorial Civitas |
| Carlomagno | Blume |
| Comedia Infantil | Diaz de Santos |
| Hunderna i Riga | Diaz de Santos |
+----------------------------------------------+-------------------+
27 rows in set (0.00 sec)
%ero Bay otra manera $ue consiste en utili/ar 01I2L
SELECT titulo, nombreEdit
FROM titulos LEFT JOIN editoriales
ON titulos.editID = editoriales.editID;
> si el nombre de la columna es el mismo en las dos tablasL
SELECT titulo, nombreEdit
FROM titulos LEFT JOIN editoriales
USING (editID);
MySQL S*L*C&
La sinta?is completa de S)L)C' en M>SQL es la si+uienteL
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, ...
[FROM table_references
[WHERE where_condition]
[GROUP BY {col_name | expr | position}
[ASC | DESC], ... [WITH ROLLUP]]
[HAVING where_condition]
[ORDER BY {col_name | expr | position}
[ASC | DESC], ...]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
[PROCEDURE procedure_name(argument_list)]
[INTO OUTFILE 'file_name' export_options
| INTO DUMPFILE 'file_name'
| INTO var_name [, var_name]]
[FOR UPDATE | LOCK IN SHARE MODE]]
)n roAo estn las partes de SELECT ms com@nmente usadas. #Bora daremos una bree
descripcin de las opciones particulares de MySQLL
ALL4 DISTINCT4 DISTINCTROW. Siren para determinar $i $ueremos $uedarnos
con todos los re+istros (#LL4 alor por de3ecto* o $ueremos eliminar los duplicados
(DISTINCT4 DISTINCTROW son sinnimos*.
HIGH=PRIORITY. 6a prioridad al SELECT sobre instrucciones INSERT $ue se
estJn eAecutando al mismo tiempo. Solo a3ecta a tablas $ue solo disponen de
blo$ueo de tabla (MyIS#M4 M)M1.>4 M).E)*.
STRAIGHT=JOIN. <uer/a al optimi/ador a eAecutar el JOIN en el orden e?acto en
en $ue se especi3ica en la sentencia SELECT. Se usa cuando sabemos $ue el
optimi/ador produce una orden $ue de BecBo no es ptimo.
SQL_BIG_RESULT. Se puede usar con GROUP BY y DISTINCT para decirle al
optimi/ador $ue el resultado a a ser muy +rande. )so le dice al optimi/ador $ue
debe usar tablas temporales en disco.
SQL_BUFFER_RESULT. <uer/a a $ue los resultados sean almacenados en una
tabla temporal. )sto ayuda a MySQL a liberar los blo$ueos de tabla rpidamente y
ayuda en casos en $ue tarda mucBo tiempo en eniar el resultado al cliente.
SQL_SMALL_RESULT puede usarse con GROUP BY o DISTINCT para decir al
optimi/ador $ue el conAunto de resultados es pe$ue8o. )n este caso4 MySQL usa
tablas temporales rpidas para almacenar la tabla resultante en lu+ar de usar
ordenacin. )n MySQL !.;4 esto no Bar 3alta normalmente.
SQL_CALC_FOUND_ROWS le dice a MySQL $ue calcule cuntos re+istros Babrn en
el conAunto de resultados4 sin tener en cuenta nin+una clusula LIMIT. )l n@mero
de re+istros pueden encontrarse con SELECT FOUND_ROWS().
SQL_CACHE le dice a MySQL $ue almacene el resultado de la consulta en la cacBJ
de consultas si est usando un alor de $uery=cacBe=type de 2 o DEMAND. %ara
una consulta $ue use 52I12 o subconsultas4 esta opcin a3ecta a cual$uier
S)L)C' en la consulta.
SQL_NO_CACHE le dice a MySQL $ue no almacene los resultados de consulta en la
cacBJ de consultas. %ara una consulta $ue use UNION o subconsultas esta opcin
a3ecta a cual$uier SELECT en la consulta.
!.2.# Modi3icar datos 'I2S*.&4 5%(A&*4 y (*L*&*)
Con la instruccin I2S).' se pueden a8adir re+istros a una tabla. %or eAemploL
INSERT INTO titulos (titulo, ao)
VALUES ('MySQL', 2007)
Se puede esco+er $ue columnas rellenar4 aun$ue siempre teniendo en cuenta $ue solo se
pueden i+norar las $ue admiten un alor 25LL4 o las $ue son #5'1=I2C.)M)2'. Si no
se especi3ica $ue columnas se estn rellenando4 Bay $ue dar alores para todasL
INSERT INTO titulos
VALUES (NULL, 'MySQL', '', 1, NULL, NULL, NULL, 2007, NULL, NULL, NULL)
'ambiJn se pueden insertar arios re+istros a la e/L
INSERT INTO titulos (titulo, ao)
VALUES ('tituloA', '2007'), ('tituloB', 2007), ('tituloC', 2007)
Con la instruccin 5%6#') se pueden modi3icar re+istros ya e?istentes. )n +enral se usa
de la 3ormaL
UPDATE nombre_de_tabla
SET columna1=valor1, columna2=valor2, ...
WHERE id_columna=n
> con el comando 6)L)') se pueden borrar re+istros de una tabla. %or eAemploL
DELETE FROM nombre_de_tabla
WHERE id_columna=n
%ara borrar tablas $ue estn enla/adas con claes e?ternas4 se pueden borrar re+istros
de di3erentes tablas a la e/L
DELETE t1, t2 FROM t1, t2, t3 WHERE condicion1 AND condicion2 ...
%or eAemplo4 usando el eAemplo de la biblioteca4 si $ueremos borrar un titulo tenemos $ue
tener en cuenta sus relacionesL
DELETE titulos FROM titulos, rel_titulo_autor, autores
WHERE titulos.tituloID = titulo_autor.tituloID
AND autores.autorID = rel_titulo_autor.autorID
AND autores.nombreAutor = 'Costa Pau'
I2S*.&
La sinta?is MySQL de esta instruccin esL
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name [(col_name,...)]
VALUES ({expr | DEFAULT},...),(...),...
[ ON DUPLICATE KEY UPDATE
col_name=expr
[, col_name=expr] ... ]
Las opciones en roAo son las ms com@nmente usadas4 y a continuacin e?plicaremos el
si+ni3icado del resto de opcionesL
Si se usa la palabra DEL%<ED4 el seridor pone el re+istro o re+istros a ser
insertados en un b@33er4 y el cliente reali/ando el comando I=SERT DEL%<ED
puede continuar. Si la tabla est en uso4 el seridor trata los re+istros. Cuando la
tabla se libera4 el seridor comien/a a insertar re+istros4 cBe$ueando
peridicamente para er si Bay al+una peticin de lectura para la tabla. Si la Bay4 la
cola de re+istros retardados se suspende Basta $ue la tabla se libera de nueo.
Si se usa la palabra LO>?.RIORIT< 4 la eAecucin de I=SERT se retrasa Basta $ue
no Bay otros clientes leyendo de la tabla. )sto incluye a otros clientes $ue
comiencen a leer mientras $ue los clientes e?istentes estn leyendo4 y mientras el
comando I=SERT LO>?.RIORIT< est en espera. )s posible4 por lo tanto4 para
un cliente $ue realice un comando I=SERT LO>?.RIORIT< esperar durante
mucBo tiempo (o incluso para siempre* en un entorno de mucBas lecturas. ()sto es
un contraste de I=SERT DEL%<ED4 $ue deAa al cliente continuar. 'ener en cuenta
$ue LO>?.RIORIT< no debe usarse normalmente con tablas MyIS%M y $ue
Bacerlo desBabilita inserciones concurrentes.
Si especi3ica 7I"7?.RIORIT<4 desBabilita el e3ecto de la opcin --lo8-
$riority-#$dates si el seridor se arranc con esa opcin. -ace $ue las
inserciones concurrentes no se usen.
Los alores a3ectados por un I=SERT pueden usarse usando la 3uncin
mysql?a@@e/ted?ro8s9; de la #%I de C.
Si se usa la palabra I"=ORE en un comando I=SERT 4 los errores $ue ocurren
mientras se eAecuta el comando se tratan como adertencias. %or eAemplo4 sin
I"=ORE4 un re+istro $ue dupli$ue un 7ndice A=IBAE e?istente o alor .RIM%R<
CE< en la tabla Bace $ue un error de clae duplicada en el comando se aborte. Con
I"=ORE4 el re+istro toda7a no se inserta4 pero no se muestra error. Las
conersiones de datos disparar7an errores y abortar7an el comando si no se
especi3icara I"=ORE . Con I"=ORE4 los alores inlidos se aAustan al alor ms
cercano y se insertanR las adertencias se producen pero el comando no se aborta.
Se puede determinar con la 3uncin mysql?in@o9; de la #%I de C cuntos
re+istros se insertan realmente en la tabla.
Si se especi3ica O= DA.LIC%TE CE< A.D%TE4 y se inserta un re+istro $ue
duplicar7a un alor en un 7ndice A=IBAE o .RIM%R< CE<4 se reali/a un A.D%TE
del anti+uo re+istro. %or eAemplo4 si la columna a se declara como A=IBAE y
contiene el alor !4 los si+uientes dos comandos tienen e3ectos idJnticosL
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;
)l alor de re+istros a3ectados es 1 si el re+istros se inserta como un nueo
re+istro y 2 si un alor e?istente se actuali/a.
2otaL Si la columna es @nica4 el I=SERT ser7a e$uialente a este comando
A.D%TE L
mysql> UPDATE table SET c=c+1 WHERE a=1 OR b=2 LIMIT 1;
Si aD! OR D& se cumple para arios re+istros4 slo un re+istro se actuali/a. )n
+eneral4 deber7a intentar eitar usar una clusula O= DA.LIC%TE CE< en tablas
con claes @nicas m@ltiples.
MySQL !.; permite el uso de la 3uncin E%LAES9/ol?name; en la clusula
A.D%TE $ue se re3iere a los alores de columna de la porcin I=SERT del
comando I=SERT ::: A.D%TE . )n otras palabras4 E%LAES9/ol?name; en la
clusula A.D%TE se re3iere al alor de /ol?name $ue se insertar7an4 no ocurre
con3licto de clae duplicada. )sta 3uncin es especialmente @til en inserciones de
m@ltiples re+istros. La 3uncin E%LAES9; tiene sentido slo en comandos I=SERT
::: A.D%TE y retorna =ALL de otro modo.
)AemploL
mysql> INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6)
-> ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);
)ste comando es idJntico a los si+uientes dos comandosL
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 O= DA.LIC%TE CE< A.D%TE4 la opcin DEL%<ED se i+nora.
%uede encontrar el alor usado para una columna %ATO?I=CREME=T usando la
3uncin SQL L%ST?I=SERT?ID9; . 6esde la #%I C4 use la 3uncin
mysql?insert?id9; . Sin embar+o4 debe tener en cuenta $ue las dos 3unciones
no siempre se comportan idJnticamente.
(*L*&*4 5%(A&*
La sinta?is de 6)L)') y 5%6#') esL
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM tl?name
[WHERE 8Fere?de@inition]
[ORDER BY ...]
[LIMIT ro8?/o#nt]
UPDATE [LOW_PRIORITY] [IGNORE] tbl_name
SET col_name1=expr1 [, col_name2=expr2 ...]
[WHERE where_condition]
[ORDER BY ...]
[LIMIT row_count]
)stas instrucciones no tienen opciones espec73icas a parte de L1,=%.I1.I'> $ue ya la
Bemos isto antes. Si se usa la opcin BAICC 4 el motor de almacenamiento no me/cla las
BoAas del 7ndice durante el borrado4 $ue puede acelerar al+unos tipos de operaciones de
borrado.
!.2.5 Crear bases de datos4 tablas e 6ndices
2ormalmente usaremos una Berramienta interactia para crear bases de datos4 tablas4
7ndices. Sin embar+o todas estas Berramientas lo $ue Bacen es usar instrucciones SQL.
%or eAemplo4 para crear una base de datos usaremos C.)#') 6#'#B#S)L
CREATE DATABASE biblioteca
1pcionalmente se puede especi3icar la codi3icacin de los caracteresL
CREATE DATABASE biblioteca
DEFAULT CHARACTER SET latin1 COLLATE latin1_general_ci
%ara crear una tabla usaremos C.)#') '#BL). La sinta?is simpli3icada esL
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] nombre_tabla (
nombre_columna1, tipo_columna opciones_de_columna referencia,
nombre_columna2, tipo_columna opciones_de_columna referencia, ...
[ , index1, index2 ...] )
[ ENGINE = MyISAM|InnoDB|HEAP ]
[ DEFAULT CHARSET = csname [ COLLATE = collname ]]
%or eAemplo4 para crear la tabla titulos de la base de datos biblioteca usaremos
estoL
CREATE TABLE IF NOT EXISTS `titulos` (
`tituloID` int(11) NOT NULL AUTO_INCREMENT,
`titulo` varchar(100) COLLATE latin1_spanish_ci NOT NULL DEFAULT '',
`subtitulo` varchar(100) COLLATE latin1_spanish_ci DEFAULT NULL,
`edition` tinyint(4) DEFAULT NULL,
`editID` int(11) DEFAULT NULL,
`catID` int(11) DEFAULT NULL,
`idiomaID` int(11) DEFAULT NULL,
`ao` int(11) DEFAULT NULL,
`isbn` varchar(20) COLLATE latin1_spanish_ci DEFAULT NULL,
`comentario` varchar(255) COLLATE latin1_spanish_ci DEFAULT NULL,
`ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE
CURRENT_TIMESTAMP,
`autores` varchar(255) COLLATE latin1_spanish_ci DEFAULT NULL,
PRIMARY KEY (`tituloID`),
KEY `publIdIndex` (`editID`),
KEY `idiomaID` (`idiomaID`),
KEY `catID` (`catID`),
KEY `titulo` (`titulo`),
INDEX idxTitulo ('titulo'),
CONSTRAINT `titulos_ibfk_3` FOREIGN KEY (`idiomaID`) REFERENCES `idiomas`
(`idiomaID`),
CONSTRAINT `titulos_ibfk_1` FOREIGN KEY (`editID`) REFERENCES `editoriales`
(`editID`),
CONSTRAINT `titulos_ibfk_2` FOREIGN KEY (`catID`) REFERENCES `categorias`
(`catID`);
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_spanish_ci;
#l crear esta tabla ya Bemos creado los 7ndices y las claes e?ternas. Sin embar+o esto
se puede Bacer despuJs de crear la tabla con instrucciones separadasL
CREATE INDEX idxTitulo ON titulos (titulo)
o
ALTER TABLE titulos ADD INDEX idxTitulo (titulo)
'ambiJn podemos crear nueas tablas a partir de un S)L)C'L
CREATE TABLE libros_fantasia
SELECT * FROM titulos WHERE catID=65
6esde este momento la tabla libros_fantasia se puede usar de 3orma
independiente. > cuando ya no la necesitemos4 la podemos borrar as7L
DROP TABLE libros_fantasia
!.2.7 Cambiar dise8o de tablas
Con #L'). '#BL) podemos cambiar los detalles de una tabla como a8adir o eliminar
columnas4 cambiar las propiedades de las columnas (como el tipo de datos*4 y de3inir o
borrar 7ndices. %or eAemplo4 si $ueremos aumentar el n@mero m?imo de caracteres
asi+nados a la columna titulo de la tabla titulos Baremos lo si+uienteL
ALTER TABLE titulos CHANGE titulo titulo VARCHAR(150) NOT NULL
%ara a8adir un columna4 la sinta?is +eneral esL
ALTER TABLE nombre_tabla ADD nombre_columna_nueva tipo_columna
opciones_columna
[FIRST | AFTER columna_existente]
%ara borrar una columnaL
ALTER TABLE nombre_tabla DROP nombre_columna
!.2.9 Borrar bases de datos y tablas
%ara borrar bases de datos y tablasL
DROP TABLE nombre_tabla
DROP DATABASE nombre_bd
!.! Cambios de dise8o automticos
Cuando creamos una tabla con C.)#') '#BL) o Bacemos un cambio con #L').
'#BL)4 MySQL puede4 baAo determinadas circunstancias4 Bacer cambios en el dise8o
de la tabla. La ra/n es $ue la tabla4 con estos cambios4 ser ms e3iciente4 o $ue los
cambios $ue $ueremos Bacer no son posibles con MySQL. %ara ase+urarnos $ue el
dise8o de la tabla es e?actamente lo $ue pensamos $ue es4 podemos usar S-1,
C.)#') '#BL). %or eAemplo4 si creamos la si+uiente tablaL
CREATE TABLE test1 (col1 VARCHAR(20), col2 CHAR(20))
Sin embar+o4 si usamos S-1, C.)#') '#BL) obtendremos lo si+uienteL
SHOW CREATE TABLE test1
CREATE TABLE 'test1' (
'col1' varchar(20) default NULL,
'col2' varchar(20) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
MySQL Ba trans3ormado la columna 2 de CHAR(20) a VARCHAR(20)4 y adems Ba
a8adido el atributo DEFAULT NULL a las dos columnas.
)n +eneral4 estos son los cambios ms importante $ue MySQL e3ect@a en el dise8o de las
tablasL
Las columnas C#.C-#.(n* con nS4 se trans3orman en C-#.(n*
Las columnas C-#.(n* con nT3 se trans3orman en C#.C-#.(n* si e?iste en la
tablas al+una columna adicional del tipo C#.C-#.4 ')D' o BL1B. Si no4 se deAa
como est.
Las columnas de tipo 'IM)S'#M% no pueden almacenar alores 25LL. Cuando
se de3ine una columna de este tipo con el atributo 25LL4 el e3ecto es $ue se
almacena el alor ;;;;G;;G;; ;;L;;L;;.
Las columnas $ue son %.IM#.> Q)> siempre tienen asi+nado el atributo 21'
25LL4 aun$ue no lo Bayamos especi3icado.
Si no se de3ine el alor por de3ecto de una columna4 MySQL de3inir uno apropiado
(25LL4 ;4 una cadena de caracteres ac7a*.
!.# Inspeccionar meta datos 'S-1,)
La manera de recuperar in3ormacin sobre los datos almacenados es el comando S-1,.
%or eAemplo4 S-1, 6#'#B#S)S muestra una lista de las bases de datos del sistema4
S-1, '#BL)S muestra una lista con las tablas e?istentes en una bases de datos4
S-1, C1L5M2S muestra la in3ormacin sobre las columnas de una tabla.
%or eAemplo4 podemos inspeccionar la estructura de una tablaL
mysql> SHOW COLUMNS FROM titulos;
+------------+--------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+-------------------+-----------------------------+
| tituloID | int(11) | NO | PRI | NULL | auto_increment |
| titulo | varchar(100) | NO | MUL | | |
| subtitulo | varchar(100) | YES | | NULL | |
| edition | tinyint(4) | YES | | NULL | |
| editID | int(11) | YES | MUL | NULL | |
| catID | int(11) | YES | MUL | NULL | |
| idiomaID | int(11) | YES | MUL | NULL | |
| ao | int(11) | YES | | NULL | |
| isbn | varchar(20) | YES | | NULL | |
| comentario | varchar(255) | YES | | NULL | |
| ts | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| autores | varchar(255) | YES | | NULL | |
+------------+--------------+------+-----+-------------------+-----------------------------+
12 rows in set (0.00 sec) 'col1' varchar(20) default NULL,
Las 3ormas ms comunes de usar S-1, sonL
Instruccin :uncin
SHOW DATABASES
Muestra un lista de todas las bases
de datos
SHOW TABLES FROM nombre_db
Muestra una lista de todas las tablas
en la base de datos nombre=db
SHOW [FULL] COLUMNS FROM nombre_tabla
Muestra in3ormacin detallada de
todas las columnas de la tabla
nombre=tabla
SHOW INDEX FROM nombre_tabla
Muestra una lista de los 7ndices de la
tabla nombre=tabla
(*SC.IB*
)ste comando es muy @til cuando no sabemos cual es la estructura de una tabla. %or
eAemplo4 si $ueremos saber cual es la estructura de la tabla autores de la base de datos
biblioteca Baremos estoL
mysql> DESCRIBE autores;
+-------------+-------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-------------+------+-----+-------------------+-----------------------------+
| autorID | int(11) | NO | PRI | NULL | auto_increment |
| nombreAutor | varchar(60) | NO | MUL | | |
| ts | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-------------+-------------+------+-----+-------------------+-----------------------------+
%odemos er como este comando nos da in3ormacin sobre cada columnaL nombre4 tipo4
25LLM21' 25LL4 tipo de clae(%.IL primaria4 M5LL no @nica*4 alor por de3ecto4 e
in3ormacin adicional como si es #5'1=I2C.)M)2'4 ...
!.5 &ablas I2:1.MA&I12;SC-*MA
'odas las bases de datos relacionales almacenan datos acerca de ellas mismas en una
coleccin de tablas de sistema no estndar. )stas tablas contienen metadatos4 esto es4
datos acerca de obAetos en la base de datos. )s desaconseAable escribir consultas
directamente sobre estas tablas ya $ue su estructura puede cambiar. %ara eitar este
problema desde SQLL92 se de3ini una base de datos estndar $ue contiene todos estos
metadatosL I2<1.M#'I12=SC-)M#. Ms precisamente4 I2<1.M#'I12=SC-)M# es
un conAunto de CI),S con acceso de lectura @nicamente.
MySQL trata I2<1M#'I12=SC-)M# como si 3uera una base de datos4 por lo cual se le
pueden diri+ir consultas como si 3uera una bases de datos normal. )sto es
e?tremadamente @til ya $ue de esta manera este tipo de consultas son ms 3cilmente
trasladables de MySQL a otros sistema de bases de datos $ue si+a el estndar SQL
%or eAemploL
mysql> use information_schema;
Database changed
mysql> show tables;
+---------------------------------------+
| Tables_in_information_schema |
+---------------------------------------+
| CHARACTER_SETS |
| COLLATIONS |
| COLLATION_CHARACTER_SET_APPLICABILITY |
| COLUMNS |
| COLUMN_PRIVILEGES |
| ENGINES |
| EVENTS |
| FILES |
| GLOBAL_STATUS |
| GLOBAL_VARIABLES |
| KEY_COLUMN_USAGE |
| PARTITIONS |
| PLUGINS |
| PROCESSLIST |
| REFERENTIAL_CONSTRAINTS |
| ROUTINES |
| SCHEMATA |
| SCHEMA_PRIVILEGES |
| SESSION_STATUS |
| SESSION_VARIABLES |
| STATISTICS |
| TABLES |
| TABLE_CONSTRAINTS |
| TABLE_PRIVILEGES |
| TRIGGERS |
| USER_PRIVILEGES |
| VIEWS |
+---------------------------------------+
27 rows in set (0.00 sec)
)sta es la lista de tablas disponible en MySQL !.1. Los detalles de los contenidos de
estas tablas pueden encontrarse enL
BttpLMMde.mys$l.comMdocMre3manM!.1MenMin3ormationGscBema.Btml
*lustraci+n 6( 1iagrama de relaciones entre las tablas *#&7R)!8*7#9SC:-)!
# continuacin daremos una bree descripcin sobre las ms importantesL
SC-)M#'#. %roporciona in3ormacin sobre las bases de datos $ue Bay en el
sistema. Bsicamente4 los nombres y el Aue+o de caracteres usado.
'#BL)S. 6escribe las propiedades de todas las tablas.
C1L5M2S. 6escribe las propiedades de todas las columnas de todas las tablas.
S'#'IS'ICS. Contiene la in3ormacin sobre los 7ndices e?istentes en el sistema.
CI),S. 6escribe las propiedades de todas las istas del sistema. )so incluye su
de3inicin4 es decir4 la sentencia SQL $ue se us para crearla.
'#BL)=C12S'.#I2'S. Contiene todas las restricciones de las tablas.
Q)>=C1L5M2=5S#E). Contiene tambiJn todos los 7ndices4 pero con in3ormaci
a8adida sobre sus restricciones.
.)<).)2'I#L=C12S'.#I2'S. Contiene la in3ormacin sobre todas las claes
3orneas.
5S).=%.ICIL)E)S. Lista de todos los usuarios MySQL. La in3ormacin de esta
tabla iene de la tabla mysql.user. Contiene in3ormacin sobre los priile+ios de
cada usuario dentro del sistema.
SC-)M#=%.ICIL)E)S. Contiene in3ormacin sobre los priile+ios espec73icos
sobre cada base de datos. La in3ormacin de esta tabla iene de mysql.db.
'#BL)=%.ICIL)E)S. Contiene in3ormacin sobre los priile+ios espec73icos sobre
cada tabla. La in3ormacin de esta tabla iene de mysql.tables_priv.
C1L5M2=%.ICIL)E)S. Contiene in3ormacin sobre los priile+ios espec73icos
sobre cada columna. La in3ormacin de esta tabla iene de
mysql.columns_priv.
C-#.#C').=S)'S. 6escribe todos los Aue+os de caracteres disponibles.
C1LL#'I12S. )speci3ica $ue es$uemas de ordenacin estn disponibles para
cada Aue+o de caracteres.
.15'I2)S. Contiene in3ormacin acerca de todos las 3unciones almacenadas
(stored /rocedures*.
'.IEE).S. Contiene in3ormacin sobre todos los tri++ers del sistema.
#. Caracter6sticas espec63icas de MySQL
)n este cap7tulo eremos dos aspectos 3undamentales de MySQLL
'ipos de tablas o motores de almacenamiento. MySQL dispone de una #%I para
$ue puedan desarrollarse di3erentes mJtodos de almacenamiento para las tablas.
Ceremos cuales son los ms importante y entraremos en pro3undidad en los tres
ms usadosL MyIS#M4 Inno6B y M)M1.>.
'ipos de datos. MySQL dispone de una serie de tipos de datos preestablecidos
para las columnas $ue no pueden ser e?tendidos por el usuario. Ceremos las
caracter7sticas de dicBos tipos y de sus peculiaridades concretas en MySQL.
#.1 &ipos de tablas
5na peculiaridad de MySQL es $ue cuando se crea una nuea tabla se puede especi3icar
su tipo. MySQL soporta una serie de tipos de tablas $ue se distin+uen por tener
propiedades di3erenciadas. Las tres ms importantes son MyIS#M4 Inno6B y M)M1.>.
Si al crear una tabla no se especi3ica el tipo4 el seridor decide por nosotros basndose en
su con3i+uracin.
Sin embar+o4 el tipo de tablas disponible en MySQL es muy amplio. #$u7 mostramos un
pe$ue8o resumenL
MyIS%M trata tablas no transaccionales. %roporciona almacenamiento y
recuperacin de datos rpida4 as7 como posibilidad de b@s$uedas 3ullte?t. MyIS%M
se soporta en todas las con3i+uraciones MySQL4 y es el motor de almacenamiento
por de3ecto a no ser $ue ten+a una con3i+uracin distinta a la $ue iene por de3ecto
con MySQL.
)l motor de almacenamiento MEMOR< proporciona tablas en memoria. )l motor de
almacenamiento MER"E permite una coleccin de tablas MyIS%M idJnticas ser
tratadas como una simple tabla. Como MyIS%M4 los motores de almacenamiento
MEMOR< y MER"E tratan tablas no transaccionales y ambos se incluyen en MySQL
por de3ecto.
2otaL )l motor de almacenamiento MEMOR< anteriormente se conoc7a como 7E%..
Los motores de almacenamiento InnoD2 y 2D2 proporcionan tablas
transaccionales. 2D2 se incluye en la distribucin binaria MySQLGMa? en a$uellos
sistemas operatios $ue la soportan. InnoD2 tambiJn se incluye por de3ecto en
todas las distribuciones binarias de MySQL !.; . )n distribuciones 3uente4 puede
actiar o desactiar estos motores de almacenamiento con3i+urando MySQL a su
+usto.
)l motor de almacenamiento EG%M.LE es un motor de almacenamiento UtontoU $ue
no Bace nada. %uede crear tablas con este motor4 pero no puede almacenar datos
ni recuperarlos. )l obAetio es $ue sira como eAemplo en el cdi+o MySQL para
ilustrar cmo escribir un motor de almacenamiento. Como tal4 su interJs primario es
para desarrolladores.
=D2 Cl#ster es el motor de almacenamiento usado por MySQL Cluster para
implementar tablas $ue se particionan en arias m$uinas. )st disponible en
distribuciones binarias MySQLGMa? !.;. )ste motor de almacenamiento est
disponible para Linu?4 Solaris4 y Mac 1S D . Se a8adir soporte para este motor de
almacenamiento en otras plata3ormas4 incluyendo ,indoOs en pr?imas ersiones.
)l motor de almacenamiento %RC7IEE se usa para +uardar +randes cantidades de
datos sin 7ndices con una Buella muy pe$ue8a.
)l motor de almacenamiento CSE +uarda datos en 3icBeros de te?to usando 3ormato
de alores separados por comas.
)l motor de almacenamiento FEDER%TED se a8adi en MySQL !.;.3. )ste motor
+uarda datos en una base de datos remota. )n esta ersin slo 3unciona con
MySQL a traJs de la #%I MySQL C Client. )n 3uturas ersiones4 ser capa/ de
conectar con otras 3uentes de datos usando otros driers o mJtodos de cone?in
clientes.
#.1.1 MyISAM
)ste tipo de tablas est maduro4 es estable4 y simple de utili/ar. Si no tenemos una ra/n
espec73ica para ele+ir otro tipo de tabla4 deber7amos esco+er esta. -ay dos ariantes de
esta tabla4 $ue MySQL esco+e automticamente se+@n considere apropiadoL
MyISAM staticL este tipo de usa cuando todas las tablas de la columna tienen un
tama8o 3iAo y predeterminado. )l acceso a estas tablas es muy e3iciente4 incluso si
la tabla es modi3icada (I2S).'4 5%6#')4 6)L)')* con mucBa 3recuencia.
#dems4 la se+uridad de los datos es muy alta ya $ue si se produce una corrupcin
de los 3icBeros es muy 3cil recuperar re+istros.
MyISAM dynamicL si en la declaracin de una tabla Bay un solo alor de tipo
C#.C-#.4 ')D' o BL1B4 entonces MySQL esco+e este tipo de tabla. La entaAa
sobre el tipo static es $ue el espacio $ue se necesita para +uardar estas tablas es
menor ya $ue se +uarda estrictamente lo necesario.
Sin embar+o4 como los re+istros no tienen el mismo tama8o4 si se modi3ican4 su
posicin en la base de datos cambia y aparece un Va+uAeroW en el 3icBero. 'ambiJn
puede suceder $ue un re+istro no estJ almacenado conti+uamente. 'odo esto Bace
$ue se incremente el tiempo de acceso con3orme las tablas se an 3ra+mentando
con las modi3icaciones. %ara eitar esta de3ra+mentacin se puede usar el
comando 1%'IMIX) '#BL)4 o un pro+rama e?terno como myisamchk.
# parte de estas dos ariantes4 las tablas MyIS#M pueden estar comprimidas con el
pro+rama e?terno myisamchk. )sto Bace $ue el espacio de almacenamiento se
redu/ca4 en promedio4 a menos de la mitad. Sin embar+o4 cada e/ $ue la tabla es
accedida Bay $ue e3ectuar un proceso de descompresin. La +ran desentaAa de estas
tablas es $ue no pueden ser modi3icadas4 es decir4 son solo de lectura.
Las caracter7sticas de las tablas MyIS#M sonL
'odos los datos se almacenan con el byte menor primero (little;endian*. )sto Bace
$ue sean independientes de la m$uina y el sistema operatio. )l @nico
re$uerimiento para portabilidad binaria es $ue la m$uina use enteros con si+no en
complemento a dos (como todas las m$uinas en los @ltimos 2; a8os* y 3ormato en
coma 3lotante I))) (tambiJn dominante en todas las m$uinas*. )l @nico tipo de
m$uinas $ue pueden no soportar compatibilidad binaria son sistemas empotrados4
$ue a eces tienen procesadores peculiares.
2o Bay penali/acin de elocidad al almacenar el byte menor primeroR los bytes en
un re+istro de tabla normalmente no estn alineados y no es un problema leer un
byte no alineado en orden normal o inerso. #dems4 el cdi+o en el seridor $ue
esco+e los alores de las columnas no es cr7tico respecto a otro cdi+o en cuanto a
elocidad.
<icBeros +randes (Basta lon+itud de "3 bits* se soportan en sistemas de 3icBeros y
sistemas operatios $ue soportan 3icBeros +randes.
.e+istros de tama8o dinmico se 3ra+mentan mucBo menos cuando se me/clan
borrados con actuali/aciones e inserciones. )sto se Bace combinando
automticamente blo$ues borrados adyacentes y e?tendiendo blo$ues si el
si+uiente blo$ue se borra.
)l m?imo n@mero de 7ndices por tabla MyIS%M en MySQL !.; es "4. )sto puede
cambiarse recompilando. )l m?imo n@mero de columnas por 7ndice es 1".
La lon+itud m?ima de clae es 1;;; bytes. )sto puede cambiarse recompilando.
)n caso de clae mayor a 2!; bytes4 se usa un tama8o de blo$ue mayor4 de 1;24
bytes.
Las columnas 2LO2 y TEGT pueden inde?arse.
Calores =ALL se permiten en columnas inde?adas. )sto ocupa ;G1 bytes por clae.
'odos los alores de clae numJrico se almacenan con el byte mayor primero para
meAor compresin de 7ndice.
Cuando se insertan re+istros en orden (como al usar columnas
%ATO?I=CREME=T *4 el rbol 7ndice se diide de 3orma $ue el nodo mayor slo
conten+a una clae. )sto meAora la utili/acin de espacio en el rbol 7ndice.
)l tratamiento interno de una columna %ATO?I=CREME=T por tabla. MyIS%M
actuali/a automticamente esta columna para operaciones I=SERT y A.D%TE .
)sto Bace las columnas %ATO?I=CREME=T ms rpidas (al menos 1;Y*. Los
alores iniciales de la secuencia no se re@san tras ser borrados. (Cuando una
columna %ATO?I=CREME=T se de3ine como la @ltima columna de un 7ndice de
arias columnas4 se re@san los alores borrados iniciales de la secuencia.* )l alor
%ATO?I=CREME=T puede cambiarse con %LTER T%2LE o myisamc<=.
Si una tabla no tiene blo$ues libres en medio del 3icBero de datos4 puede I=SERT
nueos re+istros a la e/ $ue otros 3luAos leen de la tabla. ()sto se conoce como
inserciones concurrentes.* 5n blo$ue libre puede ser resultado de borrar o
actuali/ar re+istros de lon+itud dinmica con ms datos $ue su contenido. Cuando
todos los blo$ues libres se usan (se rellenan*4 las inserciones 3uturas uelen a ser
concurrentes.
%uede tener el 3icBero de datos e 7ndice en directorios distintos para obtener ms
elocidad con las opciones D%T% DIRECTOR< y I=DEG DIRECTOR< para CRE%TE
T%2LE.
Cada columna de caracteres puede tener distintos Aue+os de caracteres.
-ay un 3la+ en el 3icBero 7ndice MyIS%M $ue indica si la tabla se Ba cerrado
correctamente. Si mys$ld se arranca con la opcin --myisam-re/o0er 4 Las
tablas MyIS%M se comprueban automticamente al abrirse4 y se reparan si la tabla
no se cierra correctamente.
myisamc<= marca las tablas como cBe$ueadas si se eAecuta con la opcin
--#$date-state . myisamc<= >>3ast cBe$ue slo las tablas $ue no tienen esta
marca.
myisamc<= >>analy/e almacena estad7sticas para partes de las claes4 as7 como
para las claes enteras.
myisampac= puede comprimir columnas 2LO2 y E%RC7%R .
%demHs de todo estoI MyIS%M soporta las si+uientes caracter7sticasL
Soporte de un tipo E%RC7%R autJnticoR una columna E%RC7%R comien/a con la
lon+itud almacenada en dos bytes.
'ablas con E%RC7%R pueden tener lon+itud de re+istro 3iAa o dinmica.
E%RC7%R y C7%R pueden ser de Basta "4QB.
5n 7ndice BasB puede usarse para A=IBAE. )sto le permite tener A=IBAE o
cual$uier combinacin de columnas en una tabla . (Sin embar+o4 no puede buscar
en un 7ndice A=IBAE .*
#.1.2 Inno(B
MySQL soporta un se+undo 3ormato de tablas llamado Inno6B. )ste motor de
almacenamiento no es desarrollado por MySQL sino $ue pertenece a la empresa
Innobase 1y $ue es la propietaria del so3tOare. Inno6B est baAo la licencia E%L 2. )s
una alternatia moderna a las tablas MyIS#M4 $ue o3rece las si+uientes 3uncionalidades
adicionalesL
&ransacciones. Las operaciones sobre las tablas Inno6B se pueden eAecutar
como transacciones. )sto permite eAecutar arias operaciones SQL conectadas
como una sola entidad. Si ocurre un error durante una transaccin4 todos los
comandos de la transaccin son anulados4 no solo el $ue se estaba eAecutando en
el monento de la transaccin. )sto es muy @til para ase+urar la se+uridad de las
aplicaciones sobre bases de datos.
Blo$ueo a ni"el de re+istro. %ara implementar transacciones4 las tablas Inno6B
usan internamente blo$ueo a niel de re+istro. )sto si+ni3ica $ue durante una
transaccin no se necesita blo$uear la tabla entera4 y eso permite $ue otros
usuarios puedan acceder a otros re+istros de la tabla simultneamente. )sto
permite una +ran e3iciencia en los casos en $ue mucBos usuarios acceden a la e/
a una misma tabla.
.estricciones sobre cla"es 3orneas. Cuando se de3inen relaciones entre tablas
usando claes 3orneas4 las tablas Inno6B automticamente ase+uran la inte+ridad
re3erencial de los datos cuando se usan comandos 6)L)'). %or eAemplo4 es
imposible $ue un re+istro en una tabla # re3erenc7e a otro ine?istente en una tabla
B.
.ecuperacin de datos perdidos. 6espuJs de una ca7da del sistema4 las tablas
Inno6B se llean a un estado consistente de 3orma automtica y muy rpida
(siempre $ue el sistema de 3icBeros no Baya $uedado da8ado*.
Limitaciones de las tablas Inno6BL
#dministracin del espacio de tablas. Mientras $ue las tablas MyIS#M utili/an un
3icBero para cada tabla4 $ue crece o se reduce se+@n el uso4 las tablas Inno6B
almacenan todos los datos y los 7ndices en un solo espacio de tablas4 $ue puede
estar en uno o arios 3icBeros4 $ue 3orman una especie de sistema de 3icBeros
irtual. )stos 3icBero no pueden reducirse. 'ampoco es posible parar el seridor y
copiar el 3icBero a otro seridor. %ara trasladar una base de datos con tablas
Inno6B se tiene $ue utili/ar el comando mysqldump.
.e$uerimiento de espacio. Las tablas Inno6B ocupan mucBo ms $ue las
MyIS#M.
Indices 3ullGte?t. Las tablas Inno6B no pueden usar 7ndices 3ullGte?t.
%roblema con ANALIZE TABLE. )s di37cil establecer en un momento determinado
el n@mero e?cato de re+istros de una tabla. #dems4 eAecutar SELECT COUNT(*)
FROM TABLE es mucBo ms lento $ue las tablas MyIS#M. )sta limitacin deber7a
desaparecer en pr?imas ersiones.
Las columnas AUTO_INCREMENT llean un 7ndice por de3ecto4 y no pueden 3ormar
parte de un 7ndice multiGcolumna.
Cuando se produce un I2S).' en una tabla con columna #5'1=I2C.)M)2'4 se
produce un blo$ueo del 7ndice entero llamado #5'1GI2C. 6urante este blo$ueo no
se pueden Bacer nueos I2S).' Basta $ue termine el anterior. # partir de MySQL
!.1.22 las tablas Inno6B Ban meAorado mucBo su elocidad a la Bora de +enerar
los alores AUTO_INCREMENT. -asta dicBa ersin4 las tablas Inno6B necesitaban
de un blo$ueo de tabla especial llamado AUTO-INC para +aranti/ar la unicidad de
los enteros +enerados. )ste blo$ueo era e3ectio mientras duraba una instruccin
INSERT4 por lo $ue la insercin de mucBas 3ilas en una sola instruccin si+ni3icaba
el blo$ue entero de la tabla. Sin embar+o4 a partir de !.1.22 se Ba introducido un
nueo mecanismo $ue elimina la necesidad de usar el blo$ue de tabla #5'1=I2C
para I2S).' de los $ue se sabe de antemano el n@mero de re+istros a insertar (lo
$ue ocurre la mayor7a de las eces*.
Blo$ueo de tablas. Las tablas Inno6B usan su propio al+oritmo de blo$ueo al
eAecutar transacciones. #s7 pues4 Bay $ue eitar usar L1CQ '#BL) ...
.)#6M,.I'). )n su lu+ar Bay $ue usar S)L)C' ... I2 S-#.) M16) o
S)L)C' ... <1. 5%6#'). )stos comandos tienen la entaAa adicional de $ue
blo$uean solo re+istros indiiduales4 y no tablas enteras.
'ablas mys$l. Las tablas de la base de datos especial mys$l no se pueden
trans3ormar a Inno6B y deben permanecer del tipo MyIS#M.
-ay un l7mite de 1;23 transacciones concurrentes.
Costes de licencia. #8adir soporte comercial de Inno6B a una licencia cuesta el
doble.
# parte de todas estas caracter7sticas de tipo +eneral $ue se encuentran en todas las
ersiones de MySQL4 e?isten mucBas caracter7sticas espec73icas $ue Ban aparecido en la
ersin de Inno6B para MySQL !.1 en su ersin %lu+in 1.; (a partir de !.1.23*. )s
importante recordar $ue la ersin de Inno6B $ue iene con MySQL !.1 no tiene estas
caracter7sticas4 y $ue solo la ersin %lu+in 1.; las tieneL
Creacin rpida de 7ndices. Si tenemos una tabla con datos4 crear o borrar un
7ndice es mucBo ms rpido. -asta aBora4 las instrucciones C.)#') I26)D y
6.1% I26)D representaban crear una tabla nuea ac7a para los nueos 7ndices4
y entonces se copiaban uno a uno los nueos.
Con la nuea ersin no se produce esta copia.
Compresin de datos. 2o solo reduce el tama8o de las tablas en disco sino $ue
permite tener ms in3ormacin e3ectia en memoria reduciendo la entradaMsalida.
Columnas de lon+itud ariable. Los re+istros de una tabla estn +uardados en un
BGtree. )sta estructura de datos permite +uardar elementos ordenados de manera
$ue cada nodo puede contener un n@mero ariable de elementos. )n la <i+ura &
podemos er un eAemplo.
La ordenacin corresponde a la clae primaria. Los datos de cada re+istro se
almacenan en los nodos. Los 7ndices secundarios tambiJn son BG'rees $ue en sus
nodos contienen re3erencias a los nodos del BG'ree VprimarioW.
Sin embar+o4 cuando los re+istros tienen campos de tipo BL1B o C#.C-#. $ue
son demasiado +randes para almacenarlos en los nodos del rbol4 se +uardan en
p+inas de disco aparte (Voer3loOW* en 3orma de lista enla/ada.
Se introducen siete tablas nueas en la base de datos I2<1.M#'I12=SC-)M#
$ue permiten conocer el estado del motor Inno6B en un momento determinado.
)stas tablas son INFORMATION_SCHEMA tables INNODB_CMP4
INNODB_CMP_RESET4 INNODB_CMPMEM4 INNODB_CMPMEM_RESET4 INNODB_TRX4
INNODB_LOCKS y INNODB_LOCK_WAITS contienen in3ormacin puntual sobre las
tablas comprimidas4 el bu33er pool comprimido4 las transacciones $ue se estn
eAecutando en el momento4 los blo$ueos correspondientes a las transacciones4 y a
$uJ blo$ueo est esperando cada transaccin.
#.1.! MyISAM "s Inno(B
)n MySQL se pueden especi3icar los tipos de tabla indiidualmente4 de manera $ue
di3erentes tipos de tabla pueden ser usados simultneamente en una misma base de
datos. )so permite esco+er el tipo ptimo para cada tabla dependiendo de la aplicacin
$ue las aya a usar.
Las tablas MyIS#M estn recomendadas para casos en los $ue se necesita el m?imo de
elocidad y el espacio de almacenamiento es pe$ue8o. %or otro lado4 las tablas Inno6B
estn recomendadas cuando nuestra aplicacin necesita usar transacciones4 necesita
ms se+uridad sobre los datos4 o a a ser accedida por mucBos usuarios a la e/ para
Bacer modi3icaciones.
&igura <( -5em/lo de =;8ree
2o Bay una respuesta +eneral sobre la pre+unta de $uJ tipo de tabla o3rece una
respuesta ms rpida. )n principio4 debido a $ue las transacciones re$uieren un tiempo
e?tra y las tablas Inno6B ocupan ms espacio en disco4 MyIS#M deber7an tener entaAa.
%ero con las tablas Inno6B se puede eitar el blo$ueo de tablas4 lo $ue le da una entaAa
a Inno6B en ciertas situaciones.
#dems4 la elocidad de una aplicacin depende mucBo en el tipo de BardOare donde se
eAecuta4 la con3i+uracin del seridor MySQL y otros 3actores. 2ormalmente4 la @nica
manera de obtener una respuesta para una determinada aplicacin es Bacer pruebas de
elocidad e?tensias usando ambos tipos de tablas.
Sin embar+o4 la +ran di3erencia entre estos dos tipos de tablas $ue puede a3ectar
seriamente a la elocidad es el BecBo de $ue Inno6B dispone de blo$ueo por re+istro
mientras $ue MyIS#M solo lo tiene por tabla. Si nuestra aplicacin reali/a mucBos
I2S).' o 5%6#') mientras a la e/ tambiJn Bay mucBos S)L)C'4el uso de MyIS#M
puede erse muy penali/ado ya $ue los blo$ueos por tabla por cada modi3icacin Bar
$ue se blo$ueen las lecturas. )n este caso las tablas Inno6B son ms recomendables. SI
por otro lado4 nuestra aplicacin tiene mucBos menos I2S).' y 5%6#') comparados
con los S)L)C'4 los blo$ueos de tabla en MyIS#M se notarn poco y nos puede
compensar la elocidad e?tra en los S)L)C' de este tipo de tabla.
1tra di3erencia importante es la inte+ridad de los datos cuando Bay ca7das del sistema. )l
motor MyIS#M no tiene nin+@n mecanismo para recuperarse4 mientras $ue Inno6b s7.
)n +eneral4 las entaAas de Inno6B sonL
%restaciones. # pesar de considerarse Bistricamente ms lento $ue MyIS#M4 las
recientes optimi/aciones Ban BecBo $ue la di3erencia sea muy pe$ue8a4 a pesar de
ser un motor transaccional.
Concurrencia. Sobre todo cuando se me/clan I2S).' y S)L)C'. )l mecanismo
de blo$ueo por re+istro da una enorme entaAa a Inno6B.
:iabilidad. )l tener transacciones #CI6 y la capacidad para recuperarse de ca7das
del sistema es una +ran entaAa en este motor.
Se+uridad de los datos. Inno6B puede Bacer respaldos con mucBos menos
blo$ueos $ue las tablas MyIS#M
> las entaAas de MyIS#M sonL
Simplicidad. )l motor es muy sencillo y 3cil de entender lo $ue 3acilita desarrollar
complementos e?ternos para Jl.
1ptimi/acin. #l ser el motor $ue ms tiempo llea con MySQL est muy
optimi/ado y mucBas aplicaciones estn escritas pensando en este motor. > la
b@s$ueda 3ullte?t les una +ran entaAa sobre Inno6B.
5so de recursos. )n +eneral consumen menos C%5 y menos espacio de disco.
#.1.# M*M1.?
Las tablas M)M1.> son un tipo de tablas muy espec73ico cuya caracter7stica
3undamental es $ue siempre residen en memoria .#M4 y nunca en el disco. 5san un
7ndice BasB $ue les da un tiempo de acceso muy rpido a re+istros indiiduales. )stas
tablas se usan normalmente para almacenar datos temporales.
)n comparacin con las tablas normales4 las tablas M)M1.> presentan un +ran n@mero
de restricciones4 de la cual la ms importante es $ue no pueden usar columnas del tipo
')D' o BL1B. Los re+istros solo se pueden buscar usando Z SZT. #5'1=I2C.)M)2'
no se puede usar. Los 7ndices solo se pueden crear para columnas 21' 25LL.
)stas tablas solo deber7an usarse cuando se necesite m?ima elocidad para acceder a
un conAunto pe$ue8o de datos. #l ser tablas $ue se +uardan en memoria .#M4
desaparecen cuando MySQL termina. )l tama8o m?imo de estas tablas est
determinado en el 3icBero de con3i+uracin por el parmetro max_heap_table_size.
#.1.5 2B(CL5S&*.
)ste motor est pensado para aplicaciones $ue necesitan un +ran tr3ico de datos4 con
mucBa concurrencia4 y con nieles muy altos de disponibilidad y se+uridad. Se construye
usando un conAunto de ordenadores entre los $ue no Bay comparticin de recursos. La
caracter7stica 3undamental es $ue los datos se almacenan en memoria.
6esde !.1.24 este motor no se distribuye en la ersin estndar de MySQL4 sino $ue se
Bace @nicamente en la ersin MySQLGCluster. %odemos er la ar$uitectura de este
sistema en la <i+ura 9.
MySQL est compuesto de una serie de nodos $ue reali/an di3erentes 3unciones. -ay tres
tipos de nodosL
2odos de control. 2ormalmente Bay solo uno e?cepto para con3i+uraciones muy
+randes. )ste nodo se encar+a de controlar a los dems4 de iniciarlos y pararlos4
de Bacer respaldos4 y de las tareas administratias en +eneral. )s el primero en
iniciarse y corresponde al pro+rama ndb_mgmd.
&igura >( !rquitectura de )ySQL;Cluster
2odos de datos. Son los $ue +uardan los datos de las tablas en memoria. Cada
nodo +uarda una copia de una parte de la base de datos. Se inicia con el pro+rama
ndbd.
2odos SQL. Son nodos $ue eAecutan seridores MySQL con motor NDB y $ue
Bacer de inter37cie para las aplicaciones de manera transparente. Se inicia con el
pro+rama ndbdcluster.
Comparacin con replicacin
)ste sistema tiene parecidos con Bacer replicacin4 pero Bay una serie de di3erencias muy
importantes. #l Bacer replicacin tenemos un seridor maestro y 2 esclaos4 con lo cual4
en situaciones de mucBa car+a4 todo Ba de pasar por un solo nodo maestro. Con MySQLG
Cluster no e?iste este cuello de botella ya $ue el trabaAo est distribuido entre mucBos
nodos.
6espuJs est el problema de $ue con replicacin todas las transacciones se eAecutan de
3orma secuencial4 lo $ue impide tener concurrencia a ese niel. )n MySQLGCluster las
transacciones se eAecutan de manera concurrente.
1tra de las entaAas de MySQLGCluster sobre replicacin es $ue +aranti/a la
sincroni/acin de los los datos.
#.2 &ipos de datos
Cada tabla est compuesta por un n@mero de columnas. %ara cada columna Bay $ue
especi3icar un tipo de datos. Los tipos de datos en MySQL se pueden clasi3icar en cuatro
tiposL
1. 2umJricos
2. <ecBa y tiempo
3. Cadenas de caracteres
4. EIS
)n esta seccin daremos una bree descripcin de los tipos espec73icos dentro de cada
cate+or7a.
#.2.1 *nteros '@@@I2&)
)s un tipo numJrico con el $ue se pueden representar n@mero enteros positios y
ne+atios. Con el atributo 52SIE2)6 el ran+o se restrin+e a n@meros positios. MySQL
soporta los tipos enteros estndar de SQLL I=TE"ER4 SM%LLI=T4 DECIM%L4 =AMERIC:
Como e?tensin4 MySQL soporta los tipos adicionales TI=<I=T4 MEDIAMI=T4 y 2I"I=T:
Los ran+os de alores de cada tipo estn detallados en la 'abla 1.
&ipo MySQL Si+ni3icado
TINYINT(m)
)ntero de & bits (1 byte4 G12& a K12:*R el ar+umento m es el
ancBo de la columna en los resultados S)L)C'4 pero no
in3luye en el ran+o de n@meros representados.
SMALLINT(m)
)ntero de 1"Gbits (2 bytes4 G32.:"& a K32.:":*
MEDIUMINT(m)
)ntero de 24Gbits (3 bytes4 G&.3&&.";& a K&.3&&.";:*
INT(m), INTEGER(m)
)ntero de 32Gbits (4 bytes4 G2.14:.4&3."4& a K2.14:.4&3."4:*
BIGINT(m)
)ntero de "4Gbits (& bytes4 [9.22\1;]1&*
SERIAL
Sinnimo de BIGINT AUTO_INCREMENT NOT NULL
PRIMARY KEY
8abla '( 8i/os de enteros
1tra e?tensin de MySQL es uso de la 3orma INT(n) en el $ue se determina el n@mero
m7nimo n de caracteres $ue se usar para mostrar ese entero. Si el entero tiene menos
de n ci3ras4 se rellenarn con espacios. SI se Ba especi3icado la opcin ZEROFILL
entonces se rellenar con ceros. %or eAemplo4 una columna de tipo INT(5) ZEROFILL
mostrar el alor ! como ;;;;!. #dems4 ZEROFILL implica automticamente
UNSIGNED.
#.2.2 *nteros A5&1;I2C.*M*2&
Cuando se usa el atributo opcional #5'1=I2C.)M)2' se consi+ue $ue MySQL4 cada
e/ $ue se crea un nueo re+istro4 automticamente inserte un alor $ue es 1 ms $ue el
alor ms +rande en la columna correspondiente. )sto se usa +eneralmente para de3inir
columnas $ue se utili/arn como claes primarias de la tabla. Las re+las $ue ri+en este
atributo sonL
Solo se puede usar cuando uno de los atributos 21' 25LL4 %.IM#.> Q)>4 o
52IQ5) se usa tambiJn.
5na tablas solo puede tener una columna #5'1=I2C.)M)2'.
La +eneracin automtica de un nueo alor solo 3unciona cuando se crean nueos
re+istros usando I2S).' y no se proporciona un alor espec73ico o 25LL.
%ara saber el @ltimo alor +enerado automticamente despuJs de una instruccin
I2S).'4 eAecutar el comando S)L)C' L#S'=I2S).'=I6(*. 5n detalle importante
es $ue en un I2S).' m@ltiple4 esta 3uncin retorna el entero +enerado para el
primer re+istro.
Si el contador de #5'1=I2C.)M)2' alcan/a el alor m?imo4 dependiendo del
tipo de entero $ue estemos usando4 no se incrementar ms. 2o se permitirn ms
operaciones de I2S).'. Con tablas sobre las $ue se reali/an mucBos I2S).' y
6)L)')4 puede ocurrir $ue un entero de 32Gbits I2' alcance su alor m?imo4
independientemente de $ue Baya pocos re+istros en la tabla. )n estos casos Bay
$ue usar un BIEI2'.
)n las tablas MyIS#M se puede especi3icar una columna secundaria como
#5'1=I2C.)M)2' cuando 3orma parte de un 7ndice multicolumna. )n este caso4 el
alor +enerado por la columna #5'1=I2C.)M)2' se calcula comoL
MAX(columa_auto_increment) + 1 WHERE prefix=given-prefix
)sto es @til cuando se $uiere almacenar datos ordenados por +rupos. %or eAemploL
CREATE TABLE animals (
grp ENUM('fish','mammal','bird') NOT NULL,
id MEDIUMINT NOT NULL AUTO_INCREMENT,
name CHAR(30) NOT NULL,
PRIMARY KEY (grp,id)
);
INSERT INTO animals (grp,name) VALUES
('mammal','dog'),('mammal','cat'),
('bird','penguin'),('fish','lax'),('mammal','whale'),
('bird','ostrich');
SELECT * FROM animals ORDER BY grp,id;
Que retornaL
+--------+----+---------+
| grp | id | name |
+--------+----+---------+
| fish | 1 | lax |
| mammal | 1 | dog |
| mammal | 2 | cat |
| mammal | 3 | whale |
| bird | 1 | penguin |
| bird | 2 | ostrich |
+--------+----+---------+
#.2.! (atos binarios 'BI& y B11L)
)n MySQL4 el tipo de datos B11L es sinnimo de 'I2>I2'. )sto tambiJn era cierto con
BI' Basta la ersin !.;.2. # partir de esa ersin BI' es un tipo de datos aparte para
representar in3ormacin binaria Basta "4 bits.
#.2.# 2Ameros en coma 3lotante ':L1A& y (15BL*)
6esde la ersin 3.23 de MySQL4 los tipos FLOAT y DOUBLE corresponden a los tipos
numJricos I))) de precisin normal y doble (single and double* $ue usan la mayor7a de
len+uaAes de pro+ramacin.
1pcionalmente4 el n@mero de d7+itos en FLOAT y DOUBLE se puede determinar con los
parmetros m y d. )n ese caso4 m especi3ica el n@mero de d7+itos antes del punto
decimal4 y d determina el n@mero de d7+itos despuJs del punto di+ital. Las caracter7sticas
+enerales de estos tipos estn resumidas en la 'abla 2.
&ipo de datos Si+ni3icado
FLOAT(m, d)
2@mero en coma 3lotante4 precisin de 4 bytes. Los alores m y d
solo a3ectan a como son presentados los alores en un S)L)C'4
pero no a3ectan a su alor almacenado.
DOUBLE(m, d)
2@mero en coma 3lotante4 precisin de & bytes.
REAL(m, d)
Sinnimo de 615BL)
8abla ,( #?mero en coma flotante
#.2.5 2Ameros de coma 3iBa '(*CIMAL)
)ste tipo se usa cuando el redondeo $ue se produce en operaciones con los tipos <L1#'
y 615BL) es inaceptable4 por eAemplo4 cuando maneAamos precios. Los n@meros son
almacenados como cadenas de caracteres y por ello el coste de almacenamiento es
mucBo ms alto. #dems4 el ran+o de alores es ms pe$ue8o ya $ue no se puede usar
la notacin e?ponencial.
#.2.7 :ec<a y <ora '(A&*4 &IM*4 (A&*&IM*4 &IM*S&AM%)
Los tipos de datos para almacenar datos temporales estn resumidos en la 'abla 3.
&ipo de datos Si+ni3icado
DATE
<ecBa en la 3orma I2;;&G12G31I4 ran+o desde 1;;;G;1G;1 Basta
9999G12G31 (3 bytes*
TIME
'iempo en la 3orma I23L!9L!9I4 ran+o [&3&L!9L!9 (3 bytes*
DATETIME
Combinacin de DATE ms TIME
YEAR
#8o 19;;G21!! (1 byte*
TIMESPAMP
Lo mismo $ue DATETIME4 pero con iniciali/acin automtica al d7a y
Bora en $ue se Bace la modi3icacin
8abla .( -s/ecificaci+n de ti/os que re/resentan fec@a y @ora
# partir de la ersin !.;.2 de MySQL Bay un mecanismo muy potente de alidacin de
3ecBas4 de 3orma $ue solo 3ecBas lidas pueden ser almacenadas. #un as7 se permite
colocar un ; para el d7a o el mes4 y tambiJn la 3ecBa ;;;;G;;G;;. Sin embar+o4 Bay
atributos $ue permiten anular estas posibilidades. La 'abla 4 resume estos atributos.
Atributo Si+ni3icado
ALLOW_INVALID_DATES
%ermite 3ecBas incorrectas4 como 2;;&G;2G31.
NO_ZERO_DATE
2o permite la 3ecBa ;;;;G;;G;;.
NO_ZERO_IN_DATE
2o permite el ; como mes o d7a.
8abla 0( !tributos /ara 1!8-
)l tipo 'IM)S'#M% tiene una serie de particularidades. La 3undamentas es $ue es
modi3icado cada e/ $ue el re+istro al $ue pertenece es modi3icado y de esa manera
re3leAa el momento de la @ltima modi3icacin. %or eso4 este tipo solo suele usarse para el
control interno de los datos4 no como dato VrealW. -ay mucBa librer7as $ue solo
3uncionarn si cada tabla tiene una columna del tipo 'IM)S'#M%.
La actuali/acin automtica no re$uiere de nin+una 3uncin especial4 y la columna no
debe de tener nin+@n alor e?pl7cito almacenado4 ni un 25LL.
#.2.9 Cadenas de caracteres 'C-A.4 CA.C-A.4 @@@&*D&)
La 'abla ! resume los di3erentes tipos de datos $ue se usan para almacenar cadenas de
caracteres.
'ipo Si+ni3icado
CHAR(n)
Cadena de caracteres con lon+itud espec73ica n4 m?imo 2!!.
VARCHAR(n)
Cadena de caracteres de lon+itud ariable4 m?imo n caracteres4 con
nS2!" en ersiones Basta 4.14 y nS"!!3" para ersiones !.;.3 o
superiores
TINYTEXT
Cadena de caracteres de lon+itud ariable4 m?imo 2!! bytes.
TEXT
Cadena de caracteres de lon+itud ariable4 m?imo 2
1"
1
MEDIUMTEXT
Cadena de caracteres de lon+itud ariable4 m?imo
2
24
1
LONGTEXT
Cadena de caracteres de lon+itud ariable4 m?imo 2
32
1
8abla 2( 8i/os de cadenas de caracteres
Con C-#.4 la lon+itud de la cadena es 3iAa y est de3inida estrictamente. %or eAemplo4
C-#.(2;* +uardar 2; bytes en cada re+istro4 independientemente de si todos se usan.
#l contrario4 las cadenas C#.C-#. tienen lon+itud ariable y los re$uerimientos de
almacenamiento ar7an se+@n el tama8o real de la cadena.
#un$ue los tipos C#.C-#. y ')D' puedan parecer idJnticos4 tienen una di3erencia
si+ni3icatia. )n el caso de C#.C-#.4 el tama8o m?imo tiene $ue ser especi3icado por
el usuario en el momento de de3inir la tabla. Las cadenas $ue sean ms lar+as sern
truncadas sin nin+@n aiso.
# partir de MySQL !.; Bay dos noedades importantes para C#.C-#.L
)l tama8o m?imo es "!!3! bytes4 mientras $ue antes era de 2!!. )s importante
resaltar $ue el tama8o m?imo est medido en bytes4 por lo $ue el m?imo de
caracteres puede ser menor ya $ue se+@n el tipo de codi3icacin se necesita ms
de 1 byte para codi3icar un carcter.
Los espacios al principio y 3inal de la cadena aBora son almacenados4 mientras $ue
antes eran eliminados antes de almacenar la cadena.
Los tipos C-#. y C#.C-#. pueden llear el atributo BI2#.>. )n este caso la columna
se comporta esencialmente como un BL1B (er ms delante*. )ste atributo puede ser @til
ya $ue cuando se usa4 el criterio de ordenacin se riAe e?clusiamente por el alor binario
de los bytes de la cadena4 y no depende del Aue+o de caracteres $ue estemos usando.
0ue+os de caracteres
)n las columnas de tipo te?to se puede usar el atributo adicionalL
CHARACTER_SET nombre_juego_caracteres COLLATE criterio_ordenacin
Los Aue+os de caracteres especi3ican la manera en $ue los caracteres son codi3icados y el
criterio para ordenar las cadenas de caracteres. La mayor7a de los Aue+os de caracteres
tienen en com@n la codi3icacin de los 12& caracteres Vin+lesesW de #SCII. )l problema
comien/a con la codi3icacin de los caracteres internacionales. 6esde la perspectia
VeuroGan+losaAonaW4 Bay dos +randes 3amilias de Aue+os de caracteresL
0ue+os de caracteres latinos. )n el pasado4 cada re+in desarroll su propia
codi3icacin de 1 byte4 de las cuales el Aue+o Latin Ba sido el ms e?tendidoL Latin'
(IS1G&&!9G1* los caracteres ms comunes de )uropa occidental (^_`Dabc etc*.
Latin, (IS1G&&!9G2* contiene caracteres de idiomas de la )uropa de este y oriental.
LatinA (o Latin>4 IS1G&&!9G1!* es el mismo $ue Latin' pero con el s7mbolo del )uro
a8adido (d*.
)l problema con estos Aue+os es $ue nin+uno contiene todos los caracteres de los
idiomas europeos.
5nicode. %ara resoler el problema de los Aue+os Latin se cre el Aue+o 5nicode
$ue usa 2 bytes por carcter. Con "!!3" caracteres posibles4 cubre no solo )uropa
sino la mayor7a de los idiomas asiticos.
%ero no pod7a ser tan 3cil ... 5nicode solo determina $uJ cdi+o est asociado a
cada carcter4 no como los cdi+os se +uardan internamente. %or ello Bay
di3erentes ariantes4 de las cuales 5CSG2 (5niersal CBaracter Set* y 5'<G&
(5nicode trans3er 3ormat* son las ms importantes.
5CSG24 tambiJn llamado 5'<G1"4 representa lo $ue aparentemente es la solucin
ms simple4 $ue es usar 2 bytes para codi3icar cada carcter. Sin embar+o4 tiene
dos inconenientesL el espacio para almacenar cadenas de caracteres se duplica4
incluso cuando se estn representando cadenas de idiomas europeos. Se+undo4 el
se+undo byte usualmente es ;4 especialmente cuando se representan cadenas en
in+lJs. MucBos pro+ramas escritos en C consideran $ue un carcter ; si+ni3ica el
3inal de una cadena4 lo cual puede dar lu+ar a problemas.
%or esto4 5'<G& es la alternatia ms popular a 5'<G1". )n este caso4 los
caracteres #SCII se representan con un solo byte4 cuyo primer bit es ;. )l resto de
caracteres 5nicode se representan con 2 4 bytes. La desentaAa de este 3ormato
es $ue no Bay una relacin directa entre el tama8o en bytes de una cadena y su
tama8o en caracteres. )ste 3ormato es el ms estndar para representar 5nicode.
# pesar de las entaAas de 5nicode4 no todo es sencillo. )l principal problema es
$ue las cadenas de caracteres en 5nicode son incompatibles con las clsicas en
#SCII. #dems4 el soporte a 5nicode en al+unas Berramientas Oeb no est
presente. %or eAemplo4 solo la @ltima ersin de %-% (!.2* incorpora soporte para
5nicode.
5na e/ se Ba esco+ido un Aue+o de caracteres4 tambiJn se puede esco+er el criterio de
ordenacin. )sto es debido a $ue un mismo Aue+o de caracteres contiene elementos de
mucBos idiomas al mismo tiempo4 por lo $ue cuando $ueremos ordenar al3abJticamente
un conAunto de cadenas de caracteres4 depender del idioma $uerremos un resultado u
otro. %ara determinar el orden al3abJtico a usar con un determinado Aue+o de caracteres
usaremos el atributo C1LL#') al de3inir un Aue+o de caracteres. %ara er todas las
opciones $ue tiene nuestro seridor usaremos S-1, C1LL#')L
mysql> show collation;
+----------------------+----------+-----+---------+----------+---------+
| Collation | Charset | Id | Default | Compiled | Sortlen |
+----------------------+----------+-----+---------+----------+---------+
| big5_chinese_ci | big5 | 1 | Yes | Yes | 1 |
| big5_bin | big5 | 84 | | Yes | 1 |
| dec8_swedish_ci | dec8 | 3 | Yes | Yes | 1 |
| dec8_bin | dec8 | 69 | | Yes | 1 |
| cp850_general_ci | cp850 | 4 | Yes | Yes | 1 |
| cp850_bin | cp850 | 80 | | Yes | 1 |
| hp8_english_ci | hp8 | 6 | Yes | Yes | 1 |
| hp8_bin | hp8 | 72 | | Yes | 1 |
| koi8r_general_ci | koi8r | 7 | Yes | Yes | 1 |
| koi8r_bin | koi8r | 74 | | Yes | 1 |
| latin1_german1_ci | latin1 | 5 | | Yes | 1 |
| latin1_swedish_ci | latin1 | 8 | Yes | Yes | 1 |
| latin1_danish_ci | latin1 | 15 | | Yes | 1 |
| latin1_german2_ci | latin1 | 31 | | Yes | 2 |
| latin1_bin | latin1 | 47 | | Yes | 1 |
| latin1_general_ci | latin1 | 48 | | Yes | 1 |
| latin1_general_cs | latin1 | 49 | | Yes | 1 |
| latin1_spanish_ci | latin1 | 94 | | Yes | 1 |
| latin2_czech_cs | latin2 | 2 | | Yes | 4 |
| latin2_general_ci | latin2 | 9 | Yes | Yes | 1 |
| latin2_hungarian_ci | latin2 | 21 | | Yes | 1 |
| latin2_croatian_ci | latin2 | 27 | | Yes | 1 |
| latin2_bin | latin2 | 77 | | Yes | 1 |
| swe7_swedish_ci | swe7 | 10 | Yes | Yes | 1 |
| swe7_bin | swe7 | 82 | | Yes | 1 |
| ascii_general_ci | ascii | 11 | Yes | Yes | 1 |
| ascii_bin | ascii | 65 | | Yes | 1 |
| ujis_japanese_ci | ujis | 12 | Yes | Yes | 1 |
| ujis_bin | ujis | 91 | | Yes | 1 |
| sjis_japanese_ci | sjis | 13 | Yes | Yes | 1 |
| sjis_bin | sjis | 88 | | Yes | 1 |
| hebrew_general_ci | hebrew | 16 | Yes | Yes | 1 |
| hebrew_bin | hebrew | 71 | | Yes | 1 |
| tis620_thai_ci | tis620 | 18 | Yes | Yes | 4 |
| tis620_bin | tis620 | 89 | | Yes | 1 |
| euckr_korean_ci | euckr | 19 | Yes | Yes | 1 |
| euckr_bin | euckr | 85 | | Yes | 1 |
| koi8u_general_ci | koi8u | 22 | Yes | Yes | 1 |
| koi8u_bin | koi8u | 75 | | Yes | 1 |
| gb2312_chinese_ci | gb2312 | 24 | Yes | Yes | 1 |
| gb2312_bin | gb2312 | 86 | | Yes | 1 |
| greek_general_ci | greek | 25 | Yes | Yes | 1 |
| greek_bin | greek | 70 | | Yes | 1 |
| cp1250_general_ci | cp1250 | 26 | Yes | Yes | 1 |
| cp1250_czech_cs | cp1250 | 34 | | Yes | 2 |
| cp1250_croatian_ci | cp1250 | 44 | | Yes | 1 |
| cp1250_bin | cp1250 | 66 | | Yes | 1 |
| cp1250_polish_ci | cp1250 | 99 | | Yes | 1 |
| gbk_chinese_ci | gbk | 28 | Yes | Yes | 1 |
| gbk_bin | gbk | 87 | | Yes | 1 |
| latin5_turkish_ci | latin5 | 30 | Yes | Yes | 1 |
| latin5_bin | latin5 | 78 | | Yes | 1 |
| armscii8_general_ci | armscii8 | 32 | Yes | Yes | 1 |
| armscii8_bin | armscii8 | 64 | | Yes | 1 |
| utf8_general_ci | utf8 | 33 | Yes | Yes | 1 |
| utf8_bin | utf8 | 83 | | Yes | 1 |
| utf8_unicode_ci | utf8 | 192 | | Yes | 8 |
...
Como se puede er4 para cada Aue+o de caracteres e?isten di3erentes opciones de orden4
normalmente una por idioma.
#.2.E (atos binarios '@@@BL1B y BI&)
%ara el almacenamiento de datos binarios Bay cuatro ariantes del tipo BL1B4 de manera
similar al tipo ')D'. La di3erencia es $ue los datos binarios siempre se ordenan y se
compran usando directamente su alor sin mediar nin+una codi3icacin.
)l uso de este tipo tiene entaAas y desentaAas. Si $ueremos almacenar im+enes o
sonido4 podemos usar el tipo BL1B. La entaAa es $ue los datos estn inte+rados en la
base datos4 con lo cual entran dentro de los bacHups4 de las recuperaciones cuando Bay
ca7das del sistema4 .. etc. Sin embar+o4 ralenti/a el 3uncionamiento de la base de datos.
1tra desentaAa es $ue normalmente los datos BL1B solo se pueden leer enteros4 es
decir4 no se pueden leer partes de ellos.
La alternatia a usar el tipo BL1B es tener los datos binarios en 3icBeros e?ternos.
La 'abla " muestra las caracter7sticas de las ariantes del tipo BL1B.
&ipo Si+ni3icado
BIT(n)
6atos en bits4 donde n es el n@mero de bits (m?imo "4*
TINYBLOB
6atos binarios de tama8o ariable4 m?imo 2!! bytes
BLOB
6atos binarios de tama8o ariable4 m?imo 2
1"
1 bytes
MEDIUMBLOB
6atos binarios de tama8o ariable4 m?imo 2
24
1 bytes
LONGBLOB
6atos binarios de tama8o ariable4 m?imo 2
32
1 bytes
8abla 4( 8i/os /ara datos binarios
#.2.F 1tros tipos
-ay dos tipos de datos $ue son particulares de MySQLL )25M y S)'. %ermiten el maneAo
e3iciente de conAuntos y enumeraciones.
Con )25M se puede representar una lista de Basta "!!3! cadenas de caracteres a las
$ue se asi+nan n@meros enteros consecutios (similar al tipo )25M de C*.
)l tipo S)' es parecido4 pero adems distin+ue el orden en $ue los elementos estn
dispuesto4 permitiendo la representacin de combinaciones. .e$uiere ms espacio de
almacenamiento y adems solo puede maneAar como m?imo "4 alores.
#.2.1G 1pciones y atributos
-ay una +ran ariedad de opciones y atributos $ue se pueden especi3icar cunado una
columna es creada. )n la 'abla podemos er una lista de los ms importantes. -ay $ue
considerar $ue no todos los atributos se pueden aplicar a todos los tipos de datos.
1pcin o atributo Si+ni3icado
NULL
La columna puede contener alores nulos (3unciona por
de3ecto*.
NOT NULL
)l alor 25LL no est permitido.
DEFAULT xxx
)l alor por de3ecto ??? se usar si no se especi3ica uno.
DEFAULT
CURRENT_TIMESTAMP
%ara columnas 'IM)S'#M%4 la Bora actual se almacenar
cuando se creen nueos re+istros
ON UPDATE
CURRENT_TIMESTAMP
%ara columnas 'IM)S'#M%4 la Bora actual se almacenar
cuando se produ/ca una modi3icacin del re+istro.
PRIMARY_KEY
6e3ine la columna como clae primaria.
AUTO_INCREMENT
Se asi+na un entero secuencialmente usar con columnas
tipo I2')E).. #dems4 Ba de ir acompa8ado de 21' 25LL
y %.IM#.>=Q)>.
UNSIGNED
%ara alores I2')E).4 no permite alores ne+atios.
CHARACTER SET nombre
[COLLATE orden]
%ara cadenas de caracteres4 especi3ica el Aue+o de
caracteres4 y opcionalmente el orden al3abJtico a usar.
#.2.11 (atos HIS
EIS si+ni3ica eogra/@ical *nformation System, decir4 sistemas de in3ormacin +eo+r3ica.
MySQL tiene una serie de tipos de datos $ue siren para almacenar datos $ue
representan in3ormacin +eo+r3ica4 como puntos4 l7neas4 pol7+onos4 ...
MySQL implementa un subconAunto de SQL with Geometry Types $ue representa un
entorno para almacenar in3ormacin espacial en bases de datos relacionales. Las
especi3icaciones de este entorno Ban sido publicadas por el consorcio 1penEIS y pueden
ser consultadas a$u7L
BttpLMMOOO.open+is.or+MdocsM99G;49.pd3
Los obAetos de tipo EIS tienen dos caracter7sticas 3undamentalesL
6eben estar asociados a un sistema de re3erencia espacial.
6eben ser parte de una Aerar$u7a de obAetos +eomJtricos.
La Aerar$u7a disponible en MySQL es la si+uienteL
Eeometry (no instanciable*
%oint (instanciable*
Cure (no instanciable*
LineStrin+ (instanciable*
Line (instanciable*
Line.in+ (instanciable*
Sur3ace (no instanciable*
%oly+on (instanciable*
EeometryCollection (instanciable*
Multi%oint (instanciable*
MultiCure (no instanciable*
MultiLineStrin+ (instanciable*
MultiSur3ace (no instanciable*
Multi%oly+on (instanciable*
)l cali3icatio de instanciable para un tipo se re3iere a $ue es posible declarar una
columna de dicBo tipo. Si es no instanciable $uiere decir $ue no se puede declarar una
columna de ese tipo.
Los datos de tipo EIS se pueden maneAar en dos 3ormatos de3inidos por 1penEISL
,Q' (Bell Cnown 8ext*L un 3ormato de te?to
,QB (Bell Cnown =inary*L un 3ormato binario
)stos 3ormatos se utili/an para maneAar los datos $ue recuperamos de MySQL4 pero el
seridor los almacena en otro 3ormato di3erente internamente.
)l 3ormato ,Q' representa los obAetos +eomJtricos de la si+uiente maneraL
POINT(15 20)
LINESTRING(0 0, 10 10, 20 25, 50 60)
POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5))
MULTIPOINT(0 0, 20 20, 60 60)
MULTILINESTRING((10 10, 20 20), (15 15, 30 15))
MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0)),((5 5,7 5,7 7,5 7, 5 5)))
GEOMETRYCOLLECTION(POINT(10 10), POINT(30 30), LINESTRING(15 15, 20 20))
> el 3ormato ,QB utili/a enteros de 1 byte y de 4 bytes4 y n@mero en coma 3lotante de "4
bits. %or eAemplo4 el obAeto I%1I2'(1 1*I se representa comoL
0101000000000000000000F03F000000000000F03F
Que corresponde a:
Byte order : 01
WKB type : 01000000
X : 000000000000F03F
Y : 000000000000F03F
)l primer bytes es ; 1 para indicar si los datos se almacenan en little;endian o big;
endian. Los cuatro bytes si+uientes son un entero $ue representa el tipo de obAeto. Los 1"
bytes si+uiente son dos n@mero en coma 3lotante con precisin de "4 bits.
)stos tipos de datos se pueden usar de la misma manera $ue el resto de tipos de MySQL.
%ara crear una tabla con columnas de tipo EIS BaremosL
CREATE TABLE geom (g GEOMETRY)
#8adir y eliminar columnasL
ALTER TABLE geom ADD pt POINT
ALTER TABLE geom DROP pt
Insertar re+istrosL
INSERT INTO geom VALUES (GeomFromText('POINT(1 1)'));
SET @g = GeomFromText('POINT(1 1)');
INSERT INTO geom VALUES (@g);
SET @g = 'POINT(1 1)';
INSERT INTO geom VALUES (PointFromText(@g))
Leer re+istrosL
SELECT g FROM geom
SELECT AsText(g) FROM geom
SELECT AsBinary(g) FROM geom
5. Modos SQL
Cuando se arranca el seridor mysqld se puede Bacer en di3erentes modos4 y se puede
aplicar estos modos de 3orma distinta a di3erentes clientes. )sto permite $ue cada
aplicacin aAuste el modo de operacin del seridor a sus propios re$uerimientos.
Los modos de3inen $uJ sinta?is SQL debe soportar MySQL y $ue clase de
comprobaciones de alidacin de datos debe reali/ar. )sto Bace ms 3cil de usar MySQL
en distintos entornos y usar MySQL Aunto con otros seridores de bases de datos.
Se puede especi3icar el modo SQL por de3ecto arrancando mysqld con la opcin --sql-
modeDJmodesJ. )l alor puede deAarse en blanco (--sql-modeDJJ* si se desea
resetearlo.
# partir de MySQL !.;4 tambiJn se puede cambiar el modo SQL una e/ arrancado el
seridor cambiando la ariable sql_mode usando el comando SET [SESSION|GLOBAL]
sql_mode='modes' . #si+nar la ariable GLOBAL re$uiere el priile+io SUPER y a3ecta
las operaciones de todos los clientes $ue conecten a partir de entonces. #si+nar la
ariable SESSION a3ecta slo al cliente actual. Cual$uier cliente puede cambiar el alor de
sql?mode en su sesin en cual$uier momento.
modes es una lista de los di3erentes modos separados por comas (III* . Se puede
consultar el modo actual mediante el comando SELECT @@sql_mode . )l alor por
de3ecto es ac7o (sin modo seleccionado*.
Los alores de los modos sql_mode ms importantes son los si+uientesL
ANSI: Cambia el comportamiento y la sinta?is para cumplir meAor el estndar
SQL.
STRICT?TR%=S?T%2LES* Si un alor no puede insertarse tal y como se da en
una tabla transaccional4 se aborta el comando. %ara tablas no transaccionales4
aborta el comando si el alor se encuentra en un comando $ue impli$ue un slo
re+istro o el primer re+istro de un comando de arios re+istros.
TR%DITIO=%L* -ace $ue MySQL se comporte como un sistema de bases de
datos SQL eetradicionalII. 5na simple descripcin de este modo es ee da un error en
lu+ar de un aisoII cuando se inserta un alor incorrecto en la columna. 2otaL
I=SERTMA.D%TE aborta as7 $ue se detecta un error. %uede $ue no sea lo $ue se
$uiere si est usando un motor de almacenamiento no transaccional4 ya $ue los
cambios en los datos anteriores al error no se desBacen4 resultando en una
actuali/acin eeparcialII .
Cuando nos re3erimos al Vmodo estrictoW4 implica un modo donde al menos
STRICT?TR%=S?T%2LES o STRICT?%LL?T%2LES est actiado..
La si+uiente lista describe todos los modos soportadosL
%LLO>?I=E%LID?D%TES
2o Bace una comprobacin total de los datos en modo estricto. Comprueba slo
$ue los meses se encuentran en el ran+o de 1 a 12 y $ue los d7as estn en el
ran+o de 1 a 31. )sto es muy coneniente para aplicaciones ,eb donde
obtenemos un a8o4 mes y d7a en tres campos distintos y $uiere +uardar
e?actamente lo $ue inserta el usuario (sin alidacin de datos*. )ste modo se
aplica a columnas D%TE y D%TETIME . 2o se aplica a columnas TIMEST%M. 4 $ue
siempre re$uieren una 3ecBa lida.
)ste modo se implement en MySQL !.;.2. #ntes de !.;.24 este era el modo por
de3ecto de MySQL para tratar datos. 6esde !.;.24 el permitir el modo estricto
prooca $ue el seridor re$uiera $ue el mes y d7a se eal@en como alores le+ales
y no simplemente en los ran+os de 1 a 12 y de 1 a 314 respectiamente. %or
eAemplo4 K&''(-'(-+!K es le+al con el modo estricto desactiado4 pero ile+al con
el modo estricto actiado. %ara permitir tales 3ecBas en modo estricto4 Babilite
%LLO>?I=E%LID?D%TES tambiJn.
%=SI?BAOTES
'rata IJI como un identi3icador delimitador de carcter (como ILI * y no como un
delimitador de cadenas de caracteres. %uede usar ILI para delimitar identi3icadores
en modo #2SI. Con %=SI?BAOTES actiado4 puede usar doble delimitadores para
delimitar una cadena de caracteres literales4 ya $ue se interpreta como un
identi3icador.
ERROR?FOR?DIEISIO=?2<?MERO
%roduce un error en modo estricto (de otra 3orma una adertencia* cuando
encuentra una diisin por cero (o MOD9GI';* durante un I=SERT o A.D%TE4 o en
cual$uier e?presin (por eAemplo4 en una lista de SELECT o clusula >7ERE * $ue
implica datos de tablas y una diisin por cero. Si este modo no se da4 MySQL
retorna =ALL para una diisin por cero. Si se usa I=SERT I"=ORE o A.D%TE
I"=ORE4 MySQL +enera una adertencia de diisin por cero4 pero el resultado de
la operacin es =ALL. (Implementado en MySQL !.;.2*
7I"7?=OT?.RECEDE=CE
6esde MySQL !.;.2 4 la precedencia del operador =OT se trata tal $ue e?presiones
como =OT a 2ET>EE= %=D / se parsean como =OT 9a 2ET>EE= %=D
/;. #ntes de MySQL !.;.24 la e?presin se parseaba como 9=OT a; 2ET>EE=
%=D /. )l anti+uo comportamiento de mayorGprecedencia puede obtenerse
permitiendo el modo SQL 7I"7?=OT?.RECEDE=CE . (#8adido en MySQL !.;.2*
mysql> SET sql_mode = '';
mysql> SELECT NOT 1 BETWEEN -5 AND 5;
-> 0
mysql> SET sql_mode = 'broken_not';
mysql> SELECT NOT 1 BETWEEN -5 AND 5;
-> 1
I"=ORE?S.%CE
%ermite nombres entre el nombre de 3uncin y el carcter I9I . )sto 3uer/a $ue
todos los nombres de 3uncin se traten como palabras reseradas. Como resultado4
si $uiere acceder a cual$uier base de datos4 tabla4 o nombre de columna $ue sea
una palabra reserada4 debe delimitarla. %or eAemplo4 y como Bay una 3uncin
ASER9; 4 el nombre de la tabla #ser en la base de datos mysql y la columna
Aser en esa table se resera4 as7 $ue debe delimitarlaL
SELECT JAserJ FROM mysql:J#serJ;
=O?%ATO?CRE%TE?ASER
%reiene $ue "R%=T cree automticamente nueos usuarios si de otra 3orma se
Bar7a4 a no ser $ue se especi3i$ue un usuario. (#8adido en MySQL !.;.2*
=O?%ATO?E%LAE?O=?MERO a3ecta el tratamiento de las columnas
%ATO?I=CREME=T . 2ormalmente4 +enera el si+uiente n@mero de secuencia para
la columna insertando =ALL o ' en ella. =O?%ATO?E%LAE?O=?MERO suprime este
comportamiento para ' de 3orma $ue slo =ALL +enera el si+uiente n@mero de
secuencia.
)ste modo puede ser @til si ' se Ba almacenado en una tabla con columnas
%ATO?I=CREME=T . ()sta no es una prctica recomendada4 de todos modos.* %or
eAemplo4 si uelca la tabla con mys$ldump y posteriormente la recar+a4
normalmente MySQL +enera un nueo n@mero de secuencia cuando encuentra los
alores ' 4 resultando en una tabla con distinto contenido $ue la $ue 3ue olcada.
#ctiar =O?%ATO?E%LAE?O=?MERO antes de recar+ar el 3icBero con el olcado
resuele el problema. )n MySQL !.;4 mys$ldump incluye automticamente en su
salida un comando permitiendo =O?%ATO?E%LAE?O=?MERO.
=O?2%CCSL%S7?ESC%.ES
6esactia el uso del carcter de barra inertida (INI* como carcter de escape en
cadenas de caracteres. Con este modo actiado4 la barra inertida se conierte en
un carcter ordinario como cual$uier otro. (Implementado en MySQL !.;.1*
=O?DIR?I=?CRE%TE
Cuando crea una tabla4 i+nora todas las directias I=DEG DIRECTOR< y D%T%
DIRECTOR<. )ste opcin es @til en seridores de replicacin esclaos.
=O?E="I=E?SA2STITATIO=
SI no est actiado4 cuando se intenta crear una tabla con un motor de
almacenamiento no disponible4 MySQL usa el motor por de3ecto y da un aiso. Si
se intenta cambiar de motor a uno no disponible con en ALTER TABLE4 el sistema
da un aiso y el ALTER no tiene e3ecto. SI la opcin est actiada4 se obtiene en
ambos casos un error.
=O?FIELD?O.TIO=S
2o muestra opciones espec73icas para columnas de MySQL en la salida de S7O>
CRE%TE T%2LE. )ste modo se usa con mys$ldump en modo de portabilidad.
=O?CE<?O.TIO=S
2o muestra opciones espec73icas para 7ndices de MySQL en la salida de S7O>
CRE%TE T%2LE. )ste modo se usa con mys$ldump en modo de portabilidad.
=O?T%2LE?O.TIO=S
2o muestra opciones espec73icas para tablas (tales como E="I=E* en la salida de
S7O> CRE%TE T%2LE. )ste modo se usa con mys$ldump en modo de
portabilidad.
=O?A=SI"=ED?SA2TR%CTIO=
)n operaciones de resta4 no marca el resultado como A=SI"=ED si uno de los
operandos no tiene si+no. 2ote $ue esto Bace $ue A=SI"=ED 2I"I=T no sea
1;;Y usable en todos los conte?tos.
=O?MERO?D%TE
)n modo estricto4 no permite K''''-''-''K como 3ecBa lida. %uede insertar
3ecBas ; con la opcin I"=ORE . Cuando no est en modo estricto4 la 3ecBa se
acepta pero se +enera una adertencia. (#8adido en MySQL !.;.2*
=O?MERO?I=?D%TE
)n modo estricto4 no acepta 3ecBas la parte del mes o d7a es ;. Se usa con la
opcin I"=ORE 4 inserta una 3ecBa K''''-''-''K para cual$uiera de estas
3ecBas. Cuando no est en modo estricto4 la 3ecBa se acepta pero se +enera una
adertencia. (#8adido en MySQL !.;.2*
O=L<?FALL?"ROA.?2<
2o permite consultas $ue en la parte del "ROA. 2< se re3ieran a una columna $ue
no apare/can en la parte S)L)C' o -#CI2E.
.%D?C7%R?TO?FALL?LE="T7
%or de3ecto4 los espacios al 3inal de las cadenas de caracteres son eliminados en
las columnas C-#. cuando se leen de los re+istros. Si esta opcin est actiada4
esto no ocurre y se conseran. )ste modo no se aplica para columnas C#.C-#.
$ue siempre conseran esos espacios 3inales. )ste modo se a8adi en !.1.2;.

mysql> CRE%TE T%2LE t! 9/! C7%R9!';;;
Query OK, 0 rows affected (0.37 sec)
mysql> I=SERT I=TO t! 9/!; E%LAES9K3yK;;
Query OK, 1 row affected (0.01 sec)
mysql> SET sql?mode D KK;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT /!I C7%R?LE="T79/!; FROM t!;
+------+-----------------+
| c1 | CHAR_LENGTH(c1) |
+------+-----------------+
| xy | 2 |
+------+-----------------+
1 row in set (0.00 sec)
mysql> SET sql?mode D K.%D?C7%R?TO?FALL?LE="T7K;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT /!I C7%R?LE="T79/!; FROM t!;
+------------+-----------------+
| c1 | CHAR_LENGTH(c1) |
+------------+-----------------+
| xy | 10 |
+------------+-----------------+
1 row in set (0.00 sec)
.I.ES?%S?CO=C%T
'rata || como un concatenador de columnas de caracteres (lo mismo $ue
CO=C%T9;* en lu+ar de como sinnimo de OR.
RE%L?%S?FLO%T
'rata RE%L como un sinnimo de FLO%T en lu+ar de sinnimo de DOA2LE.
STRICT?%LL?T%2LES
#ctia el modo estricto para todos los motores de almacenamiento. .ecBa/a los
datos inlidos. 6etalles adicionales a continuacin. (#8adido en MySQL !.;.2*
STRICT?TR%=S?T%2LES
-abilita el modo estricto para motores de almacenamiento transaccionales4 y
cuando sea posible tambiJn para los no transaccionales.
)l modo estricto controla cmo MySQL trata los alores de entrada inlidos o no
presentes. 5n alor puede ser inlido por distintas ra/ones. %or eAemplo4 puede tener un
tipo de datos incorrecto para la columna4 o puede estar 3uera de ran+o. 5n alor no est
presente cuando el re+istro a insertarse no tiene un alor para una columna $ue no tiene
la clusula DEF%ALT e?pl7cita en su de3inicin.
%ara tablas transaccionales4 se +enera un error para alores inlidos o no presentes en
un comando con los modos STRICT?%LL?T%2LES o STRICT?TR%=S?T%2LES
Babilitados. )l comando se aborta y desBace.
%ara tablas no transaccionales4 el comportamiento es el mismo para cual$uier modo4 si un
alor incorrecto se encuentra en el primer re+istro a insertar o actuali/ar. )l comando se
aborta y la tabla contin@a i+ual. Si el comando inserta o modi3ica arios re+istros y el alor
incorrecto aparece en el se+undo o posterior re+istro4 el resultado depende de $uJ modo
estricto estJ BabilitadoL
%ara STRICT?%LL?T%2LES4 MySQL deuele un error e i+nora el resto de los
re+istros. Sin embar+o4 en este caso4 los primeros re+istros se insertan o
actuali/an. )sto si+ni3ica $ue puede producirse una actuali/acin parcial4 $ue
puede no ser lo $ue desea. %ara eitarlo4 es meAor usar comandos de un @nico
re+istro ya $ue pueden abortarse sin cambiar la tabla.
%ara STRICT?TR%=S?T%2LES4 MySQL conierte los alores inlidos en el alor
lido ms pr?imo para la columna e inserta el nueo alor. Si un alor no est
presente4 MySQL inserta el alor por de3ecto impl7cito para el tipo de la columna.
)n ese caso4 MySQL +enera una adertencia en lu+ar de un error y contin@a
procesando el comando.
)l modo estricto no permite 3ecBas inlidas como K&''(-'(-+!K. )sto si+ue
permitiendo 3ecBas con partes con ceros4 como &''(-'(-''K o 3ecBas eeceroII. %ara no
permitirlas tampoco4 actie los modos SQL =O?MERO?I=?D%TE y =O?MERO?D%TE
adems del modo estricto.
Si no usa el modo estricto (esto es4 ni STRICT?TR%=S?T%2LES ni STRICT?%LL?T%2LES
estn actiados*4 MySQL inserta alores aAustados para alores inlidos o no presentes y
produce adertencias. )n modo estricto4 puede producir este comportamiento usando
I=SERT I"=ORE o A.D%TE I"=ORE.
Los si+uientes modos especiales se proporcionan como abreiaciones de combinaciones
de modos de la lista precedente. 'odos estn disponibles en MySQL !.; empe/ando en la
ersin !.;.;4 e?cepto para TR%DITIO=%L4 $ue se implement en MySQL !.;.2.
La descripcin incluye todos los modos $ue estn disponibles en la ersin ms
reciente de MySQL. %ara ersiones anteriores4 un modo de combinacin no incluye
todos los modos indiiduales $ue slo estn disponibles en las ersiones ms
recientes.
%=SI* )$uialente a RE%L?%S?FLO%T4 .I.ES?%S?CO=C%T4 %=SI?BAOTES4
I"=ORE?S.%CE. #ntes de MySQL !.;.34 %=SI tambiJn incluye
O=L<?FALL?"ROA.?2<. Consulte Seccin 1.:.34 V)Aecutar MySQL en modo #2SIW .
D2&* )$uialente a .I.ES?%S?CO=C%T4 %=SI?BAOTES4 I"=ORE?S.%CE4
=O?CE<?O.TIO=S4 =O?T%2LE?O.TIO=S4 =O?FIELD?O.TIO=S.
M%GD2* )$uialente a .I.ES?%S?CO=C%T4 %=SI?BAOTES4 I"=ORE?S.%CE4
=O?CE<?O.TIO=S4 =O?T%2LE?O.TIO=S4 =O?FIELD?O.TIO=S4
=O?%ATO?CRE%TE?ASER.
MSSBL* )$uialente a .I.ES?%S?CO=C%T4 %=SI?BAOTES4 I"=ORE?S.%CE4
=O?CE<?O.TIO=S4 =O?T%2LE?O.TIO=S4 =O?FIELD?O.TIO=S.
M<SBL+&+* )$uialente a =O?FIELD?O.TIO=S4 7I"7?=OT?.RECEDE=CE.
M<SBL('* )$uialente a =O?FIELD?O.TIO=S4 7I"7?=OT?.RECEDE=CE.
OR%CLE* )$uialente a .I.ES?%S?CO=C%T4 %=SI?BAOTES4 I"=ORE?S.%CE4
=O?CE<?O.TIO=S4 =O?T%2LE?O.TIO=S4 =O?FIELD?O.TIO=S4
=O?%ATO?CRE%TE?ASER.
.OST"RESBL* )$uialente a .I.ES?%S?CO=C%T4 %=SI?BAOTES4
I"=ORE?S.%CE4 =O?CE<?O.TIO=S4 =O?T%2LE?O.TIO=S4 =O?FIELD?O.TIO=S.
TR%DITIO=%L* )$uialente a STRICT?TR%=S?T%2LES4 STRICT?%LL?T%2LES4
=O?MERO?I=?D%TE4 =O?MERO?D%TE4 ERROR?FOR?DIEISIO=?2<?MERO4
=O?%ATO?CRE%TE?ASER.
7. (ise8o de bases de datos
# la Bora de dise8ar una base datos Bay $ue tener en cuenta una serie de re+las
+eneralesL
Las tablas no deben contener in3ormacin redundante. Si Bay datos repetidos4 es
$ue el dise8o es incorrecto.
Las tablas no deber7an tener columnas como /edido'4 /edido,4 /edido.4 ...
#un$ue ten+amos 1; columnas para almacenar pedidos4 lle+ar un d7a en $ue un
cliente Bar 11 pedidos y nos 3or/ar a cambiar la estructura de la tabla.
Se deber7a limitar al m?imo el espacio necesario para almacenar los datos.
Las consultas ms 3recuentes a la base de datos deber7an ser lo ms simples y
e3icientes posible. -ay $ue pensar siempre $ue podemos lle+ar a tener miles o
millones de re+istros en una tabla a la Bora de dise8ar consultas.
'ambiJn es necesario se+uir una serie de normas a la Bora de poner nombres a las tablas
y las columnasL
MySQL distin+ue entre may@sculas y min@sculas en los nombres de bases de
datos y tablas4 pero no para los nombres de columnas. %or ello4 es importante $ue
los nombres de las bases de datos y las tablas ten+an el mismo patrn de uso de
may@sculas y min@sculas.
Los nombres las bases de datos y tablas tienen un m?imo de "4 caracteres.
)itar el uso de caracteres especiales en los nombres (p.e. fbg*. #un$ue MySQL
permite usar cual$uier carcter4 di3erentes sistemas operatios o ersiones de
Linu? usan di3erentes Aue+os de caracteres y ello puede dar lu+ar a problemas.
)sco+er nombres $ue describan con precisin los datos $ue representan. %or
eAemplo nombreAutor es meAor $ue nombre.
5tili/ar un sistema coBerente para poner nombres. Si usamos nombreAutor en
una tabla4 no usar nombre_editorial en otra.
1tro detalle importante es decidir si usaremos plural o sin+ular para los nombres de
las tablas. )le+ir uno u otro4 pero ser siempre coBerentes.
)n +eneral4 no es 3cil de3inir una estructura de tablas $ue represente la in3ormacin $ue
deseamos almacenar de manera e3iciente tanto en elocidad de acceso como en espacio.
-ay dos re+las +enerales a se+uirL
)mpe/ar el dise8o de las tablas usando una metodolo+7a clara. )n particular4 usar
5ML (5ni3ied Modelin+ Lan+ua+e* para establecer $ue tablas usar y $uJ relaciones
Bay entre ellas.
)mpe/ar con un conAunto de datos pe$ue8o pero representatio para reali/ar
pruebas4 antes de trabaAar con datos reales.
)n el resto del cap7tulo eremos una serie de tJcnicas para dise8ar una base de datos de
3orma e3iciente. 6urante todo el cap7tulo utili/aremos la base de datos biblioteca $ue
ya Bemos isto en eAemplos anteriores.
7.1 2ormali/acin
)n la base de datos biblioteca +uardaremos la in3ormacin sobre una lista de libros. )n
principio esta es una parte de la in3ormacin $ue $ueremos almacenarL
&6tulo *ditorial A8o Autor1 Autor2 Autor!
Linu? Erupo #naya 2;;4 Mi$uel %Jre/
'Be 6e3initie ... Erupo %laneta 2;;3 Mi$uel %Jre/ 6aid %ui+
ClientMSerer Erupo #naya 199: 0osep Mart7n 6an Lpe/ .obert Cila
,eb #pplication ... Crisol 2;;; %au Costa 'ob7as hlare/
8abla 6( %rimer intento con biblioteca
%ara optimi/ar la manera en la cual estructuramos la in3ormacin se+uiremos el proceso
denominado normali/acin. )ste proceso est compuesto de tres 3ormas normales.
%rimera 3orma normal
La primera 3orma normal consiste en aplicar las si+uientes re+lasL
Las columnas con contenido similar deben ser eliminadas ya $ue limitan los datos
$ue podemos almacenar.
Se debe crear una tabla para cada tipo de in3ormacin.
Cada re+istro se tiene $ue poder identi3icar con una clae primaria.
)n nuestro eAemplo4 La primera re+la se aplica a las columnas #utor2.
La se+unda re+la parece no aplicable ya $ue nuestra base de datos +uarda @nicamente
libros. Ms tarde eremos $ue no no es as7.
%ara aplicar la tercera re+la4 lo $ue Baremos es a8adir una columna de tipo entero $ue
utili/aremos para identi3icar cada libro.
#s7 pues4 nuestra tabla $uedar7a de la si+uiente maneraL
tituloI( &6tulo *ditorial A8o Autor
1 Linu? Erupo #naya 2;;4 Mi$uel %Jre/
2 'Be 6e3initie ... Erupo %laneta 2;;3 Mi$uel %Jre/
3 'Be 6e3initie ... Erupo %laneta 2;;3 6aid %ui+
4 ClientMSerer Erupo #naya 199: 0osep Mart7n
! ClientMSerer Erupo #naya 199: 6an Lpe/
" ClientMSerer Erupo #naya 199: .obert Cila
: ,eb #pplication ... Crisol 2;;; %au Costa
& ,eb #pplication ... Crisol 2;;; 'ob7as hlare/
)l problema de las columnas #utor2 est resuelto ya $ue aBora podemos representar
cual$uier n@mero de autores. Sin embar+o4 el precio $ue pa+amos es $ue el resto de la
in3ormacin se repite por cada autor $ue a8adimos.
Se+unda 3orma normal
Consiste en aplicar dos re+lasL
Cada e/ $ue el contenido de una columna se repita $uiere decir $ue esa tabla
debe ser diidida en otras tablas.
)stas tablas deben ser enla/adas usando claes 3orneas.
)n nuestro eAemplo emos $ue prcticamente todas las columnas repiten in3ormacin. )l
problema iene de $ue cada t7tulo tiene arios autores4 y eso Bace $ue cada autor $ue
a8adimos repli$ue toda la in3ormacin sobre el libro. #s7 pues4 lo $ue Baremos ser crear
una tabla de autores de manera $ue nuestras tablas $uedar as7L
tituloI( &6tulo *ditorial A8o
1 Linu? Erupo #naya 2;;4
2 'Be 6e3initie ... Erupo %laneta 2;;3
3 ClientMSerer Erupo #naya 199:
4 ,eb #pplication ... Crisol 2;;;
autorI( tituloI( Autor
1 1 Mi$uel %Jre/
2 2 Mi$uel %Jre/
3 2 6aid %ui+
4 3 0osep Mart7n
! 3 6an Lpe/
" 3 .obert Cila
: 4 %au Costa
& 4 'ob7as hlare/
Cada 3ila de esta tabla representa la aparicin de un autor en un libro. La columna tituloI6
enla/a con los datos del libro correspondiente.
Sin embar+o4 si+uen Babiendo repeticiones en la tabla de autores4 ya $ue los nombres se
repiten por cada e/ $ue un autor sale en un libro. La @nica solucin es crear una tabla de
autores en $ue los datos de cada autor solo se almacenen una e/4 y crear una tabla ms
$ue almacene la relacin entre libro y autor.
tituloI( &6tulo *ditorial A8o
1 Linu? Erupo #naya 2;;4
2 'Be 6e3initie ... Erupo %laneta 2;;3
3 ClientMSerer Erupo #naya 199:
4 ,eb #pplication ... Crisol 2;;;
autorI( Autor
1 Mi$uel %Jre/
2 6aid %ui+
3 0osep Mart7n
4 6an Lpe/
! .obert Cila
" %au Costa
: 'ob7as hlare/
tituloI( autorI(
1 1
2 1
2 2
3 3
3 4
3 !
4 "
4 :
)sta @ltima tabla representa la relacin entre t7tulos de libros y autores. 6e BecBo4 es la
representacin de una relacin nLm $ue en 5ML se representar7a comoL
&ercera 3orma normal
Consiste en aplicar esta re+laL
Las columnas $ue no estn directamente relacionadas con la clae primaria deben
ser eliminadas y su in3ormacin traspasada a una tabla propia.
)n nuestro caso4 en la tabla titulos la columna editorial no 3orma parte de la clae
primaria ya $ue arios t7tulos pueden compartir una misma editorial. #s7 pues4 la tabla
titulos y la nuea editoriales $uedar7an as7L
tituloI( &6tulo editI( A8o
1 Linu? 1 2;;4
2 'Be 6e3initie ... 2 2;;3
3 ClientMSerer 1 199:
4 ,eb #pplication ... 3 2;;;
editI( nombre
1 Erupo #naya
2 Erupo %laneta
3 Crisol
7.2 Inte+ridad re3erencial
Las relaciones entre las clases se representan mediante claes primarias y 3orneas.
Las claes primarias siren para locali/ar4 lo ms rpido posible4 un re+istro en una tabla.
#dems4 una clae primaria identi3ica de manera unioca un re+istro en un tabla. Las
claes primarias estn 3ormadas por una o ms columnas de una tabla. 'iene $ue cumplir
las si+uientes propiedadesL
6ebe ser @nica.
6ebe ser lo ms compacta posible. %rimero4 Bay $ue mantener un 7ndice para la
clae primaria4 con lo cual contra ms compacta sea la clae primaria ms e3iciente
(en elocidad y espacio* ser el 7ndice. %or ello se suelen usar enteros.
Se+undo4 la clae primaria puede ser usada como 3ornea en otras tablas4 por lo
$ue la e3iciencia no solo se re3iere a la propia tabla donde est la clae primaria4
sino a todas las tablas relacionadas a traJs de claes 3orneas.
)n la mayor7a de sistemas de bases de datos la prctica Babitual es usar enteros de 32
"4 bits +enerados automticamente como una secuencia (#5'1=I2C.)M)2'*. 6e esta
manera el pro+ramador no se tiene $ue preocupar de +enerar alores. )n SQLL
CREATE TABLE editoriales
(editID INT NOT NULL AUTO_INCREMENT,
otras columnas ...,
PRIMARY KEY (pubID))
Si creemos $ue el n@mero de re+istros puede ser muy eleado4 o $ue amos a tener
mucBos I2S).' y 6)L)')4 podemos usar BIGINT en lu+ar de INT.
%or otro lado4 las claes 3orneas se usan para re3erenciar re+istros de otras tablas. )stas
solo se usan cuando se tiene $ue consultar la base de datos. %or eAemplo4 si $ueremos
mostrar los t7tulos Aunto con el nombre de la editorial4 ordenados al3abJticamente por el
t7tulo4 Baremos los si+uienteL
SELECT titulos.titulo, editoriales.nombreEditorial FROM titulos, editoriales
WHERE titulos.editID = editoriales.editID
ORDER BY titulo
)sta clae 3ornea se de3ine de la si+uiente maneraL
CREATE TABLE titulos
(columna1, columna2, ...,
editID INT,
FOREIGN KEY (editID) REFERENCES editoriales (editID)
)sto $uiere decir $ue titulos.editID es una clae 3ornea $ue re3erencia la clae
primaria editoriales.editID. Las re+las de inte+ridad re3erencial $ue se aplicarn
automticamente sernL
)n titulos4 no se puede insertar un re+istro con un editID $ue no e?ista en la
tabla editoriales.
2o se puede cambiar el alor de titulos.editID si no e?iste en editoriales.
2o se puede borrar un re+istro de editoriales $ue estJ re3erenciado por la tabla
titulos.
#dems4 estas re+las a3ectan al orden en $ue se reali/an las operaciones. %or eAemplo4 si
$ueremos a8adir un nueo t7tulo de una editorial $ue no e?iste4 primero deberemos
insertar el re+istro de la editorial4 y lue+o el del t7tulo.
La sinta?is +eneral de una clae 3ornea esL
FOREIGN KEY [nombre] (columna1) REFERENCES tabla2 (columna2)
[ON DELETE {CASCADE | SET NULL | NO ACTION | RESTRICT}]
[ON UPDATE {CASCADE | SET NULL | NO ACTION | RESTRICT}]
La parte opcional determina el comportamiento del sistema cuando se borra o actuali/a
un re+istro de tabla2. -ay cuatro posibilidadesL
.)S.IC'. )s el comportamiento por de3ecto. La instruccin 6)L)') causa un
error y el re+istro no se borra.
S)' 25LL. Se permite borrar el re+istro de tabla2. )n tabla14 todos los
re+istros $ue re3erencian al re+istro borrado tendrn 25LL en columna1. Se
asume $ue 25LL es un alor permitido para columna1.
C#SC#6). )l re+istro de tabla2 es borrado4 y adems4 tambiJn se borran todos
los re+istros de tabla1 $ue re3erencian al $ue estamos borrando en tabla2.
21 #C'I12. 2o se Bace nada y se pierde la inte+ridad re3erencial.
# pesar de Baber e?plicado estas cuatro opciones para el caso de 6)L)')4 en el caso de
5%6#') el comportamiento es anlo+o.
Cuando a8adimos una restriccin a las re+las de inte+ridad re3erencial4 se deben de
cumplir una serie de condicionesL
Las columnas tabla1.columna1 y tabla2.columna2 deben de tener al menos
un 7ndice ordinario. )l 7ndice no se crea automticamente al usar <1.)IE2 Q)> y
por lo tanto debe ser de3inido e?pl7citamente.
Los tipos de datos de tabla1.columna1 y tabla2.columna2 deben ser
compatibles de manera $ue se puedan comparar sin re$uerir nin+una
trans3ormacin. Los ms 3cil es $ue ambas sean I2' o BIEI2'. 'ambiJn las dos
deben de ser del mismo si+no (las dos SIE2)6 o las dos 52SIE2)6*.
Si se Ba usado la opcin S)' 25LL4 entonces la columna tabla1.columna1
debe permitir alores 25LL.
Las restricciones deben cumplirse desde el inicioL si las tablas ya estn creadas y
se se est a8adiendo una restriccin con #L'). '#BL)4 si no se cumplen las
condiciones con los datos e?istentes4 se producir un error.
Si al a8adir una restriccin obtenemos un error4 para poder locali/arlo Bay $ue encontrar
los re+istros $ue no cumplen la inte+ridad re3erencial. 5sando el caso de la biblioteca4
supon+amos $ue a8adimos la restriccin de $ue titulos.editI6 re3erencia editoriales.editI6.
Si obtenemos un error4 la manera de er $uJ re+istros lo Ban proocado serL
SELECT tituloID, editID FROM titulos
WHERE editID NOT IN (SELECT editID FROM editoriales)
Lo $ue Bacemos es buscar todos los re+istros de titulos cuya columna editID contiene
un alor $ue no e?iste en nin+uno de los alores de la columna editID de
editoriales.
%ara borrar una restriccinL
ALTER TABLE nombre_tabla DROP FOREIGN KEY foreign_key_id
%ara conocer el nombre $ue MySQL asi+na a las restricciones (foreign_key_id*
podemos usar S-1, C.)#') '#BL).
Si en al+@n momento tenemos problemas con la inte+ridad re3erencial y $ueremos
desactiarla4 usaremosL
SET foreign_key_checks=0
9. Indices
5no de los elementos de una base de datos $ue ms a3ecta a su rendimiento son los
7ndices. %or eso es importante saber $uJ son y $uJ particularidades tiene MySQL con
respecto a ellos. )se conocimiento nos permitir optimi/ar el rendimiento de nuestras
aplicaciones.
9.1 Conceptos bsicos
%ara entender la utilidad de los 7ndices lo meAor es 3iAarse en como 3unciona una consulta.
Ima+inemos $ue tenemos una tabla listin_telefonico $ue contiene los nombre y
telJ3onos de los Babitantes de un pa7s. )so puede suponer decenas de millones de
re+istros4 y recordemos $ue estos no se +uardan de manera ordenada en una tabla.
#Bora consideremos la si+uiente consultaL
SELECT * FROM listin_telefonico WHERE apellido1='Martn'
Sino disponemos de nin+@n 7ndice esto supone $ue MySQL deber leer todos los
re+istros de la tabla (arios millones* y seleccionar a$uellos $ue cumplan la condicin.
)identemente la consulta ser muy ine3iciente ya $ue tiene un coste lineal u 1(n*.
Sin embar+o4 si pensamos en un list7n de telJ3onos real4 lo $ue Bar7amos nosotros para
buscar a al+uien con el apellido IMart7nI ser7a ir directamente a la p+ina donde estn los
apellidos $ue empie/an por IMI y lue+o usar el orden al3abJtico para ir casi directamente a
donde empie/an los IMart7nI.
5n 7ndice4 en el 3ondo4 es una lista ordenada $ue nos permite4 al i+ual $ue en el caso del
list7n4 reducir la cantidad de re+istros a leer. )l eAemplo anterior lo $ue Bar7amos es crear
un 7ndice para la columna Iapellido1I de esta maneraL
ALTER TABLE listin_telefonico ADD INDEX (apellido1)
Con esto Bacemos $ue MySQL cree una lista ordenada de apellidos de la tabla
listin=tele3onico. Con cada apellido di3erente se +uardar la lista de posiciones de los
re+istros correspondientes (esto no es e?actamente as7 ya $ue MySQL tiene estrate+ias
para reducir el tama8o de los 7ndices*.
Los problemas comien/an cuando consideramos tablas $ue son modi3icadas
3recuentemente. )so $uiere decir $ue Bay $ue mantener el 7ndice4 $ue re$uiere un
es3uer/o mantenerlo ordenado. )sto $uiere decir $ue los 7ndices re$uieren espacio de
almacenamiento e?tra y tiempo de C%5 e?tra. # cambio4 pueden acelerar tremendamente
determinadas consultas. 6ebido al coste e?tra4 deberemos saber esco+er $uJ columnas
llearn 7ndices4 intentando $ue sean las menos posibles.
Indices parciales
Los 7ndices son un compromiso entre el espacio e?tra $ue re$uieren y la aceleracin $ue
proporcionan. %ero Bay eces $ue el espacio en disco puede ser un 3actor cr7tico e
inde?ar una columna $ue ocupa mucBo puede si+ni3icar 7ndices muy +randes.
#3ortunadamente MySQL tiene un mecanismo $ue permite limitar la cantidad de
in3ormacin $ue se utili/ada de una columna para 3ormar el 7ndice.
Ima+inemos $ue en el eAemplo anterior el tama8o medio de apellido1 es & bytes y $ue
tenemos 1;; millones de n@meros de telJ3ono almacenados. )so supone
apro?imadamente un 7ndice de unos &EB. Si consideramos $ue es demasiado4 podemos
reducirlo a la mitad creando el 7ndice de la si+uiente maneraL
ALTER TABLE listin_telefonico ADD INDEX (apellido1(4))
6e esta manera le decimos a MySQL $ue solo use los 4 primeros bytes de la columna
apellido1 para con3ormar el 7ndice. Cual es el problema i Que los apellidos IMartiI4
IMart7nI4 IMart7ne/I4 ... $uedan a+rupados en un mismo +rupo. )so reduce la e3iciencia del
7ndice al Bacer b@s$uedas ya $ue se eliminan menos re+istros.
Indices multicolumna
Como mucBas bases de datos relacionales4 MySQL permite tener 7ndices compuestos de
arias columnas.
ALTER TABLE listin_telefonico ADD INDEX (nombre, apellido1)
)sto puede ser @til si Bacemos mucBas consultas en las $ue aparecen las dos columnas
en la clusula ,-).)4 o si una columna no tiene su3iciente ariedad. %or supuesto4 se
pueden combinar los 7ndices parciales con los multicolumna para limitar su tama8oL
ALTER TABLE listin_telefonico ADD INDEX (nombre(4), apellido1(4))
)sto acelerar mucBo consultas del tipoL
SELECT * FROM listin_telefonico WHERE nombre='Ignacio' AND apellido1='Martin'
)sto es debido a $ue el n@mero de re+istros $ue cumplirn la condicin ser muy
pe$ue8o4 e incluso con el 7ndice parcial4 se leern muy pocos re+istros de la tabla.
)n este punto podr7amos pre+untarnos por$uJ no crear dos 7ndices4 uno para nombre y
otro para apellido1. %odr7amos Bacerlo4 pero MySQL nunca usar7a los dos a la e/. )s
ms4 MySQL solo usar un 7ndice por tabla por consulta. )ste dato es e?tremadamente
importante ya $ue es el 3actor principal a la Bora de considerar $ue 7ndices se usarn en
cada consulta.
Cuando Bay ms de un 7ndice posible para acceder a una tabla4 entonces MySQL decide
cual es el meAor. )so lo Bace en base a unas estad7sticas $ue se +uardan internamente.
%ero est decisin puede no ser ptima4 especialmente cuando la distribucin de los
re+istros en el 7ndice es muy Betero+Jnea.
1rdenar con 6ndices
Si se usa un sistema de bases de datos relacional4 los resultados de una consulta pueden
ordenarse4 tanto en sentido ascendente como descendente. MySQL no o3rece nin+@n tipo
de control sobre como +estiona la ordenacin internamente. > no Bace 3alta $ue lo Ba+a
ya $ue es muy e3iciente en cual$uier tipo de ordenacin.
%or eAemplo4 Bay sistemas de bases de datos $ue eAecutarn muy e3icientemente esta
consultaL
SELECT * FROM listin_telefonico WHERE apellido1='Martin'
ORDER BY nombre DESC
y sin embar+o esta otra consulta puede ser muy ine3icienteL
SELECT * FROM listin_telefonico WHERE apellido1='Martin'
ORDER BY nombre ASC
)sto es debido a $ue al+unos sistemas +uardan el 7ndice ordenado de manera
descendente y est optimi/ado para $ue los resultados sean retornados en ese orden. >
cuando se solicita el orden inerso Bay $ue dar un se+undo paso adicional para ordenar
los resultados en sentido contrario.
Sin embar+o4 MySQL est dise8ada para ser e3iciente independientemente de cual sea el
orden solicitado.
Los 6ndices como restricciones
Los 7ndices no solo se usan para locali/ar re+istros rpidamente. 5n 7ndice del tipo
52IQ5) +aranti/a $ue cada alor solo aparece en un @nico re+istro. %or eAemplo4
podr7amos crear un 7ndice de este tipo si $uisiJramos tener un solo re+istro por cada
n@mero de telJ3onoL
ALTER TABLE listin_telefonico ADD UNIQUE (numero)
)n este caso el 7ndice tienen una 3uncin doble. %or una parte acelera las consultas del
tipoL
SELECT * FROM listin_telefonico WHERE numero='972123456'
> a la e/ nos ase+ura $ue si intentamos insertar un re+istro con un n@mero $ue ya e?iste
el sistema no nos deAar.
)l problema de esta doble 3uncin es $ue no se puede separar. )s decir4 $ue si solo
$ueremos utili/ar la restriccin4 pero no $ueremos crear el 7ndice por$ue no lo
necesitamos para las consultas4 no se puede Bacer. %ara MySQL la restriccin y el 7ndice
52IQ5) son sinnimos. MySQL $uiere modi3icar este comportamiento para separar el
7ndice de la restriccin. 6e BecBo las tablas MyIS#M ya lo Bacen internamente pero no
e?ponen la 3uncionalidad a niel de SQL.
Indices clusteri/ados y secundarios
Las tablas MyIS#M +uardan los 7ndices en 3icBeros separados $ue contienen la clae
primaria (y las posibles secundarias*. #dems por cada alor de la clae se +uarda la
posicin del re+istro en la tabla4 ya $ue los re+istros se +uardan sin nin+@n tipo de orden.
Los 7ndices clusteri/ados 3uncionan al reJs. )l 7ndice y los re+istros se +uardan Auntos y
en el orden de la clae primaria. )ste es el sistema $ue utili/a Inno6B. Cuando los datos
son accedidos casi siempre por la clae primaria4 las consultas pueden lle+ar a ser muy
e3icientes. )so es debido a $ue solo se necesita reali/ar una lectura para obtener el
re+istro ya $ue al leer la clae primaria tambiJn leemos el re+istro (en la cacBe*. Mientras
$ue las tablas MyIS#M necesitan dos lecturas4 una para la clae y otra para el re+istro. )s
importante recalcar $ue esta e3iciencia solo 3unciona cuando la consulta usa la clae
primaria.
Sin embar+o4 los 7ndices clusteri/ados pueden dar problemas serios de almacenamiento.
)sto es debido a $ue los 7ndices secundarios no apuntan directamente al re+istro (lo $ue
no necesitar7a mucBo espacio4 un entero de "4 bits* sino $ue +uardan una copia de la
clae primaria para acceder al re+istro. Si la clae primaria tiene un tama8o considerable4
los 7ndices secundarios pueden lle+ara ocupar mucBo espacio.
1tro problema menos com@n sur+e cuando se modi3ica la clae primaria de un re+istro.
)so implica reali/ar las si+uiente operacionesL
#ctuali/ar el re+istro
6eterminar la nuea clae primaria
Moer el re+istro a su nuea posicin
#ctuali/ar todos los 7ndices secundarios
'odas estas operaciones pueden lle+ar a ser muy costosas por lo $ue es muy importante
esco+er bien las claes primarias y ase+urarse de $ue sea casi imposible $ue cambien.
%or eAemplo4 usar 2I<s4 n@mero de la se+uridad social4 ... etc.
52IQ5* "s %.IMA.? J*?
)n las tablas MyIS#M prcticamente no Bay di3erencia entre las dos opciones. La @nica
di3erencia es $ue los 7ndices de clae primaria no pueden contener alores 25LL. 6e esa
manera4 un 7ndice %.IM#.> es simplemente un 7ndice 21' 25LL 52IQ5).
%or el contrario4 las tablas Inno6B siempre llean una clae primaria. 2o Bace 3alta
especi3icar una e?pl7citamente4 ya $ue si no se Bace MySQL crea una oculta
automticamente. )n ambos casos las claes primarias son enteros #5'1=I2C.)M)2'.
Si se a8ade una clae primaria despuJs de crear una tabla4 entonces MySQL destruir la
oculta $ue cre por de3ecto.
Inde@ar 25LLs
)s importante recalcar $ue MySQL utili/a una l+ica de tres estados cuando reali/a
operaciones l+icas. Cuando se Bace una comparacin Bay tres resultados posiblesL
cierto si los alores son e$uialentes4 3also si los alores no son e$uialentes4 y 25LL si
al+uno de los alores a comparar es 25LL.
Como se tratan los alores 25LL en los 7ndices i Los alores 25LL se pueden usar en
7ndices no 52IQ5). 6ebido $ue al comparar dos alores 25LL no se obtiene cierto4 sino
25LL4 este alor no se puede utili/ar en 7ndices 52IQ5).
Sin embar+o4 el alor 25LL puede aparecer una sola e/ en un 7ndice de clae primaria.
)ste comportamiento es estndar SQL. )s una de las pocas cosas $ue di3erencian un
7ndice 52IQ5) de uno de clae primaria. > para terminar4 el usar 25LL en un 7ndice de
clae primaria no a3ecta al rendimiento.
Indices en tablas Inno(B
Los 7ndices son ms importantes en tablas Inno6B $ue en las MyIS#M. )n las primeras4
los 7ndices no solo son usados para buscar re+istros sino tambiJn para poder reali/ar
blo$ueos a niel de re+istro. )sto a3ecta4 entre otros comandos4 a S)L)C' ... L1CQ I2
S-#.) M16)4 S)L)C' ... <1. 5%6#')4 e I2S).'4 5%6#') y 6)L)'). )l eti$uetado
de $uJ re+istros estn blo$ueados no se almacena en la tabla sino en los 7ndices. %ero
para ello debe Baber un 7ndice disponible.
Limitaciones
MySQL no puede usar 7ndices cuando se usan operadores de desi+ualdad
(,-).) columna PZ ...*
MySQL no puede usar 7ndices cuando se usan comparaciones $ue contienen
ealuaciones de 3unciones (,-).) 6#>(columna* Z ...*
)n operaciones 01I2 los 7ndices solo se pueden usar cuando la clae primaria y
las 3orneas son del mismo tipo de datos.
Si se usan los operadores LIQ) y .)E)D% en las comparaciones4 los 7ndices solo
se usaran cuando no Baya nin+@n comod7n al principio del patrn de b@s$ueda. %or
eAemplo4 con LIQ) IabcYI s7 $ue se usarn 7ndices4 mientras $ue con LIQ) IYabcI
no.
Los 7ndices son ine3icientes si la columna correspondiente contiene mucBos alores
repetidos. %or eAemplo4 es completamente in@til inde?ar una columna $ue +uarda
;M1 o SIM21.
Indices :ull>te@t
5n 7ndice ordinario de3inido en una columna de tipo te?to solo sire para buscar
caracteres $ue se encuentran al principio de cada campo. La consecuencia es $ue si
tenemos te?tos lar+os con mucBas palabras y $ueremos buscar palabras usando LIQ)
IYOordYI la consulta es muy poco e3iciente ya $ue el 7ndice no ayuda a encontrar las
palabras $ue buscamos.
)n estos casos es @til usar un 7ndice <ullG'e?t. Con este tipo de 7ndice4 MySQL crea una
lista de todas las palabras $ue aparecen en el te?to. )l 7ndice puede ser creado al crear la
tabla4 o posteriormenteL
ALTER TABLE nombre_tabla ADD FULLTEXT(columna1, columna2)
)n una consulta4 se pueden buscar re+istros $ue conten+an una o ms palabrasL
SELECT * FROM nombre_tabla
WHERE MATCH(columna1, columna2) AGAINST ('palabra1', palabra2', 'palabra3')
La desentaAa de este tipo de 7ndices es $ue solo 3unciona para tablas del tipo MyIS#M.

9.2 *structuras de datos
)n esta seccin eremos las estructuras de datos ms usadas para almacenar 7ndices.
2o son espec73icas de MySQL por lo $ue se pueden encontrar en otros sistemas de bases
de datos.
Indices B>&ree
Bsicamente son rboles balanceados4 y es la estructura de datos ms com@n para
almacenar 7ndices. Casi todos los sistemas de bases de datos o3recen esta estructura de
datos para almacenar los 7ndices. )llo es debido a la buena combinacin de 3le?ibilidad4
tama8o y e3iciencia +eneral.
Los nodos del rbol se +uarda ordenados por la clae $ue se almacena. la clae est en
$ue el rbol se mantiene balanceado despuJs de a8adir y borrar nodos. 13recen un
tiempo de acceso 1(lo+ n* para b@s$uedas de un solo re+istro. # di3erencia de los rboles
binarios4 cada nodo +uarda un n@mero indeterminado de alores. .
'ambiJn o3recen muy buenos resultados en consultas de tipo range. )n la <i+ura 1;
podemos er un eAemplo de rbol balanceado.
Si $ueremos buscar un ran+o de alores4 solo Bay $ue locali/ar uno de los e?tremos4 y
entonces recorrer el rbol para obtener todos los alores ordenados.
Indices <as<
La se+unda estructura ms usada son los 7ndices BasB. Como su nombre indica4 esta
estructura no es de tipo rbol sino $ue es una tabla BasB. )n lu+ar de Bacer una
b@s$ueda en el rbol4 las tablas BasB locali/an los elementos aplicando una 3uncin BasB
para determinar en $ue porcin de la tabla se encuentra el re+istro.
5na 3uncin BasB muy com@n y muy usada es M6!. )sta 3uncin puede usarse
directamente en MySQLL
mysql> SELECT MD5('Smith');
+----------------------------------+
| MD5('Smith') |
+----------------------------------+
| e95f770ac4fb91ac2e4873e4b2dfc0e6 |
+----------------------------------+
)l problema es $ue retorna enteros de 12& bits4 un ran+o demasiado +rande para los
sistemas de almacenamiento actuales.
5na solucin com@n para reducir el ran+o de la 3uncin BasB es crear un n@mero +rande
de bucHets (espacio donde se almacenan los datos correspondientes a un mismo
resultado de la 3uncin BasB*4 y diidir el resultado de la 3uncin por este n@mero. )n este
caso4 arios resultados de la 3uncin BasB irn a parar al mismo bucHet.
)ste sistema promete un acceso 1(1*4 pero la e3iciencia real depende de lo buena $ue
sea la 3uncin BasB para distribuir los elementos de 3orma Bomo+Jnea entre los bucHets.
# pesar de su meAor e3iciencia en b@s$uedas de un re+istro4 son peores cuando se busca
un ran+o ordenado de alores ya $ue los re+istros no estn almacenados en nin+@n
orden.
Indices .>&ree
Son 7ndices para +uardar danos con 2 dimensiones. <ueron introducidos para poder tener
7ndices en datos de tipo +eo+r3ico. #dems de como 7ndice4 se usan para resoler
consultas de tipo +eomJtrico. %odemos er un eAemplo de estructura de .G'ree en la
<i+ura 11.
&igura 'A( -5em/lo de Drbol balanceado
9.! Indices y tipos de tablas
9.!.1 &ablas MyISAM
5sa por de3ecto BG'rees y para los datos espaciales usa .G'rees. )n el caso de los BG
'rees4 adems de una buena implementacin4 se o3recen dos caracter7sticas importantesL
Compresin de pre3iAo. %ara 7ndices sobre cadenas de caracteres4 MySQL puede
reconocer pre3iAos comunes y comprimirlos para $ue los 7ndices ocupen menos. )l
eAemplo t7pico es un 7ndice sobre direcciones Oeb donde todas comien/an por
http:// y http://www.
Claes empa$uetadas. )s un mecanismo parecido al anterior pero para enteros.
)n los 7ndices los enteros se almacenan con el byte ms si+ni3icatio primero. )ste
suele ariar muy poco con3orme incrementamos los alores4 de manera $ue se
pueden a+rupar ran+os en los $ue no se almacenar la clae entera. %ara
actiarlos a8adiremos PACKED_KEY = 1 al crear la tabla.
*scritura de cla"e retardada
5na de las optimi/aciones de este tipo de tablas es la capacidad para retrasar la escritura
del 7ndice a disco. 2ormalmente esta escritura se Bace inmediatamente despuJs de $ue
Baya una modi3icacin4 pero este comportamiento puede cambiar si a8adimos
DELAY_KEY_WRITE al crear la tabla. )n este caso4 el comportamiento e?acto depender
&igura ''( -5em/lo de R;8ree
de la ariable delay_key_write4 $ue puede tener tres aloresL
12L la escritura a disco se produce cuando la tabla se cierra4 y eso ocurre baAo
determinadas circunstancias $ue dependen del estado de la cacBe4 con lo cual no
es posible controlarlo.
1<<L la opcin DELAY_KEY_WRITE se i+nora.
#LLL actia el retraso en la escritura para todas las tablas MyIS#M
independientemente del alor DELAY_KEY_WRITE de cada una.
1biamente4 el problema de usar este mecanismo es $ue los 7ndices pueden estar mal
sincroni/ados con el contenido de sus respectias tablas4 y eso es especialmente
peli+roso si se produce una caida del sistema Austo en ese momento.
9.!.2 &ablas -*A%
Se puede esco+er entre usar BG'rees o BasB. )ste @ltimo es el alor por de3ecto4 y para
cambiarlo Bay $ue Bacer lo si+uienteL
mysql> create table heap_test (
-> name varchar(50) not null,
-> index using btree (name)
-> ) type = HEAP;
#l combinar el almacenamiento en memoria con los BG'rees4 la e3iciencia de estas tablas
es muy alta4 especialmente si Bacemos consultas de ran+os.
9.!.! &ablas Inno(B
Solo implementan 7ndices BG'ree4 y no tiene las optimi/aciones de las tablas MyIS#M.
#dems4 Inno6B re$uiere una clae primaria por tabla (con su correspondiente 7ndice*. Si
no se especi3ica una4 MySQL crear una por de3ecto con un entero de "4 bits.
Inno6B almacena el 7ndice en el espacio de tablas com@n4 y utili/a 7ndices clusteri/ados.
)sto Bace $ue buscar un re+istro en este tipo de tablas sea muy rpido.
9.# Indices :ull>te@t
)s un tipo de 7ndice especial para columnas de tipo te?to $ue permite buscar palabras
muy rpidamente. Solo estn disponibles para tablas MyIS#M. Se pueden construir para
una o ms columnas de tipo te?to.
Se construye creando un rbol BG'ree con dos componentes4 uno C#.C-#. y otro
<L1#'. )l primero contiene una palabra inde?ada4 y el se+undo su peso en el re+istro.
)so si+ni3ica $ue Babr un elemento por cada palabra en el campo del 7ndice4 lo $ue
si+ni3ica $ue el tama8o del 7ndice puede ser muy +rande. #s7 $ue este 7ndice es un
compromiso entre espacio y elocidad.
E. 1ptimi/acin de consultas
5na de las tareas principales a la Bora de Bacer nuestras aplicaciones e3icientes es la
optimi/acin de las consultas a la base de datos. )n esta seccin eremos como procesa
las consultas MySQL y $uJ aspectos Bay $ue tener en cuenta para acelerar consultas
lentas.
E.1 Hestin interna de las consultas
MySQL reali/a la eAecucin de las consultas en arias etapas.
E.1.1 Cac<e de consultas
)ste mecanismo se puede actiar y desactiar a oluntad en el 3icBero de con3i+uracin
del seridor a traJs de la ariableL
query_cache_type = 1
Cuando est actiada4 MySQL intenta locali/ar la consulta en la cacBe antes de
anali/arla. %ara ello dispone de una tabla BasB interna en donde las claes son el te?to
e?acto de las consultas. )so $uiere decir $ue es sensible a cual$uier ariacin en la
manera de escribir las consultas. %or eAemplo4 estas dos consultas son di3erentes desde
el punto de ista de la cacBeL
SELECT * FROM nombre_tabla
select * FROM nombre_tabla
)l simple BecBo de usar min@sculas en lu+ar de may@sculas Bar $ue la cacBe identi3i$ue
las dos consultas como di3erentes. > lo mismo pasa si se usa un n@mero di3erente de
espacios en blanco.
)s importante recalcar $ue MySQL solo +uarda consultas del tipo S)L)C' ya $ue son las
@nicas $ue tiene sentido +uardar.
E.1.2 Anlisis sintctico y optimi/acin
Cuando una consulta lle+a a MySQL y no se encuentra en la cacBe4 lo primero $ue se
Bace es anali/arla sintcticamente y e?traer in3ormacin de su estructuraL
'ipoL S)L)C'4 I2S).'4 5%6#') o 6)L)')4 o al+@n tipo de comando
administratio como E.#2' o S)'.
QuJ tablas aparecen4 y $uJ alias se usan.
Como es la clusula ,-).).
QuJ otros atributos aparecen.
5na e/ $ue la consulta se descompone en partes ms bsicas4 empie/a la parte
complicada donde se decide como se eAecutar. #$u7 es donde empie/a el trabaAo del
optimi/ador4 cuya tarea es eAecutar la consulta lo ms e3icientemente posible. La mayor7a
de las eces este trabaAo consiste en reducir al m?imo el n@mero de re+istros a
consultar. )sto es debido a $ue la mayor7a de eces el tiempo de entradaGsalida a disco
es el 3actor ms importante en el tiempo total de eAecucin.
MySQL tiene una serie de re+las y Beur7sticas $ue Ban ido eolucionando con las
di3erentes ersiones. > por su propia naturale/a4 3uncionan bien la mayor7a de las eces4
mientras $ue otras producen resultados subptimos.
)l optimi/ador trata de responder una serie de cuestionesL
-ay al+@n 7ndice $ue potencialmente pueda usarse para reducir el n@mero de
re+istros a consultar i
Cual es el meAor 7ndice i SI Bay arias tablas en la consulta4 cual es el meAor para
cada tabla i
QuJ tabla depende de otras en un 01I2 i
Cual es el orden de tablas ptimo en un 01I2 i
)stas pre+untas tienen $ue ser respondidas en muy poco tiempo y eso implica $ue no
tiene tiempo para probar todas las opciones.
)l trabaAo principal se centra en los 7ndices y en el orden de los 01I2.
E.2 *D%LAI2 S*L*C&
La Berramienta 3undamental para anali/ar una consulta y determinar si el optimi/ador
Bace un buen trabaAo4 o como meAorarla4 tenemos el la instruccin )D%L#I2 $ue
colocaremos delante de cada S)L)C' $ue $ueramos anali/ar.
%or eAemplo4 consideremos la tabla titulos de la base de datos bibliotecaL
mysql> DESCRIBE titulos;
+------------+--------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+-------------------+-----------------------------+
| tituloID | int(11) | NO | PRI | NULL | auto_increment |
| titulo | varchar(100) | NO | MUL | | |
| subtitulo | varchar(100) | YES | | NULL | |
| edition | tinyint(4) | YES | | NULL | |
| editID | int(11) | YES | | NULL | |
| catID | int(11) | YES | MUL | NULL | |
| idiomaID | int(11) | YES | MUL | NULL | |
| ao | int(11) | YES | | NULL | |
| isbn | varchar(20) | YES | | NULL | |
| comentario | varchar(255) | YES | | NULL | |
| ts | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| autores | varchar(255) | YES | | NULL | |
+------------+--------------+------+-----+-------------------+-----------------------------+
12 rows in set (0.00 sec)
Si $ueremos consultar un t7tulo por su identi3icador Baremos estoL
mysql> SELECT titulo, subtitulo FROM titulos WHERE tituloID=11;
+-----------------------------+-----------+
| titulo | subtitulo |
+-----------------------------+-----------+
| A Guide to the SQL Standard | NULL |
+-----------------------------+-----------+
1 row in set (0.00 sec)
)n este caso es obio $ue solo puede Baber un resultado ya $ue estamos Baciendo la
consulta para un alor de la clae primaria. La estrate+ia para buscar el re+istro es muy
simpleL buscar en el 7ndice el alor dado y acceder al re+istro directamente. %ara
comprobarlo4 usemos )D%L#I2L
mysql> EXPLAIN SELECT titulo, subtitulo FROM titulos WHERE tituloID=11 \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: titulos
type: const
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: const
rows: 1
Extra:
1 row in set (0.02 sec)
Como esperbamos4 solo Bay un re+istro $ue cumple la condicin (rows: 1*. SIn
embar+o4 lue+o eremos $ue no siempre este alor es e?acto. %ero )D%L#I2 nos da
mucBa ms in3ormacin $ue el n@mero de re+istros e?aminados. Ceamos cual esL
idL el identi3icador del S)L)C'. )n la tabla $ue produce )D%L#I2 solo Bay un
re+istro por cada tabla $ue aparece en la consulta.
select_typeL cual es el papel de esta tabla en toda la consulta i Los alores
posibles son SIMPLE4 PRIMARY4 UNION4 DEPENDENT UNION4 SUBSELECT4 y
DERIVED. Con3orme eamos consultas ms compleAas eremos $ue $uieren decir.
tableL el nombre de la tabla correspondiente.
typeL $uJ tipo de 01I2 se a a usar i )n el eAemplo emos const ya $ue Bay un
alor constante en la consulta. 1tros alores posibles son system4 eq_ref4 ref4
range4 index4 y ALL. Ceremos $ue $uieren decir en la seccin sobre 01I2.
possible_keysL lista de todos los 7ndices $ue MySQL puede utili/ar para buscar
re+istros en la tabla correspondiente.
keyL el 7ndice $ue MySQL esco+e como el meAor y $ue debe estar listado en
possible_keys. -ay e?peciones.
refL indica la columna o columnas $ue se compararan con los alores del 7ndice
esco+ido en key.
rowsL el n@mero de re+istros $ue MySQL piensa $ue Ba de leer para satis3acer la
consulta. Si se Bacen mucBas inserciones y borrados de re+istros4 es coneniente
eAecutar #2#LIX) '#BL)S 3recuentemente para mantener actuali/adas las
estad7sticas $ue MySQL usa para esta estimacin.
extraL in3ormacin adicional $ue MySQL Ba usado para anali/ar la consulta.
Compli$uemos li+eramente el eAemplo y bus$uemos un ran+o de aloresL
mysql> EXPLAIN SELECT titulo FROM titulos WHERE tituloID BETWEEN 1 AND 11 \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: titulos
type: range
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: NULL
rows: 7
Extra: Using where
1 row in set (0.05 sec)
)n este caso type Ba cambiado de const a range para indicar $ue estamos buscando
un ran+o de re+istros4 no uno solo. 'ambiJn Ba aparecido Using where en el campo
Extra. )so indica $ue MySQL adierte de $ue se aplican las restricciones de la clusula
,-).) a lo Bora de seleccionar re+istros.
#Bora amos a er si Bacemos una consulta por una columna sin 7ndices en una tabla con
1 milln de re+istrosL
mysql> select count(*) from titulos_big where titulo >= "The";
+----------+
| count(*) |
+----------+
| 285344 |
+----------+
1 row in set (4.62 sec)
)ste es el tiempo de eAecucin la primera e/ $ue accedemos a la tabla despuJs de
iniciali/ar el seridor. Si olemos a eAecutar la misma consulta inmediatamente despuJs
obtenemos estoL
mysql> select count(*) from titulos_big where titulo >= "The";
+----------+
| count(*) |
+----------+
| 285344 |
+----------+
1 row in set (1.17 sec)
Como puede obserarse el tiempo es mucBo menor. )sto es debido a $ue la mayor7a de
los datos $ue Bay $ue consultar estn en la cacBe en la se+unda eAecucin. )ste es un
detalle important7simo a la Bora de reali/ar tests de elocidad. Siempre $ue Ba+amos una
prueba debemos ase+urarnos $ue la cacBe est ac7a4 ya $ue si no los resultados $ue
obten+amos no tendrn en cuenta de 3orma correcta los accesos a disco necesarios. -ay
$ue pensar $ue en un entorno de produccin con mucBas consultas concurrentes4 es
probable $ue la parte de la cacBe disponible para nuestra consulta sea muy pe$ue8a4 por
lo $ue siempre tendremos $ue considerar el caso peor en $ue nada est en la cacBe
antes de la consulta. )sta consideracin es ms importante si la tabla cabe entera en
memoria ya $ue puede proocar $ue la consulta ni si$uiera acceda a disco.
)l comando )D%L#I2 nos con3irma $ue la consulta no Ba usado nin+@n 7ndiceL
mysql> EXPLAIN select count(*) from titulos_big where titulo >= "The" \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: titulos_big
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 1004142
Extra: Using where
1 row in set (0.00 sec)
#8adamos un 7ndice por la columna titulo para intentar meAorar la elocidad de la
consultaL
mysql> ALTER TABLE titulos_big ADD INDEX `titulo_index`(`titulo`);
Query OK, 1000000 rows affected (11 min 19.12 sec)
Records: 1000000 Duplicates: 0 Warnings: 0
6el resultado de esta accin Bay $ue destacar el tiempo de eAecucin4 $ue es muy
eleado. )ste tiempo es para una tabla de 1 milln de re+istro4 pero Bay $ue pensar $ue
en bases de datos reales podemos tener 1;; millones 3cilmente. )so $uiere decir $ue si
nos damos cuenta tarde de la necesidad de un 7ndice4 tendremos $ue parar el seridor un
tiempo considerable para crear el 7ndice.
)l tiempo de eAecucin con el 7ndice disminuyeL
mysql> select count(*) from titulos_big where titulo >= "The";
+----------+
| count(*) |
+----------+
| 285344 |
+----------+
1 row in set (2.51 sec)
> en una se+unda eAecucin se nota msL
mysql> select count(*) from titulos_big where titulo >= "The";
+----------+
| count(*) |
+----------+
| 285344 |
+----------+
1 row in set (0.37 sec)
#Bora la in3ormacin $ue da )D%L#I2 es meAorL
mysql> EXPLAIN select count(*) from titulos_big where titulo >= "The" \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: titulos_big
type: range
possible_keys: titulo_index
key: titulo_index
key_len: 102
ref: NULL
rows: 502071
Extra: Using where; Using index
1 row in set (0.01 sec)
#Bora se est usando el 7ndice titulo_index y la consulta es tipo range. )l campo
)?tra nos indica con Using index $ue la consulta @nicamente accede al 7ndice y no lee
nin+@n re+istro. )sto es debido a $ue lo @nico $ue Bacemos es contar re+istros y no
Bacemos nada ms con los datos.
1tro detalle importante es er la discrepancia entre la estimacin de re+istros $ue da
EXPLAIN y la cantidad real de re+istros $ue realmente se acceden en la consulta (en esta
caso casi la mitad*.
#Bora eamos un eAemplo con subselectsL
mysql> SELECT titulo FROM titulos_big WHERE tituloID IN (SELECT MAX(tituloID)
FROM titulos_big);
+---------------------------------------+
| titulo |
+---------------------------------------+
| A Guide to the SQL Standard 722530606 |
+---------------------------------------+
1 row in set (1.38 sec)
mysql> SELECT titulo FROM titulos_big WHERE tituloID = (SELECT MAX(tituloID)
FROM titulos_big);
+---------------------------------------+
| titulo |
+---------------------------------------+
| A Guide to the SQL Standard 722530606 |
+---------------------------------------+
1 row in set (0.00 sec)
)stas dos consultas son semnticamente i+uales4 y la una di3erencia es $ue en la primera
se usa el operador I2 para seleccionar el re+istro $ue buscamos4 mientras $ue en la
se+unda se usa el operador Z. Sin embar+o el tiempo de eAecucin es radicalmente
di3erente. )sto es una muestra de $ue el optimi/ador de MySQL no siempre act@a como
podr7amos esperar. Ceamos como usando )D%L#I2 podemos er $uJ Ba ocurridoL
mysql> EXPLAIN SELECT titulo FROM titulos_big WHERE tituloID IN (SELECT
MAX(tituloID) FROM titulos_big)\G
*************************** 1. row ***************************
id: 1
select_type: PRIMARY
table: titulos_big
type: index
possible_keys: NULL
key: titulo_index
key_len: 102
ref: NULL
rows: 1004142
Extra: Using where; Using index
*************************** 2. row ***************************
id: 2
select_type: DEPENDENT SUBQUERY
table: NULL
type: NULL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: NULL
Extra: Select tables optimized away
2 rows in set (0.00 sec)
)l campo type de la primera 3ila es index lo $ue $uiere decir $ue MySQL Ba recorrido
todo el 7ndice de tabla para er $ue alores estaban IN. <iAarse $ue el campo rows tiene
un alor de 1 milln apro?imadamente. )n la se+unda tabla todo es 25LL ya $ue se+@n el
campo Extra: Select tables optimized away $uiere decir $ue el alor del select
se Ba obtenido de manera optima internamente.
Ceamos $ue nos dice )D%L#I2 de la se+unda ersinL
mysql> EXPLAIN SELECT titulo FROM titulos_big WHERE tituloID = (SELECT
MAX(tituloID) FROM titulos_big)\G
*************************** 1. row ***************************
id: 1
select_type: PRIMARY
table: titulos_big
type: const
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: const
rows: 1
Extra:
*************************** 2. row ***************************
id: 2
select_type: SUBQUERY
table: NULL
type: NULL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: NULL
Extra: Select tables optimized away
2 rows in set (0.00 sec)
#Bora en la primera 3ila el campo type es const4 lo $ue $uiere decir $ue se Ba accedido
a un alor directamente a traJs del 7ndice4 por lo $ue el campo rows ale 1. %or eso es
mucBo ms rpido.
Sin embar+o4 las dos consultas representan lo mismo4 pero el optimi/ador de MySQL no
Ba sabido resolerlo en uno de los casos. %ara eso Bemos utili/ado )D%L#I2 y Bemos
isto cual era la ra/n.
#Bora eamos un eAemplo donde la consulta depende de los alores de dos columnas con
7ndice. %or eAemploL
mysql> SELECT COUNT(*) FROM titulos_big WHERE tituloID > 500000 AND editID <
5;
+----------+
| COUNT(*) |
+----------+
| 276810 |
+----------+
1 row in set (0.26 sec)
mysql> EXPLAIN SELECT COUNT(*) FROM titulos_big WHERE tituloID > 500000 AND
editID < 5 \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: titulos_big
type: range
possible_keys: PRIMARY,publIdIndex
key: publIdIndex
key_len: 5
ref: NULL
rows: 245798
Extra: Using where; Using index
1 row in set (0.00 sec)
)n este caso MySQL tiene dos posibles 7ndices para reali/ar el S)L)C'. )n +eneral se
esco+er el $ue ms redu/ca el n@mero de re+istros a e?aminar. )n este caso4 como
editID < 5 representa menos de la mitad de los re+istros y tituloID > 500000
representa Austo la mitad4 MySQL esco+e el 7ndice correspondiente a editID. Sin
embar+o4 si cambiamos el alor $ue se compara con editIDL
mysql> EXPLAIN SELECT COUNT(*) FROM titulos_big WHERE tituloID > 500000 AND
editID < 15 \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: titulos_big
type: range
possible_keys: PRIMARY,publIdIndex
key: PRIMARY
key_len: 4
ref: NULL
rows: 490916
Extra: Using where
1 row in set (0.00 sec)
)n este caso editID < 15 representa ms de la mitad de los re+istros4 y MySQL
cambia a PRIMARY.
)n +eneral4 es importante recordar $ue MySQL toma sus decisiones en lo $ue es capa/
de adiinar o estimar de los datos. )sto se Bace en base a unas estad7sticas $ue cambian
con el tipo de tabla4 por lo $ue los resultados obtenidos podr7an ser di3erentes con otro
tipo de tablas (Bemos usado Inno6B*. #dems4 si eAecutamos #2#LIX) '#BL)
actuali/aremos las estad7sticas4 y por tanto a3ectaremos las decisiones del optimi/ador.
01I2
Las cosas se complican cuando empe/amos a usar ms de una tabla en una consulta.
%or eAemplo4 si $ueremos obtener una lista no ordenada de todos los libros con todos sus
autores4 utili/aremos la si+uiente consultaL
mysql> EXPLAIN SELECT titulo, nombreAutor FROM titulos_big,
rel_titulo_autor_big, autores WHERE rel_titulo_autor_big.IDautor =
autores.IDautor AND rel_titulo_autor_big.tituloID = titulos_big.tituloID \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: autores
type: index
possible_keys: PRIMARY
key: nombreAutor
ref: NULL
rows: 26
Extra: Using index
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: rel_titulo_autor_big
type: ref
possible_keys: PRIMARY,IDautor
key: IDautor
ref: biblioteca.autores.IDautor
rows: 128309
Extra: Using index
*************************** 3. row ***************************
id: 1
select_type: SIMPLE
table: titulos_big
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
ref: biblioteca.rel_titulo_autor_big.tituloID
rows: 1
Extra:
3 rows in set (0.00 sec)
La primera 3ila se re3iere a autores4 por lo $ue S)L)C' comien/a por acceder a esta
tabla. Como type es index $uiere decir $ue accede a todos los re+istros de la tabla a
traJs del 7ndice4 sin leerlos. Sin embar+o a$u7 podemos er una e?cepcin $ue Bace
$ue la clae esco+ida no estJ entre las listadas en possible_keys. )sto ocurre cuando
las columnas a seleccionar de la tabla estn contenidas 7nte+ramente en un 7ndice4 y de
esa manera es ms e3iciente $ue acceder por el 7ndice primario y leer los re+istros.
)n un se+undo paso se accede a rel_titulo_autor. )l tipo de 01I2 es ref lo $ue
$uiere decir es $ue para cada re+istro anterior (autores* se acceder a arios de
rel_titulo_autores para los cuales coincida la clae IDautor (campo key* .
#dems nos dice $ue la clae se Ba comparado con autores.IDautor de cada
re+istro preio. )n este momento4 el campo roOs da una media de los re+istros $ue se
tienen $ue consultar de rel_titulo_autores por cada re+istro de autores del paso
anterior.
)n el @ltimo paso se Ba accedido a la tabla titulos4 solo se Ba accedido a un re+istro
por cada +rupo de re+istros del paso anterior (type es eq_ref* 4 se Ba usado la clae
primaria para seleccionar el re+istro (key es PRIMARY* 4 y esta se Ba comparado con la
columna rel_titulo_autor.tituloID (campo ref* de cada re+istro el paso anterior.
#$u7 tenemos otro eAemploL
mysql> EXPLAIN SELECT titulo, nombreAutor FROM titulos, rel_titulo_autor,
autores
WHERE titulos.editID=2 AND titulos.tituloID = rel_titulo_autor.tituloID
AND autores.IDautor = rel_titulo_autor.IDautor
ORDER BY titulo \G
*************************** 1. row ***************************
select_type: SIMPLE
table: titulos_big
type: ref
possible_keys: PRIMARY,publIdIndex
key: publIdIndex
ref: const
rows: 42458
Extra: Using where; Using filesort
*************************** 2. row ***************************
select_type: SIMPLE
table: rel_titulo_autor_big
type: ref
possible_keys: PRIMARY,IDautor
key: PRIMARY
ref: biblioteca.titulos_big.tituloID
rows: 1
Extra: Using index
*************************** 3. row ***************************
select_type: SIMPLE
table: autores
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
ref: biblioteca.rel_titulo_autor_big.IDautor
rows: 1
Extra:
)ste resultado nos dice $ue la consulta est bien optimi/ada ya $ue en cada paso se usa
un 7ndice para acceder a los re+istros (la columna key no tiene nin+@n 25LL*. La primera
3ila contiene un Using filesort4 y eso $uiere decir $ue se necesita un paso e?tra4es
decir4 primero se acede a la lista de claes primarias $ue pasan el test del ,-).)
(Using where*4 se ordenan4 y despuJs se accede a los re+istros. %ero como a
precedido del Using where si+ni3ica $ue este paso se aplica a pocos re+istros. )n este
primer paso se seleccionan los t7tulos $ue pertenecen a la editorial correspondiente
(editI6Z2*
Las dos 3ilas restantes tienen lo $ue esperamos. #cceso a traJs de clae primaria a muy
pocos elementos ya $ue por cada t7tulo seleccionado accederemos a muy pocos autores.
#Bora podr7amos Bacer la prueba de eliminar el 7ndice publInde? de la tabla titulos=bi+
para er como reacciona MySQL.
mysql> EXPLAIN SELECT titulo, nombreAutor FROM titulos_big,
rel_titulo_autor_big, autores WHERE titulos_big.editID=2 AND
titulos_big.tituloID = rel_titulo_autor_big.tituloID AND autores.IDautor =
rel_titulo_autor_big.IDautor ORDER BY titulo \G
*************************** 1. row ***************************
select_type: SIMPLE
table: titulos_big
type: index
possible_keys: PRIMARY
key: titulo_index
ref: NULL
rows: 998706
Extra: Using where
*************************** 2. row ***************************
select_type: SIMPLE
table: rel_titulo_autor_big
type: ref
possible_keys: PRIMARY,IDautor
key: PRIMARY
ref: biblioteca.titulos_big.tituloID
rows: 1
Extra: Using index
*************************** 3. row ***************************
select_type: SIMPLE
table: autores
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
ref: biblioteca.rel_titulo_autor_big.IDautor
rows: 1
Extra:
)n este caso el orden de acceso a las tablas Ba cambiado. )l primer paso es aBora
recorrer toda la tabla titulos=bi+ usando el 7ndice de la clae primaria. # partir de a$u7 se
busca los autores de cada t7tulo accediendo primero a rel_titulo_autor_big y lue+o
a autor.
6esa3ortunadamente4 la estrate+ia de MySQL para determinar el orden ptimo de acceso
a las tablas en un 01I2 no es muy buena. 6e BecBo4 se comprueban todas las posibles
combinaciones de tablas para determinar la meAor4 y en el caso de tener mucBas4 eso
supone un n@mero muy alto de combinaciones $ue en ocasiones puede lle+ar a Bacer
$ue el tiempo dedicado por el optimi/ador sea mucBo mayor $ue el de la consulta en s7 P
Ms adelante eremos como se puede 3or/ar a MySQL a $ue si+a un determinado orden.
E.! Caracter6sticas del optimi/ador
Cuando se $uiere comprobar si una consulta es e3iciente4 una 3uente de problemas com@n
es como MySQL trata los datos de prueba. SI no se sabe como 3unciona el optimi/ador4
se puede perder mucBo tiempo intentando solucionar un problema $ue no e?iste4 o lo $ue
es peor4 $ue Ba sido creado con los datos de prueba.
)n +eneral4 MySQL usa un 7ndice siempre $ue crea $ue usarlo dar meAor rendimiento
$ue no Bacerlo. )sto puede llear a situaciones e$uiocadas durante la 3ase de pruebas.
)sto es debido4 en +eneral4 a dos problemas.
%oca di"ersidad
# pesar de +enerar miles o millones de re+istros de prueba4 MySQL puede ele+ir no usar
nuestros 7ndices si los datos contienen poca diersidad. %or $uJ puede ocurrir i
Ima+inemos una tabla $ue +uarda datos Bistricos sobre el clima de mucBas ciudadesL
CREATE TABLE weather
(
city VARCHAR(100) NOT NULL,
high_temp TINYINT NOT NULL,
low_temp TINYINT NOT NULL,
the_date DATE NOT NULL,
INDEX (city),
INDEX (the_date),
)
Supon+amos $ue para Bacer pruebas consideramos los datos de dos a8os4 por eAemplo
19&; y 19&1. 6espuJs de al+unas consultas nos damos cuanta $ue MySQL no usa nunca
el 7ndice the_date. )l problema es $ue usar ese 7ndice solo puede descartar el !;Y de
los re+istros4 y en ese caso el sistema considera $ue es ms rpido leer la tabla
directamente $ue usar el 7ndice.
Ms o menos el punto en el $ue MySQL decide usar un 7ndice es cuando puede descartar
ms del :;Y de los re+istros4 aun$ue este n@mero no iene de nin+una 3rmula sino de la
e?periencia de los desarrolladores de MySQL. #dems4 di3erentes motores de
almacenamiento tienen umbrales di3erentes.
La ra/n de esto es el tiempo de acceso al disco. Los 7ndices se acceden en orden4 y por
lo tanto4 no de manera secuencial se+@n su disposicin en el disco4 por lo $ue las lecturas
no son e3icientes en este sentido. Su e3iciencia iene de $ue se leen mucBa menos
cantidad de datos. %or otro lado4 las tablas4 a leerse sin orde4 se Bace si+uiendo su
disposicin en disco4 por lo $ue los tiempos de espera son muy e3icientes4 aun$ue como
contrapartida se lee mucBa ms cantidad de datos.
1rdenacin con 6ndices
5no de los puntos dJbiles de MySQL es la ordenacin de los resultados de una consulta.
-ay dos problemas con la ordenacin. %rimero4 ordenar siempre a8ade coste de C%54 y
eso no Bay manera de resolerlo a parte de usar C%5s ms rpidas. )l otro problema
importante es $ue Bay $ue recordar $ue MySQL solo puede usar un 7ndice por tabla en
una consulta. 6e manera $ue si tenemos un 7ndice $ue podr7a ser utili/ado para ordenar4
probablemente no lo ser por$ue ya se Babr usado otro para acceder a los datos. )s el
caso t7pico en $ue el optimi/ador accede a los datos a traJs de una clae primaria4 y
lue+o solicitamos ordenacin por otra columna.
La @nica manera de solucionar el se+undo problema es a8adir la columna por la cual
$ueremos ordenar al 7ndice. 5sando el eAemplo de los datos meteorol+icos4 si $ueremos
$ue esta consulta sea e3icienteL
SELECT * FROM weather WHERE city = 'Toledo' ORDER BY the_date DESC
#8adiremos este 7ndiceL
ALTER TABLE weather DROP INDEX city, ADD INDEX (city, the_date)
#$u7 es importante recordar $ue el orden de las columnas en el 7ndice es mu importante.
Si $ueremos acceder a los datos a traJs de city4 est columna debe aparecer lo ms a
la i/$uierda del 7ndice.
)n este punto podr7amos estar tentados de suprimir el 7ndice the_date4 pero solo
deberemos Bacerlo cuando no Baya nin+una consulta $ue use esta columna en una
clusula WHERE. %or$ue la parte the_date del 7ndice compuesto no se puede usar para
acceder a los datos ya $ue est en la parte derecBa.
Consultas imposibles
Ima+inemos una consulta como estaL
mysql> SELECT titulo FROM titulos_big WHERE tituloID < 100000 AND tituloID >
200000;
Empty set (0.16 sec)
)identemente no retorna nin+@n resultado ya $ue la clusula ,-).) is imposible $ue
se cumpla. # pesar de ello4 MySQL no nos aisa. Sin embar+o4 si usamos )D%L#I2L
mysql> EXPLAIN SELECT titulo FROM titulos_big WHERE tituloID < 100000 AND
tituloID > 200000 \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: NULL
type: NULL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: NULL
Extra: Impossible WHERE noticed after reading const tables
Cemos $ue MySQL s7 $ue detecta $ue es una consulta imposible4 y nos lo dice en el
campo )?tra.
E.# Identi3icar consultas lentas
Saber por$uJ una consulta es lenta es di37cil4 pero para detectar cuales son esas
consultas MySQL proporciona el mecanismo del slow query log. )ste mecanismo se
actia al poner el marcBa el seridor con la opcinL
--lo6-slo8-q#eriesODfile_nameP
#l actiarlo4 MySQL +uardar in3ormacin de todas las consultas $ue tarden ms de
long_query_time se+undos y Bayan le7do como m7nimo min_examined_row_limit
re6istros:
Si lo actiamos4 MySQL +uardar un re+istro de todas las consultas $ue tarden ms de un
tiempo especi3icado. #dems de la consulta en s74 re+istra ms datos.
# Time: 030303 0:51:27
# User@Host: user[user] @ client.example.com [192.168.50.12]
# Query_time: 25 Lock_time: 0 Rows_sent: 3949 Rows_examined: 378036
select ArticleHtmlFiles.SourceTag, ArticleHtmlFiles.AuxId from
ArticleHtmlFiles left
join Headlines on ArticleHtmlFiles.SourceTag = Headlines.SourceTag and
ArticleHtmlFiles.AuxId = Headlines.AuxId where Headlines.AuxId is NULL;
# pesar de $ue se nos da mucBa in3ormacin4 Bay $ue ser cuidadoso al interpretarla. )l
BecBo de $ue una consulta Baya tardado mucBo tiempo en un determinado momento4 no
$uiere decir $ue siempre aya a serlo. )so puede ser por arios motiosL
La tabla puede haber estado bloqueada en el momento de hacer la consulta, y dentro del
tiempo que ha tardado est incluido el tiempo de espera hasta que la tabla ha sido liberada.
Par ello se nos proporciona el tiempo Lock_time $ue se Ba esperado por blo$ueos.
No hay ningn parte de esa tabla en la cache. Por ejemplo, la primera vez que se ejecuta una
consulta despus de poner en marcha el servidor.
-ab7a un proceso Baciendo un respaldo en ese mismo momento y eso reduce
mucBo el tiempo de acceso a disco.
)l seridor puede Baber tenido un pico de trabaAo Austo en ese momento
)n resumen4 este re+istro nos aisa de errores potenciales4 pero no es un prueba
de3initia de $ue una consulta deba optimi/arse. #Bora bien4 si una misma consulta
aparece mucBas eces y en situaciones di3erentes4 Bay mucBas posibilidades de $ue
Baya $ue prestarle atencin.
E.5 Modi3icar el comportamiento de MySQL
MucBos sistemas de bases de datos relaciones implementan una serie de atributos o
@ints $ue permiten dar pistas al optimi/ador para meAorar sus resultados. )n esta seccin
eremos al+unos de esos Bints. )stos casi siempre aparecen Austo despuJs de S)L)C'L
SELECT SQL_CACHE * FROM mytable ...
Sin embar+o4la mayor7a de ellos no son SQL estndar4 as7 $ue podemos usarlos de esta
maneraL
SELECT /*! SQL_CACHE */ * FROM mytable ...
6e esta manera solo MySQL interpretar los Bints4 y el resto de seridores se los saltarn
como si 3uese un comentario. Incluso se puede especi3icar $ue ersin de seridor puede
usar el Bint o noL
CREATE /*!32302 TEMPORARY */ TABLE t (a INT);
6e esta manera el atributo ')M%1.#.> solo ser tenido en cuenta por seridores
MySQL con ersin 3.23.;2 o superiores.
1rden de los 01I2
MySQL no se preocupa del orden en $ue aparecen las tablas en un 01I2. )L optimi/ador
probar todas las combinaciones y esco+er la $ue crea ms e3iciente. )sto puede
proocar $ue al+unas eces la eleccin no sea la ms ptima. %ara comprobarlo siempre
podemos usar )D%L#I2. SI el resultado nos con3irma $ue e?iste un orden meAor4 se
puede usar S'.#IE-'=01I2L
SELECT * FROM table1 STRAIGHT_JOIN table2 WHERE ...
)n este caso el orden del 01I2 ser e?actamente el indicado en el S)L)C'.
5so de 6ndices
)l optimi/ador tambiJn decide $uJ 7ndices usar en cada consulta. > como en el caso de
01I24 tambiJn e?isten Bints para 3or/ar un comportamiento di3erente al del optimi/ador.
%or eAemplo4 se puede 3or/ar a MySQL a $ue escoAa un 7ndice de una lista $ue le demos4
en lu+ar de considerarlos todosL
SELECT * FROM titulos USE INDEX (editIDindex, catIDindex) WHERE ...
1 podemos Bacer lo contrario y decirle a MySQL $uJ 7ndices no $ueremos considerar4 y
$ue use los restantesL
SELECT * FROM titulos IGNORE INDEX (tituloIDindex) WHERE ...
> si $ueremos 3or/ar a usar un 7ndice en concretoL
SELECT * FROM titulos FORCE INDEX (editIDindex) WHERE ...
)sta @ltimo Bint puede ser desobedecido si MySQL detecta $ue es imposible resoler la
consulta usndolo.
# partir de MySQL !.1.1: Ba Babido al+unos cambios a esta sinta?is. %rimero4 se puede
usar el tributo 5S) I26)D ac7oL
SELECT * FROM titulos USE INDEX () WHERE ...
)sto si+ni3ica $ue $ueremos $ue MySQL no use nin+@n 7ndice para esa tabla.
1tra noedad es $ue se puede especi3icar a $uJ parte de la consulta se aplica la
restriccinL FOR ORDER BY, FOR GROUP BY, FOR JOIN. %or eAemploL
SELECT * FROM t1 USE INDEX (i1) IGNORE INDEX FOR ORDER BY (i2) ORDER BY a;
Con esto decimos al optimi/ador $ue no use el 7ndice i2 a la Bora de reali/ar la
ordenacin.
&ama8o de los resultados
-ay unos Bints $ue permiten decirle al seridor como tratar los resultados en 3uncin de
su tama8o. -ay $ue usarlos solo cuando estemos realmente se+uros de $ue los
necesitamos para meAorar la e3iciencia de una consulta. %or$ue si los usamos demasiado
podemos Bacer $ue el seridor aya ms lento en conAunto.
Si usamos SQL=B5<<).=.)S5L' 3or/amos a $ue MySQL +uarde los resultados en una
tabla temporal. )so puede ser @til cuando el n@mero de re+istros es muy alto y el cliente
puede tardar mucBo tiempo en procesarlos. )l e3ecto es $ue si Bemos BecBo un blo$ueo
para reali/ar la consulta lo podremos liberar antes.
1tro Bint $ue podemos usar cuando sabemos $ue el resultado de una consulta puede ser
muy +rande es SQL=BIE=.)S5L'. )n es te caso MySQL puede ser mucBo ms a+resio
a la Bora de decidir usar tablas temporales en disco. #dems puede decidir no crear
7ndices en los resultados para ordenarlos.
Cac<e de consultas
Como Bemos e?plicado anteriormente4 MySQL tiene una cacBe para las consultas
S)L)C'. Se puede controlar si una consulta Ba de ser almacenada en la cacBe o no. )l
comportamiento de estos Bints depende del alor de la ariable query_cache_type:
Si ale ;4 entonces la cacBe est desconectada y no se puede 3or/ar a $ue
3uncione.
Si ale 1 la cacBe est actiada y toda las consultas se +uardan4 e?cepto las $ue
llean SQL=21=C#C-)
Si ale 2 la cacBe est desactiada e?cepto para a$uellas consultas $ue llean
SQL=C#C-)
F. Cistas
Las istas ("iews* Bacen posible el de3inir representaciones especiales de una tabla. 5na
ista se comporta de manera casi idJntica a una tabla. Se pueden consultar con S)L)C'
y modi3icar con I2S).'4 5%6#') y 6)L)'). Las istas se pueden usar en MySQL
desde la ersin !.;. -ay dos ra/ones bsicas para usar istasL
Se+uridad. -ay ocasiones en las $ue $uerr7amos $ue un usuario pudiera acceder
a una tabla4 pero no a todos sus re+istros. 5n eAemplo es una tabla con los datos
de los empleados de una empresa. )n +enera4 $uerremos $ue todos los
empleados accedan a esa tabla4 pero $ue no puedan acceder a todos las columnas
de cada re+istro donde probablemente Bay in3ormacin con3idencial.
La solucin es crear una ista de la tabla de empleados en la $ue solo apare/can
las columnas con in3ormacin p@blica4 y permitir el acceso a la ista y no a la tabla
ori+inal.
*3iciencia. )n mucBas ocasiones las aplicaciones eAecutan mucBas eces la
misma consulta para seleccionar un mismo conAunto de re+istros de una tabla. )n
lu+ar de deAar $ue cada usuario o pro+ramador repita una y otra e/ la misma
consulta4 podemos crear una ista con dicBa consulta y Bacerla isible a los
usuarios o pro+ramadores.
Las istas son como tablas irtuales cuyo contenido es el resultado de un S)L)C'. %or
eAemplo4 si $ueremos $ue los al+unos usuarios de la base de datos biblioteca ten+an
acceso a la tabla titulos4 pero solo a las columnas tituloID4 titulo y subtitulo
ordenadas al3abJticamente Baremos los si+uienteL
CREATE VIEW v1 AS
SELECT tituloID, titulo, subtitulo FROM titulos
ORDER BY title, subtitle
%ero la de3inicin puede ser tan compleAa como nuestras necesidades. 1tro eAemploL si
$ueremos determinados usuarios de biblioteca solo puedan acceder a la lista de libros en
espa8ol4 y de cada uno solo saber la editorial y la cate+or7a crearemos la si+uiente istaL
CREATE VIEW v2 AS
SELECT titulo, nombreEditorial, nombreCat FROM titulos, editoriales,
categorias
WHERE titulos.editID = editoriales.editID
AND titulos.catID = categorias.catID
AND langID = 5
%ara modi3icar una ista con I2S).'4 5%6#') y 6)L)') la @nica restriccin $ue se
aplica es el comando S)L)C' $ue se Ba usado para crearla. %ara ello se aplican las
si+uientes re+lasL
)l comando S)L)C' no debe contener E.15% B>4 6IS'I2C'4 LIMI'4 52I12 o
-#CI2E.
Las istas $ue se 3orman con la consulta de dos o ms tablas son casi siempre
imposibles de modi3icar.
Las istas deber7an contener todas las columnas para las $ue Bay claes primarias
o 7ndices @nicos o claes 3orneas. Si no lo Bacen4 la opcin
updatable_views_with_limit de MySQL de3ine $uJ cambios deben producir
un aiso (comportamiento por de3ecto* o dar un error.
#l crear una ista Bay una serie de atributos $ue podemos usar. La sinta?is de C.)#')
CI), es la si+uienteL
CRE%TE OOR RE.L%CEP O%L"ORIT7M D A=DEFI=ED | MER"E | TEM.T%2LEP
EIE> name O9/ol#mnlist;P %S sele/t /ommand
O>IT7 OC%SC%DED | LOC%LP C7ECC O.TIO=P
)l si+ni3icado de las opciones esL
1. .)%L#C) si+ni3ica $ue si e?ist7a una ista con el mismo nombre debe de ser
reempla/ada con la nuea de3inicin sin dar nin+@n mensaAe de error.
#LE1.I'-M nos dice como se representa la ista internamente. )sta opcin est
sin documentar Basta el momento.
,I'- C-)CQ 1%'I12 si+ni3ica $ue est permitido modi3icar los re+istros solo si
las condiciones ,-).) del S)L)C' se continuaran cumpliendo despuJs de la
modi3icacin. )sta opcin solo tiene sentido si la ista $ue $ueremos crear a a ser
modi3icada.
La ariante L1C#L a3ecta a las istas $ue se derian a su e/ de otras istas.
)sto si+ni3ica $ue solo se consideran las condiciones ,-).) de la primera
ista4 no las de las si+uientes.
)l e3ecto de la ariante C#SC#6) es el contrario. Se consideran todas las
condiciones ,-).).
1G. %rocedimientos Almacenados
Los procedimientos almacenados (Stored %rocedures, S%* suponen una importante
innoacin introducida en MySQL en la ersin !.;. Son 3unciones SQL de3inidas por el
usuario $ue se eAecutan directamente en el seridor. Con los S% es posible +uardar parte
de la l+ica de la aplicacin clienteGseridor en el seridor.
)n este cap7tulo eremos por$uJ los S% son una buena idea (ms elocidad4 ms
se+uridad para los datos4 menos duplicacin de cdi+o4 ...*.
)n +eneral4 la/ ra/ones para usar S% sonL
Celocidad. )n mucBas ocasiones4 determinadas operaciones de una aplicacin
pueden suponer $ue mucBos datos sean eniados del seridor al cliente y
iceersa. )l cliente eAecuta un S)L)C' $ue produce mucBos resultados4 $ue son
eniados desde el seridor al cliente. )l cliente los procesa y en7a una +ran lista
de 5%6#')s de uelta al seridor. Si todos estos pasos se pudieran eAecutar en el
seridor nos eitar7amos una +ran sobrecar+a de la comunicacin clienteMseridor.
#dems4 MySQL puede preprocesar el cdi+o de los S%4 eitando tener $ue
compilar el cdi+o de un S% cada e/ $ue se eAecuta. Sin embar+o4 MySQl no
documenta $ue tipo de optimi/aciones reali/a cuando precompila los S%.
6e todas 3ormas4 usar S% no +aranti/a una meAora en la elocidad de eAecucin de
nuestras aplicaciones. Solo se consi+uen meAoras si el cdi+o del S% es e3iciente.
> como SQL es un len+uaAe mucBo ms primitio $ue otros4 no siempre es posible
escribir cdi+o e3iciente.
1tro aspecto a tener en cuenta es $ue los S% aumentan la car+a del seridor4
mientras $ue la reducen en la parte del cliente. )l resultado de este balance
depender mucBo de como estJ con3i+urado nuestro sistema y de cuales sean los
cuellos de botella de nuestra aplicacin.
.eutili/acin de cdi+o. 1curre 3recuentemente $ue di3erentes aplicaciones4 o
di3erentes usuarios de una misma aplicacin reali/an la misma operacin una y
otra e/. Si la l+ica de estas operaciones puede ser trasladada al seridor en
3orma de S%s entonces se consi+ue reducir la redundancia de cdi+o4 y adems4 y
muy importante4 el sistema es mucBo ms 3cil de mantener.
Se+uridad de los datos. -ay mucBas aplicaciones en la $ue la inte+ridad de los
datos es cr7tica4 como las relacionadas con el sector 3inanciero. )n estos casos4 es
deseable $ue los usuarios no puedan acceder directamente a determinadas tablas.
La manera de obtener los datos es a traJs de S%s $ue se encar+an de reali/ar los
S)L)C'4 5%'#') o I2S).' a traJs de los S%s $ue son isibles a los usuarios.
5n bene3icio adicional es $ue los administradores pueden monitori/ar los accesos
a la base de datos mucBo ms 3cilmente.
La +ran desentaAa de los S% es $ue normalmente su portabilidad es muy baAa4 con los
$ue las 3unciones escritas para un sistema concreto no se eAecutaran directamente en otro
sistema. La ra/n es $ue cada sistema de bases de datos usa su propia sinta?is y sus
propias e?tensiones para los S%4 de 3orma $ue estos no estn estandari/ados.
(e3inir un S%
La meAor manera de ilustrar como 3unciona un S% es con un eAemplo. )l primer detalle a
tener en cuenta es $ue al de3inir un S% utili/aremos el carcter IRI $ue es el delimitador por
de3ecto. %or esta ra/n deberemos cambiar el delimitador4 y en este eAemplo usaremos la
secuencia IjjI.L
mysql> delimiter $$
#Bora el eAemplo. Supon+amos $ue tenemos una tabla en la $ue almacenamos en 3orma
de te?to comentarios de los usuarios4 de un m?imo de 2!! caracteres de lon+itud.
#dems4 tenemos una columna en la $ue +uardamos un resumen de n<255 caracteres
del comentario. # la Bora de +uardar el resumen podemos Bacer dos cosasL i+norar el
l7mite de n y MySQL truncar la cadena y se $uedar con el principio de comentario4 o
Bacer al+o ms complicado como +uardar el principio y el 3inal del comentario4 colocando
la cadena I...I en medio. %ara Bacer esto de3iniremos un S% como esteL
mysql> CREATE FUNCTION acortar(s VARCHAR(255), n INT)
-> RETURNS VARCHAR(255)
-> BEGIN
-> IF ISNULL(s) THEN
-> RETURN '';
-> ELSEIF n<15 THEN
-> RETURN LEFT(s, n);
-> ELSE
-> IF CHAR_LENGTH(s) <= n THEN
-> RETURN s;
-> ELSE
-> RETURN CONCAT(LEFT(s, n-10), ' ... ', RIGHT(s, 5));
-> END IF;
-> END IF;
-> END$$
)ste procedimiento lo $ue Bace es recibir una cadena de caracteres s (tipo
C#.C-#.(2!!** y un entero n (tipo I2'* y retorna una cadena de caracteres
(C#.C-#.(2!!**. )l entero n indica a $uJ lon+itud $ueremos acortar la cadena inicial s.
Si nS1!4 consideramos $ue son muy pocos caracteres como para +uardar el principio y el
3inal y simplemente +uardamos el principio. Si nTZ1! y la cadena de entrada es mayor
$ue n entonces +eneramos el resumen del comentario de la manera $ue Bemos e?plicado
anteriormente.
%ara probar si 3uncionaL
mysql> SELECT acortar("Este comentario no significa nada y solo sirve de
ejemplo", 15);
+--------------------------------------------------------------------------+
| acortar("Este comentario no significa nada y solo sirve de ejemplo", 15) |
+--------------------------------------------------------------------------+
| Este ... emplo |
+--------------------------------------------------------------------------+
1 row in set (0.00 sec)
1 podemos utili/arlo para +enerar una lista compacta de los t7tulos de la base de datos
bibliotecaL
mysql> SELECT titulo, acortar(titulo, 20) FROM titulos LIMIT 10;
+------------------------------------------+----------------------+
| titulo | acortar(titulo, 20) |
+------------------------------------------+----------------------+
| Linux | Linux |
| The Definitive Guide to Excel VBA | The Defini ... l VBA |
| Client/Server Survival Guide | Client/Ser ... Guide |
| Web Application Development with PHP 4.0 | Web Applic ... P 4.0 |
| MySQL | MySQL |
| MySQL & mSQL | MySQL & mSQL |
| A Guide to the SQL Standard | A Guide to ... ndard |
| Visual Basic 6 | Visual Basic 6 |
| Excel 2000 programmieren | Excel 2000 ... ieren |
| PHP - Introduccin | PHP - Introduccin |
+------------------------------------------+----------------------+
10 rows in set (0.00 sec)
Implementacin de S%
#3ortunadamente los S% de MySQL si+uen el estndar SQLL2;;3. 6e esta manera4 los
S% de MySQL se pueden portar 3cilmente al sistema 6BM2 de IBM. Sin embar+o4 no se
pueden portar a 1racle o Microso3t SQL Serer ya $ue estos no si+uen el estndar.
)l almacenamiento interno de los S% se Bace en la tabla mysql.proc. )n las columnas
de esta tabla estn almacenados todos los datos relatios al S%. Si no tenemos acceso a
la abse de datos mysql4 podemos recuperar la misma in3ormacin con
INFORMATION_SCHEMA.ROUTINES.
Crear4 editar y borrar S%s
La sinta?is para crear un S% esL
CREATE FUNCTION nombre ([parametro[,...]) RETURNS tipo_de_datos
[opciones] codigo_sql
CREATE PROCEDURE nombre ([parametro[,...])
[opciones] codigo_sql
La @nica di3erencia entre los dos es $ue FUNCTION retorna un alor y PROCEDURE no. )l
S% creado se asocia a la base de datos actual. %uede Baber una FUNCTION y un
PROCEDURE con el mismo nombre. Los parmetros tienen la sinta?isL
parametro:
[IN | OUT | INOUT] nombre_parametro
Los parmetros de FUNCTION son todos IN por de3ecto. Los parmetros $ue son OUT en
un PROCEDURE son alores $ue se retornan y $ue se iniciali/an a NULL. Los INOUT son
parmetros de PROCEDURE $ue son tanto de entrada como de salida.
#l+unas de las opciones $ue se puede especi3icar sonL
L#2E5#E) SQLL el @nico alor posible de momento. Se preJ $ue en el 3uturo se
puedan usar otros len+uaAes de pro+ramacin.
k21'l 6)').MI2IS'ICL un S% est considerado determinista cuando siempre
retorna el mismo resultado con los mismos parmetros. Los S% $ue dependen de
una tabla de la base de datos son no deterministas obiamente.
%or de3ecto los S% son no deterministas. Sin embar+o4 los S% $ue s7 lo son pueden
eAecutarse de una manera mucBo ms e3iciente ya $ue4 por eAemplo4 los resultados
se pueden almacenar en una cacBe. 6e cual$uier manera4 actualmente esta opcin
es i+norada por MySQL.
SQL S)C5.I'> 6)<I2). o I2C1Q).L el modo SQL S)C5.I'> especi3ica los
priile+ios de acceso al S%.
C1MM)2' Ite?tIL el comentario se almacena con el S% a modo de documentacin.
%ara borrar un S%L
DELETE FUNCTION [IF EXISTS] nombre
DELETE PROCEDURE [IF EXISTS] nombre
La opcin I< )DIS'S Bace $ue si el S% no e?iste no se produ/ca nin+@n error.
Los S% pueden modi3icarse con #L').. Se necesita el priile+io #L'). .15'I2) para
Bacerlo. La sinta?is esL
ALTER FUNCTION/PROCEDURE nombre
[NAME nombre_nuevo]
[SQL SECURITY DEFINER/INVOKER]
[COMMENT 'nuevo comentario']
Con la ersin actual de MySQL (!.1* no se puede modi3icar el cdi+o del S%.
1G.1 Sinta@is
Los S% estn compuestos principalmente de un conAunto de instrucciones SQL ordinarias.
Sin embar+o Bay una serie de instrucciones adicionales $ue permiten control de 3luAo4
alternatias4 cursores4 ... %rimero eremos cuales son las di3erencias entre <52C'I12 y
%.1C)65.)4 $ue estn resumidas en 'abla &.
%.1C*(5.* :52C&I12
Llamada Solo con C#LL %osible en todas las
instrucciones SQL (S)L)C'4
5%6#')4 ...*
.etorno %uede retornar uno o ms
S)L)C'
.etorna un alor @nico de un
tipo determinado.
%armetros %ermite por alor y por
re3erencia (I24 15'4 I215'*
Solo parmetros por alor.
Instrucciones permitidas 'odas las SQL 2o se puede acceder a tablas
Llamadas a otras 3unciones
o procedimientos
%uede llamar a otros
procedimientos yMo 3unciones
Solo puede llamar otras
3unciones
8abla <( 1iferencias entre &$#C8*7# y %R7C-1$R-
Las re+las +enerales para escribir S% sonL
%unto y coma. %ara separar las di3erentes instrucciones $ue componen un S% se
utili/a el carcter IRI.
B)EI2G)26. Las instrucciones $ue no se encuentran entre dos palabras
reseradas (p.e. I<4 '-)24 )LS)* Ban de ponerse entre un B)EI2 y un )26.
Salto de l7nea. Los saltos de l7nea son considerados como espacios en blanco.
Cariables. Las ariables locales y los parmetros se acceden sin un carcter m al
principio. )l resto de ariables SQL deben comen/ar con m.
May@sculasMmin@sculas. MySQL no las distin+ue al de3inir el nombre del S%.
Caracteres especiales. )itar el uso de caracteres 3uera del cdi+o #SCII (acentos4
84 ...*. # pesar de estar permitidos4 pueden aparecer problemas al administrar la
base de datos.
Comentarios. Los comentarios se introducen con IGGI y se e?tienden Basta el 3inal de
la l7nea.
1G.2 Llamadas
Las 3unciones y los procedimientos tienen di3erentes maneras de inocarse. #dems4 los
S% estn asociados a una base de datos con lo $ue si $ueremos eAecutar un S% de otra
base de datos debemos Bacerlo poniendo el nombre de la base de datos delante se+uido
por un punto (p.e. nombre=bd.nombre=sp(**
:unciones
Las 3unciones4 como las prede3inidas por SQL4 se pueden inte+rar en comandos SQL. %or
eAemplo4 la 3uncin acortar $ue Bemos de3inido antes la Bemos usado dentro de un
S)L)C'. %or eAemploL
SELECT acortar(titulo, 30), acortar(titulo, 20) FROM titulos
UPDATE titulos SET titulo = acortar(titulo, 70) WHERE CHAR_LENGHT(title)>70
#dems tambiJn se puede almacenar el resultado de una 3uncin en una ariable SQLL
mysql> SET @s = " una cadena de caracteres my larga ";
Query OK, 0 rows affected (0.00 sec)
mysql> SET @a = acortar(@s, 15);
Query OK, 0 rows affected (0.00 sec)
mysql> select acortar(@s, 10) INTO @b;
Query OK, 1 row affected (0.00 sec)
mysql> SELECT @s, @a,@b;
+-------------------------------------+-----------------+------------+
| @s | @a | @b |
+-------------------------------------+-----------------+------------+
| una cadena de caracteres my larga | una ... arga | una caden |
+-------------------------------------+-----------------+------------+
1 row in set (0.00 sec)
%rocedimientos
Los procedimientos deben ser llamados con C#LL. Se puede retornar como resultadp una
tabla (i+ual $ue con un comando S)L)C'*. 2o se pueden usar procedimientos dentro de
sentencias SQL.
%or eAemplo4 podemos usar un procedimiento para obtener el titulo4 subtitulo y editorial de
cada libroL
CREATE PROCEDURE imartin.obtener_titulo(IN id INT)
BEGIN
SELECT titulo, subtitulo, nombreEdit
FROM titulos, editoriales
WHERE titulos.tituloID = id
AND titulos.editID = editoriales.editID;
END
> para usarloL
mysql> CALL obtener_titulo(1);
+--------+--------------------------------------------+-------------+
| titulo | subtitulo | nombreEdit |
+--------+--------------------------------------------+-------------+
| Linux | Instalacion, Configuracion, Administracion | Grupo Anaya |
+--------+--------------------------------------------+-------------+
)n el caso de procedimientos con ariables de salida4 el resultado solo puede ser
ealuado si se pasa una ariable SQLL
mysql> delimiter ;
mysql> CREATE PROCEDURE mitad(IN a INT, OUT b INT) BEGIN SET b = a/2; END$$
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> CALL mitad(10, @resultado);
Query OK, 0 rows affected (0.04 sec)
mysql> SELECT @resultado;
+------------+
| @resultado |
+------------+
| 5 |
+------------+
.ecursi"idad
)n el cdi+o de un procedimiento se pueden llamar a otros procedimientos o 3unciones4
mientras $ue en el cdi+o de una 3uncin solo se pueden llamar a otras 3unciones.
#dems4 3unciones y procedimientos pueden llamarse a ellos mismos4 con lo cual se
pueden implementar al+oritmos recursios. %or eAemplo4 podemos implementar el t7po
eAemplo de calcular el 3actorial con una 3uncinL
CREATE FUNCTION factorial(n BIGINT) RETURNS BIGINT
BEGIN
IF n>=2 THEN
RETURN n * factorial(n-1);
ELSE
RETURN n;
END IF;
END
#l instalar el seridor de MySQL la recursin est desactiada por de3ecto. %ara poder
actiarla Bay $ue cambiar la ariable ma3?s$?re/#rsion?de$tF a un alor mayor $ue
;. )l alor $ue colo$uemos ser el niel m?imo de recursin permitido. -ay $ue tener
cuidado con esta ariable ya $ue al actiar la recursin4 y sobre todo con un alor alto4
podemos sobrecar+ar el seridor si nuestras 3unciones o procedimientos estn mal
dise8ados.
1G.! %armetros y "alores de retorno
-ay una serie de detalles importantes acerca de como MySQL +estiona los parmetros
$ue se pasan a 3unciones y procedimientos.
%rocedimientos
.ecordar $ue la sinta?is para crear un procedimiento esL
CREATE PROCEDURE nombre ([[IN OUT INOUT] nombre_parametro
tipo_parametro[,...])
Los atributos I24 15' e I215' determinan si el parmetro ser usado solo como entrada4
solo como salida4 o como en las dos direcciones.
Se pueden usar todos los tipos de datos de MySQL. Sin embar+o4 no se pueden usar
atributos para los tipos4 como 25LL4 21' 25LL. #ctualmente MySQL no Bace nin+@n tipo
de comprobacin de tipos de los parmetros.
# pesar $ue los procedimientos no pueden retornar un solo alor4 s7 $ue se pueden usar
instrucciones S)L)C' normales. Incluso se pueden eAecutar arios S)L)C' en
secuencia. )n ese caso4 el procedimiento retorna el resultado en 3orma de arias tablas.
Sin embar+o4 solo los len+uaAes de pro+ramacin $ue soportan el atributo
M5L'I=.)S5L' pueden acceder a esos resultados m@ltiples.
:unciones
La sinta?is para crear un 3uncin esL
CREATE FUNCTION nombre ([nombre_parametro tipo_datos[,...]) RETURNS
tipo_datos
)n este caso todos los parmetros son de entrada (por alor*.
Las 3uncionas retornan un solo alor del tipo especi3icado con la sentencia .)'5.24 $ue
adems termina la eAecucin de la 3uncin.
1G.# Cariables
(eclaracin
Se pueden declarar ariables locales dentro de los procedimientos y 3unciones. La sita?is
esL
DECFLARE nombre_var1, nombre_var2, .... tipo_datos [DEFAULT valor];
Se debe de3inir el tipo de datos para todas las ariables. Se iniciali/an con 25LL4 a menos
$ue se les de un alor e?pl7cito.
-ay $ue tener cuidado de no dar a las ariables los mismos nombres $ue columnas o
tablas de la base de datos ya $ue4 a pesar de estar permitido4 puede dar lu+ar a errores
muy di37ciles de rastrear.
Asi+nacin
Las asi+naciones de tipo x E x F ' no estn permitidas en SQL. -ay $ue usar S)' o
S)L)C' I2'1. )ste @ltimo es una ariante de S)L)C' $ue acaba en I2'1
nombre=ariable. )sta ariante solo se puede usar cuando la instruccin S)L)C' retorna
un solo re+istro. )n las 3unciones solo se puede usar S)'4 y no S)L)C' I2'1.
)AemplosL
SET var1=valor1, var2=valor2, ...
SELECT var:=valor
SELECT 2*7 INTO var
SELECT COUNT(*) FROM tabla WHERE condicion INTO var
SELECT titulo, subtitulo FROM titulos WHERE tituloID=3
INTO mititulo,misubtitulo
1G.5 *ncapsulacin de instrucciones
Cada 3uncin o procedimiento consiste en una o ms instrucciones SQL $ue comien/an
con un B)EI2 y terminan con un )26. 5na construccin B)EI2G)26 puede incluirse
dentro de otra si tenemos $ue declarar determinadas ariables $ue solo an a ser
utili/adas en un determinado mbito. 6entro de una construccin B)EI2G)26 Bay $ue
se+uir un determinado ordenL
BEGIN
DECLARE variables;
DECLARE cursores;
DECLARE condiciones;
DECLARE handlers;
instrucciones SQL;
END;
#ntes de B)EI2 puede a8adirse una eti$ueta4 $ue se puede usar en conAuncin con la
instruccin L)#C) $ue sire para abandonar un determinado mbito de3inido por un
B)EI2G)26. Sinta?isL
nombre_bloque:BEGIN
instrucciones;
IF condicion THEN LEAVE nombre_bloque; ENDE IF;
instrucciones;
END nombre_bloque;
6e esta manera4 con el comando L)#C) podemos esco+er $uJ mbito $ueremos
abandonar.
1G.7 Control de 3luBo
-ay bsicamente dos maneras de controlar el 3luAo en S%s.
I:>&-*>*LS*
La sinta?is de esta construccin esL
IF condicion THEN
instrucciones;
[ELSE IF condicion THEN
instrucciones;]
[ELSE
instrucciones;]
END IF;
2os es necesario usar B)EI2G)26 dentro de estas estructuras de control. La condicin
puede 3ormularse usando consultas con ,-).) o -#CI2E.
CAS*
)s una ariante de I< $ue es @til cuando todas las condiciones dependen de un solo alor
de una e?presin. La sinta?is esL
CASE expresion
WHEN valor1 THEN
instrucciones;
[WHEN valor2 THEN
instrucciones;]
[ELSE
instrucciones;]
END CASE;
1G.9 Bucles
MySQL o3rece una serie de opciones para construir bucles. Curiosamente4 la opcin de
<1. no e?iste.
.*%*A&>52&IL
Las instrucciones dentro de esta construccin se eAecutan Basta $ue se cumple una
determinada condicin. Como la condicin se eal@a al 3inal del bucle4 este siempre se
eAecuta al menos una e/.
)l bucle puede llear opcional mente una eti$ueta4 $ue puede ser usada para abandonar
el bucle usando la instruccin L)#C)4 o repetir una iteracin con I').#') (er ms
adelante*.
[nombre_loop:] REPEAT
instrucciones;
UNTIL condicion1
END REPEAT [nombre_loop];
%or eAemplo4 aBora mostraremos una 3uncin $ue retorna una cadena de caracteres
compuesta por n caracteres I\IL
CREATE FUNCTION asteriscos(n INT) RETURNS TEXT
BEGIN
DECLARE i INT DEFAULT 0;
DECLARE s TEXT DEFAULT '';
bucle1: REPEAT
SET i = i + 1;
SET s = CONCAT(s, *);
UNTIL i>=n END REPEAT;
RETURN s;
END;
,-IL*>(1
Las instrucciones entre ,-IL) y 61 se eAecutan siempre $ue la condicin
correspondiente sea cierta. Como la condicin se eal@a al principio del bucle4 es posible
$ue no se produ/ca nin+una iteracin. Sinta?isL
[nombre_bucle:] WHILE condicion DO
instrucciones;
END WHILE [nombre-.bucle];
L11%
Con esta construccin se de3ine un bucle $ue se eAecuta Basta $ue se sale de Jl mediante
una instruccin L)#C). Sinta?isL
nombre_bucle: LOOP
instrucciones;
END LOOP nombre_loop;
L*AC* e I&*.A&*
L)#C) nombre=bucle aborta la eAecucin de un bucle o de una construccin B)EI2G)26.
I').#') nombre=bucle sire para eAecutar las instrucciones del bucle nombre=bucle una
e/. I').#') no puede usarse con B)EI2G)26.
1G.E Hestin de errores '<andlers)
6urante la eAecucin de instrucciones SQl dentro de un S% pueden producirse errores.
SQL de3ine un mecanismo de Bandlers para +estionar esos errores. 5n Bandler debe ser
de3inido despuJs de la declaracin de ariables4 cursores y condiciones4 pero antes del
blo$ue B)EI2G)26. Sinta?isL
DECLARE tipo HANDLER FOR condicion1, condicion2, ... instruccin;
Los elementos $ue interienen en esta declaracin sonL
ti$oL puede ser C12'I25) o )DI'. )l primero si+ni3ica $ue la eAecucin del
pro+rama continuar a pesar del error. )DI' si+ni3ica salir del blo$ue B)EI2G)26.
-ay preista una tercera opcin $ue ser 5261 y $ue serir para desBacer los
cambios producidos Basta ese momento por el S%.
/ondi/ionL indica baAo $uJ condiciones deber7a actiarse el Bandler. -ay arias
opcionesL
SQLS'#') Icodi+o=errorIL especi3ica un error concreto mediante su cdi+o.
SQL,#.2I2EL comprende todos los estados SQLS'#') ;1nnn.
21' <1526L comprende el resto de errores.
codi+o=error=mys$lL se especi3ica el n@mero de error MySQL.
nombre=condicionL se re3iera a una condicin $ue Ba sido declarada entes con
6)CL#.) C126I'I12.
instr#//iQnL esta instruccin es eAecutada cuando se produce un error.
Las condiciones Bacen posible dar a cierto +rupo de errores un nombre claro. La sinta?is
para declarar una condicin esL
DECLARE nombre CONDITION FOR condicion;
La condicin se puede 3ormular con SBLST%TE K/odi6o?errorK o
n#m?error?mysql. %or eAemplo4 si $ueremos +estionar el error $ue se produce al
insertar un re+istro con una clae duplicada4 Baremos estoL
6)CL#.) claedup C#.C-#.(1;;*R
6)CL#.) clae=duplicada C126I'I12 <1. SQLS'#') I23;;;IR
6)CL#.) C12'I25) -#26L). <1. clae=duplicada S)' mi=errorZIclaedupI
6es+raciadamente MySQL no permite $ue se pueda actiar un error en un momento
dado. La @nica manera es eAecutando una sentencia $ue sabemos $ue producir el error
deseado.
1G.F Cursores
5n cursor 3unciona como un puntero a un re+istro. Con ellos se puede iterar sobre todos
los re+istros de una tabla. 2ormalmente se usan para 3acilitar el dise8o de 3unciones y
procedimientos $ue modi3ican los datos de una tabla4 y $ue si se tuieran $ue Bacer con
5%6#') ser7an muy complicados.
6e todas maneras4 Bay detractores del uso de cursores. La ra/n $ue es+rimen es $ue
cual$uier al+oritmo $ue use cursores se puede reescribir de manera ms ele+ante4 y a
eces ms e3iciente4 sin usar cursores.
Sinta@is
)l uso de cursores re$uiere arios pasos. %rimero Bay $ue declarar el cursor conL
6)LC#.) nombre=cursor C5.S1. <1. S)L)C' ...R
Se puede usar cual$uier comando S)L)C'. 6espuJs Bay $ue actiar el cursor conL
1%)2 nombre=cursorR
# partir de ese momento se puede usar el comando <)'C-L
<)'C- nombre=cursor I2'1 ar14 ar24 ...R
6e esta manera4 la primera columna del re+istro al $ue apunta nomre?/#rsor se
almacena en la ariable 0ar!4 la se+unda en 0ar&4 y as7 sucesiamente. )stas ariables
tienen $ue Baber sido declaradas con anterioridad4 y Ban de ser del tipo correcto.
%ara saber cuando se Ban acabado de leer los re+istros correspondientes al S)L)C' del
cursor4 MySQL emite el error 1329 (no data to fetc@* $ue corresponde a SQLS'#') ;2;;.
)ste error no se puede eitar4 pero se puede capturar con un Bandler. 6e esta manera4
siempre $ue usemos cursores tendremos $ue de3inir el Bandler correspondiente.
2ormalmente se usa 21' <1526 como condicin4 donde se en+loban todos los
SQLS'#') ;snnn.
)l cursor se puede cerrar conL
CL1S) nombre=cursorR
6e todas maneras4 esto no se suele Bacer ya $ue el cursor es automticamente cerrado
al 3inal del blo$ue B)EI2G)26.
Limitaciones
-ay tres limitaciones principales en el uso de cursoresL
Los cursores son solo de lectura4 no se pueden modi3icar los datos a los $ue
apunta.
Los cursores solo pueden aan/ar4 de manera $ue los datos deben ser procesados
en el orden en el $ue Ban sido proporcionados por el seridor.
2o se puede cambiar la estructura de las tablas mientras se estn leyendo datos
con un cursor. Si se Bace4 MySQL no +aranti/a un comportamiento consistente.
Como eAemplo Baremos un procedimiento $ue recorre todos los re+istros de la tabla titulo
y suma el n@mero de caracteres de titulo y subtitulo. #l 3inal4 la suma se diide por el
n@mero de re+istros lo $ue nos da el n@mero medio de caracteres para titulo ms
subtituloL
CREATE PROCEDURE biblioteca.testCursor(OUT longitud_media DOUBLE)
BEGIN
DECLARE t, subt VARCHAR(100);
DECLARE terminado INT DEFAULT 0;
DECLARE n BIGINT DEFAULT 0;
DECLARE cnt INT;
DECLARE miCursor CURSOR FOR
SELECT titulo, subtitulo FROM titulos;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET terminado=1;
SELECT COUNT(*) FROM titulos INTO cnt;
OPEN miCursor;
miBucle: LOOP
FETCH miCursor INTO t, subt;
IF terminado=1 THEN LEAVE miBucle; END IF;
SET n = n + CHAR_LENGTH(t);
IF NOT ISNULL(subt) THEN
SET n = n + CHAR_LENGTH(subt);
END IF;
END LOOP miBucle;
SET longitud-media = n/cnt;
END
> si lo eAecutamos obtendremos al+o comoL
mysql> CALL testcursor(@result);
Query OK, 0 rows affected (0.02 sec)
mysql> SELECT @result;
+--------------+
| @result |
+--------------+
| 31.629629629 |
+--------------+
> para ilustrar como se podr7a Baber BecBo lo mismo sin un S%L
mysql> SELECT (SUM(CHAR_LENGTH(titulo)) +
SUM(CHAR_LENGTH(subtitulo)))/COUNT(*) AS longitud_media FROM titulos;
+----------------+
| longitud_media |
+----------------+
| 31.6296 |
+----------------+
11. &ri++ers
)s un mecanismo muy li+ado a los S%. Los tri++ers son conAuntos de sentencias SQL o
S%s $ue son eAecutados automticamente antes o despuJs de una modi3icacin de la
base de datos (5%6#')4 I2S).'4 6)L)')*. Se usan para mantener condiciones sobre
los datos de la base de datos y para monitori/ar las operaciones.
-ay $ue tener en cuenta $ue un tri++er se eAecuta por cada modi3icacin4 as7 $ue si las
operaciones a reali/ar automticamente son muy complicadas4 puede llear a una
ralenti/acin considerable de nuestra aplicacin. )sto se puede dar particularmente
cuando se Bacen modi3icaciones a mucBos re+istros al mismo tiempo4 ya $ue se eAecutar
un tri++er por cada re+istro modi3icado.
Lo $ue e?plicaremos a continuacin sobre tri++ers se aplica solamente a ersiones
si+uales o superiores a !.1.".
La sinta?is para la creacin de tri++ers esL
CREATE
[DEFINER = { #s#ario | CURRENT_USER }]
TRIGGER nomre?tri66er tiem$o?tri66er e0ento?tri66er
ON nomre?tala FOR EACH ROW sentencia_tri66e
5n tri++er es un eento li+ado a una base de datos y a la tabla nombre_tabla4 $ue Ba
de ser de tipo permanente4 es decir4 no puede ser de tipo ')M%1.#.> ni CI),. )l
tri++er se eAecuta cuando se produce una determinada operacin. %ara crear un tri++er se
necesita el priile+io '.IEE). para la tabla asociada.
)l atributo 6)<I2). determina el conte?to de se+uridad $ue se usar para determinar los
priile+ios de acceso en el momento de actiacin. )l atributo nombre=tri++er determina si
la actiacin se debe de Bacer antes (B)<1.)* o despuJs (#<').* de modi3icar un
re+istro.
)l tipo de accin $ue actia el tri++er iene determinado por eento=tri++er. Los alores
posibles sonL
I2S).'. )l tri++er se actia cuando se inserta un re+istro. )sto incluye las
instrucciones SQL I2S).'4 L1#6 6#'# y .)%L#C).
5%6#'). )l tri++er se actia cuando se modi3ica un re+istro. )sto corresponde a la
instruccin SQL 5%6#').
6)L)'). )l tri++er se actia cuando se borra un re+istro. %or eAemplo cuando se
usan instrucciones SQL como 6)L)') y .)%L#C). Sin embar+o4 si se borran
re+istro usando 6.1% '#BL) o '.5C#') no se actian estos tri++ers ya $ue
estas instrucciones no se trans3orman en 6)L)').
)s importante recalcar $ue estos tres tipos de eentos no se corresponden con las
instrucciones SQL $ue tienen el mismo nombre4 sino $ue son tipos de eentos $ue
pueden en+lobar uno o ms tipos de instrucciones SQL.
Como eAemplo de posible con3usin tenemos el si+uiente comandoL
INSERT INTO ... ON DUPLICATE KEY UPDATE ...
# pesar de se un comando I2S).'4 se pueden producir modi3icaciones si Bay claes
duplicados4 con lo $ue en este solo comando se pueden actiar tri++ers de tipo I2S).' y
5%6#').
2o se pueden tener dos tri++ers de3inidos para la misma tabla4 el mismo tiempo y el
mismo eento. %or eAemplo4 para una tabla solo puede Baber un tri++er del tipo B)<1.)
I2S).'.
La accin SQL $ue se eAecuta si se actia el trui++er es sentencia_trigger. Si se
$uieren eAecutar arias instrucciones SQL se puede usar B)EI2G)26. )so $uiere decir
$ue se puede usar la misma sinta?is $ue para los procedimientos almacenados. 6e todas
maneras4 Bay una serie de restricciones para los tri++ers en relacin a las instrucciones
$ue estn permitidas. Las ms importantes sonL
LOCK TABLES, UNLOCK TABLES.
LOAD DATA, LOAD TABLE.
Las instrucciones PREPARE, EXECUTE, DEALLOCATE PREPARE no se pueden
usar.
2o se pueden Bacer commit ni rollbacH.
Ms in3ormacin enL
BttpLMMde.mys$l.comMdocMre3manM!.1MenMroutineGrestrictions.Btml
1tra limitacin en este momento es $ue los tri++ers no se actian cuando se eAecuta un
C#SC#6) en una clae 3ornea. )sta restriccin est preista eliminarla pronto.
Ceamos un eAemplo de como 3uncionan los tri++ersL
CREATE TABLE test1(a1 INT);
CREATE TABLE test2(a2 INT);
CREATE TABLE test3(a3 INT NOT NULL AUTO_INCREMENT PRIMARY KEY);
CREATE TABLE test4(
a4 INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
b4 INT DEFAULT 0
);
DELIMITER |
CREATE TRIGGER testref BEFORE INSERT ON test1
FOR EACH ROW BEGIN
INSERT INTO test2 SET a2 = NEW.a1;
DELETE FROM test3 WHERE a3 = NEW.a1;
UPDATE test4 SET b4 = b4 + 1 WHERE a4 = NEW.a1;
END;
|
DELIMITER ;
INSERT INTO test3 (a3) VALUES
(NULL), (NULL), (NULL), (NULL), (NULL),
(NULL), (NULL), (NULL), (NULL), (NULL);
INSERT INTO test4 (a4) VALUES
(0), (0), (0), (0), (0), (0), (0), (0), (0), (0);
#Bora reali/amos un I2S).' en la la tablas test1L
mysql> INSERT INTO test1 VALUES (1), (3), (1), (7), (1), (8), (4), (4);
Query OK, 8 rows affected (0.04 sec)
Records: 8 Duplicates: 0 Warnings: 0
)n esta instruccin4 al Baberse producido I2S).'s en la tabla test14 el tri++er testre3 se
Ba actiado para cada uno de los I2S).'S. Ceamos si se Ba eAecutado correctamenteL
mysql> SELECT * FROM test1;
+------+
| a1 |
+------+
| 1 |
| 3 |
| 1 |
| 7 |
| 1 |
| 8 |
| 4 |
| 4 |
+------+
8 rows in set (0.00 sec)
La tabla test14 eidentemente4 contiene los alores $ue Bemos insertado directamente.
Ceamos el resto de tablas a3ectadas. La tabla test2 Ba $uedado as7L
mysql> SELECT * FROM test2;
+------+
| a2 |
+------+
| 1 |
| 3 |
| 1 |
| 7 |
| 1 |
| 8 |
| 4 |
| 4 |
+------+
8 rows in set (0.00 sec)
)sto es debido a $ue el tri++er lo @nico $ue Bace es insertar un re+istro en test2 $ue en
la columna a2 contiene los mismo $ue la columna a1 del nueo re+istro (NEW.a1* $ue se
est a punto de insertar.
La tabla test3 Ba $uedado as7L
mysql> SELECT * FROM test3;
+----+
| a3 |
+----+
| 2 |
| 5 |
| 6 |
| 9 |
| 10 |
+----+
5 rows in set (0.00 sec)
La tabla test3 se Bab7a iniciali/ado insertando re+istro con alor NULL4 pero al ser su
columna a3 de tipo NOT NULL PRIMARY KEY4 el sistema iniciali/ los alores de esta
columna con 142434 ... 1;. #l eAecutarse el se+undo INSERT4 el $ue actia los tri++ers4
cada e/ $ue se inserta un re+istro en test14 se borran todos los re+istro de test3 cuya
columna a3 es i+ual a la columna a1 del re+istro $ue se est a punto de insertar.
> 3inalmente eamos como Ba $uedado la tabla test4L
mysql> SELECT * FROM test4;
+----+------+
| a4 | b4 |
+----+------+
| 1 | 3 |
| 2 | 0 |
| 3 | 1 |
| 4 | 2 |
| 5 | 0 |
| 6 | 0 |
| 7 | 1 |
| 8 | 1 |
| 9 | 0 |
| 10 | 0 |
+----+------+
10 rows in set (0.00 sec)
Si nos 3iAamos en la instruccin del tri++er $ue a3ecta a la tabla test44 eremos $ue lo
@nico $ue Bace es contar cuantos re+istros insertados contienen el alor 1 en a14 el alor
24 y as7 sucesiamente.
%ara re3erirnos al re+istro $ue se a a insertar o modi3icar en un tri++er B)<1.)
podemos usar 2),4 y para re3erirnos al re+istro $ue se Ba borrado o modi3icado en un
tri++er #<'). podemos usar 1L6.
'ambiJn podemos alterar un re+istro $ue se a a insertar o modi3icar. %or eAemplo4
podemos Bacer cosas como estaL
CREATE TRIGGER sdata_insert BEFORE INSERT ON `sometable`
FOR EACH ROW
BEGIN
SET NEW.guid = UUID();
END;
Sin embar+o4 esto solo est permitido cuando el tri++er es de tipo B)<1.). Si lo usamos
en uno #<'). obtendremos un error.
5n punto importante a tener en cuenta es el uso de tri++ers B)<1.) con tablas Inno6B.
Si Bemos de3inido restricciones4 puede ser $ue determinados I2S).' 3allen debido a
dicBas restricciones4 pero los tri++ers s7 $ue se actiarn PP %or eso es recomendable usar
tri++ers de tipo #<'). siempre $ue sea posible.
Borrar tri++ers
%ara borrar un tri++er e?istente eAecutaremos 6.1% '.IEE).. )s necesarios especi3icar
la tabla a la $ue est asociadoL
DROP TRIGGER nombre_tabla.nombre_trigger
12. &ransacciones
Las transacciones son un mecanismo SQL para ase+urar $ue un +rupo de instrucciones
se eAecutan de 3orma atmica. )so $uiere decir $ue el sistema nos ase+ura $ue o se
eAecutan todas o nin+una4 pero no puede ser $ue se eAecute una parte. )sto es
especialmente importante para mantener la inte+ridad de nuestros datos en situaciones
de ca7das de sistema o de acceso concurrente.
Ima+inemos una base de datos de un banco en $ue e?iste una tabla cuenta en la $ue se
almacenan los datos sobre el dinero de los usuario4 y Bay una columna balance $ue
contiene el saldo de la cuenta. Ima+inemos $ue $ueremos Bacer una trans3erencia de !;;
euros de una cuenta a otra. Simpli3icando4 las instrucciones SQL $ue necesitar7amos
ser7anL
UPDATE cuenta SET balance = balance + 500 WHERE cuenta.id = 1;
UPDATE cuenta SET balance = balance 500 WHERE cuenta.id = 2;
)n principio este cdi+o es correcto y Bar lo $ue $ueremos. %ero $uJ pasa si despuJs de
la primera instruccin Bay una ca7da del sistema i La cuenta 1 tendr !;; euros ms4
pero la se+unda se+uir como antes. Como la trans3erencia no se Ba terminado4 el
sistema4 probablemente4 oler a intentar Bacerla. Se uelen a a eAecutar las dos
instrucciones y esta e/ todo sale bien. QuJ Ba ocurrido i Que la cuenta 1 tiene !;;
euros ms $ue le lle+aron en la primera trans3erencia $ue no termin.
)n este caso lo $ue $ueremos es $ue las dos instrucciones se eAecuten en una
transaccin y $ue el sistema nos ase+ure $ue o se eAecutan las do o nin+una. %ara ello
Baremos lo si+uienteR
START TRANSACTION;
UPDATE cuenta SET balance = balance + 500 WHERE cuenta.id = 1;
UPDATE cuenta SET balance = balance 500 WHERE cuenta.id = 2;
COMMIT;
)sto nos ase+ura $ue o las dos cuentas se actuali/an o nin+una. )s ms4 si otro usuario
accede de 3orma concurrente al sistema y consulta los saldos de las cuentas 1 y 24 nunca
obtendr un resultado $ue corresponda a un estado intermedio de la transaccin. )s
decir4 o er las dos cuentas sin actuali/ar4 o er las dos actuali/adas.
5na transaccin Ba de cumplir cuatro re+lasL
#tomicidad. 1 se eAecuta todo4 o nada
Consistencia. 6urante la transaccin se pueden romper restricciones de inte+ridad4
pero al acabar se deben restaurar.
#islamiento. Los datos $ue se actuali/an en un transaccin no estn isibles para
otras transacciones Basta $ue esta acaba.
6urabilidad. 5na e/ la transaccin Ba sido cerrada no se puede desBacer.
Si durante una transaccin comprobamos $ue no podemos se+uir y $ue Bay $ue anular
todo lo $ue se Ba BecBo desde el principio de dicBa transaccin4 usaremos la instruccin
.1LLB#CQ.
A5&1C1MMI&
MySQL considera cada instruccin aislada como una transaccin4 de manera $ue al
terminar sus e3ectos son permanentes. )ste comportamiento se puede cambiar conL
SET AUTOCOMMIT = 0;
6e esta manera las instrucciones SQL $ue eniemos al seridor no tendrn e3ecto Basta
$ue Ba+amos C1MMI'.
Ms in3ormacin sobre transacciones enL
BttpLMMde.mys$l.comMdocMre3manM!.1MenMcommit.Btml
1!. .espaldos 'bac=ups)
Los respaldos (bacHups* son una de las tareas ms importante dentro de la
administracin de una base de datos.
La manera ms simple de Bacer un respaldo con MySQL es usar el comando
mysqldump. )ste retorna un 3icBero con instrucciones SQL para +enerar las tablas de la
base de datos y rellenarlas con ls in3ormacin $ue conten7a en el momento de eAecutar el
mysqldump. )ste sistema es lento4 pero o3rece el m?imo de compatibilidad a la Bora de
Bacer una mi+racin. %ara reconstruir la base de datos se usa el comando mysql.
Si se usan tablas MyIS#M Bay un sistema ms rpido y se+uro $ue es copiar los
directorios de la base de datos. )sto siempre Bay $ue Bacerlo con el seridor parado.
%ara Bacer esto se puede usar el comando mysqlhotcopy. %ara reconstruir la base de
datos4 simplemente Bay $ue copiar los directorios donde corresponda.
1tra opcin es crear 3icBeros de lo+s con los cambios $ue se an produciendo en la base
de datos4 y de esta manera tener un respaldo incremental. Sin embar+o4 si el olumen de
cambios en la base de datos es muy alto4 puede suponer un problema de espacio en el
disco.
Henerando respaldos
)l comando mysqldump +enera un 3icBero de instrucciones SQL $ue son capaces de4
posteriormente4 oler a +enerar la misma base de datos $ue ten7amos. 2ormalmente4
este 3icBero contiene un C.)#') '#BL) por cada tabla de la base de datos4
instrucciones para crear 7ndices4 y numerosos I2S).' para llenar las tablas con datos
(uno por re+istro*.
%or eAemplo4 esto es lo $ue +enera mys$ldump para la base de datos bibliotecaL
-- MySQL dump 10.13 Distrib 5.1.23-rc, for redhat-linux-gnu (i686)
--
-- Host: 127.0.0.1 Database: biblioteca
-- ------------------------------------------------------
-- Server version 5.1.23-rc
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS,
FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `autores`
--
DROP TABLE IF EXISTS `autores`;
SET @saved_cs_client = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE `autores` (
`autorID` int(11) NOT NULL AUTO_INCREMENT,
`nombreAutor` varchar(60) COLLATE utf8_spanish_ci NOT NULL DEFAULT '',
`ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE
CURRENT_TIMESTAMP,
PRIMARY KEY (`autorID`),
KEY `nombreAutor` (`nombreAutor`)
) ENGINE=InnoDB AUTO_INCREMENT=90 DEFAULT CHARSET=utf8
COLLATE=utf8_spanish_ci;
SET character_set_client = @saved_cs_client;
--
-- Dumping data for table `autores`
--
LOCK TABLES `autores` WRITE;
/*!40000 ALTER TABLE `autores` DISABLE KEYS */;
INSERT INTO `autores` VALUES (1,'Perez Miquel','2008-04-03 16:48:25'),
(2,'Puig David','2008-04-03 16:48:25'),(3,'Vila Robert',
'2008-04-03 16:48:25'),(4,'Lopez Dan','2008-04-03 16:48:25'),(5,'Martin
Josep','2008-04-03 16:48:25'),(6,'Alvarez Tobias','200
8-04-03 16:48:25'),(7,'Costa Pau','2008-04-03 16:48:25'),(12,'Gil
Carles','2008-04-03 16:48:25'),(13,'Garcia Jordi','2008-04-0
3 16:48:25'),(14,'Reig Tomas','2008-04-03 16:48:25'),(15,'Ortega
Narcis','2008-04-03 16:48:25'),(16,'Molina Marc','2008-04-03
16:48:25'),(17,'Font Xavier','2008-04-03 16:48:25'),(20,'Abreu
Raul','2008-04-03 16:48:25'),(21,'Coma Miquel','2008-04-03 16:4
...
/*!40000 ALTER TABLE `titulos` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2008-04-19 15:08:57
Las l7neas $ue comien/an por IGGI se consideran comentarios en SQL. #dems4 al i+ual
$ue en C4 los caracteres IM\I inician un comentario. %ero4 si an se+uidas de un n@mero n4
entonces si la ersin de MySQL $ue eAecute ese arcBio4 si su ersin es mayor o i+ual
$ue n entonces no ser considerado comentario y se eAecutar su contenido. )so es para
preenir errores de sinta?is cuando trabaAamos con 3icBeros SQL en di3erentes ersiones
de seridores.
Las instrucciones S)' iniciales ($ue solo se eAecutarn en seridores con ersions
mayores o i+uales a 4.1.1 y 4.;.14* +uardan el Aue+o de caracteres actual y lo actuali/an a
ut3&. #dems4 se desactian los test sobre claes 3orneas y @nicas para conse+uir
mayor e3iciencia (se supone $ue la base de datos 3ue creada en un estado lido y esas
comprobaciones no son necesarias al re+enerarla*.
# partir de entonces Bay una serie de instrucciones por cada tabla. Lo primero es 6.1%
'#BL) $ue borra la tabla $ue estamos a punto de crear para $ue no se me/cle con datos
ya e?istentes. 6espuJs se crea la tabla con C.)#') '#BL) y se rellena con I2S).'. #l
3inal se restaura el Aue+o de caracteres $ue estaba actio al principio y se restauran otros
estados.
La sinta?is de mys$ldump esL
mysqldump [opcions] nombre_bd [tablas] backup.sql
Si no se especi3ican tablas entonces se uelcan todas. 'ambiJn se pueden olcar arias
bases de datos4 o incluso todasL
mysqldump [opciones] databases nombre_bd1 nombre_bd2 ...
mysqldump [opciones] all-databases
Los detalles del respaldo se pueden controlar mediante un +ran n@mero de opciones.
%ara Bacer un respaldo normal se pueden usar las opciones por de3ecto. )stas tienen los
si+uientes e3ectosL
6urante el respaldo se eAecuta un blo$ueo de lectura para cada tabla.
)l 3icBero resultante es el ms pe$ue8o posible.
)l 3icBero contiene un 6.1% '#BL) por cada tabla para borrarla si ya e?iste
cuando se restaura la base de datos.
'odas las caracter7sticas de la base de datos se preseran4 incluidos detalles
espec73icos de MySQL $ue podr7an di3icultar la mi+racin a otro sistema.
)l respaldo se crea usando ut3& y contiene las instrucciones necesarias para
restaurar el Aue+o de caracteres cuando la base de datos es restaurada.
)stas opciones no deben usarse si las tablas de la base de datos son Inno6B y las tablas
pueden cambiar indiidualmente durante el respaldo4 a3ectando a la inte+ridad. 'ampoco
deber7an usarse cuando se $uiere el m?imo de compatibilidad con otros sistemas.
Cuando necesitemos blo$uear todas las tablas durante el respaldo para no perder la
inte+ridad se puede usar la opcin lock-all-tables.
Si la base de datos contiene tablas del tipo Inno6B Bay $ue eitar el uso de las opciones
por de3ecto usando --skip-opt4 y en ese caso Bay $ue especi3icar todas las opciones
$ue necesitemosL
mysqldump -u root -p skip-opt single-transaction ad-drop-table \
--create-options quick extended-insert \
--set-charset disable-keys nombre_bd > backup.sql
)ste comando tambiJn +uardar las istas correspondientes a las bases de datos. Si
$ueremos $ue adems tambiJn se uel$uen las 3unciones y los procedimientos
almacenados necesitaremos usar la opcin routines.
.estaurar una base de datos
Si tenemos un 3icBero bacHup.s$l $ue contiene una sola base de datos4 la podemos
restaurar as7L
mysql -u root -p nombre_db < backup.sql
La base de datos nombre_bd debe e?istir. Si $ueremos restaurar arias bases de datos
$ue estn en un solo 3icBero4 este contendr los comandos C.)#') 6#'#BS)
correspondientes. Simplemente Bay $ue BacerL
mysql -u root -p < backup.sql
1#. Administracin de accesos y se+uridad
)s normal $ue en una base de datos no toda la in3ormacin sea accesible por todos sus
usuarios. %or ello4 MySQL tiene un sistema +ranular para controlar $uien puede acceder a
determinados datos4 y $uJ tipo de acceso tendr. MySQL tiene dos nieles de controlar el
acceso a sus bases de datos. )n un primer niel4 se determina si un usuario tiene permiso
para establecer una cone?in con el seridor. )n un se+undo niel4 se determina $uJ
acciones tiene permitido reali/ar el usuario (S)L)C'4 I2S).'4 6.1%4 ...* con cada base
de datos4 tabla o columna.
1#.1 &ipos de cone@iones
)l primer punto de control es el momento en $ue el cliente solicita una cone?in al
seridor. )sto puede producirse a traJs de un script4 usando el comando mysql4 desde
pBpMy#dmin4 ... etc. -ay arias maneras de $ue se produ/ca esta cone?in.
Cone@in remota
Cuando el cliente y el seridor se eAecutan en ordenadores di3erentes la cone?in se Ba
de reali/ar a traJs del protocolo 'C%MI%. 'ienen $ue darse dos condicionesL
Los dos ordenadores deben ser accesibles 7a 'C%MI%
)L puerto 33;"4 el $ue usa por de3ecto MySQL4 no debe estar blo$ueado por un
corta3ue+os.
Cone@in local
Cuando el cliente y el seridor se eAecutan en el mismo ordenador Bay arias
posibilidadesL
'C%MI%L en este caso tambiJn se puede usar este protocolo.
SocHet (solo uni?Mlinu?*L un socHer permite la comunicacin e3iciente entre dos
pro+ramas $ue se eAecutan en un sistema operatio uni?Mlinu?. )s el tipo de
comunicacin por de3ecto en uni?Mlinu?.
%ipes (solo ,indoOs 2;;;MD%*L es el e$uialente a socHets de uni?Mlinu?. Sin
embar+o4 esta opcin est desactiada por de3ecto. #dems4 el cliente debe
soportar esta ariante4 lo cual es bastante raro4 por lo $ue este sistema de
comunicacin se usa poco.
Memoria compartida (solo ,indoOsMD%*L es otra alternatia a la ariante de socHets
de uni?Mlinu?. )n este caso4 cliente y seridor comparten una re+in de memoria
para comunicacin. Sin embar+o4 este mJtodo tampoco es muy usado ya $ue solo
3unciona si la opcin shared_memory est actiada en la con3i+uracin del
seridor.
1#.2 Administracin de accesos
)n una base de datos puede Baber mucBos y muy di3erentes nieles de accesos para los
di3erentes tipos de usuarios. MySQL o3rece un sistema muy +ranular para controlar el tipo
de acceso.
Cambiar los pri"ile+ios
-ay arias maneras de cambiar los priile+iosL
La ms simple es usar un pro+rama de administracin con inter37cie +r3ica (p.e.
MySQL #dministrator o pBpMy#dmin*.
5sando directamente el comando mysql.
5sando las instrucciones SQL E.#2' y .)C1Q).
5sando el script %erl mysql_setpermission.pl.
2ombre de usuario4 passKord y nombre de <ost
La primara 3ase de acceso4 la cone?in del cliente al seridor4 depende de tres elementosL
2ombre de usuario. )s el nombre con el $ue el cliente se identi3ica delante del
seridor. Los usuarios de MySQL no tienen nin+una cone?in con los usuarios del
sistema operatio4 aun$ue normalmente coinciden.
%assOord. 1curre lo mismo $ue con los nombre de usuario4 no tienen cone?in con
el passOord del sistema operatio4 y son almacenados y +estionados
independientemente por MySQL.
-ost. #l establecer la cone?in Bay $ue especi3icar el ordenador en el $ue se
eAecuta el seridor. Se puede dar como una direccin I% o con un nombre. #L
recibir una cone?in4 el seridor usa la direccin del ordenador cliente para
determinar los derecBos de acceso ya $ue un mismo usuario puede tener permiso
para conectarse solo desde determinadas direcciones.
1#.! Creacin de bases de datos4 usuarios y sus
pri"ile+ios
%ara crear una base de datos y dar priile+io de acceso a ella a un determinado usuario
de 3orma local BaremosL
CREATE DATABASE nombre_bd
GRANT ALL ON nombre_bd.* TO nombre_usuario@localhost IDENTIFIED BY 'xxx'
)n este caso se otor+an todos los priile+ios (#LL* sobre toda la base de datos
(nombre=bd.\* a un usuario $ue se conecta localmente (nombre=usuariomlocalBost*
usando el passOord I???I.
Sin embar+o4 podemos dar unos priile+ios ms delimitados con4 por eAemploL
GRANT Select, Insert, Update, Delete ON nombre_bd.*
)sto ser7a el acceso bsico a una base de datos. SI $ueremos ampliarlo con permisos
ms espec73icosL
GRANT Lock Tables, CreateTemporary Tables, Execute ON nombre_bd.*
Con esto permitimos al usuario blo$uear tablas4 crear tablas temporales4 y eAecutar
procedimientos almacenados.
)s importante remarcar $ue al identi3icar al usuario con nombre_usuario@localhost
estamos restrin+iendo su acceso al modo local con socHets. Si $ueremos proporcionar
acceso local por 'C%MI% debemos usar nombre_usuario@nombre_ordenador.
Crear nue"os usuarios
La sinta?is para crear un nueo usuario esL
CREATE USER nombre_usuario IDENTIFIED BY 'password'
Cambiar pri"ile+ios
-asta aBora Bemos isto al+unos eAemplos de como otor+ar priile+ios4 pero la sinta?is
completa esL
GRANT privilegios
ON [nombre_bd.]nombre_tabla o nombre_bd.nombre_procedimiento
TO usuario@host [IDENTIFIED BY 'password']
[WITH GRANT OPTION]
> para retirar priile+iosL
REVOKE privilegios
ON [nombre_bd.]nombre_tabla o nombre_bd.nombre_procedimiento
FROM usuario@host
1#.# Base de datos Lmys$lL
'oda la in3ormacin sobre los priile+ios en un seridor MySQL estn almacenados en
una base de datos especial llamada mysql. Contiene una +ran cantidad de tablas con
in3ormacin sobre el sistema. 6e ellas4 Bay " $ue +uardan la in3ormacin sobre los
priile+ios. La 'abla 9 describe cuales son y $uJ in3ormacin contienen.
2ombre Si+ni3icado
user
Controla $uJ usuarios pueden conectarse al seridor y desde $uJ
ordenador. )sta tabla tambiJn contiene priile+ios +lobales.
db
)speci3ica $uJ usuarios pueden acceder a $uJ bases de datos
host
)?tiende la tabla db con in3ormacin de los ordenadores $ue tienen
acceso.
tables_priv
)speci3ica $uien puede acceder a las tablas de una base de datos
columns_priv
)speci3ica $uien puede acceder a las columnas de una tabla
func
%ermite la +estin de 3unciones de3inidas por el usuario (use;
defined functions*. )st sin documentar.
procs_priv
)speci3ica $uien puede eAecutar procedimientos almacenados
indiiduales.
8abla >( 1escri/ci+n de las tablas mysql que almacenan la informaci+n sobre /ri"ilegio

También podría gustarte