Sie sind auf Seite 1von 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 pri ile+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. # tra Js de la tabla de pedidos ser7a posible acceder a los datos de las otras dos tablas (por eAemplo4 a tra Js de los identi3icadores de cliente y producto*. Como eAemplos de sistemas de bases de datos relacionales tenemos MySQL4 1racle4 %ost+reSQL4 Microso3t SQL Ser er4 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 ser idor de bases de datos. Como contraposicin a las bases de datos relacionales tenemos las bases de datos orientadas a obAetos. )stas pueden almacenar obAetos indi iduales 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 0a a4 ...*. # 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 b sicos


>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 obAeti o de la compatibilidad no siempre se alcan/a. Cuando las tablas crecen Basta un tama8o considerable4 la elocidad de las consultas depende si+ni3icati amente 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 cla e (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 cla es 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 cla es 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 toda 7a 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 clienteMser idor 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 cla es 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 0a a4 %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 ser idor MySQL puede 3uncionar sobre una ariedad de sistemas operati os 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 resol er 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 nue as 3uncionalidades4 y cambios $ue las Ba+an incompatibles con ersiones anteriores. 'ambiJn es probable $ue ten+an errores se eros. Beta. La ersin est casi completa4 pero no Ba sido probada e?tensi amente. >a no se introducirn +randes cambios. Eamma. La ersin Beta Ba alcan/ado cierta estabilidad. Se resol ern 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. )sta ersin est en estado de Release Candidate )sta ersin est en estado #lpBa y por lo tanto leAos de poder usada. Incluir el nue o motor de almacenamiento <alcon

!.1L Boy (!.1.24*

".;L Boy (".;.4*


1.!.2 Licencia
5na de las caracter7sticas ms atracti as de MySQL es su licencia. MySQL 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 necesidad de proporcionar el cdi+o 3uente de nuestra aplicacin4 entonces se comprar una licencia comercial. es un ( #$ sin la puede

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.

&igura '( !rquitectura L!)%

)sta ar$uitectura es muy utili/ada para ser idores de aplicaciones Oeb. Consiste en ordenadores 3uncionando con el sistema operati o E25MLinu? $ue eAecutan el ser idor Oeb #pacBe y el ser idor 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 0a a.

2. Ar$uitectura
Base de datos 1 &abla1
col1 col2 . . . . . . col3 ? .e+istro

&abla2
col1 ? . . . col2 . . . col3 .e+istro

Cla e primaria Fndice Cla e 3ornea

Cla e primaria

*lustraci+n ,( -squema de una base de datos relacional 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 cla es primarias y cla es 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

&*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 tra Js 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

&igura 0( 1escri/ci+n de la ca/a l+gica )n esta capa se reali/an arias operaciones. La primera y $ue sir e 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 2( !rquitectura de )ySQL

)sta ar$uitectura +eneral sir e 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 ser idor. La <i+ura " muestra como es el 3luAo de eAecucin de una sentencia SQL dentro del ser idor. Bsicamente4 las consultas entran a tra Js de un protocolo clienteMser idor pro enientes

&igura 4( &lu5o de e5ecuci+n del ser"idor )ySQL

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 sir en 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 tra Js 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.

!. SQL y MySQL
)n esta seccin daremos un bre e 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 sir en 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 sir en 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 b sicas


!.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 | nom reEdit | ts | +--------+-------------------+---------------------+ | ! | "r#$o %naya | &''(-!&-'& !)*+,*-) | | & | "r#$o .laneta | &''(-!&-'& !)*+,*-) | | + | Crisol | &''(-!&-'& !)*+,*-) | | ( | Edi/iones Destino | &''(-!&-'& !)*+,*-) | | - | Editorial Ci0itas | &''(-!&-'& !)*+,*-) | | 1 | 2l#me | &''(-!&-'& !)*+,*-) | | !, | .arado3 Li ros | &''(-!&-'& !)*+,*-) | | !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 bre e descripcin de las opciones particulares de MySQLL

ALL4 DISTINCT4 DISTINCTROW. Sir en 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 en iar 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 cla es 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 ser idor 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 ser idor trata los re+istros. Cuando la tabla se libera4 el ser idor 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 nue o. 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 ser idor 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 ad ertencias. %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 cla e duplicada en el comando se aborte. Con I"=ORE4 el re+istro toda 7a no se inserta4 pero no se muestra error. Las con ersiones de datos disparar7an errores y abortar7an el comando si no se especi3icara I"=ORE . Con I"=ORE4 los alores in lidos se aAustan al alor ms cercano y se insertanR las ad ertencias 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 nue o re+istro y 2 si un alor e?istente se actuali/a. 2otaL Si la columna A.D%TE L es @nica4 el I=SERT ser7a e$ui alente a este comando

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 e itar usar una clusula O= DA.LIC%TE CE< en tablas con cla es @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 cla e 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 t l?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 interacti a 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 cla es 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 nue as 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 autom ticos


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 SHOW DATABASES SHOW TABLES FROM nombre_db :uncin Muestra un lista de todas las bases de datos 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 cla e(%.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 e itar 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 bre e 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 cla es 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 pri ile+ios de cada usuario dentro del sistema. SC-)M#=%.ICIL)E)S. Contiene in3ormacin sobre los pri ile+ios espec73icos sobre cada base de datos. La in3ormacin de esta tabla iene de mysql.db. '#BL)=%.ICIL)E)S. Contiene in3ormacin sobre los pri ile+ios espec73icos sobre cada tabla. La in3ormacin de esta tabla iene de mysql.tables_priv. C1L5M2=%.ICIL)E)S. Contiene in3ormacin sobre los pri ile+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 nue a 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 ser idor 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 operati os $ue la soportan. InnoD2 tambiJn se incluye por de3ecto en todas las distribuciones binarias de MySQL !.; . )n distribuciones 3uente4 puede acti ar o desacti ar 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 obAeti o es $ue sir a 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 tra Js de la #%I MySQL C Client. )n 3uturas ersiones4 ser capa/ de conectar con otras 3uentes de datos usando otros dri ers 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 e itar 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 des entaAa 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 operati o. )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 in erso. #dems4 el cdi+o en el ser idor $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 operati os $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 cla e es 1;;; bytes. )sto puede cambiarse recompilando. )n caso de cla e 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 cla e. 'odos los alores de cla e 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 di ide de 3orma $ue el nodo mayor slo conten+a una cla e. )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 nue os 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 uel en 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 cla es4 as7 como para las cla es 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 alternati a 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 ni el 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 3or neas. Cuando se de3inen relaciones entre tablas usando cla es 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 lle an 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 ser idor y copiar el 3icBero a otro ser idor. %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 lle an 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 nue os 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 e3ecti o 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 nue o 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 e itar 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 indi iduales4 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 nue a ac7a para los nue os 7ndices4 y entonces se copiaban uno a uno los nue os. Con la nue a 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 e3ecti a 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.

&igura <( -5em/lo de =;8ree La ordenacin corresponde a la cla e 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 (Vo er3loOW* en 3orma de lista enla/ada.

Se introducen siete tablas nue as 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 indi idualmente4 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.

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 e itar 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 ser idor MySQL y otros 3actores. 2ormalmente4 la @nica manera de obtener una respuesta para una determinada aplicacin es Bacer pruebas de elocidad e?tensi as 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 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 lle a 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.

> las entaAas de MyIS#M sonL

#.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 indi iduales. )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 ni eles 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.

&igura >( !rquitectura de )ySQL;Cluster 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 administrati as en +eneral. )s el primero en iniciarse y corresponde al pro+rama ndb_mgmd.

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 ser idores 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 ser idor maestro y 2 escla os4 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 ni el. )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 bre e 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 positi os y ne+ati os. Con el atributo 52SIE2)6 el ran+o se restrin+e a n@meros positi os. 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 TINYINT(m)

Si+ni3icado )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. )ntero de 1"Gbits (2 bytes4 G32.:"& a K32.:":* )ntero de 24Gbits (3 bytes4 G&.3&&.";& a K&.3&&.";:* )ntero de "4Gbits (& bytes4 [9.22\1;]1&* Sinnimo de BIGINT PRIMARY KEY AUTO_INCREMENT NOT NULL

SMALLINT(m) MEDIUMINT(m) BIGINT(m) SERIAL 8abla '( 8i/os de enteros

INT(m), INTEGER(m) )ntero de 32Gbits (4 bytes4 G2.14:.4&3."4& a K2.14:.4&3."4:*

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 nue o 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 cla es 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 nue o alor solo 3unciona cuando se crean nue os 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 FLOAT(m, d)

Si+ni3icado 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. 2@mero en coma 3lotante4 precisin de & bytes. Sinnimo de 615BL)

DOUBLE(m, d) REAL(m, d)

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 DATE TIME DATETIME YEAR TIMESPAMP Si+ni3icado <ecBa en la 3orma I2;;&G12G31I4 ran+o desde 1;;;G;1G;1 Basta 9999G12G31 (3 bytes* 'iempo en la 3orma I23L!9L!9I4 ran+o [&3&L!9L!9 (3 bytes* Combinacin de DATE ms TIME #8o 19;;G21!! (1 byte* 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 ALLOW_INVALID_DATES NO_ZERO_DATE NO_ZERO_IN_DATE 8abla 0( !tributos /ara 1!8-

Si+ni3icado %ermite 3ecBas incorrectas4 como 2;;&G;2G31. 2o permite la 3ecBa ;;;;G;;G;;. 2o permite el ; como mes o d7a.

)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 CHAR(n) VARCHAR(n) Si+ni3icado Cadena de caracteres con lon+itud espec73ica n4 m?imo 2!!. 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 Cadena de caracteres de lon+itud ariable4 m?imo 2!! bytes. Cadena de caracteres de lon+itud ariable4 m?imo 2 1" 1 Cadena de caracteres de lon+itud ariable4 m?imo 2 24 1 Cadena de caracteres de lon+itud ariable4 m?imo 2 32 1

TINYTEXT TEXT MEDIUMTEXT LONGTEXT

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+ni3icati a. )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 a iso. # partir de MySQL !.; Bay dos no edades 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 lle ar 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?clusi amente 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 perspecti a 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 resol er 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 (5ni ersal 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 incon enientesL 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 alternati a 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 des entaAa 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 ser idor 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_bin | cp1250_polish_ci | gbk_chinese_ci | gbk_bin | latin5_turkish_ci | latin5_bin | armscii8_general_ci | armscii8_bin | utf8_general_ci | utf8_bin | utf8_unicode_ci ...

| | | | | | | | | | | |

cp1250 cp1250 cp1250 gbk gbk latin5 latin5 armscii8 armscii8 utf8 utf8 utf8

| 44 | 66 | 99 | 28 | 87 | 30 | 78 | 32 | 64 | 33 | 83 | 192

| | | | | | | | | | | |

Yes Yes Yes Yes

| | | | | | | | | | | |

Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes

| | | | | | | | | | | |

1 1 1 1 1 1 1 1 1 1 1 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 des entaAas. 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 des entaAa es $ue normalmente los datos BL1B solo se pueden leer enteros4 es decir4 no se pueden leer partes de ellos. La alternati a 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 BIT(n) TINYBLOB BLOB MEDIUMBLOB LONGBLOB Si+ni3icado 6atos en bits4 donde n es el n@mero de bits (m?imo "4* 6atos binarios de tama8o ariable4 m?imo 2!! bytes 6atos binarios de tama8o ariable4 m?imo 2 1" 1 bytes 6atos binarios de tama8o ariable4 m?imo 2 24 1 bytes 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 consecuti os (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 NULL NOT NULL DEFAULT xxx DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP PRIMARY_KEY AUTO_INCREMENT Si+ni3icado La columna puede contener de3ecto*. )l alor 25LL no est permitido. )l alor por de3ecto ??? se usar si no se especi3ica uno. %ara columnas 'IM)S'#M%4 la Bora actual se almacenar cuando se creen nue os re+istros %ara columnas 'IM)S'#M%4 la Bora actual se almacenar cuando se produ/ca una modi3icacin del re+istro. 6e3ine la columna como cla e primaria. Se asi+na un entero secuencialmente usar con columnas tipo I2')E).. #dems4 Ba de ir acompa8ado de 21' 25LL y %.IM#.>=Q)>. %ara alores I2')E).4 no permite alores ne+ati os. alores nulos (3unciona por

UNSIGNED

CHARACTER SET nombre %ara cadenas de caracteres4 especi3ica el Aue+o de [COLLATE orden] 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 sir en 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* Cur e (no instanciable*

LineStrin+ (instanciable*

Line (instanciable* Line.in+ (instanciable*

Sur3ace (no instanciable*

%oly+on (instanciable* Multi%oint (instanciable* MultiCur e (no instanciable*

EeometryCollection (instanciable*

MultiLineStrin+ (instanciable* Multi%oly+on (instanciable*

MultiSur3ace (no instanciable*

)l cali3icati o 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 ser idor 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 WKB type X Y : : : : 01 01000000 000000000000F03F 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 ser idor 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 ser idor 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 ser idores de bases de datos. Se puede especi3icar el modo SQL por de3ecto arrancando mysqld con la opcin --sqlmodeDJmodesJ. )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 ser idor cambiando la ariable sql_mode usando el comando SET [SESSION|GLOBAL] sql_mode='modes' . #si+nar la ariable GLOBAL re$uiere el pri ile+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 a isoII 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 acti ado.. 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 con eniente 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 pro oca $ue el ser idor re$uiera $ue el mes y d7a se e al@en como alores le+ales y no simplemente en los ran+os de 1 a 12 y de 1 a 314 respecti amente. %or eAemplo4 K&''(-'(-+!K es le+al con el modo estricto desacti ado4 pero ile+al con el modo estricto acti ado. %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 I LI para delimitar identi3icadores en modo #2SI. Con %=SI?BAOTES acti ado4 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 ad ertencia* cuando encuentra una di isin 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 di isin por cero. Si este modo no se da4 MySQL retorna =ALL para una di isin por cero. Si se usa I=SERT I"=ORE o A.D%TE I"=ORE4 MySQL +enera una ad ertencia de di isin 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 -> 0 mysql> SET sql_mode mysql> SELECT NOT 1 -> 1 = ''; BETWEEN -5 AND 5; = 'broken_not'; BETWEEN -5 AND 5;

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 reser adas. Como resultado4 si $uiere acceder a cual$uier base de datos4 tabla4 o nombre de columna $ue sea una palabra reser ada4 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 reser a4 as7 $ue debe delimitarlaL
SELECT JAserJ FROM mysql:J#serJ;

=O?%ATO?CRE%TE?ASER %re iene $ue "R%=T cree automticamente nue os 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 nue o n@mero de secuencia cuando encuentra los alores ' 4 resultando en una tabla con distinto contenido $ue la $ue 3ue olcada. #cti ar =O?%ATO?E%LAE?O=?MERO antes de recar+ar el 3icBero con el olcado resuel e 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 6esacti a el uso del carcter de barra in ertida (INI* como carcter de escape en cadenas de caracteres. Con este modo acti ado4 la barra in ertida se con ierte 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 directi as I=DEG DIRECTOR< y D%T% DIRECTOR<. )ste opcin es @til en ser idores de replicacin escla os.

=O?E="I=E?SA2STITATIO= SI no est acti ado4 cuando se intenta crear una tabla con un motor de almacenamiento no disponible4 MySQL usa el motor por de3ecto y da un a iso. Si se intenta cambiar de motor a uno no disponible con en ALTER TABLE4 el sistema da un a iso y el ALTER no tiene e3ecto. SI la opcin est acti ada4 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 ad ertencia. (#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 ad ertencia. (#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 acti ada4 esto no ocurre y se conser an. )ste modo no se aplica para columnas C#.C-#. $ue siempre conser an 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 #cti a el modo estricto para todos los motores de almacenamiento. .ecBa/a los datos in lidos. 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 in lidos o no presentes. 5n alor puede ser in lido 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 in lidos 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 de uel e 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 e itarlo4 es meAor usar comandos de un @nico re+istro ya $ue pueden abortarse sin cambiar la tabla. %ara STRICT?TR%=S?T%2LES4 MySQL con ierte los alores in lidos en el alor lido ms pr?imo para la columna e inserta el nue o 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 ad ertencia en lu+ar de un error y contin@a procesando el comando.

)l modo estricto no permite 3ecBas in lidas como K&''(-'(-+!K. )sto si+ue permitiendo 3ecBas con partes con ceros4 como &''(-'(-''K o 3ecBas eeceroII. %ara no permitirlas tampoco4 acti e 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 acti ados*4 MySQL inserta alores aAustados para alores in lidos o no presentes y produce ad ertencias. )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 abre iaciones 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 indi iduales $ue slo estn disponibles en las ersiones ms recientes. %=SI* )$ui alente 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&* )$ui alente 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* )$ui alente 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* )$ui alente 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+&+* )$ui alente a =O?FIELD?O.TIO=S4 7I"7?=OT?.RECEDE=CE. M<SBL('* )$ui alente a =O?FIELD?O.TIO=S4 7I"7?=OT?.RECEDE=CE. OR%CLE* )$ui alente 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* )$ui alente 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* )$ui alente 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 operati os 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 representati o 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 Linu? 'Be 6e3initi e ... ClientMSer er

*ditorial Erupo #naya Erupo %laneta Erupo #naya

A8o

Autor1

Autor2

Autor!

2;;4 Mi$uel %Jre/ 2;;3 Mi$uel %Jre/ 6a id %ui+ 199: 0osep Mart7n 6an Lpe/ 2;;; %au Costa 'ob7as hl are/ .obert Cila

,eb #pplication ... Crisol 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 cla e 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 1 2 3 4 ! " : & Linu? 'Be 6e3initi e ... 'Be 6e3initi e ... ClientMSer er ClientMSer er ClientMSer er ,eb #pplication ... ,eb #pplication ... *ditorial Erupo #naya Erupo %laneta Erupo %laneta Erupo #naya Erupo #naya Erupo #naya Crisol Crisol A8o Autor 2;;4 Mi$uel %Jre/ 2;;3 Mi$uel %Jre/ 2;;3 6a id %ui+ 199: 0osep Mart7n 199: 6an Lpe/ 199: .obert Cila 2;;; %au Costa 2;;; 'ob7as hl are/

)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 di idida en otras tablas. )stas tablas deben ser enla/adas usando cla es 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 1 2 3 4 autorI( 1 2 3 4 ! " : & Linu? 'Be 6e3initi e ... ClientMSer er ,eb #pplication ... tituloI( 1 2 2 3 3 3 4 4

*ditorial Erupo #naya Erupo %laneta Erupo #naya Crisol Autor Mi$uel %Jre/ Mi$uel %Jre/ 6a id %ui+ 0osep Mart7n 6an Lpe/ .obert Cila %au Costa 'ob7as hl are/

A8o 2;;4 2;;3 199: 2;;;

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 1 2 3 4 Linu? 'Be 6e3initi e ... ClientMSer er ,eb #pplication ...

*ditorial Erupo #naya Erupo %laneta Erupo #naya Crisol

A8o 2;;4 2;;3 199: 2;;;

autorI( Autor 1 2 3 4 ! " : Mi$uel %Jre/ 6a id %ui+ 0osep Mart7n 6an Lpe/ .obert Cila %au Costa 'ob7as hl are/

tituloI( autorI( 1 2 2 3 3 3 4 4 1 1 2 3 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 cla e 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 cla e primaria ya $ue arios t7tulos pueden compartir una misma editorial. #s7 pues4 la tabla titulos y la nue a editoriales $uedar7an as7L

tituloI( &6tulo 1 2 3 4 Linu? 'Be 6e3initi e ... ClientMSer er

editI( A8o 1 2 1 2;;4 2;;3 199: 2;;;

,eb #pplication ... 3

editI( nombre 1 2 3 Erupo #naya Erupo %laneta Crisol

7.2 Inte+ridad re3erencial


Las relaciones entre las clases se representan mediante cla es primarias y 3orneas. Las cla es primarias sir en para locali/ar4 lo ms rpido posible4 un re+istro en una tabla. #dems4 una cla e primaria identi3ica de manera uni oca un re+istro en un tabla. Las cla es 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 cla e primaria4 con lo cual contra ms compacta sea la cla e primaria ms e3iciente (en elocidad y espacio* ser el 7ndice. %or ello se suelen usar enteros. Se+undo4 la cla e 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 cla e primaria4 sino a todas las tablas relacionadas a tra Js de cla es 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 ele ado4 o $ue amos a tener mucBos I2S).' y 6)L)')4 podemos usar BIGINT en lu+ar de INT. %or otro lado4 las cla es 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 cla e 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 cla e 3ornea $ue re3erencia la cla e 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 nue o 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 cla e 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 pro ocado 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 desacti arla4 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 b sicos


%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 lle arn 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 in erso 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 ni el de SQL.

Indices clusteri/ados y secundarios


Las tablas MyIS#M +uardan los 7ndices en 3icBeros separados $ue contienen la cla e primaria (y las posibles secundarias*. #dems por cada alor de la cla e 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 re Js. )l 7ndice y los re+istros se +uardan Auntos y en el orden de la cla e primaria. )ste es el sistema $ue utili/a Inno6B. Cuando los datos son accedidos casi siempre por la cla e 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 cla e primaria tambiJn leemos el re+istro (en la cacBe*. Mientras $ue las tablas MyIS#M necesitan dos lecturas4 una para la cla e y otra para el re+istro. )s importante recalcar $ue esta e3iciencia solo 3unciona cuando la consulta usa la cla e 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 cla e primaria para acceder al re+istro. Si la cla e 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 cla e primaria de un re+istro. )so implica reali/ar las si+uiente operacionesL

#ctuali/ar el re+istro 6eterminar la nue a cla e primaria Mo er el re+istro a su nue a 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 cla es 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 cla e 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 lle an una cla e primaria. 2o Bace 3alta especi3icar una e?pl7citamente4 ya $ue si no se Bace MySQL crea una oculta automticamente. )n ambos casos las cla es primarias son enteros #5'1=I2C.)M)2'. Si se a8ade una cla e 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$ui alentes4 3also si los alores no son e$ui alentes4 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 cla e primaria. )ste comportamiento es estndar SQL. )s una de las pocas cosas $ue di3erencian un 7ndice 52IQ5) de uno de cla e primaria. > para terminar4 el usar 25LL en un 7ndice de cla e 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 ni el 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 e aluaciones de 3unciones (,-).) 6#>(columna* Z ...* )n operaciones 01I2 los 7ndices solo se pueden usar cuando la cla e 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 sir e 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 des entaAa 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 cla e $ue se almacena. la cla e 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.

&igura 'A( -5em/lo de Drbol 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 di idir 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 resol er consultas de tipo +eomJtrico. %odemos er un eAemplo de estructura de .G'ree en la <i+ura 11.

&igura ''( -5em/lo de R;8ree

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. Cla es empa$uetadas. )s un mecanismo parecido al anterior pero para enteros. )n los 7ndices los enteros se almacenan con el byte ms si+ni3icati o 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 cla e entera. %ara acti arlos 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

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 acti a el retraso en la escritura para todas las tablas MyIS#M independientemente del alor DELAY_KEY_WRITE de cada una.

1b iamente4 el problema de usar este mecanismo es $ue los 7ndices pueden estar mal sincroni/ados con el contenido de sus respecti as 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 cla e 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 acti ar y desacti ar a oluntad en el 3icBero de con3i+uracin del ser idor a tra Js de la ariableL
query_cache_type = 1

Cuando est acti ada4 MySQL intenta locali/ar la consulta en la cacBe antes de anali/arla. %ara ello dispone de una tabla BasB interna en donde las cla es 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 An lisis sint ctico 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 administrati o 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 e olucionando 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 ob io $ue solo puede Baber un resultado ya $ue estamos Baciendo la consulta para un alor de la cla e 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 con eniente 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 ad ierte 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 ser idor. Si ol emos 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 obser arse 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 pro ocar $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 consultaL

elocidad de la

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 ele ado. )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 ser idor 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 tra Js 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 resol erlo 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 adi inar 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 tra Js del 7ndice4 sin leerlos. Sin embar+o a$u7 podemos er una e?cepcin $ue Bace $ue la cla e 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 cla e IDautor (campo key* . #dems nos dice $ue la cla e se Ba comparado con autores.IDautor de cada re+istro pre io. )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 cla e 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 cla es 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 tra Js de cla e 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 cla e 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 lle ar a situaciones e$ui ocadas 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 di ersidad. %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) high_temp TINYINT low_temp TINYINT the_date DATE INDEX (city), INDEX (the_date), )

NOT NOT NOT NOT

NULL, NULL, NULL, NULL,

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 resol erlo 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 tra Js de una cla e 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 tra Js 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 a isa. 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 acti a al poner el marcBa el ser idor con la opcinL
--lo6-slo8-q#eriesODfile_nameP

#l acti arlo4 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 acti amos4 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 moti osL

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 ser idor puede Baber tenido un pico de trabaAo Austo en ese momento

)n resumen4 este re+istro nos a isa de errores potenciales4 pero no es un prueba de3initi a 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 ser idores se los saltarn como si 3uese un comentario. Incluso se puede especi3icar $ue ersin de ser idor 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 ser idores 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 pro ocar $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 resol er 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 no edad 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 ser idor 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 ser idor 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+resi o 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 acti ada y toda las consultas se +uardan4 e?cepto las $ue lle an SQL=21=C#C-) Si ale 2 la cacBe est desacti ada e?cepto para a$uellas consultas $ue lle an 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 cla es primarias o 7ndices @nicos o cla es 3orneas. Si no lo Bacen4 la opcin updatable_views_with_limit de MySQL de3ine $uJ cambios deben producir

un a iso (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 nue a 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 deri an 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 inno acin introducida en MySQL en la ersin !.;. Son 3unciones SQL de3inidas por el usuario $ue se eAecutan directamente en el ser idor. Con los S% es posible +uardar parte de la l+ica de la aplicacin clienteGser idor en el ser idor. )n este cap7tulo eremos por$uJ los S% son una buena idea (ms se+uridad para los datos4 menos duplicacin de cdi+o4 ...*. )n +eneral4 la/ ra/ones para usar S% sonL

elocidad4 ms

Celocidad. )n mucBas ocasiones4 determinadas operaciones de una aplicacin pueden suponer $ue mucBos datos sean en iados del ser idor al cliente y ice ersa. )l cliente eAecuta un S)L)C' $ue produce mucBos resultados4 $ue son en iados desde el ser idor al cliente. )l cliente los procesa y en 7a una +ran lista de 5%6#')s de uelta al ser idor. Si todos estos pasos se pudieran eAecutar en el ser idor nos e itar7amos una +ran sobrecar+a de la comunicacin clienteMser idor. #dems4 MySQL puede preprocesar el cdi+o de los S%4 e itando 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 primiti o $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 ser idor4 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 ser idor 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 tra Js de S%s $ue se encar+an de reali/ar los S)L)C'4 5%'#') o I2S).' a tra Js 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 des entaAa 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 Ser er 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 relati os 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 pre J $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 ob iamente. %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 pri ile+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 pri ile+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 alternati as4 cursores4 ... %rimero eremos cuales son las di3erencias entre <52C'I12 y %.1C)65.)4 $ue estn resumidas en 'abla &. %.1C*(5.*
Llamada Solo con C#LL

:52C&I12
%osible en todas las instrucciones SQL (S)L)C'4 5%6#')4 ...* .etorna un alor @nico de un tipo determinado. Solo parmetros por alor. 2o se puede acceder a tablas Solo puede llamar otras 3unciones

.etorno %ar metros Instrucciones permitidas

%uede retornar uno o ms S)L)C' %ermite por alor y por re3erencia (I24 15'4 I215'* 'odas las SQL

Llamadas a otras 3unciones %uede llamar a otros o procedimientos procedimientos yMo 3unciones

8abla <( 1iferencias entre &$#C8*7# y %R7C-1$RLas 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 reser adas (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 in ocarse. #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 e aluado 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 recursi os. %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 ser idor de MySQL la recursin est desacti ada por de3ecto. %ara poder acti arla Bay $ue cambiar la ariable ma3?s$?re/#rsion?de$tF a un alor mayor $ue ;. )l alor $ue colo$uemos ser el ni el m?imo de recursin permitido. -ay $ue tener cuidado con esta ariable ya $ue al acti ar la recursin4 y sobre todo con un alor alto4 podemos sobrecar+ar el ser idor si nuestras 3unciones o procedimientos estn mal dise8ados.

1G.! %ar metros 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 sir e 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 e al@a al 3inal del bucle4 este siempre se eAecuta al menos una e/. )l bucle puede lle ar 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 e al@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 sir e 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 inter ienen 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 pre ista una tercera opcin $ue ser 5261 y $ue ser ir para desBacer los cambios producidos Basta ese momento por el S%. /ondi/ionL indica baAo $uJ condiciones deber7a acti arse 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 cla e duplicada4 Baremos estoL
6)CL#.) cla edup C#.C-#.(1;;*R 6)CL#.) cla e=duplicada C126I'I12 <1. SQLS'#') I23;;;IR 6)CL#.) C12'I25) -#26L). <1. cla e=duplicada S)' mi=errorZIcla edupI

6es+raciadamente MySQL no permite $ue se pueda acti ar 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 tu ieran $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 acti ar 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 nom re?/#rsor se almacena en la ariable 0ar!4 la se+unda en 0ar&4 y as7 sucesi amente. )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 e itar4 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 a an/ar4 de manera $ue los datos deben ser procesados en el orden en el $ue Ban sido proporcionados por el ser idor. 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 di ide 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 lle ar 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 si+uales o superiores a !.1.". La sinta?is para la creacin de tri++ers esL
CREATE [DEFINER = { #s#ario | CURRENT_USER }] TRIGGER nom re?tri66er tiem$o?tri66er e0ento?tri66er ON nom re?ta la FOR EACH ROW sentencia_tri66e

ersiones

5n tri++er es un e ento 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 pri ile+io '.IEE). para la tabla asociada. )l atributo 6)<I2). determina el conte?to de se+uridad $ue se usar para determinar los pri ile+ios de acceso en el momento de acti acin. )l atributo nombre=tri++er determina si la acti acin se debe de Bacer antes (B)<1.)* o despuJs (#<').* de modi3icar un re+istro. )l tipo de accin $ue acti a el tri++er iene determinado por e ento=tri++er. Los alores posibles sonL

I2S).'. )l tri++er se acti a 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 acti a cuando se modi3ica un re+istro. )sto corresponde a la instruccin SQL 5%6#'). 6)L)'). )l tri++er se acti a 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 acti an estos tri++ers ya $ue estas instrucciones no se trans3orman en 6)L)').

)s importante recalcar $ue estos tres tipos de e entos no se corresponden con las instrucciones SQL $ue tienen el mismo nombre4 sino $ue son tipos de e entos $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 cla es

duplicados4 con lo $ue en este solo comando se pueden acti ar 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 e ento. %or eAemplo4 para una tabla solo puede Baber un tri++er del tipo B)<1.) I2S).'. La accin SQL $ue se eAecuta si se acti a 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 acti an cuando se eAecuta un C#SC#6) en una cla e 3ornea. )sta restriccin est pre ista 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 acti ado 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 e identemente4 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 nue o 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 acti a 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 sucesi amente. %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 podemos Bacer cosas como estaL a a insertar o modi3icar. %or eAemplo4

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 acti arn 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 ol er a intentar Bacerla. Se uel en 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 en iemos al ser idor 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 ser idor 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 ol er 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 /*!40014 /*!40014 /*!40101 /*!40101 /*!40101 /*!40111 SET SET SET SET SET SET SET SQL_MODE=@OLD_SQL_MODE */; FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 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 arcBi o4 si su ersin es mayor o i+ual $ue n entonces no ser considerado comentario y se eAecutar su contenido. )so es para pre enir errores de sinta?is cuando trabaAamos con 3icBeros SQL en di3erentes ersiones de ser idores. Las instrucciones S)' iniciales ($ue solo se eAecutarn en ser idores 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 desacti an los test sobre cla es 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 acti o 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 preser an4 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 indi idualmente 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 e itar 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 ni eles de controlar el acceso a sus bases de datos. )n un primer ni el4 se determina si un usuario tiene permiso para establecer una cone?in con el ser idor. )n un se+undo ni el4 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 ser idor. )sto puede producirse a tra Js 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 ser idor se eAecutan en ordenadores di3erentes la cone?in se Ba de reali/ar a tra Js 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 ser idor se eAecutan en el mismo ordenador Bay posibilidadesL

arias

'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 operati o uni?Mlinu?. )s el tipo de comunicacin por de3ecto en uni?Mlinu?. %ipes (solo ,indoOs 2;;;MD%*L es el e$ui alente a socHets de uni?Mlinu?. Sin embar+o4 esta opcin est desacti ada 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 alternati a a la ariante de socHets de uni?Mlinu?. )n este caso4 cliente y ser idor 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 acti ada en la con3i+uracin del ser idor.

1#.2 Administracin de accesos


)n una base de datos puede Baber mucBos y muy di3erentes ni eles 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 pri ile+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 ser idor4 depende de tres elementosL

2ombre de usuario. )s el nombre con el $ue el cliente se identi3ica delante del ser idor. Los usuarios de MySQL no tienen nin+una cone?in con los usuarios del sistema operati o4 aun$ue normalmente coinciden. %assOord. 1curre lo mismo $ue con los nombre de usuario4 no tienen cone?in con el passOord del sistema operati o4 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 ser idor. Se puede dar como una direccin I% o con un nombre. #L recibir una cone?in4 el ser idor 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 pri ile+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 pri ile+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 pri ile+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 nue o usuario esL
CREATE USER nombre_usuario IDENTIFIED BY 'password'

Cambiar pri"ile+ios
-asta aBora Bemos isto al+unos eAemplos de como otor+ar pri ile+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 pri ile+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 pri ile+ios en un ser idor 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 pri ile+ios. La 'abla 9 describe cuales son y $uJ in3ormacin contienen. 2ombre user db host tables_priv columns_priv func procs_priv Si+ni3icado Controla $uJ usuarios pueden conectarse al ser idor y desde $uJ ordenador. )sta tabla tambiJn contiene pri ile+ios +lobales. )speci3ica $uJ usuarios pueden acceder a $uJ bases de datos )?tiende la tabla db con in3ormacin de los ordenadores $ue tienen acceso. )speci3ica $uien puede acceder a las tablas de una base de datos )speci3ica $uien puede acceder a las columnas de una tabla %ermite la +estin de 3unciones de3inidas por el usuario (use; defined functions*. )st sin documentar. )speci3ica $uien puede eAecutar procedimientos almacenados indi iduales.

8abla >( 1escri/ci+n de las tablas mysql que almacenan la informaci+n sobre /ri"ilegio

Das könnte Ihnen auch gefallen