Enreas
Registrarse
Advertisement

Operaciones sobre tablas[]

En el tercer capítulo del libro se pueden encontrar varios fragmentos de código para ilustrar las diferentes operaciones que se pueden realizar con tablas. En primer lugar, la creación de tablas, de la que ya vimos algo en el capítulo 2:

USE pruebas;
CREATE TABLE persona(
  id INTEGER NOT NULL,
  nombre VARCHAR(16) NOT NULL,
  apellidos VARCHAR(64) NOT NULL DEFAULT ''
);

Continuamos cambiando algunas propiedades de esta tabla. En concreto, aumentamos la capacidad del campo nombre, y añadimos uno que almacenará la edad:

ALTER TABLE persona
  MODIFY nombre VARCHAR(32) NOT NULL,
  ADD edad INTEGER NOT NULL;

También comprobamos que es posible cambiar el nombre de las tablas:

RENAME TABLE persona TO individuo;

Dejamos para el final la más drástica de las operaciones, el borrado de tablas:

DROP TABLE IF EXISTS individuo;

Visite las siguientes páginas para más información sobre:

  1. creación de tablas: [1].
  2. modificación de tablas: [2].
  3. cambio de nombre de tablas: [3].
  4. borrado de tablas: [4].

Tipos de tabla[]

MySQL permite trabajar con diferentes tipos de tablas.

El tipo InnoDB nos permite trabajar con transacciones. Vamos a crear una tabla muy sencilla para los saldos de los clientes del banco dentro de la base de datos de pruebas para cómo se trabaja con transacciones:

USE pruebas;
DROP TABLE IF EXISTS cuenta;
CREATE TABLE cuenta(
  idcliente INTEGER NOT NULL,
  saldo DOUBLE NOT NULL DEFAULT 0
)ENGINE=InnoDB;

Insertemos un par de valores para almacenar el saldo de dos clientes:

INSERT INTO cuenta VALUES(212, 220.50);
INSERT INTO cuenta VALUES(555, 1200.00);

Para realizar una transferencia han de completarse dos pasos: la cantidad transferida debe sumarse en la cuenta de destino y restarse de la cuenta que origina la transferencia. Una operación tras la otra:

UPDATE
  cuenta
SET
  saldo=saldo+300
WHERE idcliente=212;

UPDATE
  cuenta
SET
  saldo=saldo-300
WHERE idcliente=555;

¿En que situación nos encontramos si ocurre algún problema entre el primer y el segundo paso, como un corte de suministro eléctrico, un fallo en el hardware del ordenador que hospeda el servidor del bases de datos, etcétera? El importe a transferir se habrá sumado a la cuenta destino, pero no se habrá restado de la emisora. Si nos ponemos en el lugar del banco, no se trata de una situación deseable. Todo lo contrario si somos los clientes. La gestión de las transacciones se realiza mediante unas instrucciones muy sencillas. Siguiendo con nuestro ejemplo, la transferencia se realizaría de la siguiente forma:

START TRANSACTION;

UPDATE
  cuenta
SET
  saldo=saldo+300
WHERE idcliente=212;

UPDATE
  cuenta
SET
  saldo=saldo-300
WHERE idcliente=555;

COMMIT;

Las tablas MERGE nos permiten combinar varias y trabajar con ellas como si de una sola tabla se tratase. Podemos tener todas estas tablas:

CREATE TABLE citas_enero(
  id INTEGER NOT NULL,
  descripcion VARCHAR(64) NOT NULL,
  fecha DATE NOT NULL,
  hora TIME NOT NULL
);

CREATE TABLE citas_febrero(
  id INTEGER NOT NULL,
  descripcion VARCHAR(64) NOT NULL,
  fecha DATE NOT NULL,
  hora TIME NOT NULL
);
...
CREATE TABLE citas_diciembre(
  id INTEGER NOT NULL,
  descripcion VARCHAR(64) NOT NULL,
  fecha DATE NOT NULL,
  hora TIME NOT NULL
);

y utilizarlas como si sólo existiese la tabla citas, con esta instrucción:

CREATE TABLE citas(
  id INTEGER NOT NULL,
  descripcion VARCHAR(64) NOT NULL,
  fecha DATE NOT NULL,
  hora TIME NOT NULL
)
ENGINE=MERGE
UNION=(
  citas_enero,citas_febrero,citas_marzo,
  citas_abril,citas_mayo,citas_junio,
  citas_julio,citas_agosto,citas_septiembre,
  citas_octubre,citas_noviembre,
  citas_diciembre 
);

A continuación enumeramos los vistos, junto con un enlace a la documentación que MySQL proporciona al respecto:

  1. MyISAM: [5].
  2. InnoDB: [6].
  3. HEAP: [7].
  4. MERGE: [8].

Puede encontrar más información sobre todos los tipos de tabla disponibles en MySQL aquí: [9]. Quizá encuentre interesante este artículo sobre transacciones que el grupo MySQL Hispano ha publicado: [10].

Tipos de datos[]

Dependiendo del tipo seleccionado para una columna que almacenará información de texto, el orden en el que los datos son devueltos variará. Veámoslo. Creemos una tabla de pruebas:

USE pruebas;
DROP TABLE IF EXISTS texto;
CREATE TABLE texto(
  cadena VARCHAR(32)
);

Insertemos algunas cadenas de texto:

USE pruebas;
INSERT INTO texto VALUES('d');
INSERT INTO texto VALUES('a');
INSERT INTO texto VALUES('A');
INSERT INTO texto VALUES('b');

Y hagamos una consulta a los valores de esa tabla, ordenados de forma alfabética:

USE PRUEBAS;
SELECT * FROM texto ORDER BY cadena;

Si repetimos la operación, pero creamos la tabla así:

CREATE TABLE texto(
  cadena VARCHAR(32) BINARY
);

comprobaremos que el orden del resultado cambia. Veamos ahora un ejemplo de enumeraciones. Este código crea una tabla con un campo de tipo ENUM:

USE pruebas;
DROP TABLE IF EXISTS pelicula;
CREATE TABLE pelicula(
  titulo VARCHAR(64),
  soporte ENUM('VHS','DVD')
);

Sólo se podrán insertar en el campo soporte los valores VHS y DVD:

USE pruebas;
INSERT INTO pelicula VALUES('Alien','VHS');
INSERT INTO pelicula VALUES('TRON','DVD');

La inserción de cualquier otro valor resultará en una cadena vacía:

INSERT INTO pelicula VALUES(
  'Blade Runner','VCD'
);

Para terminar con los tipos de texto, veamos los conjuntos. Cree una tabla con un campo de tipo SET utilizando este fragmento de código:

USE pruebas;
DROP TABLE pelicula IF EXISTS;
CREATE TABLE pelicula(
  titulo VARCHAR(64),
  categoria SET(
    'ciencia-ficción','terror','thriller'
  )
);

Podrá realizar inserciones de esta manera:

USE pruebas;
INSERT INTO pelicula VALUES(
  'Alien','ciencia-ficción,terror'
);
INSERT INTO pelicula VALUES(
  'Blade Runner','ciencia-ficción,thriller'
);
INSERT INTO pelicula VALUES(
  'Contact','ciencia-ficción'
);

Es muy sencillo crear tablas con tipos númericos enteros:

USE pruebas;
DROP TABLE IF EXISTS enteros;
CREATE TABLE enteros(
  entero INT(4) UNSIGNED ZEROFILL
);

El siguiente conjunto de inserciones, junto con la consulta de selección, ilustran el uso de ZEROFILL:

INSERT INTO enteros values(1);
INSERT INTO enteros values(10);
INSERT INTO enteros values(100);
INSERT INTO enteros values(1000);

Y luego la consulta de selección:

USE PRUEBAS;
SELECT * FROM enteros;

Esta inserción rebasa el límite del entero, no afectándolo ZEROFILL:

INSERT INTO enteros VALUES(10000);

Podemos controlar el formato de los números decimales:

USE pruebas;
DROP TABLE IF EXISTS decimales;
CREATE TABLE decimales(
  precio FLOAT(6,2) ZEROFILL
);

como puede verse al seleccionar los valores que vamos a insertar:

INSERT INTO decimales VALUES(20.99);
INSERT INTO decimales VALUES(30);
INSERT INTO decimales VALUES(199.994);
INSERT INTO decimales VALUES(199.995);
SELECT * FROM decimales;

A veces, el uso del tipo FLOAT puede plantear problemas:

USE pruebas;
DROP TABLE IF EXISTS decimales2;
CREATE TABLE decimales2(
  precio FLOAT(10,5)
);
INSERT INTO decimales2 VALUES(3835.38000);
SELECT * FROM decimales2;

Podrá comprobar que el valor resultante de la selección no es el mismo que hemos insertado. Esto se debe a que, internamente, MySQL utiliza precisión doble para los cálculos en coma flotante. MySQL también nos proporciona tipos para gestionar fechas y horas. Entre estos tipos, TIMESTAMP permite conocer la última vez que se modifico un determinado registro:

USE pruebas;
DROP TABLE IF EXISTS pelicula;
CREATE TABLE pelicula(
  titulo VARCHAR(64),
  modificado TIMESTAMP
);
INSERT INTO pelicula(titulo) VALUES('Alieni');

Al consultar los datos de esta tabla, podremos ver la fecha de modificación en la columna modificado. Podemos comprobar como cambia su valor al corregir el título de la película:

USE pruebas;
UPDATE
  pelicula
SET
  titulo='Alien'
WHERE
  titulo='Alieni';

Puede encontrar más información sobre estos tipos de datos en la sección correspondiente de la documentación de MySQL: [11].
El grupo MySQL Hispano ha publicado un interesante artículo sobre tipos de datos: [12].

Advertisement