¿Qué alternativas existen cuando una tabla requiere demasiadas claves foráneas?

8

Tenemos una tabla base que define partes y contiene información como número de parte, descripción, precio, peso, etc. También tenemos aproximadamente 400 tablas que hacen referencia a la tabla base y proporcionan información adicional sobre las partes en función de su tipo / categoría.

Comenzamos utilizando restricciones de clave externa para que una parte no se pueda eliminar de la tabla base si se hace referencia a ella en una de las tablas específicas de 400 partes, pero rápidamente alcanzamos el máximo de 253 claves externas recomendadas para SQL Server 2005.

¿Hay alguna alternativa a las claves externas en esta situación que garantice la integridad de los datos? No hemos visto problemas de rendimiento al acceder a los datos, pero la actualización de una parte existente en la tabla base fallará ya que el plan de consulta es demasiado complejo.

jellomonkey
fuente
14
¿Realmente crees que necesitas 400 tablas de partes específicas? ¿Cuán diferentes son realmente cada una de estas tablas? Creo que estás tratando de arreglar la parte incorrecta de este diseño.
Aaron Bertrand
2
¿Aproximadamente cuántas filas está tratando en esta base de datos?
Jon Seigel
44
Tengo que estar de acuerdo con Aaron Bertrand, si su diseño requiere que maximice las claves externas que admite el servidor sql, puede ser hora de considerar un rediseño.
DForck42
55
He realizado muchos diseños en esta área: precios, gestión de productos, especificaciones de productos. Incluso en diseños altamente normalizados, nunca me he acercado a tantos FK en la misma mesa. ¿Tal vez estás haciendo algún tipo de estrategia de partición de datos (por cliente o tiempo o algo así) que te hizo diseñar en esta dirección? Es difícil proporcionar una respuesta sin más información sobre su diseño y objetivos de diseño.
Karen Lopez
44
¿Podría proporcionar un ejemplo de esquema para decir 5 de estas tablas ...
Damir Sudarevic

Respuestas:

6

Si hay alguna forma de agrupar partes, es posible que pueda introducir tablas intermedias como solución alternativa. Esto no funcionara.

Parts
+ Table 1
+ Table 2
+ ...
+ Table 400

Pero algo así podría ser.

Parts
+ RedOrangeYellow parts
  + Table 1
  + Table 2
  + ...
  + Table 200

+ GreenBlueIndigoViolet parts
  + Table 201
  + Table 202
  + ...
  + Table 400

Sin embargo, me gustaría echar un vistazo a tu DDL antes de recomendarlo . Y si haces esto, no comiences a tirar números de identificación por todas partes. Debería poder unir "Tabla 400" directamente a "Piezas" sin incluir "Piezas GreenBlueIndigoViolet".

Mike Sherrill 'Retiro del gato'
fuente
-4

Reemplace las más de 400 mesas con una. Solo necesita 3 campos (+1 autonumber o cualquier clave principal si lo desea, no tiene que tenerlo, puede formarlo a partir de los otros campos)

ID del artículo Valor de atributo

Entonces, donde en sus otras tablas cada campo representa un atributo, en esta tabla sus atributos están todos en un campo. Tendrías algo como esto

Valor de atributo de ID de artículo

Calcetín Material Lana

Calcetín Color Rojo

Peso del calcetín 20 libras

Alien Planet Alpha Centauri

Alien Color Púrpura

Alien Friendly No

Los ItemID probablemente deberían ser un número / alfanumérico de c. Luego, solo tiene una tabla de referencias cruzadas con Atributos como encabezados de columna cuando sea necesario para generar las tablas que desee. Esto también permite mejores consultas para cosas como "Muéstrame todos los artículos que son de Alpha Centauri" que podrían devolverte el Alien y también el fragmento de Meteorito que contenía la plaga que aniquila a la humanidad (está llegando .....)

La optimización puede ser complicada dependiendo de cuántos registros haya, pero es una forma mucho mejor de diseñar esto. Hice lo mismo para una base de datos que contenía un montón de recetas (10k +) que tenían pocas superposiciones. Funcionó bien en ese caso. Realmente no tuve problemas de velocidad. El tuyo puede ser más difícil dependiendo de con cuántos estés lidiando.

user2125055
fuente
44
Esto se llama modelo de valor de atributo de entidad y normalmente es una idea bastante terrible por muchas razones. Para su ejemplo del escenario "alfa centauri", probablemente miraría 2 escaneos de tabla, y los índices no se pueden usar. Además, anula cualquier ventaja para los tipos de datos, hace que las restricciones relacionales sean imposibles y, en general, no es optimizable ni escalable en ningún grado. Si necesita almacenar más de cien filas como esta, no lo haga.
JNK
2
Como señala @JNK, generalmente no es una buena solución. Y aún peor cuando lo haces con una sola mesa. Yo diría que la mínima es de 3 tablas ( Entity, Entity_Attribute, Entity_Attribute_Value). Si desea agregar un tratamiento semi-adecuado para diferentes tipos de datos y restricciones referenciales, necesitará más.
ypercubeᵀᴹ
1
Si bien el OP puede estar llegando a algún tipo de límite con el diseño normalizado tradicional debido a la gran complejidad de las entidades en su sistema, la mayoría de los sistemas extremadamente complejos no se manejan mejor en EAV, ya que ofrece un soporte de tipo mucho más débil y un nivel de aplicación integridad referencial ya que todos los datos se almacenan de manera bastante genérica. EAV tiene su lugar útil, pero no estaría listo para recomendarlo como respuesta a este problema como se indica actualmente.
Cade Roux
Huh, aprende algo nuevo todos los días. Soy autodidacta y eso fue algo que se me ocurrió para resolver el problema de la receta que estaba teniendo, que suena similar a este problema de chicos. Ah bueno. Gracias por la información sobre eso, buscaré en EAV, tal vez también haya una forma más limpia de resolver mi problema. Podría ser más fácil para mí ya que todos los valores eran del mismo tipo de datos. No se.
user2125055
2
@ user2125055 No hay problema, y ​​no tome ninguna de las críticas personalmente. ¡Solo estamos rechazando la idea de usar EAV! Definitivamente, hay casos de uso en los que tiene sentido, pero debido a los inconvenientes, debe tener mucho cuidado con eso.
JNK