2010-10-18 8 views
5

Tengo una rutina que creará tablas individuales (Sql Server 2008) para almacenar los resultados de los informes generados por mi aplicación (Asp.net 3.5). Cada informe necesitará su propia tabla, ya que las columnas de la tabla variarán en función de la configuración del informe. Una tabla contendrá entre 10 y 5.000 filas, raramente más de 10.000.¿Hay alguna razón para una columna de clave principal que nunca se usaría?

Se aplicarán las siguientes reglas de uso:

  • Una vez almacenados, los datos nunca serán actualizados.
  • Cuando se accede a los resultados de la tabla, se recuperarán todos los datos.
  • Ninguna otra tabla necesitará realizar una combinación con esta tabla.

Sabiendo esto, ¿hay alguna razón para crear una columna de índice PK en la tabla? Si lo hace, ayudará a la recuperación de los datos de cualquier manera, y si lo hiciera, ¿superaría esto la carga adicional de actualizar el índice al insertar datos (sé que 10K registros es una cantidad relativamente pequeña, pero esta solución debe ser capaz de escalar).

actualización: Aquí están algunos detalles más sobre los datos que están siendo procesados, que entra en la decisión actual diseño de una tabla para cada informe:

  • Tablas registrará un conjunto de valores numéricos (establecido en tiempo de ejecución en función de la configuración del informe) que corresponde a un conjunto diferente de valores varchar de referencia (también se establece en el tiempo de ejecución en función de la configuración del informe).
  • Cuando se recuperan los datos, se requerirá algún procesamiento posterior en el servidor antes de que la salida pueda mostrarse al usuario (por lo tanto, siempre recuperaré todos los valores).

También sospecho de alguien que afirma que tuvo que crear una nueva tabla para cada vez que se ejecutó el informe. Sin embargo, dado que diferentes columnas (tanto en número, nombre y tipo de datos) podrían ser necesarias para cada vez que se ejecutó el informe, no veo una gran alternativa.

Lo único que puedo pensar es tener una columna de ID (identificando el ReportVersionID, correspondiente a otra tabla), columna ReferenceValues ​​(campo varchar, que contiene todos los valores de referencia, en un orden específico, separados por algún delimitador) y columna NumericValues ​​(igual que los ReferenceValues, pero para los números), y luego cuando recupero los resultados, pongo todo en objetos especializados en el sistema, separando los valores basados ​​en el delimitador definido). ¿Esto parece preferible?

+2

Esto suena muy sospechoso. Prefiero no preguntar por qué :) – leppie

+0

@leppie - ¿Qué es "sospechoso" al respecto? –

+0

Voy a configurar un experto en el servidor Sql para que responda la pregunta. Pero al igual que un FYI, en mi experiencia, agregar índices, _después_ de insertar sus filas casi siempre es una ganancia, sin duda con MySQL y Postgres. Si encuentra que sus consultas se ejecutan más rápido con el índice, intente agregarlo al final después de las inserciones. – Gray

Respuesta

3

Las claves primarias no DEBEN para todas las tablas de datos. Es cierto que, por lo general, son bastante útiles y abandonarlos es imprudente. Sin embargo,, además de las misiones principales de velocidad (que, estoy de acuerdo, se vería afectado positivamente) es también de exclusividad. Con ese fin, y valorando la consideración que ya has tomado, sugeriría que la única necesidad de una clave principal sería gobernar la singularidad esperada de la tabla.

Actualización: Usted ha mencionado en un comentario de que si se hizo una PK que incluiría una columna de identidad que en la actualidad no existe y no se necesita. En este caso, desaconsejaría el PK por completo. Como @RedFilter señaló, las claves sustitutas nunca agregan ningún valor.

+3

+1: Y, por supuesto, un 'PK 'sustituto no ayuda a proporcionar la unicidad, por lo que solo se debe considerar un' PK' natural, si corresponde. – RedFilter

+0

Lo que dijo RedFilter. Además, ¿qué defensas está tomando para asegurarse de que los mismos datos no se ingresen dos veces, en dos filas diferentes? ¿Cuáles son las consecuencias si esto ocurre? –

+0

Para juzgar si la velocidad se verá afectada positivamente, debemos saber si los datos se leerán muchas veces y cómo. Por ahora, sabemos que los datos no se actualizarán, lo que sugiere escrituras únicas y muchas lecturas. Esto sugiere que el índice podría ser útil; sin embargo, OP también afirma que siempre será necesario leer todos los datos (lo que dará como resultado escaneos para que el índice no se use). Entonces, no sabemos ... – Unreason

0

¿Será 1 tabla por cada ejecución de un informe determinado, o una tabla para todas las ejecuciones de un informe determinado? en otras palabras, si tiene el Informe n. ° 1 y lo ejecuta 5 veces, en un rango diferente de datos, ¿generará 5 tablas, o las 5 ejecuciones del informe se almacenarán en la misma tabla?

Si está almacenando las 5 ejecuciones del informe en la misma tabla, deberá filtrar los datos para que sean apropiados para la ejecución en cuestión. en este caso, tener una clave principal le permitirá hacer la instrucción where para el filtro, mucho más rápido.

si está creando una nueva tabla para cada ejecución del informe, entonces no necesita una clave principal. sin embargo, se encontrará con otros problemas de rendimiento a medida que crezca el número de tablas en su sistema ... suponiendo que no tenga algo en su lugar para eliminar tablas/datos antiguos.

+0

Crear una nueva tabla para cada ejecución del informe (ya que la configuración del informe, y por lo tanto las columnas, puede cambiar entre ejecuciones). Eventualmente habrá alguna funcionalidad de archivado para eliminar las tablas antiguas. Tienes alguna idea de qué número de tablas comenzaría a afectar el rendimiento (no me preocupa poner demasiadas tablas, ya que el servidor sql permite 2.147.483.647 objetos en cada base de datos). . –

+1

Simplemente lea este comentario que cambia mucho la imagen: si está creando una tabla para cada ejecución de un informe, ¿por qué está creando una tabla? ¿Por qué no puedes simplemente ejecutar un informe de una consulta y no almacenar los resultados en una tabla? – Unreason

+0

La ejecución del informe puede llevar horas (puede implicar literalmente cientos de consultas, golpeando tablas con millones de filas). Para la usabilidad y la estabilidad del sitio, esto se hace en un proceso en segundo plano, y el usuario es informado cuando se ejecuta. El resultado real del informe (que básicamente es una gran tabla dinámica sobre múltiples columnas, que resume los resultados de estas muchas consultas) solo puede ser una tabla de dimensiones relativamente pequeñas (20-50 columnas, 50-100 filas) en comparación con los datos establecer, pero no es práctico que el usuario espere a que termine el informe. Almacenando así los resultados en el ínterin. –

0

Si realmente no está utilizando las tablas para nada más que como un fragmento de datos de solo lectura, puede almacenar todos los informes en una sola tabla, como valores XML.

+1

Creo que procesar los datos hacia y desde XML sería un golpe de rendimiento bastante significativo. – Jay

+0

@Cyrena: Sí, pero crear una tabla también es un golpe de rendimiento significativo ... – Guffa

+0

@Cyrena, si las operaciones XML son siempre atómicas (siempre lo lee todo) y si libera al servidor de la codificación/decodificación, en realidad podría ser obtener un mejor rendimiento. – Unreason

0

¿En qué columna o columnas se basaría el índice PK? Si solo es una columna de identidad sustituta, no tendrá ningún impacto en el rendimiento al insertar filas, ya que se insertarán "en orden". Si no se trata de una clave sustituta, entonces tiene la seguridad ciertamente menor pero útil de que no tiene entradas duplicadas.

¿Se utiliza la tecla principal para controlar el orden en que se van a imprimir las filas del informe? De lo contrario, ¿cómo se asegura el orden correcto de la información? (¿O solo se trata de una tabla de datos que se suma de una forma u otra cada vez que se genera un informe?)

Si utiliza una clave principal en clúster, no utilizará tanto espacio de almacenamiento como lo haría con un no- índice agrupado.

En general, considero que si bien no todas las tablas requieren una clave principal, no está de más tener una, y dado que el diseño adecuado de la base de datos relacional requiere claves primarias en todas las tablas, es una buena práctica incluirlas siempre.

+0

PK no se usa para controlar la orden de impresión, ya que todos los resultados se recuperan y deben procesarse en el servidor antes de enviarlos al usuario. Si utilicé cualquier columna PK, sería una columna agrupada con autoincrement. –

+0

"Si usa una clave principal en clúster, no usará tanto espacio de almacenamiento como lo haría con un índice no agrupado" Eso no es cierto. Un índice agrupado suele ocupar más espacio que uno no agrupado y, a menudo, también aumenta el tamaño de los índices no agrupados en la misma tabla porque la clave del clúster se incluye en cada uno de los otros índices. Por lo tanto, los índices agrupados casi invariablemente aumentan el tamaño de los índices en total y requieren más almacenamiento que los índices no agrupados en un montón. – sqlvogel

+0

Mi declaración fue en respuesta a * esta * pregunta, y no un comentario de propósito general. La tabla que @Yaakov propuso era indiferente (o así lo interpreté), y estaba pensando en agregar solo la clave principal. Si solo hay un índice, un índice no agrupado + la tabla requerirá más espacio de almacenamiento que un índice agrupado + la tabla, ya que el índice no agrupado requerirá el nivel de hoja "adicional" del árbol de búsqueda de los índices. Como dices, las cosas serían diferentes si hubiera índices multiples presentes. –

1

Me gustaría que sea sencillo, simplemente almacenar los resultados del informe convertidos a JSON o XML, en una columna VARCHAR (MAX)

1

Uno de los más útiles y beneficios de la integridad de los datos (teclas menos enfatizados (explícitamente) primarias y referencias de claves foráneas para comenzar) es que obliga a un 'diseño por contrato' entre sus datos y su (s) aplicación (es); que detiene un montón de tipos de errores al hacer cualquier daño a sus datos. Esta es una gran ganancia y algo que se da por sentado implícitamente (no es 'la base de datos' la que lo protege, sino las reglas de integridad que usted especifica; al abandonar las reglas, expone sus datos a varios niveles de degradación).

Esto no le parece importante (por el hecho de que ni siquiera habló de lo que sería una clave principal posible) y sus datos parecen no tener relación con otras partes del sistema (por el hecho de que no hará uniones a cualquier otra tabla); pero aun así, si todo fuera igual, modelaría los datos correctamente y si las claves primarias (u otras reglas de integridad de datos) no se usan y si persiguen hasta el último bit de rendimiento, consideraría dejarlos en producción (y probarlos). cualquier ganancia real).

En cuanto a los comentarios, la creación de tablas es un golpe de rendimiento, eso es cierto, pero no nos dijo qué tan temporales son estas tablas? Una vez creados, ¿se usarán en gran medida antes de ser desechados? ¿O planea crear tablas para solo una docena de operaciones de lectura?

En caso de que se utilice en gran medida estas tablas y si les dará mecanismo de limpieza para su gestión (eliminación de ellos cuando no se utiliza, la selección de ellos, etc ...) Creo que la creación dinámica de las mesas sería perfectamente bien (que podría haber compartido más detalles sobre las mismas tablas, caso de uso sería bueno)

Notas sobre otras soluciones:

EAV model

es horrible a menos muy sp se cumplen condiciones ecológicas (por ejemplo: la flexibilidad es primordial y la automatización de DDL es una molestia). Manténgase alejado de él (o sea muy, muy bueno para anticipar qué tipos de consultas tendrá que tratar con y rigurosos al validar los datos en la interfaz).

XML/enfoque BLOB

podría ser lo correcto para usted si usted va a consumir los datos como XML/BLOB en la capa de presentación (siempre leer todas las filas, siempre escribir todo el 'objeto' y, por último, si su capa de presentación gusta XML/BLOBS)

EDIT: también, dependiendo de los patrones de uso, teniendo primaria clave puede de hecho aumentar la velocidad de recuperación, y si puedo leer el hecho de que los datos se no se actualizará ya que 'se escribirá una vez y se leerá muchas veces', entonces hay una buena probabilidad de que en realidad, tendrá una sobreponderación en el costo de actualización del índice en las inserciones.

Cuestiones relacionadas