Una base de datos es un elemento fundamental en la mayoría de las aplicaciones web. Si usamos PHP, probablemente usemos MySQL - integrante del conocido LAMP.
PHP es relativamente sencillo y la mayoría de nuevos desarrolladores pueden escribir código funcional en pocas horas. Sin embargo, construir una solida aplicación con diseño de base de datos toma su tiempo y experiencia. Por ello, siguiendo este post de sitepoint, vamos a listar los 10 peores errores de MySQL; pero, que también podrían darse con otro servidor de base de datos SQL.
1. Usar MyISAM en vez de InnoDB
MySQL tiene una variedad de motores o database engines; pero, es probable que nos hayamos encontrado casi siempre con MyISAM y/o InnoDB.
MyISAM es el motor por defecto; sin embargo, a menos que no estemos creando una base de datos sencilla o de pruebas, usar MyISAM como nuestro motor es una opción equivocada. MyISAM no soporta restricciones de claves foráneas o transacciones, esenciales para mantener la integridad referencial de los datos. Además, del hecho de que toda la tabla se bloquea cuando uno inserta o actualiza un registro, lo que provoca un efecto adverso en el rendimiento de la aplicación, cuando esta crece.
La solución: Usar InnoDB...
2. Usar las funciones MySQL de PHP
Desde sus inicios, PHP nos provee de librerías de funciones especiales para el manejo de MySQL. Muchas aplicaciones dependen de las funciones mysql_connect, mysql_query, mysql_fetch_assoc, etc. pero el propio manual de PHP dice:
Si estas usando la versión de MySQL 4.1.3 o superior se recomienda el uso de la extensión mysqli.
mysqli o la extensión mejorada de MySQL, tiene notorias ventajas:
- Una (opcional) interfaz orientada a objetos
- Declaraciones preparadas (que nos ayudan a prevenir inyecciones SQL y a incrementar el rendimiento)
- Múltiples declaraciones y soporte de transacciones
Alternativamente, debes de considerar usar PDO si deseamos mantener un soporte a múltiples bases de datos.
3. No validar el acceso de usuarios
Esta debería de ser probablemente la #1: Nunca confiar en lo que escribe el usuario. Validar cada cadena de texto que es enviada al servidor con PHP, aún cuando usamos JavaScript, debería ser la norma. Las más sencillas inyecciones de SQL dependen de códigos como este:
<?php
$username = $_POST["name"];
$password = $_POST["password"];
$sql = "SELECT userid FROM usertable WHERE username='$username' AND password='$password';";
// run query...
?>
Esto podría ser crackeado ingresando “admin’ ; –“ en el campo del nombre de usuario. El string del SQL quedaría como sigue:
SELECT userid FROM usertable WHERE username='admin';
El cracker podría loggearse como “admin”, sin necesidad de conocer la clave, ya que esta comentada en el SQL.
4. No usar UTF-8
UTF-8 resuelve muchos problemas de internacionalización. Aunque no será soportado adecuadamente en PHP hasta la versión 6.0, hay algunas cosas que podemos hacer al configurar los caracteres de MySQL como UTF-8.
5. Favorecer a PHP sobre SQL
Cuando somos nuevos con MySQL, es común resolver los problemas en el lenguaje que más conocemos. Esto nos puede conducir a un código más lento e innecesario. Por ejemplo, en vez de usar las función nativa de mysql AVG(), usamos un loop PHP para calcular el promedio obteniendo todos los valores de un conjunto de registros.
También hay que tener cuidado de las consultas SQL dentro de los bucles de PHP. Siempre es recomendable realizar una consulta y luego recorrer sus resultados.
En general, hay que utilizar los puntos fuertes de la base de datos para analizar los datos.
6. No optimizar tus consultas
El 99% de los problemas de rendimiento con PHP son causados por la base de datos y una consulta SQL mal realizada podría causar estragos en nuestra aplicación. La declaración EXPLAIN de MySQL, el Query Profiler y muchas otras herramientas, nos ayudarán a encontrar nuestra consulta acertada.
Recomendado: 10 tips para Optimizar consultas MySQL
7. Usar los tipos de datos equivocados
MySQL ofrece una variedad de tipos de datos: numéricos, de cadena y fecha. Si estamos almacenando una fecha, hay que guardarla en un campo DATE o DATETIME. Usar un INTEGER o STRING puede hacer de nuestras consultas SQL más complicadas.
A menudo podríamos tener la tentación de almacenar nuestro propio formato de datos; por ejemplo, almacenar objetos serializados de PHP como string; gestionar la base de datos sería más fácil; pero, MySQL se convertirá en un almacén de datos tontos y que, probablemente, nos lleven a más problemas.
Recomendado: Usos de Varchar y Char
8. Usar * en las consultas SELECT
No es conveniente usar el * para devolver todas las columnas de una tabla, es ocioso. Sólo debemos extraer los datos que necesitamos, incluso si requerimos de todos los campos en un momento, en el futuro, nuestras tablas pueden cambiar.
9. Sub o Sobre Indexación
Como norma general, los índices deben aplicarse a cualquier columna que vaya a ser llamada en la clausula WHERE de una consulta SELECT.
Por ejemplo, supongamos que tenemos una tabla user con un ID numérico (clave primaria) y una dirección de correo electrónico. Durante la sesión de usuario, MySQL debe localizar el ID correcto al buscar un correo electrónico. Con un índice, MySQL podría usar un algoritmo de búsqueda rápida para localizar el e-mail casi instantáneamente. Sin un índice, MySQL debe comprobar todos los registros en orden, hasta encontrar la dirección de correo.
A veces es tentador añadir índices a cada columna; sin embargo, estos se regeneran con cada INSERT o UPDATE en una tabla. Lo que podría tener un gran impacto en el rendimiento, por ello sólo debemos añadir índices a los campos estrictamente necesarios.
10. Olvidarse de hacer backups
Puede sonar raro, pero los discos duros pueden malograrse. Los servidores pueden quemarse... y la perdida de nuestros datos MySQL serían catastróficos. Por ello, hay que asegurarnos de contar con copias de seguridad automatizadas o réplicas de nuestra base datos.
11. Bonus mistake: No considerar otras bases de datos
MySQL puede ser la base de datos más popular y aceptada por los desarrolladores de PHP; pero, no es la única opción. PostgreSQL y Firebird son sus competidores más cercanos, ambos son open source y no están manejados por una corporación. Microsoft provee SQL Server Express y Oracle 10g Express; ambas son versiones gratuitas de las populares ediciones enterprise. Incluso, SQLite puede ser una alternativa viable para aplicaciones pequeñas o embebidas.
¿Me he olvidado de algún error? No olvides compartirlo.
Gracias por el artículo, como neofito en el tema me encantó.
se ve bien solida la explicacion practica
Interesante post, sin duda, recomendaciones a tener en cuenta.
ESPECTACULAR POST!. La verdad una joyita para imprimir y tener justito al costado del monitor para aquellos como que cometemos algunos de estos ORRORES :$.
Muchisimas gracias por el POST y muchas gracias por el Blog :P . Te sigo de hace mucho pero casi nunca comenté :$
Usar MyISAM no es un error. Bajo circunstancias especiales MyISAM funciona muchísimo mejor que InnoDB, aún cuando pierdas la habilidad de tener FK y transacciones y te veas obligado a desnormalizar. Usar funciones agregadas de MySQL también es una mala idea si hablamos de performance.
Con respecto a escapar los datos ingresados, es algo que todo el mundo debería hacer; aunque de todos modos generalmente el PHP viene con las 'magic_quotes' habilitadas de manera predeterminada.
Saludos!
Muy buen post. y en verdad la mayoria de nosotros los programadores no nos damos cuenta de los errores que cometemos al desarrollar una aplicacion web.
Saludos!!
Never Give Up!
Excelentes tips para el uso de MySQL, que podrian darnos un mejor rendimiento a nuestros proyectos