Particionado de tablas que no exige vigilancia constante

Fuentes: Designing Partitioning You Don't Have to Babysit

Particionar una tabla por una columna como created_at parece una decisión de almacenamiento inocua, pero termina filtrándose hacia el código de aplicación y las consultas. El artículo explica por qué ocurre esto y propone un diseño que elimina la fuga.

El problema central es doble. Primero, las bases de datos como PostgreSQL y MySQL obligan a que la clave de partición forme parte de cualquier clave primaria o restricción única. Si se particiona por fecha, la clave primaria deja de ser (id) y pasa a ser (id, created_at). Esto degrada las búsquedas por id: el optimizador deja de tratarlas como búsquedas de fila única (tipo const) y pasa a escaneos de prefijo (tipo ref), lo que puede afectar a planes de ejecución de consultas más amplias.

Segundo, la poda de particiones solo funciona cuando la cláusula WHERE incluye la clave de partición. Una consulta del tipo SELECT * FROM orders WHERE id = 12345 termina recorriendo todas las particiones: en el ejemplo, 36 lecturas en vez de una. La solución habitual, añadir created_at a cada consulta que toca la tabla, convierte una decisión de almacenamiento en un contrato que todo el código debe respetar.

La alternativa propuesta usa la propia clave primaria como clave de partición. Como en tablas con BIGINT AUTO_INCREMENT los ids crecen de forma monótona, basta con particionar por rango de id para que las búsquedas por clave primaria —la mayoría de las consultas— obtengan poda automática sin modificar el código. Las tareas mecánicas de crear, dividir y eliminar particiones se delegan a un servicio en segundo plano que vigila el crecimiento y aplica los cambios mediante DDL no bloqueante.