Problema con tablas particionadas

15/12/2004 - 16:25 por e.lorenzo | Informe spam
Hola a todos,

tenemos una aplicación que, por el volumen de información que maneja, nos
obliga a crear particiones por meses en 5 tablas del modelo. De esta
forma, mantendremos un histórico de 12 meses que iremos rotando. La idea
no es particionar para poder ejecutar las consultas en paralelo, sino por
facilitar el borrado y mantenimiento.

Cuando empezamos a analizar cómo crear estas particiones en SQL SERVER (la
aplicación también corre con Oracle y ahí hemos podido implementarlas sin
problemas), empezó nuestro "calvario".

Investigando, descubrimos que debíamos crear 12 tablas por cada una de las
que deseamos particionar y, en cada una de las 12, añadir una CHECK que
indique qué mes es el que contiene. A continuación, se crea una vista cuya
definición es un UNION ALL de cada una de las 12 tablas. Hasta aquí bien.

El problema es que una de las 5 tablas que deseamos particionar no tiene
clave primaria. Las otras cuatro sí la tienen y, además, el campo por el
que particionamos pertenece a ella.

La tabla no tiene clave primaria, porque intervienen 22 campos y no es
relevante, al controlar nosotros las inserciones. Tan sólo creamos dos
índices no únicos para optimizar las consultas que se realizan sobre ella.

Al ir a crear una partición, en SQL Server te exige que el campo sobre el
que indicas la condición forme parte de la clave primaria. Por tanto, como
no es viable crear la clave primaria con 22 campos (aparte de que el
límite son 15, el índice ocupa más que la tabla) y no queremos crear un
campo que guarde el valor de la concatenación de todos, nos planteamos
crear una PK con la fecha y un secuencial (IDENTITY). Pero nos encontramos
que en tablas particionadas no se permite usar esta funcionalidad.

Decidimos abordar el problema con un trigger que informara este valor
secuencial y nos permitiera simular la PK, pero el problema es que las
inserciones se hacen mediante INSERT...SELECT (con más de un registro) y
no éramos capaces de que le asignara un número diferente a cada registro,
sino el mismo a cada uno de los obtenidos en el SELECT.

¿Nos puede indicar alguien si hay alguna forma más sencilla de gestionar
las particiones o, si hasta ahora no hemos hecho nada mal, cómo podemos
crear una clave primaria "en tiempo de ejecución" con un INSERT..SELECT?
Por ejemplo, algo similar a la función ROWNUM de Oracle concatenada con un
timestamp. ¿Hay algo equivalente en SQL SERVER?

Contar con el agravante de que tenemos una aplicación ya rodada y con dos
gestores y queremos tratar de tener que montar un lío tremendo sólo por
SQL Server.

Muchas gracias por anticipado.

Un saludo
 

Leer las respuestas

#1 Salvador Ramos
15/12/2004 - 16:46 | Informe spam
Otra altenativa sería tener una sola tabla en la versión de SQL Server y 12
vistas indexadas (una para cada mes). Así internamente tendríais una sola
tabla, y las consultas las podríais hacer sobre las vistas indexadas.

¿ Que volumen de datos tendrían esas tablas ?

Un saludo
Salvador Ramos
Murcia - España
[Microsoft MVP SQL Server]
www.helpdna.net
¿Te interesa participar en las reuniones
del grupo de Usuarios de SQL-Server y .NET
Se harán en levante de España, (Alicante o Murcia)?

"Quique" escribió en el mensaje
news:

Hola a todos,

tenemos una aplicación que, por el volumen de información que maneja, nos
obliga a crear particiones por meses en 5 tablas del modelo. De esta
forma, mantendremos un histórico de 12 meses que iremos rotando. La idea
no es particionar para poder ejecutar las consultas en paralelo, sino por
facilitar el borrado y mantenimiento.

Cuando empezamos a analizar cómo crear estas particiones en SQL SERVER (la
aplicación también corre con Oracle y ahí hemos podido implementarlas sin
problemas), empezó nuestro "calvario".

Investigando, descubrimos que debíamos crear 12 tablas por cada una de las
que deseamos particionar y, en cada una de las 12, añadir una CHECK que
indique qué mes es el que contiene. A continuación, se crea una vista cuya
definición es un UNION ALL de cada una de las 12 tablas. Hasta aquí bien.

El problema es que una de las 5 tablas que deseamos particionar no tiene
clave primaria. Las otras cuatro sí la tienen y, además, el campo por el
que particionamos pertenece a ella.

La tabla no tiene clave primaria, porque intervienen 22 campos y no es
relevante, al controlar nosotros las inserciones. Tan sólo creamos dos
índices no únicos para optimizar las consultas que se realizan sobre ella.

Al ir a crear una partición, en SQL Server te exige que el campo sobre el
que indicas la condición forme parte de la clave primaria. Por tanto, como
no es viable crear la clave primaria con 22 campos (aparte de que el
límite son 15, el índice ocupa más que la tabla) y no queremos crear un
campo que guarde el valor de la concatenación de todos, nos planteamos
crear una PK con la fecha y un secuencial (IDENTITY). Pero nos encontramos
que en tablas particionadas no se permite usar esta funcionalidad.

Decidimos abordar el problema con un trigger que informara este valor
secuencial y nos permitiera simular la PK, pero el problema es que las
inserciones se hacen mediante INSERT...SELECT (con más de un registro) y
no éramos capaces de que le asignara un número diferente a cada registro,
sino el mismo a cada uno de los obtenidos en el SELECT.

¿Nos puede indicar alguien si hay alguna forma más sencilla de gestionar
las particiones o, si hasta ahora no hemos hecho nada mal, cómo podemos
crear una clave primaria "en tiempo de ejecución" con un INSERT..SELECT?
Por ejemplo, algo similar a la función ROWNUM de Oracle concatenada con un
timestamp. ¿Hay algo equivalente en SQL SERVER?

Contar con el agravante de que tenemos una aplicación ya rodada y con dos
gestores y queremos tratar de tener que montar un lío tremendo sólo por
SQL Server.

Muchas gracias por anticipado.

Un saludo

Preguntas similares