Anda di halaman 1dari 43

NOTAS CURSO MYSQL BSICO MYSQL es la base de datos de cdigo abierto ms popular del mundo.

Cdigo abierto significa que todo el mundo puede acceder al cdigo fuente, es decir, al cdigo de programacin de MYSQL. Todo el mundo puede contribuir para incluir elementos, arreglar problemas, realizar mejoras o sugerir optimizaciones.
Michael MONTY Widenius es el creador de MYSQL. Actualmente compite con sistemas RDBMS propietarios conocidos, como ORACLE, SQL SERVER y DB2.

MYSQL es un sistema de administracin de bases de datos relacional (RDBMS)


MYSQL utiliza el lenguaje de consulta estructurado (SQL). Para ejecutar una conexin >mysql -h nombre del anfitrin -u nombre de usuario -pcontrasea basededatos En el caso de p sin espacio en la contrasea. Para dar permisos a un usuario sobre la base de datos >GRANT ALL ON escuela.* to rios IDENTIFIED BY rios; Para codificar el password de un Usuario >INSERT INTO tabla(user,password) VALUES(rios,PASSWORD(rios)) Para desconectar basta con QUIT, EXIT o Control D

Para crear una base de datos >CREATE DATABASE nombre_base; Para seleccionar una base de datos >USE base_datos; Para crear una tabla >CREATE TABLE nombre_tabla(employee_number INT, surname VARCHAR(40), first_Name VARCHAR(30), commission TINYINT); Para Mostrar una tabla >SHOW TABLES; SHOW TABLES FROM nombre_base; Para mostrar la estructura de una tabla >DESCRIBE tabla; DESC tabla; Para insertar datos en una tabla >INSERT INTO tabla(nombre_col tipo_col,[]) VALUES(valor1,valor2....valor n); >INSERT INTO tabla VALUES(valor1,valor2...valor N);

>INSERT INTO tabla(nombre_col tipo_col,[]) VALUES(valor1,valor2..Vlor n), (valor1, valor2,......valor N); Insercin desde un archivo de texto con grandes cantidades de datos con LOAD DATA >LOAD DATA LOCAL INFILE Sales_rep.sql INTO TABLE sales_rep; y el formato es: 1\tRive\tSol\t10 1\tGordimer\tCharlene\t15 1\tRive\tMichael\t10 1\tRove\tSole\t10 Correspondencia de Patrones >SELECT * FROM sales_rep WHERE surname LIKE Sero%; El smbolo % se trata de un comodn que significa 0 o ms caracteres. Ordenacin >SELECT * FROM Sales_rep ORDER BY surname, first_name; >SELECT * FROM sales_rep ORDER BY commission DESC; Limitacin de nmero de resultados >SELECT first_name, surname, comisin FROM sales_rep ORDER BY commission DESC LIMIT 1,1; Devolucin del valor mximo con MAX() >SELECT MAX(commission) FROM sales_rep; Recuperacin de registros distintos >SELECT DISTINCT surname FROM sales_rep ORDER BY surname; Cmo contar campos

>SELECT COUNT(surname) FROM sales_rep; >SELECT COUNT(DISTINCT surname) FROM sales_rep; Realizacin de clculos en una consulta >SELECT first_name, surname, comisin+1 FROM sales_rep; Eliminacin de registros >DELETE FROM sales_rep WHERE employee_number=5; Cmo cambiar los registros de una tabla >UPDATE sales_rep SET comisin=12 WHERE employee_numbre=1; Cmo agregar una columna >ALTER TABLE sales_rep ADD date_joined DATE; >ALTER TABLE sales_rep ADD year_born YEAR;

Modificacin de una definicin de Columna >ALTER TABLE sales_rep CHANGE year_born birthday DATE; Para cambiar la definicin de una columna y no el nombre >ALTER TABLE nombre_tabla CHANGE antiguo_nombre nueva_definicin_de_columna; Si se cambia la definicin de Columna >ALTER TABLE nombre_tabla MODIFY antiguo_nombre nueva_definicin_de_columna; Cmo cambiar el nombre de una tabla >ALTER TABLE sales_rep RENAME cashflow; Cmo eliminar la columna >ALTER TABLE sales_rep DROP enhancement_value; Cmo usar LIKE en equivalencias de patrn de SQL Carcter Descripcin % cualquier nmero de caracteres _ un carcter Expresiones Regulares Las expresiones regulares permiten realizar comparaciones complejas en MYSQL. Carcter Descripcin * Equivale a cero o varias instancias de la cadena situadas por delante + Equivale a una o una instancia situadas por delante ? Equivale a un solo carcter [xyz] Equivale a cualquier x, y o z (los caracteres incluidos dentro de los corchetes) [A-Z] Equivale a cualquier letra mayscula [a-z] Equivale a cualquier letra minscula [0-9] Equivale a cualquier digito ^ Fija la equivalencia desde el principio $ Fija la correspondencia hasta el final | Separa cadenas de una expresin regular {n,m} La cadena debe tener lugar al menos n veces, pero no ms {n} La cadena debe tener lugar n veces exactamente {n,| La cadena debe tener lugar n veces al menos

antiguo_nombre

MYSQL permite devolver las fechas en un formato especial, en lugar de utilizar el formato estndar AAAA-MM-DD. Para devolver los cumpleaos de toda la plantilla en formato MM/DD/AAAA, utilice la funcin DATE_FORMAT().

>SELECT DATE FORMAT(date_joined, %m/%d/%Y) FROM sales_rep WHERE employee_number=1; Cmo especificar el formato de fecha %m devuelve el mes(01-12) %d devuelve el da(01-31) %Y devuelve el ao en formato de 4 dgitos %y devuelve el ao en formato de 2 dgitos %M devuelve el nombre del mes %w devuelve el nombre del da de la semana %e devuelve el da(1-31) %a devuelve el nombre del da de la semana en formato abreviado. %D es el da del mes con sufijo %b es el nombre del mes abreviado >SELECT DATE_FORMAT(date_joined,%a %D %b, %Y) FROM sales_rep WHERE employee_number=1; Recuperacin de la fecha y hora actual >SELECT NOW(), CURRENT_DATE(); >SELECT YEAR(birthday) FROM sales_rep; >SELECT MONTH(birthday), DAYOFMONTH(birthday) FROM sales_rep; Cmo aplicar un Nuevo encabezado a una columna con AS >SELECT surname, first_name, MONTH(birthday) AS month, DAYOFMONTH(birthday) AS day FROM sales_rep ORDER BY month; Combinacin de Columnas con CONCAT >SELECT CONCAT(first_name, , surname) AS name, MONTH(birthday) AS month, DAYOFMONTH(birthday) AS day FROM sales_rep ORDER BY month; Cmo buscar el da del ao >SELECT DAYOFYEAR(date_joined) employee_number=1;

FROM

sales_rep

WHERE

Realizacin de clculos con fechas >SELECT YEAR(NOW())-YEAR(birthday) FROM sales_rep; Funcin RIGHT La funcin RIGHT devuelve los valores de un campo de derecha a izquierda >SELECT RIGHT(CURRENT_DATE,5) FROM sales_rep

Agrupacin de una consulta

Cuando se trabaja con columnas que nos devuelven valores escalares y queremos regresar en el mismo query otros campos no escalares, es necesario agrupar el query por los campos no escalares. >SELECT sales_rep, SUM(value) as sum FROM sales GROUP BY sales_rep ORDER BY sum desc; TIPOS DE DATOS Tipos de columnas numrico UNSIGNED : no permite el uso de nmeros negativos. ZEROFILL : rellena el valor con cero. TINYINT [(M)] [UNSIGNED] [ZEROFILL] BIT BOOL SMALLINT [(M)] [UNSIGNED] [ZEROFILL] INT[(M)] [UNSIGNED] [ZEROFILL] FLOAT [(M,D)] [UNSIGNED] [ZEROFILL] Tipos de columnas de cadena CHAR(M) [BINARY] VARCHAR(M) [BINARY] BLOB TEXT ENUM(valor1,valor2, ...) SET (valor1,valor2, ...) Tipos de columnas de fecha y hora DATETIME DATE TIME YEAR OPCIONES DE MySQL Si activamos -E >SELECT * FROM CUSTOMER\G;

Si activamos -i evita errores de espacio >SELECT MAX_(value) FROM sales; La opcin -H o -html lo saca en html >SELECT * FROM customer; Anlisis de los distintos tipos de tablas

Existen 2 tipos de tablas de transicin segura (InnoDB y BDB). El resto (ISAM, M y ISAM, MERGE y HEAP) no son de transaccin segura. Tablas ISAM Las tablas ISAM (mtodo de acceso secuencial indexado) era el estndar antiguo de MySQL. Fueron sustituidas pos las tablas MyISAM a partir de 3.23 pero se conservan hasta 4.1. La diferencia es la tabla MyISAM utiliza menos recursos del sistema. Las tablas ISAM tienen las siguientes caractersticas: ISAM almacena los archivos de datos con una extensin. ISD y el archivo de ndice con .ISM

Las tablas no son archivos binarios transportables entre diferentes equipos. Como convertir una tabla ISAM a MyISAM >ALTER TABLE nombre_de_tabla TYPE = MyISAM; Tablas MyISAM Los ndices son ms pequeos sobre una seleccin; pero consumen ms recursos sobre insercin y borrado. Los archivos de datos se guardan con la extensin .MYD y la de ndice es .MYI. Existen 3 subtipos de tablas MyISAM: estticas, dinamicas y comprimidas. Al crear las tablas, MySQL escoge entre el tipo dinmico y el esttico. El valor predeterminado son las estticas y se crean s no incluyen columnas VARCHAR, BLOB o TEXT, de lo contrario la tabla se convierte en dinmica. Tablas estticas (tablas de longitud fija) Caractersticas: o Son muy rpidas o Son fciles de almacenar en cach o Resultan sencillas de reconstruir o Requieren menos espacio en disco Tablas dinmicas

Caractersticas: o Ocupan menos espacio en disco o No son sencillas de reconstruir tras un fallo o Cada nuevo registro consta de un encabezado, lo que indica que columnas de cadena estn vacas y que columnas numrica tienen cero. Tablas comprimidas Son de solo lectura, son ideales para su uso con datos comprimidos que no cambien (que slo se puedan leer y no escribir), y donde no exista mucho espacio disponible, CD_ROM. EJEMPLO: Usando el comando myisampack [opciones] nombre_del_archivo

[opciones] o o o o o o w, -wait v, -version v, -verbose f, -force s, -silent t, -test Si se est utilizando la tabla se espera y vuelve a intentarlo. Muestra informacin sobre la versin . Modo detallado. Crea un archivo temporal .TMD. Solo muestra errores. No comprime, la tabla, slo prueba el proceso de compresin.

C:\MySQL\bin> myisampack v f ..\data\firstdb\sales_rep C:\MySQL\bin> myisampack unpack ..\data\firstdb\sales_rep Tablas MERGE Fusin de dos tablas iguales en una. Tablas HEAP Son ms rpidas porque se almacenan en memoria. >CREATE TABLE sales_rep( employe_number int(11) default NULL surname varchar(40) default NULL first_name varchar(30) default NULL commission tinyint(4) default NULL date_joined date default NULL birthday date default NULL ) TYPE = MyISAM;

>CREATE TABLE heaptest TYPE = HEAP SELECT first_name, surname FROM sales_rep; Caractersticas: No admiten AUTO_INCREMENT No admiten BLOB o TEXT No admiten el uso de ndices en una columna NULL No se puede ORDER BY Buscar sobre las tablas MERGE, COMPRIMIDAS, y las INNODB y DBD.

Combinaciones avanzadas Las combinaciones avanzadas son una parte fundamental de una buena B.D. CREATE TABLE customer( id int(11) default NULL, first_name varchar(30) default NULL, surname varchar(40) default NULL )TYPE=MyISAM; INSERT INTO customer VALUES(1,'Yvonne','Clegg'); INSERT INTO customer VALUES(2,'Johnny','Boris'); INSERT INTO customer VALUES(3,'Winston','Powers'); INSERT INTO customer VALUES(4,'Patricia','Mankunku'); CREATE TABLE sales( code int(11) default NULL, sales_rep int(11) default NULL, customer int(11) default NULL, value int(11) default NULL )TYPE=MyISAM; INSERT INTO sales VALUES(1,1,1,2000); INSERT INTO sales VALUES(2,4,3,250); INSERT INTO sales VALUES(3,2,3,500); INSERT INTO sales VALUES(4,1,4,450); CREATE TABLE sales_rep( employee_number int(11) default NULL, surname varchar(40) default NULL, first_name varchar(30) default NULL,

commission tinyint(4) default NULL, date_joined date default NULL, birthday date default NULL )TYPE=MyISAM; INSERT INTO sales_rep VALUES(1,'Rive','Sol',10,'2000-02-15','1976-03-18'); INSERT INTO sales_rep VALUES(2,'Gordimer','Charlene',15,'1998-07-09','1958-11-30'); INSERT INTO sales_rep VALUES(3,'Serote','Mike',10,'2001-05-14','1971-06-18'); INSERT INTO sales_rep VALUES(4,'Rive','Morgane',10,'2002-11-23','1982-01-04'); Comencemos por una combinacin bsica: mysql> SELECT sales_rep, customer, value, first_name, surname FROM sales, sales_rep WHERE code=1 AND sales_rep.employee_number=sales.sales_rep;

Una combinacin ms compleja Mysql> SELECT sales_rep.first_name, sales_rep.surname, value, customer.first_name, customer.first_name, customer.surname FROM sales, sales_rep,customer WHERE sales_rep.employee_number = sales.sales_rep AND customer.id= sales.customer; Combinaciones Internas Las combinaciones internas son otra forma de describir el primer tipo de combinacin aprendido. Las siguientes consultas son idnticas: mysql> SELECT first_name, surname, value FROM customer, sales WHERE id=customer; mysql> SELECT first_name, surname, value FROM customer INNER JOIN sales ON id=customer; Combinaciones por la izquierda(o combinaciones externas por la izquierda) Imagine que hemos hecho otra venta, con la diferencia de que esta vez el pago se ha realizado al contado y el cliente se ha marchado con los artculos sin que hayamos tomado sus datos. No hay problema porque todava podemos agregarlos a la tabla sales utilizando un valor NULL para el cliente; mysql>INSERT INTO sales(code,sales_rep,customer,value) VALUES (7,2,NULL,670); ahora ejecutemos la instruccin anterior Mysql> SELECT sales_rep.first_name, sales_rep.surname, value, customer.first_name, customer.first_name, customer.surname FROM sales, sales_rep,customer WHERE sales_rep.employee_number = sales.sales_rep AND customer.id= sales.customer; Qu ocurre? Dnde est la nueva venta? El problema est en que como el cliente es NULL en la tabla sales, la condicin de combinacin no se cumple. La solucin es implementar una combinacin externa.Una combinacin externa por la izquierda devuelve

todas las filas coincidentes de la tabla izquierda, independientemente de si existe una fila correspondiente en la tabla de la derecha. La sintaxis es la siguiente: SELECT campo1, campo2 FROM tabla1 LEFT JOIN tabla2 ON campo1=campo2; mysql>SELECT first_name, surname, value FROM sales LEFT JOIN customer ON id=customer; mysql>SELECT first_name, surname, value FROM customer LEFT JOIN sales ON id=customer; mysql>SELECT sales_rep.first_name, sales_rep.surname, value, customer.first_name, customer.surname FROM sales LEFT JOIN sales_rep ON sales_rep.employee_number= sales.sales_rep LEFT JOIN customer ON customer.id=sales.customer;

Combinaciones por la derecha(o combinaciones externas por la derecha) mysql>SELECT first_name, surname,value FROM customer RIGHT JOIN sales ON id=customer; Combinaciones externas completas SELECT campo1,campo2 FROM tabla1 FULL OUTER JOIN tabla2 Combinaciones naturals y la palabra clave USING El campo id de la tabla customer y el campo customer de la tabla sales estn relacionados. Si les asignramos el mismo nombre, podramos utilizar varios mtodos de SQL que permiten que las instrucciones JOIN resulten ms sencillas de manejar. mysql>ALTER TABLE sales CHANGE customer id INT; ahora utilizando NATURAL mysql>SELECT first_name,surname, value FROM customer NATURAL JOIN sales; sera equivalente a: mysql>SELECT first_name,surname, value FROM customer INNER JOIN sales ON customer.id=sales.id; las combinaciones naturales tambin pueden ser por la izquierda o por la derecha. Las siguientes dos instrucciones son idnticas: mysql>SELECT first_name,surname, value FROM customer LEFT JOIN sales ON customer.id=sales.id; mysql>SELECT first_name,surname, value FROM customer NATURAL LEFT JOIN sales;

La palabra clave USING brinda un mayor control sobre una combinacin natural. Si dos tablas constan de varios campos idnticos, esta palabra clave permite especificar aquellos que se utilizarn como condiciones de comparacin SELECT * FROM A LEFT JOIN B USING (a,b,c,d) SELECT * FROM A NATURAL LEFT JOIN B Combinacin de resultados con UNION

Combin a los resultados de diferentes instrucciones SELECT. Cada instruccin debe constar del mismo nmero de columnas >SELECT id, first_name, surname FROM old_customer UNION SELECT id, first_name, surname FROM customer; no devuelve resultados duplicados. Se puede modificar este comportamiento especificando con la palabara ALL: >SELECT id FROM customer UNION ALL SELECT id FROM sales;

Subselecciones Muchas consultas realizan una operacin de seleccin dentro de una seleccin. Est programada para la versin 4.1. Cmo escribir subselecciones como combinaciones: >SELECT first_name, surname FROM sales_rep WHERE sales_rep.employee_number IN(SELECT id FROM sales WHERE value>1000); Ahora con una combinacin : >SELECT DISTINCT first_name, surname FROM sales_rep INNER JOIN sales ON employee_number=id WHERE value>1000; o alternativamente >SELECT DISTINCT first_name, surname FROM sales_rep, sales WHERE sales.id=sales_rep.employee_number AND value>1000; Para los que no hayan hecho una venta : >SELECT first_name, surname FROM sales_rep WHERE employee_number NOT IN (SELECT DISTINCT id FROM sales);

>SELECT DISTINCT first_name, surname FROM sales_rep LEFT JOIN sales ON sales_rep=employee number WHERE sales_rep is NULL;

Cmo agregar registros a una tabla desde otras tablas con INSERT SELECT

>SELECT first_name, surname,SUM(value) FROM sales NATURAL JOIN customer GROUP BY first_name, surname; >CREATE TABLE customer_sales_values( first_name VARCHAR(30), surname VARCHAR(40), value INT); >INSERT INTO customer_sales_values(first_name, surname, value) SELECT first_name, surname, SUM(value) FROM sales NATURAL JOIN Customer GROUP BY first_name, surname; >SELECT * FROM customer_sales_values; Ms sobre la agregacin de registros

INSERT tambin permite una sintaxis similar a la utilizada por una instruccin UPDATE. En lugar de la siguiente secuencia: >INSERT INTO customer_sales_values(first_name, surname, value) VALUES(Charles,Dube,0); Podramos utilizar esta otra: >INSERT INTO customer_sales_values SET first_name=Charles, surname=Dube , value=0; tambin se puede llevar a cabo una forma limitada de clculo al agregar registros. Para demostrarlo, agregue otro campo sobre la tabla customer_sales_value: >ALTER TABLE customer_sales_values ADD value2 INT; A continuacin, puede insertar elementos dentro de esta tabla y completar value2 con el doble valor: >INSERT INTO customer_sales_values(first_name, surname, value,value2) VALUES(Gladys,Malherbe,5,value*2); Este registr contiene los siguientes elementos: >SELECT * FROM customer_sales_values WHERE first_name=Gladys; Ms sobre cmo eliminar registros (DELETE y TRUNCATE) La instruccin DELETE trabaja un poco ms lento para tablas de grandes tamaos. As que se recomienda usar TRUNCATE para estos casos. >DELETE FROM customer_sales_values;

La forma ms rpida de eliminar estos valores consiste en utilizar TRUNCATE : >INSERT INTO customer_sales_values (first_name, surname, value, value2) VALUES(Johnny, chaka-chaka, 500, NULL), (Patricia, Mankunku, 450, NULL), (Winston, Powers, 750, NULL), (Yvonne, Clegg, 5800, NULL), (Charles, Dube, 0, NULL); >TRUNCATE customer_sales_values; La nica diferencia adems de la velocidad es que TRUNCATE elimina el conjunto completo sin contar los elementos eliminados y DELETE nos informa el nmero de filas que se han eliminado. Variable de usuario MySQL consta de una funcin que permite almacenar valores como variables temporales para poder utilizarlas en una instruccin posterior. Resultan tiles en la lnea de comandos. El valor de la variable se establece con la instruccin SET o en una instruccin SELECT con : = . >SELECT @avg:=AVG(commission) FROM sales_rep; >SELECT surname, first_name FROM sales_rep WHERE commission>@avg; El smbolo @ indica que es una variable de MySQL. >SET @result=22/7*33.23; >SELECT @result; Sin embargo no se pueden utilizar para sustituir parte de la consulta, o reemplazar el nombre de una tabla. >SET @t=sales; >SELECT * FROM @t; Las variables de usuario se establecen en un subproceso dado (o conexin a un servidor ) y ningn otro proceso puede acceder a ellas (es decir trabaja por sesin). Ejecucin de instrucciones SQL almacenadas en archivos A menudo se suelen guardar grupos de instrucciones SQL en un archivo para volver a utilizarlas. Esta operacin se conoce como ejecutar MySQL en modo de procesamiento por lotes. Cree un archivo de texto test.sql y agrega las siguientes lneas. >INSERT INTO customer(id, first_name, surname) VALUES(5, Francois, Papo), (6, Neil, Beneke); C:\MySQL\bin\mysql firstdb <C:\MySQL\test.sql

Para obligar a MySQL continuar procesando la accin aunque existan errores lo haremos con la opcin force: C:\MySQL\bin\mysql -f firstdb <C:\MySQL\test.sql Redireccionamiento de la salida hacia un archivo Escriba en el archivo test.sql la siguiente instruccin : >DELETE FROM customer WHERE id>=6; >INSERT INTO customer (id, first_name, surname) VALUES(6, Neil, Beneke), (7, Winnie, Dlamini); >SELECT * FROM customer; Ahora escriba la siguiente lnea : C:\MYSQL\bin\mysql -t firstdb < test.sql > test_output.txt C:\Archivos de programa\MySQL\MySQL Server 4.1\bin>mysql u root H padministrador <entrada.sql >salida.html Cmo usar archivos desde la lnea de comandos Se puede utilizar el comando SOURCE. >SOURCE test.sql Transacciones y bloqueos Con todos los tipos de tablas pueden utilizar la funcin de bloqueo, pero solos los tipos InnoDB y BDB disponen de funciones transaccionales integradas. Las transacciones en las tablas InnoDB Se pueden utilizar en transacciones bancarias. >CREATE TABLE innotest (f1 INT, f2 CHAR(10), INDEX (f1)) TYPE=InnoDB; >INSERT INTO innotest(f1) VALUES(1); >SELECT f1 FROM innotest; A continuacin procederemos a empaquetar una consulta con las instrucciones BEGIN/COMMIT : >BEGIN; >INSERT INTO innotest(f1) VALUES(2); >SELECT f1 FROM innotest; Ahora invertimos con el comando ROLLBACK:

>ROLLBACK; >SELECT f1 FROM innotest; Lecturas coherentes De manera predeterminada, las tablas InnoDB realizan una lectura coherente. Esto significa que al realizar una consulta de seleccin, MySQL devuelve los valores presentes de la base de datos hasta la ltima transaccin completa. Si en el momento de realizar la consulta existe alguna transaccin en progreso, los resultados de las instrucciones UPDATE o INSERT no se reflejarn, con una excepcin: la transaccin abierta puede modificarse (puEde que haya observado que al realizar la consulta BEGIN-INSERT-SELECT, se visualiz el resultado insertado). Para poder verlo, necesita tener dos ventanas abiertas y estar conectado la base de datos. En primer lugar agregue un registro desde una transaccin en la ventana 1: >BEGIN; >INSERT INTO innotest(f1) VALUES(3); Pase a la ventana 2: >SELECT f1 FROM innotest; El 3 que hemos insertado no se devuelve porque forma parte de una transaccin incompleta. Regrese a la ventana 1 : >COMMIT; En la ventana 2, la consulta reflejar la transaccin completada: >SELECT f1 FROM innotest;

Lectura de bloqueos para actualizaciones Las lecturas coherentes no siempre resultan adecuadas. Por ejemplo, qu ocurra si varios usuarios estn intentando agregar un nuevo registro en una tabla innotest? Cada nuevo registro inserta un nmero ascendente exclusivo. Como en este ejemplo: el campo f1 no es la clave principal o un campo de incremento automtico, por lo que nada impide que se cree un registro duplicado. Sin embargo, no queremos que esto ocurra. Lo que desearamos es leer el valor actual de f1 e insertar un nuevo valor, incrementado en una unidad. Pero esta accin no garantiza un valor nico. Examine el siguiente ejemplo, comenzando en la ventana 1: >BEGIN; >SELECT MAX (f1) FROM innotest; + +

| MAX(f1) | + + | 3 | + + Simultneamente, otro usuario realiza la misma operacin en la ventana 2: >BEGIN; >SELECT MAX (f1) FROM innotest; + + | MAX(f1) | + + | 3 | + +
1 row in set (0.11 sec)

Ahora, los dos usuarios (ventana 1 y ventana 2) agregan un nuevo registro y confirman sus transacciones: >INSERT INTO innotest (f1) VALUES (4);
Query ok, 1 row affected(0.11 sec)

>COMMIT;
Query ok, 0 row affected(0.00 sec)

Si uno de los usuarios realiza una consulta de seleccin, recibirn los siguientes resultados: >SELECT f1 FROM innotest; + + | f1 | + + | 1 | | 2 | | 3 | | 4 | | 4 | + + La lectura coherente no ha devuelto lo esperado: los registros con los valores 4 y 5. la forma de activar este resultado es realizando un bloqueo de actualizacin sobre la operacin de seleccin. Si indicamos a MySQL que estamos realizando una lectura de actualizacin, no permitir que nadie ms lea el valor hasta que nuestra transaccin se haya completado. En primer lugar, elimine el 4 incorrecto de la tabla, para realizar la operacin correctamente esta vez: >DELETE FROM innotest WHERE f!=4;
Query ok, 2 row affected(0.00 sec)

A continuacin establezca el bloqueo de actualizacin como se indica en la ventana 1: >BEGIN; >SELECT MAX (f1) FROM innotest FOR UPDATE; + + | MAX(f1) | + + | 3 | + + >INSERT INTO innotest (f1) VALUES (4);
Query ok, 1 row affected(0.05 sec)

Entretanto, la ventana 2 tambin intenta establecer en bloqueo de actualizacin: >BEGIN; >SELECT MAX (f1) FROM innotest FOR UPDATE; Fjese que no se devuelve ningn resultado. MySQL espera a que se complete la transaccin de la ventana 1. complete la transaccin en la ventana 1: >COMMIT;
Query ok, 0 row affected(0.00 sec)

La ventana 2 devolver los resultados de su consulta, tras esperar a que se complete la operacin de insercin.

>SELECT MAX (f1) FROM innotest FOR UPDATE; + + | MAX(f1) | + + | 4 | + +


1 row in set (4 min 32.65 sec)

Ahora, una vez seguros de que el 4 es el ltimo valor de la tabla, podemos agregar el 5 la ventana 2: >INSERT INTO innotest (f1) VALUES (5);
Query ok, 1 row affected(0.06 sec)

>COMMIT;
Query ok, 0 row affected(0.00 sec)

Bloqueos de lectura en modo compartido Existe otro tipo de bloqueo de lectura que no devuelve un valor si el valor que est leyendo ha sido modificado por otra transaccin incompleta. Devuelve el ltimo valor, pero no forma parte de una transaccin cuya intencin es modificar el valor. Por

ejemplo, vamos a utilizar el campo f2 creado en la tabla innotest. Asumamos que el campo f1 consta ya de elementos, pero hasta un momento posterior de la transaccin no se introducir un valor para el campo f2. Al realizar una consulta de Seleccin, no queremos recuperar un registro que disponga de un valor para f1 pero no para f2, sino que queremos obtener siempre el ltimo registro. En este caso, necesitamos esperar a que se complete la transaccin antes de que se recuperen los resultados. Por ejemplo, una transaccin comienza en la ventana 1: >BEGIN;
Query ok, 0 row affected(0.00 sec)

>INSERT INTO innotest (f1) VALUES (6);


Query ok, 1 row affected(0.00 sec)

>UPDATE innotest set f2=Sebastian WHERE f1=6;


Query ok, 1 row affected(0.05 sec) Rows matched: 1 Changed: 1 Warnings: 0

Se realiza una consulta normal de seleccin en la ventana 2, no recuperamos el ltimo valor (porque la transaccin anterior no se ha completado y la tabla InnoDB realiza una lectura coherente como parte de su comportamiento predeterminado). Sin embrago, si realiza una consulta con un bloqueo en modo compartido, no obtendr en resultado hasta que se complete la transaccin en la ventana 1. Si ejecutamos una consulta normal en la ventana 2, se recuperarn los siguientes resultados: >SELECT MAX (f1) FROM innotest; + + | MAX(f1) | + + | 5 | + +
1 row in set (0.17 sec)

Todava en la ventana 2, si realiza la misma consulta en modo de bloqueo de uso compartido no se generar ningn resultado: >SELECT MAX (f1) FROM innotest LOCK IN SHARE MODE; Complete la transaccin en la ventana 1: >COMMIT;
Query ok, 0 row affected(0.00 sec)

A continuacin la ventana 2 devolver el resultado correcto: >SELECT MAX (f1) FROM innotest LOCK IN SHARE MODE; + + | MAX(f1) | + +

| +

6 | +

1 row in set (4 min 32.98 sec)

>COMMIT;
Query ok, 0 row affected(0.00 sec)

Confirmaciones automticas De manera predeterminada, y a menos que se especifique una transaccin con BEGIN, MySQL confirmara automticamente las instrucciones. Por ejemplo, una consulta en la ventana 1 devolvera los siguientes resultados: >SELECT f1 FROM innotest; + + | f1 | + + | 1 | | 2 | | 3 | | 4 | | 5 | | 6 | + +
6 rows in set (0.11 sec)

A continuacin, el usuario de la ventana 2 inserta un registro: >INSERT INTO innotest (f1) VALUES (7);
Query ok, 1 row affected(0.00 sec)

Est inmediatamente disponible en la ventana 1 (recuerde completar todos los ejemplos anteriores con la instruccin COMMIT): >SELECT f1 FROM innotest; + + | f1 | + + | 1 | | 2 | | 3 | | 4 | | 5 | | 6 | | 7 | + +
7 rows in set (0.11 sec)

El registro insertado en la ventana 2 est inmediatamente disponible para el resto de las ventanas porque la accin predeterminada es AUTOCOMMIT. Sin embrago, en las tablas de transaccin segura (InnoDB, DBD), puede cambiar este comportamiento asignado 0 a AUTOCOMMIT. En primer lugar, realice dichas operacin en la ventana 1: >SET AUTOCOMMIT=0;
Query ok, 0 row affected(0.00 sec)

A continuacin, ejecute la consulta en la ventana 2: >SELECT f1 FROM innotest; + + | f1 | + + | 1 | | 2 | | 3 | | 4 | | 5 | | 6 | | 7 | + +


7 rows in set (0.22 sec)

Seguidamente, inserte u registro en la ventana 1; >INSERT INTO innotest (f1) VALUES (8);
Query ok, 1 row affected(0.00 sec)

En esta ocasin, no est inmediatamente disponible en la ventana 2: >SELECT f1 FROM innotest; + + | f1 | + + | 1 | | 2 | | 3 | | 4 | | 5 | | 6 | | 7 | + +


7 rows in set (0.16 sec)

Como no se ha desactivado la funcin de confirmacin automtica, la operacin de insercin de la ventana 1 no se confirmar hasta que se ejecute un comando COMMIT de manera predeterminada. Confirme la transaccin desde la ventana 1:

>COMMIT;
Query ok, 1 row affected(0.00 sec)

Ahora el nuevo registro est disponible en la ventana 2: >SELECT f1 FROM innotest; + + | f1 | + + | 1 | | 2 | | 3 | | 4 | | 5 | | 6 | | 7 | | 8 | + +


8 rows in set (0.11 sec)

Sin embargo, la secuencia AUTOCOMMIT=0 no se aplica a todo el servidor, sino slo a la sesin especificada. Si se asigna el valor 0 al comando AUTOCOMMIT en la ventana 2, el comportamiento ser diferente. En primer lugar, establezca AUTOCOMMIT en la ventana 1 y en la ventana 2: >SET AUTOCOMMIT=0;
Query ok, 0 row affected(0.00 sec)

A continuacin, ejecute la siguiente secuencia en la ventana 1 para comprobar sus elementos presentes: >SELECT f1 FROM innotest; + + | f1 | + + | 1 | | 2 | | 3 | | 4 | | 5 | | 6 | | 7 | | 8 | + +
8 rows in set (0.17 sec)

Agregue en registro en la ventana 2 y confirme la transaccin:

>INSERT INTO innotest (f1) VALUES (9);


Query ok, 1 row affected(0.00 sec)

>COMMIT;
Query ok, 0 row affected(0.00 sec)

A continuacin compruebe si aparece en la ventana 1: >SELECT f1 FROM innotest; + + | f1 | + + | 1 | | 2 | | 3 | | 4 | | 5 | | 6 | | 7 | | 8 | + +


8 rows in set (0.11 sec)

El 9 del nuevo registro no aparece, aunque hayamos confirmado los resultados. La razn es que la instruccin de seleccin de la ventana 1 forma tambin parte de una transaccin. A la lectura coherente se le ha asignado un punto temporal y este punto temporal avanza si la transaccin en la que se estableci sea completado. Confirme la transaccin en la ventana 1: >COMMIT;
Query ok, 0 row affected(0.00 sec)

>SELECT f1 FROM innotest; + + | f1 | + + | 1 | | 2 | | 3 | | 4 | | 5 | | 6 | | 7 | | 8 | | 9 | + +


9 rows in set (0.22 sec)

Como vimos anteriormente, la nica forma de examinar los ltimos resultados consiste en seleccionarlos en modo bloqueo de uso compartido. En este caso, se hubiera esperado hasta que la transaccin que realiza la operacin de insercin haya realizado una operacin de confirmacin. Transacciones en tablas DBD Las tablas DBD procesan las transacciones de forma ligeramente diferente a las tablas InnoDB. En primer lugar, cree la tabla (si no lo ha hecho en el captulo anterior) e inserte un registro desde la ventana 1: >CREATE TABLE bdbtest (f1 INT, f2 CHAR(10)) TYPE=DBD;
Query ok, 0 row affected(0.28 sec)

>BEGIN;
Query ok, 0 row affected(0.06 sec)

>INSERT INTO bdbtest (f1) VALUES (1);


Query ok, 1 row affected(0.00 sec)

A continuacin, realice la siguiente consulta desde la ventana 2: >SELECT f1 FROM bdbtest; La ventana 2 espera a que la transaccin de la ventana 1 est completada. (no devuelve un conjunto de resultados en funcin de la situacin antes de que d comienzo la transaccin de la ventana 1, como ocurre en las tablas InnoDB.) Slo cuando la ventana 1 confirma la accin, la ventana 2 recibe los resultados. Complete la transaccin de la ventana 1: >COMMIT;
Query ok, 0 row affected(0.00 sec)

Y la consulta de la ventana 2 se completa (no necesita escribirla de nuevo): >SELECT f1 FROM bdbtest; + + | f1 | + + | 1 | + +
1 rows in set (3 min 13.99 sec)

Fjese en el largo periodo de tiempo que llev la consulta. El hecho de que no se trate de una consulta de seleccin rpida en las tablas DBD significa que todas las transacciones que se pospongan pueden dar lugar a graves problemas de rendimiento.

Como en el caso de las tablas InnoDB, el modo predeterminado es AUTOCOMMIT=1. Esto significa que a menos que coloque sus cambios dentro de una transaccin (comenzando con BEGIN), se completarn inmediatamente. >SELECT f1 FROM bdbtest; + + | f1 | + + | 1 | + +
1 rows in set (0.17 sec)

A continuacin ejecute una insercin desde la ventana 2: >INSERT INTO bdbtest (f1) VALUES (2);
Query ok, 1 row affected(0.06 sec)

Resulta inmediatamente recuperable desde la ventana 1: >SELECT f1 FROM bdbtest; + + | f1 | + + | 1 | | 2 | + +


2 rows in set (0.16 sec)

Si AUTOCOMMIT se define como 0, el efecto es el mismo al de encerrar todas las instrucciones en un comando BEGIN. Asigne AUTOCOMMIT=0 e inserte un registro en la ventana 1: >SET OPTION AUTOCOMMIT=0;
Query ok, 0 row affected(0.11 sec)

>INSERT INTO bdbtest (f1) VALUES (3);


Query ok, 1 row affected(0.11 sec)

Una consulta ejecutada desde la ventana 2 esperar a que la transaccin est activa: >SELECT f1 FROM bdbtest; El resultado aparecer slo cuando la transaccin se haya confirmado: Confirme la transaccin en la ventana 1: >COMMIT;
Query ok, 0 row affected(0.05 sec)

Ahora la consulta recupera los resultados en la ventana 2 (no necesita volver a escribir la consulta): >SELECT f1 FROM bdbtest; + + | f1 | + + | 1 | | 2 | | 3 | + + Otros comportamientos transaccionales Existe una serie de comandos adicionales que finalizan automticamente una transaccin (en otras palabras, que se comportan como si hubiramos realizado una operacin de confirmacin). BEGIN ALTER TABLE CREATE INDEX RENAME TABLE (ese un sinnimo de ALTER TABLE X RENAME) TRUNCATE DROP TABLE DROP DATABASE

Incluso si el comando no produce un resultado satisfactorio, el mero hecho de aplicarlo genera una operacin de confirmacin. Por ejemplo, comencemos por la siguiente transaccin en la ventana 1: >BEGIN; >SELECT MAX (f1) FROM innotest FOR UPDATE; + + | MAX(f1) | + + | 9 | + +

Y comience otra transaccin en la ventana 2: >BEGIN; >SELECT MAX (f1) FROM innotest FOR UPDATE; Los resultados no se muestran, ya que la ventana 1 ha bloqueado la fila para su actualizacin.

Sin embrago, el usuario de la ventana 1 cambia de opinin y decide modificar primero la estructura de la tabla. Ejecutamos el comando ALTER TABLE en la ventana 1:

>ALTER TABLE innotest add f1 INT;


ERROR 1060: Duplicate column name f1

Aunque la operacin ALTER fall, se levant el bloqueo, se confirm la transaccin y la consulta de la ventana 2 se complet (no es necesario volver a introducirla). >SELECT MAX (f1) FROM innotest FOR UPDATE; + + | MAX(f1) | + + | 9 | + +
1 row in set (2 min 23.52 sec)

Bloqueo de tablas
Los bloqueos en el nivel de fila son mucho ms eficaces cuando se necesita realizar una gran cantidad de inserciones o actualizaciones en la tabla. Existen dos tipos de bloqueos de tabla: los bloqueos de lectura y los bloqueos de escritura. La sintaxis para bloquear una tabla es la siguiente: LOCK TABLE nombre_de_tabla {READ|WRITE} Para desbloquear una tabla, basta con utilizar la instruccin UNLOCK TABLE de la siguiente forma: UNLOCK TABLES; La siguiente secuencia ilustra un bloqueo en el nivel de tabla, que funcionar con todo tipo de tablas. En primer lugar, bloquee la tabla desde la ventana 1: >LOCK TABLE customer READ; Se pueden leer otros subprocesos, pero no se pueden escribir, como puede observar si prueba a utilizar el siguiente comando en la ventana 2: >SELECT * FROM customer; >INSERT INTO customer(id,first_name,surname) VALUES(5,Francois,Papo);

la instruccin INSERT no se procesa hasta que el bloqueo se libera en la ventana 1; >UNLOCK TABLES; seguidamente se completa la operacin de insercin en la ventana 2(no es necesario volver a escribirla): Tambin puede bloquear ms de una tabla a la vez . Aplique los siguientes bloqueos desde la ventana 1: >LOCK TABLE customer READ, sales WRITE; Los bloqueos de escritura tienen prioridad sobre los procesos de lectura, de manera que si un subproceso espera un bloqueo de lectura y recibe un bloqueo de escritura, el bloqueo de lectura deber esperar hasta obtener el bloqueo de escritura y a su liberacin Aplique un bloqueo de escritura en la ventana 1: >LOCK TABLE customer WRITE; Ahora intente aplicar un bloqueo de lectura desde la ventana 2: >LOCK TABLE customer READ; el bloqueo de lectura no se puede obtener hasta que se libere el bloqueo de escritura. Entretanto, se recibe otra peticin por n bloqueo de escritura, que tambin debe esperar hasta que se libere el primero Intente aplicar otro bloqueo de escritura desde una tercera ventana: >LOCK TABLE customer WRITE; A continuacin, libere el bloqueo desde la ventana 1: >UNLOCK TABLES;
Query OK, 0 rows affected (0.00 sec)

Ahora se obtiene el bloqueo de escritura de la ventana 2, aunque fue solicitado tras el bloqueo de lectura, de la siguiente forma >LOCK TABLE customer WRITE;
Query OK, 0 rows affected (0.33 sec)

>UNLOCK TABLES;
Query OK, 0 rows affected (0.00 sec) Slo cuando se libera el bloqueo de escritura de la ventana 3 se puede obtener el bloqueo de escritura de la ventana 2

>LOCK TABLE customer READ;


Query OK, 0 rows affected (4 min 2.46 sec) >UNLOCK TABLES;

Puede variar este comportamiento especificando una prioridad inferior para el bloqueo de escritura, mediante la palabra clave LOW_PRIORITY. >LOCK TABLE customer LOW_PRIORITY WRITE; los bloqueo de tabla se suelen utilizar de esta forma sobre tables que no admiten transacciones. Si est utilizando una tabla InnoDB o BDB, utilice los comando BEGIN Y COMMIT para evitar anomalas en los datos. A continuacin se incluye un ejemplo en el que podra utilizarse. Si su tabla customer_sales_values est vaca, rellnela con algunos registros: >INSERT INTO customer_sales_values(first_name, surname, value, value2) VALUES (Juan,Prez, 500, NULL),(Patricia,Cuevas,750,NULL); Imaginemos que Juan Prez ha realizado 2 ventas, cada una procesada por un administrativo diferente. La primera es de 100 dlares y la segunda de 300 dlares. Los administrativos lee el valor existente, agregan 100 o 300 a dicho valor y actualizan el registro. El problema surge si ambos realizan la operacin de seleccin antes de que cualquiera de los dos se actualice. En este caso, una de las actualizaciones sobrescribir a la otra y se perder dicho valor, de la forma en la que indica a continuacin. Realizar este ejercicio

CAPITULO II

NDICES Y OPTIMIZACION DE CONSULTAS

Un ndice es un archivo estructurado que facilita el acceso a los datos. Son listas separadas para cada campo que necesite ordenar. No contendrn todos los campos, slo aquellos que necesite ordenar y un puntero a un registro completo de la tabla. Tabla Customer ID FirstName Surname ndice Surname

1 2 3 4 5 6 7

Yvonne Johnny Winston Patricia Francois Winnie Neil

Clegg Chaka-Chak Powers Mankuku Papo Dlamini Beneke

Beneke Chaka_Chak Clegg Dlamini Mankuku Papo Powers

Creacin de un ndice Existen 4 tipos de ndice en Mysql: una clave primaria un ndice exclusivo, un ndice de texto completo y un ndice primario. Creacin de una Clave Primaria Una clave primaria es un ndice establecido sobre un campo en el que cada valor es exclusivo y ninguno de los valores es NULL. Para establecer una clave primaria al crear una tabla, utilice la instruccin PRIMARY KEY al final de las definiciones de campo. Sintaxis

>CREATE TABLE nombre_de_tabla(nombre_de_campo tipo_de_columna NOT NULL,[nombre_de_campo...,] PRIMARY KEY(nombre_de_campo1 [,nombre_de_campo2...)); Para crear una clave primaria en una tabla existente puede utilizar la palabra clave ALTER: Sintaxis >ALTER TABLE nombre_de_tabla ADD PRIMARY KEY (nombre_de_campo1 [,nombre_de_campo2...]); ejemplo: >ALTER TABLE customer MODIFY id INT NOT NULL, ADD PRIMARY KEY(id);

Creacin de una llave primaria que se compone de ms de un campo >CREATE TABLE pk2(id INT NOT NULL, id2 INT NOT NULL, PRIMARY KEY(id,id2)); O si la tabla existe >ALTER TABLE pk2 ADD PRIMARY KEY(id,id2);

Creacin de un ndice primario Los ndices que no son primarios permiten el uso de valores duplicados(a menos que los campos se especifiquen como nicos). Como siempre, es mejor crear el ndice a la vez que se crea la tabla: >CREATE TABLE nombre_de_tabla(nombre_de_campo tipo_de_columna, nombre_de_campo2 tipo_de_columna, INDEX [nombre_de_ndice] (nombre_de_campo1 [,nombre_de_campo2...])); tambin puede crear ms de una ndice al crear la tabla, separndolas sencillamente mediante comas: >CREATE TABLE nombre_de_tabla (nombre_de_campo tipo_de_columna, nombre_de_campo2 tipo_de_columna, INDEX [nombre_de_indice1] (nombre_de_campo1, nombre_de_campo2), INDEX [nombre_de_indice2] (nombre_de_campo1 [,nombre_de_campo2...])); Tambin puede crear un ndice en un momento posterior mediante el siguiente cdigo: >ALTER TABLE nombre_de_tabla ADD INDEX [nombre_de_ndice] (nombre_de_campo1 [,nombre_de_campo2...]); o con el siguiente cdigo >CREATE INDEX nombre_de_ndice ON nombre_de_tabla nombre_de_campo1 [,nombre_de_campo2.....]);

Creacin de un ndice de texto completo Puede crear ndices de texto completo en tablas MyISAM sobre cualquier campo CHAR, VARCHAR o TEXT. Los ndices de texto completo estn diseados para facilitar la bsqueda sobre palabras clave en campos de texto de tablas grandes. Para crear un ndice de texto completo al crear la tabla, utilice la siguientes sintaxis:

CREATE TABLE nombre_de_tabla (nombre_de_campo tipo_de_columna, Nombre_de_campo2 tipo_de_columna, FULLTEXT(nombre_de_campo1 [,nombre_de_campo2...])); Se puede agregar la palabra clave opcional INDEX, como muestra la siguinte sintaxis: CREATE TABLE nombre_de_tabla (nombre_de_campo tipo_de_columna, nombre_de_campo2 tipo_de_columna, FULLTEXT INDEX(nombre_de_campo1 [,nombre_de_campo2...])); Para crear un ndice de texto completo una vez creada la tabla, utilice la siguiente sintaxis: ALTER TABLE nombre_de_tabla ADD (nombre_De_campo1 [,nombre_de_campo2...]); O el siguiente cdigo CREATE FULLTEXT INDEX nombre_de_ndice nombre_de_campo [,nombre_de_campo2...]); on nombre_de_tabla FULLTEXT [nombre_de_ndice]

Uso de los ndices de texto completo Vamos a crear una tabla con un ndice de texto completo y a insertar algunos ttulos de libros para probarlo: >CREATE TABLE ft2(f1 VARCHAR(255), FULLTEXT(f1)); >INSERT INTO ft2 VALUES(Waiting for the Barbarians), (In the heart of the Country),(The Master of Petersburg), (Writing and Being),(Heart of the Beast), (Heart of the Beast), (The Beginning and the End),(Master Master),(A barbarian at my Door); Para devolver los resultados de una bsqueda de texto completo, se utiliza la funcin MATCH(), y se busca la correspondencia de un campo con un valor, como en el siguiente ejemplo, que busca ocurrencias de la palabra Master. >SELECT * FROM ft2 MATCH(f1) AGAINST (Master); NOTA: Recuerde que las bsquedas sobre campos de tipo TEXT no distinguen entre MAYSCULAS Y MINSCULAS, ni los campos VARCHAR o CHAR declarados sin la palabra clave BINARY

Palabras ruido

Ahora vamos a ejecutar otra bsqueda : >SELECT * FROM ft2 WHERE MATCH(f1) AGAINST (The Master); +------------------+ | f1 +------------------+ | Master Master | |The Master of Petersbug | +------------------+ los resultados no son los esperados. MySQL tiene lo que se conoce como umbral del 50%. Todas las palabras que aparecen en ms de un 50% de los campos se consideran como ruido y se ignoran. Todas las palabras que tengan un nmero igual o inferior a tres letras se excluyen del ndice. Existe una lista predefinida de palabras ruido, entre las que se incluyen the.

Bsquedas booleanas de texto completo Una de las optimizaciones ms tiles de MySQL 4 es su capacidad para realizar bsquedas completas booleanas. Esta funcin utiliza un conjunto completo de elementos para buscar por palabras, combinaciones de palabras, porciones de palabras y otras variantes(vase la tabla 4.1). Tabla 4.1 Operadores de bsquedas booleanas Operadores Descripcin + La palabra siguiente es obligatoria y debe aparecer en todas las filas devueltas. La palabra siguiente est prohibida y no debe aparecer en ninguna de las filas devueltas. < La palabra siguiente tiene una relevancia inferior al resto de palabras. > La palabra siguiente tiene una relevancia superior al resto de palabras () Se utiliza para agrupar palabras en subexpresiones. ~ La palabra siguiente realiza una contribucin negativa a la relevancia de la fila(no es igual al operador -, que excluye la fila completamente si se encuentra la palabra, o al operador <, que sigue asignando una relevancia positiva, aunque ms a la baja, a la palabra). El comodn que indica cero o varios caracteres Slo puede aparecer al final de . la palabra.

Cualquier expresin encerrada entre comillas dobles se toma como un conjunto.

Las bsquedas booleanas de texto completo no tienen en cuenta el umbral del 50%.para realizar una bsqueda booleana de texto completo se utiliza la clusula IN BOLEAN MODE: >SELECT * from ft2 WHERE MATCH(f1) AGAINST (+Master Petersburg IN BOOLEAN MODE); +------------------+ | f1 | +------------------+ | Master Master | +------------------+ en este ejemplo, se excluye la palabra Peterburg, por lo que no se recupera el ttulo The Master of Peterburg aunque incluye la palabra Master. Fjese en la diferencia entre estos 2 conjuntos de resultados: >SELECT * FROM ft2 WHERE MATCH(f1) AGAINST (Country Master IN BOOLEAN MODE); +------------------+ | f1 | +------------------+ | In the Heart of the Country | | The Master of Petersburg | | Master Master | +------------------+ >SELECT * FROM ft2 WHERE MATCH(f1) AGAINST (+Country Master IN BOOLEAN MODE); +------------------+ | f1 | +------------------+ | In the Heart of the Country | la palabra Country es obligatoria en la segunda bsqueda los siguientes 2 ejemplos muestran las diferencias entre una bsqueda utilizando los operadores y sin ellos. Estos operadores permiten realizar bsquedas con una correspondencia exacta en una frase: >SELECT * FROM ft2 WHERE MATCH(f1) AGAINST(the Heart of the IN BOOLEAN MODE); +------------------+ | f1 +------------------+ | In the Heart of the Country | Heart of the Beast | Heart of the Beest +------------------+

| | | |

>SELECT * FROM ft2 WHERE MATCH(f1) AGAINST(the Heart of the IN BOOLEAN MODE); +------------------+ | f1 | +------------------+ | In the Heart of the Country | no olvide colocar las comillas iniciales al utilizar el operador de comillas dobles. Si lo hace, es como si no utilizara ningn operador.

Ejercicio: realizar al menos 10 ejemplos con cada uno de los operadores booleanos.

Creacin de un ndice nico


Un ndice nico es lo mismo que un ndice ordinario con la salvedad de que no se permiten duplicaciones. Para establecer un ndice nico al crear una tabla, utilice la siguiente sintaxis: CREATE TABLE nombre_de_tabla (nombre_de_campo tipo_de_columna, nombre_de_campo_2 tipo_de_columna, UNIQUE(nombre_de_campo [,nombre_de_campo2....])); O si la tabla ya existe, puede utilizar otra sintaxis: ALTER TABLE nombre_de_tabla ADD UNIQUE [nombre_de_ndice ] (nombre_de_campo [,nombre_de_campo2...]); O esta otra: CREATE UNIQUE INDEX nombre_de_ndice ON nombre_de_tabla (nombre_de_campo [, nombre_de_campo2....]); Si el ndice contiene un solo campo, dicho campo no puede contener valores duplicados. Si el ndice contiene ms de campo, los valores de los campos individuales se puede duplicar, pero la combinacin de los valores del campo que componen el ndice entero no se pueden duplicar.

Cmo recuperar y reiniciar el valor de incremento automtico


Puede devolver el valor de incremento automtico insertado ms recientemente mediante la funcin LAST_INSERT_ID():

>SELECT LAST_INSERT_ID() FROM customer LIMIT 1 Si desea restablecer el contador de incremento automtico para que se inicie en un valor concreto, puede utilizar el siguiente cdigo: >ALTER TABLE nombre_de_tabla AUTO_INCREMENT = valor_inc_auto; NOTA : TRUNCATE, en contraposicin a DELETE, reinicia el contador de incremento automtico. NOTA: en la actualidad, est operacin slo funciona con las tablas MyISAM. Por ejemplo, el contador de incremento automtico de las tablas InnoDB no se puede establecer en un valor diferente a 1.

Eliminacin o modificacin de un ndice


Para eliminar una clave primaria utilice esta sintaxis ALTER TABLE nombre_de_tabla DROP PRIMARY KEY; Para eliminar un ndice ordinario, exclusivo o de texto completo, debemos especificar el nombre del ndice, de la siguiente forma: ALTER TABLE nombre_de_tabla DROP INDEX nombre_de_ndice; O de esta otra forma: DROP INDEX nombre_de_ndice ON nombre_de_tabla; Si no est seguro del ndice, la instruccin SHOW KEYS se lo mostrar: SHOW KEYS FROM nombre_de_tabla;

Seleccin de ndices.
Los ndices slo deberan crearse en aquellas consultas que los utilicen (por ejemplo, sobre campos de la condicin WHERE) y no sobre campos que no vayan a utilizarlos(como en caso de que el primer carcter de la condicin sea un comodn). Cree ndices que devuelvan el menor nmero de filas posible. El mejor lugar es sobre una clave primaria ya que stas se asocian de manera exclusiva a un registro. Utilice ndices cortos(cree un ndice sobre los diez caracteres de un nombre, por ejemplo, en lugar de hacerlo sobre el campo completo). No cree demasiados ndices. Los ndices aumentan el tiempo necesario para actualizar o agregar un registro. Por ello, si el ndice se crea para una consulta que

se utilice en contadas ocasiones y pueda aceptare un rendimiento ligeramente ms lento, considere la opcin de no crear un ndice. Utilice el sistema de prefijacin a la izquierda.

Las fases del desarrollo de aplicaciones


Fase1: anlisis de las necesidades El anlisis de las necesidades de un proyecto es un paso obvio en el desarrollo de una aplicacin. Los expertos repiten esta regla una y otra vez al deplorar el psimo estado del desarrollo de software. Sin embargo, se suelen escuchar excusas como no sabamos que quera eso o nunc a se nos dijo al principio para justificar el pobre resultado final de los proyectos. La primera fase de un proyecto, y quizs la ms importante, consiste en determinar las necesidades. Determinacin de las necesidades del usuario La mayor parte de las peticiones que realizan los usuarios resultan triviales, para su propia sorpresa. He conocido a usuarios, que tras trabajar con desarrolladores incompetentes o vagos, teman pedir algo ms complicado que un campo adicional de una tabla. En la mayor parte de los casos, prcticamente todo es posible siempre y cuando se solicite por adelantado. La principal dificultad no es satisfacer las necesidades del usuario, si no hacerlo una vez desarrollado el marco de trabajo inicial. Los usuarios no siempre saben lo que quieren. Necesitan que les ayudemos a formalizar sus necesidades. Asegrese, antes de nada, de que las necesidades de usuarios han quedado claras, tanto para el equipo de desarrollo como para los propios usuarios. El equipo del proyecto necesita realizar los siguientes pasos para determinar las necesidades de los usuarios: El equipo debe ayudar a los usuarios a que determinen sus necesidades. El equipo debe guiar a los usuarios, explicndoles por qu determinadas sugerencias no resultan prcticas o proponindoles alternativas mejores. El equipo debe utilizar su experiencia. Debe exponer necesidades no mencionadas para poder documentarlas . lo que resulta obvio para el usuario puede que no lo sea para los desarrolladores y puede que las necesidades importantes se pasen por alto. Las necesidades deben ser lo ms completas posibles. Por ejemplo, un usuario puede solicitar un sistema para realizar reservas. Sin embargo, esta solicitud no es adecuada ya que no se aclaran los campos necesarios para llevar a cabo la reserva ni los procesos subyacentes. Tras comprender las necesidades del usuario, el equipo debe ponerlas por escrito y presentrselas de nuevo a los usuarios y a los propietarios del proyecto(los que pagan por su desarrollo) para su confirmacin. Los usuarios deben estar seguros de lo que van a obtener. Hay que evitar las sorpresas posteriores. Obligue a los propietarios a confirmar formalmente las necesidades. De esta forma, se limita la posibilidad de que alguna de las partes quede descontenta. El incremento continuo de las necesidades durante la fase de desarrollo de un proyecto es un problema insidioso que suele producirse con frecuencia cuando no se ha llegado a un acuerdo formal sobre las necesidades en un primer momento. O bien los

propietarios del proyecto no dejan de pedir nuevos elementos o una de las partes descubre nuevos aspectos no previstos hasta entonces.

Determinacin de tecnologa necesaria La determinacin de la tecnologa necesaria es tan importante como la fase de determinacin de las necesidades de los usuarios. Puede que no resulte imposible ejecutar un sitio Web con ms de 20 millones de solicitudes al mes en un solo servidor pero si necesitar, al menos, un buen ordenador que cumpla una serie de condiciones. El equipo del proyecto no debe imponer ningn requisito previo al proyecto, como que ejecute Linux y MySQL. Se deben responder cuestiones como las siguientes: Nmero de equipos y tipo de arquitectura necesaria para unirlos? Qu tipos de equipos se necesita utilizar? Qu sistemas operativos, sistemas de bases de datos y otras aplicaciones de software se necesitan(como servidores Web, clientes de correo y dems)? Qu lenguajes se utilizan para desarrollar la aplicacin?Sern orientados a objetos?

Fase 2: Diseo de la aplicacin Una vez definidas las necesidades, llega el momento de disear la aplicacin Modelado Un modelo simplifica la estructura del programa y traduce las necesidades de los usuarios a un formato que el programador comprende de manera sencilla. Puede tratarse de modelos formales, como los del lenguaje unificado de modelado de sistemas (UML), un diagrama de flujo de datos o sencillamente un dibujo sobre un pedazo de papel. Los elementos fundamentales que debe incluir son los datos que necesita cada proceso y la informacin que genera cada uno de ellos. Uso de pseudocdigo El pseudocdigo es otro paso que puede ayudar a los programadores a desarrollar una aplicacin de forma ms rpida y sencilla. En lugar de preocuparse por los requisitos exactos de sintaxis del lenguaje de programacin, el pseudocdigo responde a las necesidades lgicas, creando los algoritmos necesarios para resolver los problemas. Codificacin ste es el paso que se suele considerar como nico. Sin embargo, la labor de codificacin resulta a menudo mucho ms sencilla cuando se ha creado documentacin en los pasos anteriores. Utilice los siguientes consejos durante la fase de codificacin:

Documente siempre su cdigo. Incluya comentarios dentro del cdigo y cree documentos aparte en los que se describan cmo se organiza la aplicacin y su funcionamiento. Si no quiere hacerlo para su uso personal, hgalo pensando en los programadores que lo vayan a utilizar posteriormente. Se puede llamar egostas a los programadores que no dejan una extensa documentacin para su uso posterior. Asegrese de asignar tiempo a esta tarea y no utilice la excusa de los plazos para pasarla por alto. Utilice nombres de archivo, de funcin y de variable claros. Pro ejemplo, la funcin f3( ) no es muy intuitiva, mientras que calcular_interes resulta ms clara. No intente reinventar la rueda. Existen muchas clases y cdigo de ejemplo disponibles. Son raros los casos en los que los programadores necesitan crear algo nico. La mayor parte del trabajo suele ser repetitivo, convirtiendo la labor de los programadores en bibliotecarios a la bsqueda dl cdigo correcto para realizar su trabajo. Inicialice todas las variables y documntelas en un lugar, incluso si est codificando en lenguajes que permiten el uso de variables antes de su inicializacin. Con ello, no slo lograr que resulten ms legibles sino tambin seguras. Divida su cdigo en partes pequeas. De esta forma le resultar ms sencillo de entender, de depurar y de mantener. En el mundo del desarrollo web por ejemplo, en algunos comandos, lo que suele dar como resultado una mezcla incomprensible. Utilice los directorios de forma inteligente. No debera incluir las distintas partes de una aplicacin dentro del mismo directorio. Agrpelas de forma lgica y en funcin de criterios de seguridad.

STORED PROCEDURE EN MYSQL >USE BASE DE DATOS; >DELIMITER $$ >DROP PROCEDURE IF EXISTS HELLOWORLD$$ >CREATE PROCEDURE HELLOWORLD( ) >BEGIN >SELECT HOLA MUNDO; >END$$ >CALL HELLOWORLD( ) $$ ------------------------------------------------------------------------------------------------------------->DELIMITER $$ >DROP PROCEDURE IF EXISTS my_sqrt$$ >CREATE PROCEDURE my_sqrt(in input_number INT) >BEGIN >DECLARE l_sqrt FLOAT; >SET l_sqrt=SQRT(input_number); >SELECT l_sqrt; >END$$ >CALL my_sqrt(9) $$ ----------------------------------------------------------------------------------------------------------->DELIMITER $$ > DROP PROCEDURE IF EXISTS my_sqrt$$ > CREATE PROCEDURE my_sqrt(in input_number INT, out out_number FLOAT) > BEGIN >SET out_number=SQRT(input_number); >END$$ >CALL my_sqrt(9,@out_value) $$ >select @out_value $$ --------------------------------------------------------------------------------------------------------------

>DELIMITER $$ >DROP PROCEDURE IF EXISTS discounted_price$$ >CREATE PROCEDURE discounted_price(in normal_price NUMERIC(8,2),out discount_price NUMERIC(8,2)) >BEGIN >IF (normal_price>500) THEN >SET discount_price=normal_price*.8; >ELSEIF (normal_price>100) THEN

>SET discount_price=normal_price*.9; >ELSE >SET discount_price=normal_price; >END IF; >END$$ >CALL discounted_price(300,@new_price) $$ >SELECT @new_price; _________________________________________________________________________ >DELIMITER $$ >DROP PROCEDURE IF EXISTS simple_loop$$ >CREATE PROCEDURE simple_loop( ) >BEGIN >DECLARE counter INTDEFAULT 0; >My_simple_loop:LOOP >SET counter=counter+1; >IF counter=10 THEN >LEAVE my_simple_loop; >END IF; >END LOOP my_simple_loop; >SELECT I can count to 10; >END$$ >Call simple_loop( ) $$

SELECT CANTIDAD INTO PARAM FROM TABLE WHERE DELIMITER // DELIMITER ; _________________________________________________________________________ Disparadores

20.1. Sintaxis de CREATE TRIGGER


CREATE TRIGGER nombre_disp momento_disp evento_disp ON nombre_tabla FOR EACH ROW sentencia_disp

Un disparador es un objeto con nombre en una base de datos que se asocia con una tabla, y se activa cuando ocurre un evento en particular para esa tabla. El disparador queda asociado a la tabla nombre_tabla. Esta debe ser una tabla permanente, no puede ser una tabla TEMPORARY ni una vista.
momento_disp es el momento en que el disparador entra en accin. Puede ser BEFORE (antes) o AFTER (despues), para indicar que el

disparador se ejecute antes o despus que la sentencia que lo activa.


evento_disp indica la clase de sentencia que activa al disparador. Puede ser INSERT, UPDATE, o DELETE. Por ejemplo, un disparador BEFORE para sentencias INSERT podra utilizarse para validar los valores a insertar.

No puede haber dos disparadores en una misma tabla que correspondan al mismo momento y sentencia. Por ejemplo, no se pueden tener dos disparadores BEFORE UPDATE. Pero s es posible tener los disparadores BEFORE UPDATE y BEFORE INSERT o BEFORE UPDATE y AFTER UPDATE.
sentencia_disp es la sentencia que se ejecuta cuando se activa el disparador. Si se desean ejecutar mltiples sentencias, deben colocarse entre BEGIN ... END, el constructor de sentencias compuestas. Esto adems posibilita emplear las mismas sentencias permitidas en rutinas almacenadas. Consulte Seccin 19.2.7, Sentencia compuesta BEGIN ... END.

Note: Antes de MySQL 5.0.10, los disparadores no podan contener referencias directas a tablas por su nombre. A partir de MySQL 5.0.10, se pueden escribir disparadores como el llamado testref, que se muestra en este ejemplo:
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);

Si en la tabla test1 se insertan los siguientes valores:


mysql> INSERT INTO test1 VALUES -> (1), (3), (1), (7), (1), (8), (4), (4); Query OK, 8 rows affected (0.01 sec) Records: 8 Duplicates: 0 Warnings: 0

Entonces los datos en las 4 tablas quedarn as:


mysql> SELECT * FROM test1; +------+ | a1 | | | | | | | | | 1 | 3 | 1 | 7 | 1 | 8 | 4 | 4 | +------+

+------+ 8 rows in set (0.00 sec) mysql> SELECT * FROM test2; +------+ | a2 |

+------+ | | | | | | | | 1 | 3 | 1 | 7 | 1 | 8 | 4 | 4 |

+------+ 8 rows in set (0.00 sec) mysql> SELECT * FROM test3; +----+ | a3 | +----+ | | | | 2 | 5 | 6 | 9 |

| 10 | +----+ 5 rows in set (0.00 sec) mysql> SELECT * FROM test4; +----+------+ | a4 | b4 | | | | | | | | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | | 3 | 0 | 1 | 2 | 0 | 0 | 1 | 1 | 0 | 0 | +----+------+

| 10 |

+----+------+ 10 rows in set (0.00 sec)

Las columnas de la tabla asociada con el disparador pueden referenciarse empleando los alias OLD y NEW. OLD.nombre_col hace referencia a una columna de una fila existente, antes de ser actualizada o borrada. NEW.nombre_col hace referencia a una columna en una nueva fila a punto de ser insertada, o en una fila existente luego de que fue actualizada. El uso de SET NEW.nombre_col = valor necesita que se tenga el privilegio UPDATE sobre la columna. El uso de SET nombre_var = NEW.nombre_col necesita el privilegio SELECT sobre la columna. Nota: Actualmente, los disparadores no son activados por acciones llevadas a cabo en cascada por las restricciones de claves extranjeras. Esta limitacin se subsanar tan pronto como sea posible. La sentencia CREATE TRIGGER necesita el privilegio SUPER