Entradas etiquetadas ‘mysql’
La otra conferencia: el futuro de Sun “al descubierto”

El pasado miércoles, coincidiendo con la presentación del iPad, Oracle ofreció una larga conferencia con su correspondiente sesión de preguntas acerca de la compra de Sun y el futuro de sus productos.
En cuanto a Java, para Oracle la máxima prioridad es sacar la nueva versión cuanto antes (Java 7 saldrá este año), y vendrá con una máquina virtual resultado de la integración entre HotSpot (de Sun) y JRocket (de Oracle / BEA). NetBeans continuará su desarrollo, aunque se centrará en lenguajes dinámicos y scripting; JDeveloper seguirá siendo la principal baza de Oracle para desarrollo Java. Y por último, GlassFish será la “implementación de referencia” de Java EE, lo cual significa que los esfuerzos seguirán centrados en su servidor comercial WebLogic.
¿Y qué pasará con MySQL? Esta base de datos fue un quebradero de cabeza para Oracle en todo este proceso de compra, pues la Unión Europea no veía con buenos ojos este posible monopolio en el terreno de las BD. Oracle parece haber convencido con su compromiso de mejorar MySQL y dedicar recursos al desarrollo de esta BD open source.
Por último, en el apartado de hardware, todo será como se había previsto, y es que Oracle está muy interesada en el combo SPARC / Solaris para ofrecer un stack completo para desarrollo y puesta en producción de aplicaciones.
Visto lo visto, no tengo nada claro que esta adquisición vaya a aportar cosas positivas a los desarrolladores Java, aunque sí es verdad que Sun estaba pasando por un mal momento y necesitaba ayuda urgentemente. El tiempo dirá si Oracle sigue invirtiendo para mejorar la tecnología o en su afán de comercializarla se pierde gran parte de la innovación.
Más info: DZone, javaHispano
Maria, el engine que reemplazará a MyISAM
El fundador de MySQL, Michael Widenius, acaba de anunciar el lanzamiento del motor que reemplazará a MyISAM, Maria.
Curiosa historia la del nombre: el primer hijo de Michael se llamaba My, de ahí MySQL; al segundo le pusieron Max, utilizado para MaxDB; supongo que todos sabrán cómo se llama la tercera hija de este señor
.
Pero volviendo al tema, las principales características de Maria serán (en la futura versión 2.0):
- ACID
- Transacciones
- Consultas concurrentes
- Bloqueo a nivel de registro
- Commit de grupos de transacciones
Maria formará parte de MySQL 6.0.
PD: no lo había comentado por aquí, pero hace unos días Sun se hizo con MySQL. En principio, una buena noticia, que por lo que se ve no está afectando al desarrollo del popular gestor de bases de datos.
Relacionado | MyISAM vs InnoDB
Valor de comienzo para campos auto_increment
Los campos tipo auto_increment, como sabemos, son generados automáticamente por la base de datos incrementando el índice en una cantidad determinada en cada inserción. Son especialmente útiles cuando no tenemos una clave primaria a priori; necesitamos crear una artificial para distinguir los registros y delegamos en la base de datos su gestión.
En ocasiones puede resultarnos interesante establecer el valor de inicio para este tipo de campo. Por ejemplo, si tenemos una web en la que se realizan pedidos podemos dar impresión de un gran volumen de cara al cliente identificando su compra con el número 1020 en lugar de con el 20.
Para modificar el valor de comienzo de un campo auto_incremente en MySQL simplemente debemos añadir al final de la sentencia de creación de la tabla lo siguiente:
[sql]
CREATE TABLE tabla (
…
) auto_increment = 1000
[/sql]
Si la tabla ya existe, podemos indicar cuál será el siguiente valor a generar de una forma similar a la anterior:
[sql]
ALTER TABLE tabla SET auto_increment = 1000;
[/sql]
Cómo almacenar imágenes en MySQL
Poco a poco y según el tiempo me lo permita intentaré ir vaciando la larga lista de borradores que tengo pendiente. Para empezar veremos cómo almacenar imágenes directamente en MySQL, un método que como habíamos visto tenía sus ventajas e inconvenientes.
Comenzamos pues con el código correspondiente al formulario desde el que enviaremos el archivo (podemos tenerlo ya en el servidor, lo cual sería todavía más sencillo). Para permitir el envío de ficheros desde un formulario:
[html]
Archivo:
[/html]
Los datos serán almacenados en una tabla que tendrá un campo de tipo longblob (para datos binarios):
[sql]
CREATE TABLE tabla (
`id` int(11) unsigned NOT NULL auto_increment,
`archivo` varchar(255) NOT NULL default ”,
`mime` varchar(255) NOT NULL default ”,
`contenido` longblob NOT NULL,
PRIMARY KEY ( `id` )
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
[/sql]
El resto de los campos servirá para almacenar información sobre el archivo (archivo para el nombre y mime para el tipo).
Finalmente, el archivo php que recuperará el fichero y lo almacenará en la base de datos:
[php]
$archivo = $_FILES['archivo']['name'];
$mime = $_FILES['archivo']['type'];
$tamano = $_FILES['archivo']['size'];
// guardamos en $tmp el contenido del fichero
$tmp = addslashes( file_get_contents( $_FILES['archivo']['tmp_name'] ) );
$consulta = “INSERT INTO tabla
(archivo, mime, contenido)
VALUES (‘$archivo’, ‘$mime’, ‘$tmp’);”;
mysql_query($consulta);
[/php]
Un script sencillito y que nos puede ahorrar mucho trabajo a la hora de gestionar los archivos, siendo mucho más sencillo hacerlo sobre una base de datos que sobre el sistema de ficheros.
Seguridad en PHP: inyección SQL
Uno de los aspectos más importantes de una aplicación web es su seguridad, debido sobre todo a la gran capacidad de interacción que tiene con los usuarios. Así, el programador debe tener en cuenta este aspecto y cuidar todas las entradas que procedan o puedan ser manipuladas por los visitantes.
La inyección SQL consiste en inyectar, valga la redundancia, código SQL dentro de una variable con el propósito de modificar la consulta que se ejecutará, intentando obtener o destruir datos. Veámoslo con un pequeño ejemplo:
[php]
$id = $_GET['id'];
$posts = mysql_query(“SELECT * FROM posts WHERE id = $id”);
[/php]
Este código recibe vía url una variable a partir de la cual recuperar unos valores en la base de datos. Sin embargo este código es vulnerable a cosas tan sencillas como que el usuario escriba en su barra de direcciones algo como script.php?id=12 UNION SELECT * FROM users.
La consulta real que se ejecutaría en este caso pasaría a ser:
[sql]
SELECT * FROM posts WHERE id = 12 UNION SELECT * FROM users
[/sql]
algo que por supuesto no querremos que suceda por la cantidad de datos que pueden quedar al descubierto. Y todavía podría ser peor si el código inyectado fuese alguna modificación o borrado.
Para solucionarlo debemos chequear al máximo cualquier entrada que proceda o pueda ser modificada por el usuario. En este caso bastaría con algo así:
[php]
$id = intval ( $_GET["id"] );
[/php]
de forma que nos aseguremos de que la variable contenga un valor numérico.
Si en lugar de números tratamos con cadenas, también existen funciones como addslashes que nos permiten “escapar” los caracteres especiales y evitar el SQL injection. Pero esto lo trataremos en otra entrada.
Generar números aleatorios en MySQL
La función RAND() de MySQL, como de su nombre cabría esperar, sirve para la generación de números aleatorios. Hace unas semanas ya le sacamos utilidad: obtener registros aleatorios.
Ahora vamos a utilizarla para rellenar una columna con valores al azar (aunque esto estrictamente no existe en computación).
[sql]
UPDATE SET campo = RAND()
[/sql]
Esto nos generaría números en punto flotante entre 0.0 y 1.0, de forma que si nuestro campo es de tipo entero sólo nos quedarían 0s y 1s. Lo arreglamos:
[sql]
UPDATE SET campo = RAND() * 1000
[/sql]
Este código nos insertaría valores comprendidos entre 0 y 1000.
Es aconsejable utilizar una semilla, a partir de la cual se generan los números aleatorios:
[sql]
UPDATE SET campo = RAND(20) * 1000
[/sql]
Nótese que para cada fila se genera un valor aleatorio.
Comprobar si existe una tabla (MySQL) con PHP
Un truco muy sencillo y útil para, por ejemplo, comprobar que la tabla sobre la que vas hacer una consulta existe.
[php]
if ( mysql_num_rows ( mysql_query (“SHOW TABLES LIKE ””) ) ) {
…
}
[/php]
Crear una tabla sólo si no existe
En SQL Server 2000:
[sql]
IF NOT EXISTS (SELECT * FROM sysobjects
WHERE name=” AND xtype=’U')
CREATE TABLE ” …
[/sql]
En MySQL:
[sql]
CREATE TABLE IF NOT EXISTS ” …
[/sql]
Inserción múltiple en SQL Server
En MySQL, cuando queremos insertar de una tacada varias filas, podemos hacerlo de la siguiente manera:
[sql]
INSERT INTO MiTabla (PrimeraColumna, SegundaColumna)
VALUES (‘hola’, 1), (‘adios’, 2), (‘ey’, 3);
[/sql]
Sin embargo, este método no está disponible en SQL Server, por lo que tenemos que recurrir a soluciones más arcaicas. Una, el copy & paste:
[sql]
INSERT INTO MiTabla (PrimeraColumna, SegundaColumna)
VALUES (‘hola’, 1);
INSERT INTO MiTabla (PrimeraColumna, SegundaColumna)
VALUES (‘adios’, 2);
INSERT INTO MiTabla (PrimeraColumna, SegundaColumna)
VALUES (‘ey’, 3);
[/sql]
Otra posibilidad sería la que nos propone Pinal Dave:
[sql]
INSERT INTO MiTabla (PrimeraColumna, SegundaColumna)
SELECT ‘hola’, 1
UNION ALL
SELECT ‘adios’, 2
UNION ALL
SELECT ‘ey’, 3;
[/sql]
En otras palabras, insertamos en una tabla el resultado de una consulta, y gracias a la cláusula UNION ALL podemos ir añadiendo nuevos valores.
Insertar datos de una tabla en otra
En ocasiones puede resultarnos útil insertar datos de una tabla en otra, por ejemplo para testear una aplicación con un subconjunto de datos reales pero en una tabla diferente para no afectar al funcionamiento normal.
Para hacerlo hay varias formas, la primera es válida tanto para MySQL como para SQL Server:
[sql]
INSERT INTO tabla2
SELECT *
FROM tabla
[/sql]
Por supuesto podemos añadir cláusulas WHERE de modo que sólo insertemos datos específicos, como si fuera una consulta normal (de hecho es una consulta normal).
La segunda técnica, parecida a ésta, es propia de SQL Server:
[sql]
SELECT *
INTO tabla2
FROM tabla
[/sql]
La diferencia estriba en que este último caso se utiliza cuando no existe la tabla a la que volcaremos los datos, la cual es creada con la sentencia.


