Vistas divididas

26/07/2004 - 09:33 por Xavi | Informe spam
Hola a todos



Estoy montando un sistema para almacenar una serie de datos. En principio,
estos datos crecerán de manera espectacular ( 1.000.000 registros
mensuales ) así que estoy haciendo resumen de cuantas posibilidades se me
ofrecen.



Por lo que he ido leyendo y siguiendo en foros y tutoriales, la mejor
solución sería crear una vista dividida ( partitioned view ). De manera
simple, crearía una tabla por mes ( supongamos Tabla072004 ).
Obligatoriamente, la fecha debería formar parte de la PK. Eso me obliga a
dos cosas: o bien la PK es múltiple ( cosa que no me gustaría por pureza del
diseño ) o bien la fecha forma parte de la PK.



Tomando la segunda opción, la PK sería un bigint de 13 dígitos: los 4
primeros la fecha ( 0704 ) y los 9 siguientes un secuencial.



Me gustaría escuchar cualquier comentario respecto a este planteamiento,
alguna experiencia con vistas divididas o alguna alternativa al modelo de
datos.



Muchas gracias.

Preguntas similare

Leer las respuestas

#1 Javier Loria
26/07/2004 - 13:38 | Informe spam
Hola:
No comparto el que una PK multiple afecte de forma negativo el diseno.
Las PK's multiples son deseables en los disenos de bases de datos
normalizadas.
Por pureza del diseno buscaria cual es la llave principal natural y
trataria de construir basado en esta la particion. Una ventaja si puedes
hacerlo con este mecanismo es que no se va a producir todos los inserts en
la misma tabla, como si ocurre cuando la base de la particion es la fecha.
Si la fecha no participa en nada en la llave natural y siempre quieres
particionar por fecha, podrias agregar una columna tipo smallint con el
numero de periodo (en este caso mes) y hacer esta columna parte de la llave
primaria.
Unicamente si no es posible encontrar una llave primaria, te
recomendaria crear una columna Entera (no es necesario un BigInt a menos que
tengas mas de 2000 meses), y en algun trabajo o procedimiento mensual,
agregaria la nueva tabla mensual con un CHECK del numero actual en adelante
y cambiaria el CHECK de la Tabla Anterior para limitarlo.
Evita la tentacion de escribir codigo contra las tablas mensuales, TODO
el codigo debe ir escrito contra la vista particionada, para asi evitar que
el diseno fisico tan especial, afecte al diseno logico.
Si nos compartes un poco del esquema de la tabla, podriamos opinar con
mas criterio.
Saludos,

Javier Loria
Costa Rica
Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
que pueda ser copiado y pegado al Query Analizer.
La version de SQL y Service Pack tambien ayuda.

Xavi escribio:
Hola a todos



Estoy montando un sistema para almacenar una serie de datos. En
principio, estos datos crecerán de manera espectacular ( 1.000.000
registros
mensuales ) así que estoy haciendo resumen de cuantas posibilidades
se me ofrecen.



Por lo que he ido leyendo y siguiendo en foros y tutoriales, la mejor
solución sería crear una vista dividida ( partitioned view ). De
manera simple, crearía una tabla por mes ( supongamos Tabla072004 ).
Obligatoriamente, la fecha debería formar parte de la PK. Eso me
obliga a dos cosas: o bien la PK es múltiple ( cosa que no me
gustaría por pureza del diseño ) o bien la fecha forma parte de la PK.



Tomando la segunda opción, la PK sería un bigint de 13 dígitos: los 4
primeros la fecha ( 0704 ) y los 9 siguientes un secuencial.



Me gustaría escuchar cualquier comentario respecto a este
planteamiento, alguna experiencia con vistas divididas o alguna
alternativa al modelo de datos.



Muchas gracias.
Respuesta Responder a este mensaje
#2 Miguel Egea
26/07/2004 - 19:40 | Informe spam
Solo una cosita, el tipo int admite desde -2^31 hasta 2^31, creo que javier
te estaba recomendando un smallint -2^15 a 2^15 es decir -32768 a 32767, lo
que te daría para 32000 meses si no usas los negativos, (no creo que yo vea
muchos más de esos :-) )


-
Miguel Egea Gómez
Microsoft SQL-Server MVP
Webmaster de PortalSql.Com
¿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)?

"Javier Loria" escribió en el mensaje
news:
Hola:
No comparto el que una PK multiple afecte de forma negativo el diseno.
Las PK's multiples son deseables en los disenos de bases de datos
normalizadas.
Por pureza del diseno buscaria cual es la llave principal natural y
trataria de construir basado en esta la particion. Una ventaja si puedes
hacerlo con este mecanismo es que no se va a producir todos los inserts en
la misma tabla, como si ocurre cuando la base de la particion es la fecha.
Si la fecha no participa en nada en la llave natural y siempre quieres
particionar por fecha, podrias agregar una columna tipo smallint con el
numero de periodo (en este caso mes) y hacer esta columna parte de la


llave
primaria.
Unicamente si no es posible encontrar una llave primaria, te
recomendaria crear una columna Entera (no es necesario un BigInt a menos


que
tengas mas de 2000 meses), y en algun trabajo o procedimiento mensual,
agregaria la nueva tabla mensual con un CHECK del numero actual en


adelante
y cambiaria el CHECK de la Tabla Anterior para limitarlo.
Evita la tentacion de escribir codigo contra las tablas mensuales,


TODO
el codigo debe ir escrito contra la vista particionada, para asi evitar


que
el diseno fisico tan especial, afecte al diseno logico.
Si nos compartes un poco del esquema de la tabla, podriamos opinar con
mas criterio.
Saludos,

Javier Loria
Costa Rica
Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
que pueda ser copiado y pegado al Query Analizer.
La version de SQL y Service Pack tambien ayuda.

Xavi escribio:
> Hola a todos
>
>
>
> Estoy montando un sistema para almacenar una serie de datos. En
> principio, estos datos crecerán de manera espectacular ( 1.000.000
> registros
> mensuales ) así que estoy haciendo resumen de cuantas posibilidades
> se me ofrecen.
>
>
>
> Por lo que he ido leyendo y siguiendo en foros y tutoriales, la mejor
> solución sería crear una vista dividida ( partitioned view ). De
> manera simple, crearía una tabla por mes ( supongamos Tabla072004 ).
> Obligatoriamente, la fecha debería formar parte de la PK. Eso me
> obliga a dos cosas: o bien la PK es múltiple ( cosa que no me
> gustaría por pureza del diseño ) o bien la fecha forma parte de la PK.
>
>
>
> Tomando la segunda opción, la PK sería un bigint de 13 dígitos: los 4
> primeros la fecha ( 0704 ) y los 9 siguientes un secuencial.
>
>
>
> Me gustaría escuchar cualquier comentario respecto a este
> planteamiento, alguna experiencia con vistas divididas o alguna
> alternativa al modelo de datos.
>
>
>
> Muchas gracias.



Respuesta Responder a este mensaje
#3 Xavi
27/07/2004 - 09:12 | Informe spam
Hola, de entrada, gracias por contestar. No entiendo el siguiente
comentario:

Unicamente si no es posible encontrar una llave primaria, te
recomendaria crear una columna Entera (no es necesario un BigInt a menos


que
tengas mas de 2000 meses)



Este campo de fecha igualmente tiene que existir, ya sea datetime o
smalldatetime, puesto que hace referencia a la fecha del registro. Es
indispensable. Cuando hablaba de bigint me refería a la PK. Tendría la PK
bigint de 13 dígitos ( 4 primeros mes y año ) y 9 siguientes secuencial por
mes/año. Igualmente, tendría el campo fecha.

Las checks de cada tabla ( llamémoslas Tabla0704 ) serían del estilo

ID / 1000000000 < 0804 and ID / 1000000000 >= 0704

Todo esto para no tener una PK múltiple. Si la PK es múltiple, evidentemente
la opción que planteas tú sería la más correcta. ¿Afecta demasiado a la
inserción un check de este estilo? A menos que el rendimiento me penalizara
mucho, seguiría con mi idea de utilizar una única PK.

Gracias

Xavi
Respuesta Responder a este mensaje
#4 Javier Loria
27/07/2004 - 17:43 | Informe spam
Hola:
Vamos a ver si me expreso un poco mejor.
Hablando de la tercera opcion. SI NO EXISTE LLAVE PRIMARIA NATURAL.
(O sea si no hay una combinacion de columnas que me garantize que una fila
es diferente a la otra y que no puedan ser nulas). Agrega una columna tipo
INT (NO tiene que ser BIGINT).
Un INT permite 4 Mil Millones de filas, los positivos son 2 Mil
Millones, o sea (2000 meses)
Si lo vieramos cronologicamente, empezando de 0 filas. El CHECK el
primer mes diria: CHECK(ID>=0)
Al final del periodo, cuando se produce un nuevo mes, creas la nueva
tabla (mensual) . Y cambias el CHECK del primer mes por: CHECK (ID BETWEEN 1
AND 994313). Esto asumiendo que el primer periodo tuvo 994,313 movimiento.
El CHECK de la nueva Tabla seria: CHECK (ID>™4314)
Si el proximo mes (2do mes) tiene 1,050,000 movimientos entonces al
final del periodo cambio el CHECK de esta tabla y queda: CHECK (ID BETWEEN
994314 AND 2,044,313). Y el CHECK de la nueva Tabla seria CHEK(ID> 44314)
Cada vez que creas un nuevo periodo, corriges el CHECK Anterior y creas
la nueva tabla. Adicionalmente es posible que quieras REINDEXAR para
asegurar un mejor desempeno. En los meses anteriores usas un
FILLFACTOR/PADINDEX muy altos (100) y en la tabla nueva bien bajos.
La ventaja de este diseno sobre el del BIGINT con meses implicitos, es
de desempeno. Con un BIGINT agregar 4 bytes innecesarios, que ocupan espacio
en la tabla haciendo la tabla mas grande, si la fila tiene 100 bytes la
aplicacion seria 4% mas lenta. Pero lo mas importante es que el Indice queda
del doble de largo o sea que ocupa mucho mas espacio, haciendo tambien mas
lento y mas lentos cualquier indice que lo referencie.
Normalmente no es necesario este tipo de consideraciones pero si vas a
tener Tablas con tantas filas si valen la pena. Por ultimo este es de las 3
opciones que te di el que menos me gusta.:(
Saludos,

Javier Loria
Costa Rica
Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
que pueda ser copiado y pegado al Query Analizer.
La version de SQL y Service Pack tambien ayuda.
Xavi escribio:
Hola, de entrada, gracias por contestar. No entiendo el siguiente
comentario:

Unicamente si no es posible encontrar una llave primaria, te
recomendaria crear una columna Entera (no es necesario un BigInt a
menos que tengas mas de 2000 meses)



Este campo de fecha igualmente tiene que existir, ya sea datetime o
smalldatetime, puesto que hace referencia a la fecha del registro. Es
indispensable. Cuando hablaba de bigint me refería a la PK. Tendría
la PK bigint de 13 dígitos ( 4 primeros mes y año ) y 9 siguientes
secuencial por mes/año. Igualmente, tendría el campo fecha.

Las checks de cada tabla ( llamémoslas Tabla0704 ) serían del estilo

ID / 1000000000 < 0804 and ID / 1000000000 >= 0704

Todo esto para no tener una PK múltiple. Si la PK es múltiple,
evidentemente la opción que planteas tú sería la más correcta.
¿Afecta demasiado a la inserción un check de este estilo? A menos que
el rendimiento me penalizara mucho, seguiría con mi idea de utilizar
una única PK.

Gracias

Xavi
Respuesta Responder a este mensaje
#5 Xavi
28/07/2004 - 12:48 | Informe spam
OK, muchas gracias!

Ahora la pregunta se amplía un poco más: la verdadera razón de utilizar una
vista dividida es el crecimiento excesivo de lo que originalmente era una
sola tabla. Como tal, tenía sus relaciones e índices.

¿Debería crear las relaciones e índices igualmente en las tablas
particionadas? Por los índices no me asusto, pero por las relaciones,
crearía un número excesivo de ellas, no?

Gracias por vuestros comentarios

Xavi


"Javier Loria" escribió en el mensaje
news:%23oghvB$
Hola:
Vamos a ver si me expreso un poco mejor.
Hablando de la tercera opcion. SI NO EXISTE LLAVE PRIMARIA NATURAL.
(O sea si no hay una combinacion de columnas que me garantize que una fila
es diferente a la otra y que no puedan ser nulas). Agrega una columna tipo
INT (NO tiene que ser BIGINT).
Un INT permite 4 Mil Millones de filas, los positivos son 2 Mil
Millones, o sea (2000 meses)
Si lo vieramos cronologicamente, empezando de 0 filas. El CHECK el
primer mes diria: CHECK(ID>=0)
Al final del periodo, cuando se produce un nuevo mes, creas la nueva
tabla (mensual) . Y cambias el CHECK del primer mes por: CHECK (ID BETWEEN


1
AND 994313). Esto asumiendo que el primer periodo tuvo 994,313 movimiento.
El CHECK de la nueva Tabla seria: CHECK (ID>™4314)
Si el proximo mes (2do mes) tiene 1,050,000 movimientos entonces al
final del periodo cambio el CHECK de esta tabla y queda: CHECK (ID BETWEEN
994314 AND 2,044,313). Y el CHECK de la nueva Tabla seria


CHEK(ID> 44314)
Cada vez que creas un nuevo periodo, corriges el CHECK Anterior y


creas
la nueva tabla. Adicionalmente es posible que quieras REINDEXAR para
asegurar un mejor desempeno. En los meses anteriores usas un
FILLFACTOR/PADINDEX muy altos (100) y en la tabla nueva bien bajos.
La ventaja de este diseno sobre el del BIGINT con meses implicitos, es
de desempeno. Con un BIGINT agregar 4 bytes innecesarios, que ocupan


espacio
en la tabla haciendo la tabla mas grande, si la fila tiene 100 bytes la
aplicacion seria 4% mas lenta. Pero lo mas importante es que el Indice


queda
del doble de largo o sea que ocupa mucho mas espacio, haciendo tambien mas
lento y mas lentos cualquier indice que lo referencie.
Normalmente no es necesario este tipo de consideraciones pero si vas a
tener Tablas con tantas filas si valen la pena. Por ultimo este es de las


3
opciones que te di el que menos me gusta.:(
Saludos,

Javier Loria
Costa Rica
Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
que pueda ser copiado y pegado al Query Analizer.
La version de SQL y Service Pack tambien ayuda.
Xavi escribio:
> Hola, de entrada, gracias por contestar. No entiendo el siguiente
> comentario:
>
>> Unicamente si no es posible encontrar una llave primaria, te
>> recomendaria crear una columna Entera (no es necesario un BigInt a
>> menos que tengas mas de 2000 meses)
>
> Este campo de fecha igualmente tiene que existir, ya sea datetime o
> smalldatetime, puesto que hace referencia a la fecha del registro. Es
> indispensable. Cuando hablaba de bigint me refería a la PK. Tendría
> la PK bigint de 13 dígitos ( 4 primeros mes y año ) y 9 siguientes
> secuencial por mes/año. Igualmente, tendría el campo fecha.
>
> Las checks de cada tabla ( llamémoslas Tabla0704 ) serían del estilo
>
> ID / 1000000000 < 0804 and ID / 1000000000 >= 0704
>
> Todo esto para no tener una PK múltiple. Si la PK es múltiple,
> evidentemente la opción que planteas tú sería la más correcta.
> ¿Afecta demasiado a la inserción un check de este estilo? A menos que
> el rendimiento me penalizara mucho, seguiría con mi idea de utilizar
> una única PK.
>
> Gracias
>
> Xavi


Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente Respuesta Tengo una respuesta
Search Busqueda sugerida