Estoy diseñando una tabla de elementos que contendrá (potencialmente) decenas de millones de registros. Algunos elementos no estarán disponibles para su uso hasta que sean "aprobados" por el administrador. Por "uso" me refiero a que dichos elementos no serán referenciados en ninguna otra tabla hasta que estén "aprobados". Hasta el 50% de los artículos pueden estar "no aprobados" en un momento dado. Los registros pueden ser "aprobados", pero no al revés.
Considero dos opciones de diseño:
- un poco de bandera
- una tabla separada de artículos "no aprobados": cuando el artículo se aprueba, se mueve a la tabla "normal" (la renovación de la ID del artículo no es un problema)
Creo que la segunda opción es mucho mejor. El indicador de bit solo toma un byte por fila, por lo que no es un problema. Pero si tenemos un millón de registros aprobados y un millón de registros no aprobados en la misma tabla, el tiempo de exploración aumenta para las operaciones con registros aprobados.
La pregunta es: ¿debería considerar la primera opción (bandera de bits) en su lugar? ¿Tiene algún beneficio en la situación descrita?
WHERE status='A'
y una consulta tieneWHERE status = 'A' AND (... other columns and parameters here...)
, entonces el índice aún podría usarse.Respuestas:
Puede tenerlo en ambos sentidos con vistas particionadas .
Se crea una tabla subyacente para cada estado, forzada por restricciones, con valores mutuamente excluyentes. Luego, una vista que une las tablas subyacentes. La vista o cada tabla base se puede referenciar explícitamente. Si el estado de una fila se ACTUALIZA a través de la vista, el DBMS lo ELIMINARÁ de una tabla base y lo insertará en la correspondiente al nuevo estado. Cada tabla base puede indexarse independientemente de acuerdo con su patrón de uso. El optimizador resolverá las referencias de índice a una sola tabla base correspondiente si puede.
Los beneficios son
a) índices menos profundos. Sin embargo, haga los cálculos en el índice de despliegue En esa escala y dividida entre sus valores de estado, es posible que los índices tengan la misma profundidad en las tablas divididas que en la tabla combinada.
b) ningún código de aplicación tiene que cambiar. Los datos continúan apareciendo como un todo continuo.
c) se pueden incluir nuevos valores de estado futuros agregando una nueva tabla base, con restricción, y recreando la vista.
El costo es todo ese movimiento de datos; Se escriben dos páginas e índices asociados para cada actualización de estado. Un montón de IO para tratar. Tanto movimiento causará fragmentación también.
fuente
En realidad, eso no es mucho, dado lo que SQL Server puede manejar de manera eficiente. Por supuesto, recuerdo uno de mis trabajos anteriores en el que una de las tablas más grandes (un sistema de instancia única) tenía 2 millones de filas y eso era lo máximo con lo que había tratado. Luego, el siguiente trabajo tuvo 17 instancias de producción con algunas tablas con cientos de millones de filas, y todas se agregaron a un Data Warehouse con múltiples tablas de hechos con más de mil millones de filas. No me malinterpreten, no me estoy burlando de decenas de millones de filas, solo estoy enfatizando que con un buen modelo de datos y una indexación adecuada (y mantenimiento del índice), SQL Server puede manejar mucho .
Hmm Eso no suena bien. La tasa de "aprobar" entradas será la mitad de la tasa de obtener nuevas entradas? Por cada 2 nuevas entradas, ¿solo 1 será "aprobado"? En su ejemplo de 2 millones de filas, y 1 millón cada una para "aprobado" y "no aprobado", unos años más tarde con otros 10 millones de entradas, ¿espera 6 millones cada una para "aprobado" y "no aprobado"? ¿O es que el millón de "no aprobado" permanecerá algo constante, de modo que con 10 millones de nuevas entradas, habrá 11 millones de "aprobado" y todavía 1 millón de "no aprobado"?
Eso es cierto hoy , pero las cosas cambian con el tiempo y, por lo tanto, siempre existe la posibilidad de que la empresa decida permitir "no aprobar", o tal vez algún otro estado, como "archivado", etc.
Entonces, veamos las opciones:
Bandera (o posiblemente incluso
TINYINT
"estado")TINYINT
columnaDos tablas separadas (una para "aprobado", una para "no aprobado")
IDENTITY
aprobada tiene una columna de ID que es una columna, y la tabla aprobada tiene una columna de ID que no es unaIDENTITY
(ya que no se necesita allí). Por lo tanto, los valores de ID permanecen consistentes a medida que el registro se mueve entre tablas.Personalmente, me inclinaría hacia la mesa individual con
StatusID
columna para empezar. Usar dos tablas parece una optimización demasiado complicada y prematura. Ese tipo de optimización puede discutirse si / cuando el número de registros está en varios cientos de millones y la indexación no proporciona ninguna ganancia de rendimiento.fuente