Comentarios anidados con PHP y MySQL

Los comentarios anidados es algo muy común entre los foros o blogs. Realizarlo es bastante sencillo, aunque quizás hacerlo de la forma más eficiente puede tener su dificultad.
En el post que referencio, nos explican paso a paso cómo hacerlo: estructura de la BD, formulario, consultas, …
La solución es de las sencillas, se trata de que cada comentario tenga un campo que enlace con el comentario padre, y luego a la hora de recuperar los comentarios, hay que ir realizando consultas de obtención de comentarios por cada comentario padre, salvo en el primer caso que se buscan los comentarios iniciales.
HOW-TO: Multi-level Comments In PHP

Ejecutar dumps extensos con phpMyAdmin

Un truco que no conocía y que me puede venir muy bien (y espero que a vosotros). Se trata de ejecutar scripts de MySQL muy extensos (provenientes de un dump, por ejemplo) sin que nos dé el problema del tamaño máximo del fichero a subir.
El truco es sencillo, nos creamos una carpeta donde subimos el fichero con los scripts, y a la hora de importar, seleccionamos el “Web server upload directory”, para lo que habrá que modificar el fichero de configuración (config.inc.php) para indicar el directorio de uploads (UploadDir).
Execute large MySQL scripts through phpMyAdmin

MySQL 5.4

Sun (o quizás Oracle) ha anunciado la salida de MySQL 5.4, la cual ya está disponible una preview para su descarga. Entre las novedades que ofrece encontramos:

  • Mejoras en escalabilidad
  • Optimización de subqueries
  • Nuevos algoritmos para sentencias
  • Mejoras en los procedimientos almacenados
  • Mejoras en el Information Schema

Sun Announces MySQL 5.4: Up To 90% Faster Response Times, and Scalability Up to 16-way x86 Servers and 64-way CMT Servers

5 consejos para optimizar sentencias en MySQL

Interesantes consejos a tener en cuenta cuando realizamos nuestras aplicaciones usando MySQL:

  • Optimización de tipos: intenta evitar el uso de NULLs ya que requieren más operaciones internas en MySQL. Usa el tamaño correcto para las variables, por ejemplo, si vas a usar un número pequeño no uses INT.
  • Cuidado con la codificación de caracteres: inserta los datos siempre en la misma codificación, si tienes orígenes con diferentes codificaciones modificalo antes de insertar.
  • Optimización de COUNT: COUNT(*) sin un WHERE no necesita acceder a la tabla para obtener los resultados, al igual sin en vez de asterisco usamos un campo de la tabla que no tenga valores NULL. En el caso de que haya WHERE, poco se puede hacer para optimizar la consulta salvo usar índices correctamente.
  • Optimización de subqueries: MySQL no optimiza muy bien las subqueries por lo que es preferibles pasarlas a una JOIN. Incluso realizar dividir en dos queries independientes puede ser una buena alternativa.
  • Optimización de UNION: UNION devuelve la unión de los datos de dos tablas que no se hayan en la otra, por lo que realizan un UNIQUE y una ordenación. Usa UNION ALL si estás seguro de que las distintas consultas no tienen datos repetidos (o no te importa que esté repetidos).

Five Query Optimizations in MySQL

openark kit: utilidades DBA para MySQL

openark kit es una serie de scripts en Python que nos facilitará las tareas de DBA (sobre todo para aquellos que no es nuestro fuerte). Consta de las siguientes aplicaciones:

openark kit

Seleccionar cercanos mediante MySQL

En algunos casos tenemos la necesidad de buscar registros cercanos a un cierto valor (numérico, logicamente). Una solución sencilla es obtener el valor absoluto de la resta entre el valor que buscamos y el valor del registro, ordenar por ese valor y limitar la búsqueda a n registros:

SELECT number, ABS( number - 2500 ) AS distance
FROM numbers
ORDER BY distance
LIMIT 6

El problema es que esta consulta es lenta, y en producción no nos podemos permitir consultas lentas, por lo que una opción mucho más eficiente es en vez de realizar esa consulta sobre todos los registros, realizarla sobre la unión de dos consultas: una de los n/2 registros con valor superior al que buscamos y otra con los n/2 registros con valor menor al que buscamos, y luego ordenando como la consulta anterior y cogiendo solo los elementos que nos interesan:

SELECT number, ABS( number - 2500 ) AS distance FROM (
(
SELECT number
FROM `numbers`
WHERE number >=2500
ORDER BY number
LIMIT 6
) UNION ALL (
SELECT number
FROM `numbers`
WHERE number <2500
ORDER BY number DESC
LIMIT 6
)
) AS n
ORDER BY distance
LIMIT 6

Selecting closest values in MySQL

Vía / dzone

Obtener logs de todas las queries con MySQL 5.0

En algunas ocasiones necesitamos tener un log de todas las queries que se realizan, sobre todo en preproducción para poder tener una visión general de qué consultas se realizan y del coste.
En MySQL 5.1 es sencillo porque se puede poner el tiempo máximo para slow queries a milisegundos, por lo que todas las queries serían lentas y obtendríamos datos de sobre las consultas bastante interesantes.
En MySQL 5.0 tan solo se puede reducir el tiempo de slow queries a un segundo, por lo que es necesario usar tcpdump para capturar el tráfico de MySQL a un log y luego mediante otros comandos obtener las queries.
Logging all the queries with MySQL 5.0

Autosugerencias usando MySQL índices fulltext

Interesante seríe de tres artículos que nos muestra como crear un autosuggest tipo Google usando los índices full-text de MySQL. El método no es nada sencillo (php, mysql y listo), por lo que no será fácil probarlo, pero tampoco complicado o imposible (se necesita ser un usuario algo más avanzado).
Se trata de coger el fichero del índice full-text y usando un programa C, que es necesario compilar junto a MySQL, accederá a los términos que cumplan el texto base del auto-suggest y lo devolverá.
Como ya he comentado se trata de una aplicación externa, por lo que su integración con nuestra aplicación web deberá ejecutarla como proceso externo.
Implementing an AutoSuggest feature using MySQL fulltext indices

Curiosidades sobre TIMESTAMP en MySQL

Interesante lo que descubre uno sobre el TIMESTAMP en MySQL:

  • Por defecto TIMESTAMP es NOT NULL, insertar un NULL hace que se almacene el DATETIME actual
  • TIMESTAMP puede tener un valor entre ‘1970-01-01 00:00:01′ y ‘2038-01-19 03:14:07′
  • Solo la primera columna con NOT NULL puede tener por defecto la propiedad CURRENT_TIMESTAMP
  • Cuando CURRENT_TIMESTAMP se indica como ON UPDATE esa columna no se actualiza si no hay cambios significativos (por ejemplo al hacer dos updates iguales)

Interesting things about TIMESTAMP data type in MySQL

Alternativa a MySQL Query Analyzer

MySQL ha lanzado su nueva versión de MySQL Query Analyzer dentro de MySQL Enterprise, de la cual hablan muy bien en casi todos los blogs. Para aquellos que usemos la versión Community, podemos usar una alternativa gratuita a esa herramienta.
Para ello debemos instalar los parches que ofrece Percona los cuales, entre otras cosas, permiten obtener métricas desde el propio servidor. También habrá que utilizar mysqlsla que parsea, filtra, analiza y ordena los logs de MySQL para crear informes personalizados de las queries y sus meta-propiedades.
An alternative to the MySQL Query Analyzer