¿Cuál es el mejor diseño de base de datos para esta situación?

8

Estoy trabajando en la creación de una aplicación comercial para mi empresa y estoy luchando por elegir el diseño de base de datos más apropiado para una situación particular. Digamos que tengo las siguientes entidades:

Aprobación

  • Carné de identidad
  • Estado
  • ...

Comentario de aprobación

  • Carné de identidad
  • Id. De aprobación
  • Comentario

Orden

  • Carné de identidad
  • ...

Factura

  • Carné de identidad
  • ...

Obviamente, puede haber múltiples tipos de aprobaciones y múltiples objetos que requieren aprobaciones. ¿Cuál sería la más apropiada de las siguientes opciones para diseñar las tablas?

OPCIÓN 1

Tener una tabla de aprobaciones con claves foráneas nulas:

Aprobaciones

  • Id PK
  • Estado
  • OrderId FK NULL
  • InvoiceId FK NULL

Comentarios de aprobación

  • Id PK
  • ApprovalId FK
  • Comentario

En este caso, tendría que agregar una columna para cada objeto que necesita una aprobación

OPCION 2

Tenga una tabla de aprobaciones principal con campos comunes y una tabla secundaria para cada objeto que necesite una aprobación:

Aprobaciones

  • Id PK
  • Estado

Comentarios de aprobación

  • Id PK
  • ApprovalId FK
  • Comentario

Aprobaciones de pedidos

  • Id. De aprobación PK FK
  • OrderId FK

Aprobaciones de facturas

  • Id. De aprobación PK FK
  • InvoiceId FK

OPCION 3

Tenga una tabla de aprobaciones para cada objeto:

Aprobaciones de pedidos

  • Id PK
  • OrderId FK
  • Estado

OrderApprovalComments

  • Id PK
  • OrderApprovalId FK
  • Comentario

Aprobaciones de facturas

  • Id PK
  • InvoiceId FK
  • Estado

Factura Aprobación Comentarios

  • Id PK
  • FactApprovalId FK
  • Comentario

Sé que todas estas son soluciones válidas, pero no puedo decidir cuál sería la mejor para agregar diferentes tipos de aprobaciones en el futuro. ¿Alguna idea?

usuario1384977
fuente

Respuestas:

10

Una regla general que uso es que es un mal diseño de la base de datos tener que modificar una tabla para acomodar un cambio de código o una nueva característica si se puede planificar en el futuro.

Dicho esto, usaría una variante de la Opción 1

Approvals
    Id PK
    ApprovalTypeID FK
    Status


ApprovalComments
    ID PK
    ApprovalId FK
    Comment

ApprovalTypes
    ID PK
    Name

Ahora, al agregar nuevos tipos de objetos que necesitan aprobación, solo necesita insertar una fila en ApprovalTypes en lugar de modificar una tabla para agregar una columna.

sreimer
fuente
¿Dónde iría la relación de identificación con un pedido / factura en particular en esta situación? Digamos que un pedido requiere una "aprobación de crédito", por lo que el tipo de aprobación sería crédito, pero ¿cómo se vincula con el pedido (o cualquier entidad)? Además, ¿a dónde irían columnas adicionales que fueran específicas solo para una aprobación de crédito?
user1384977
Eso agrega un poco de complejidad. Podría tener una tabla CreditApprovalDetails. Si necesita vincular las aprobaciones a los pedidos, necesitaría una tabla de unión, a menos que sea 1: 1. Sin embargo, sin una comprensión completa de su aplicación, no puedo hacer una sugerencia informada.
sreimer
2

Depende de la cardinalidad de su base de datos y de las cosas que desea almacenar, por ejemplo, simplemente puede hacer que aprobacion_comentario sea único y hacer una relación 1-1 entre aprobación y aprobación_comentario, por lo que omitirá crear una tabla adicional ... I Lo vi de esta manera:

Cardinality:
Approval N ---- 1 Approval_comment.
Approval 1 ----- N Order
Order N ----- 1 Invoice

ingrese la descripción de la imagen aquí

jcho360
fuente
1

Voto por la primera alternativa. Si agrega el requisito de aprobación a un elemento, altera el comportamiento de dichos elementos de manera que pueda agregarse una columna no es un gran problema. Y también, es la mejor manera de usar combinaciones en consultas.

El segundo tiene tablas adicionales inútiles, lo que puede sugerir que más de una aprobación puede pertenecer a un elemento.

El tercero contiene una gran cantidad de tablas redundantes, y probablemente un código redundante para manejarlas.

Matzi
fuente
1

Si tiene que decidir entre una de sus tres opciones, creo que la opción 2 es la mejor. @sreimer tiene razón en que tener que cambiar la estructura de su tabla para los eventos previsibles apunta a un mal diseño. Tener OrderID e InvoiceID en la tabla Aprobaciones es, como lo veo, muy cerca de un grupo repetitivo en columnas y viola el espíritu, si no la letra, de la primera forma normal.

Consideraría agregar una columna ApprovalID a cada tabla que necesita aprobación. Si el valor es nulo, no se ha aprobado. Si esa no es una opción, creo que @sreimer está en el diseño adecuado; algunas aclaraciones podrían ayudar a reafirmarlo.

mdoyle
fuente
1

Te sugiero que tengas solo una tabla =>

Aprobación

carné de identidad

estado

comentario

Y tener el ID de almacenamiento almacenado en la tabla de pedidos o de novatos. De esta manera, no tiene que agregar columnas para cada objeto y hay menos tablas para mantener. Y si tengo que elegir entre la opción que me ha proporcionado, iré con la opción 2 y combinaré el comentario de aprobación en la tabla de aprobación.

techExplorer
fuente
0

Podrías probar algo como esto:

Aprobaciones
---------
  CARNÉ DE IDENTIDAD
  estado
  nombre_aprobador
  (otras cosas)

Pedidos
------
  CARNÉ DE IDENTIDAD
  (otras cosas)

Facturas
--------
  CARNÉ DE IDENTIDAD
  (otras cosas)

objetos_aprobados
----------------
  CARNÉ DE IDENTIDAD
  Approval_id (FK - se refiere a la tabla de aprobaciones)
  Approved_object_id (FK: puede hacer referencia a la ID de facturas, pedidos, etc.)
  aprobado_objeto_tipo_id (FK se refiere a aprobado_tipo_objeto)

aprobado_objetos_tipos
---------------------
  CARNÉ DE IDENTIDAD
  Nombre

La approved_objectstabla le indica qué aprobación va con qué objeto aprobado. El objeto podría ser aprobada en invoices, orderso algo más. Usted determina en qué tabla buscar en función de approved_object_type_id. Esto será flexible, pero podría hacer que informar sea un poco complicado.

FrustratedWithFormsDesigner
fuente