Pregunta

Hay varios tipos de objetos en un sistema y cada uno tiene su propia tabla en la base de datos.Un usuario debería poder comentar sobre cualquiera de ellos.¿Cómo diseñaría la(s) tabla(s) de comentarios?Se me ocurren algunas opciones:

  1. Una tabla de comentarios, con una columna FK para cada tipo de objeto (ObjectAID, ObjectBID, etc.)
  2. Varias tablas de comentarios, una para cada tipo de objeto (ObjectAComments, ObjectBComments, etc)
  3. Un FK genérico (ParentObjectID) con otra columna para indicar el tipo ("ObjectA")

¿Cuál escogerías?¿Existe algún método mejor en el que no estoy pensando?

¿Fue útil?

Solución

@palmasey

Más o menos, pero la variación de ese patrón que he visto con mayor frecuencia elimina ObjectAID et al. ParentID se convierte tanto en PK como en FK para Parents.Eso te da algo como:

  • Parents

    • ParentID
  • ObjectA

    • ParentID (FK y PK)
    • ColumnFromA NOT NULL
  • ObjectB

    • ParentID (FK y PK)
    • ColumnFromB NOT NULL

Comments seguiría siendo el mismo.Luego sólo necesita restringir la generación de ID para no terminar accidentalmente con un ObjectA fila y un ObjectB fila que ambos apuntan a lo mismo Parents fila;La forma más fácil de hacerlo es usar la misma secuencia (o lo que sea) que estás usando para Parents para ObjectA y ObjectB.

También ves muchos esquemas con algo como:

  • Parents
    • ID
    • SubclassDiscriminator
    • ColumnFromA (nullable)
    • ColumnFromB (nullable)

y Comments permanecería sin cambios.Pero ahora no puede imponer todas las restricciones de su negocio (todas las propiedades de las subclases admiten valores NULL) sin escribir activadores o hacerlo en una capa diferente.

Otros consejos

¿Es factible diseñar el esquema de modo que las tablas comentables (a falta de una palabra mejor) sigan uno de los patrones estándar de modelado de herencia?Si es así, puede hacer que el FK de la tabla de comentarios apunte a la tabla principal común.

@Hank Gay

Entonces algo como:

  1. ObjetoA
    • ObjetoAID
    • Identificación de los padres
  2. ObjetoB
    • ObjetoBID
    • Identificación de los padres
  3. Comentarios
    • ID de comentario
    • Identificación de los padres
  4. Padres
    • Identificación de los padres

Tenga cuidado con las claves foráneas genéricas que no apuntan exactamente a una tabla.El rendimiento de las consultas se ve afectado drásticamente si tiene que dividir la condición Where en un tipo y apuntar a varias tablas diferentes.Si solo tiene unos pocos tipos y el número de tipos no aumentará, está bien tener claves externas anulables separadas para las diferentes tablas, pero si tendrá más tipos, es mejor crear un modelo de datos diferente (como sugerencia de @palmsey).

Una de las cosas que me gusta hacer es tener tablas separadas que vinculen la tabla genérica/común a todas las tablas individualizadas.

Entonces, para los objetos Foo y Bar y luego los comentarios sobre Foo y Bar, tendrías algo como esto:

  • foo
    • ID de Foo (PK)
  • Bar
    • ID de barra (PK)
  • Comentario
    • ID de comentario (PK)
    • Texto del comentario
  • FooComentario
    • ID de Foo (PK FK)
    • ID de comentario (PK FK)
  • BarraComentario
    • ID de barra (PK FK)
    • ID de comentario (PK FK)

Esta estructura:

  1. Le permite tener una tabla de comentarios común.
  2. No requiere una base de datos con herencia de tablas
  3. No contamina las tablas Foo y Bar con información relacionada con comentarios
  4. Le permite adjuntar un comentario a múltiple objetos (que pueden ser deseables)
  5. Le permite adjuntar otras propiedades a la unión de Foo/Bar y Comment si así lo desea.
  6. Aún conserva las relaciones con el estándar (es decir:rápido, simple, confiable) claves externas
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top