Pregunta

Bien, ahora mismo estoy haciendo una tabla para "Elementos de caja".

Ahora, un artículo de caja, dependiendo de para qué se utiliza/el estado del artículo, puede terminar relacionado con una casilla de "Envío" o una casilla de "Devoluciones".

Un artículo de la caja puede estar defectuoso: si lo es, se establecerá una bandera en la fila del artículo de la caja (IsDefective) y el artículo de la caja se colocará en una casilla de "Devoluciones" (con otros artículos que se devolverán a ese proveedor).De lo contrario, el artículo de la caja eventualmente se colocará en una caja de "Envío" (junto con otros artículos que se enviarán).(Tenga en cuenta que las casillas de Envío y Devoluciones tienen sus propias tablas:no hay una mesa común para todas las cajas...aunque tal vez debería considerar hacerlo si es posible como una tercera posibilidad).

Quizás hoy no estoy pensando con claridad, pero comencé a preguntarme qué se debería hacer en esta situación.

Mi instinto me dice que debería tener un campo separado para cada relación posible, incluso si solo una de las relaciones puede ocurrir en un momento dado, lo que haría que el esquema para los elementos de la caja se viera así:

BoxItemid Descripción ISDEFective ShippingBoxid ReturnBoxid, etc.

Esto aclararía las relaciones, pero parece un desperdicio (ya que sólo se utilizará una de las relaciones en cualquier momento).Entonces pensé que podría tener solo un campo para BoxID y determinar a qué BoxID se refiere (un ID de caja de envío o devoluciones) según el campo IsDefective:

BoxItemid Descripción ISDefective Boxid, etc ...

Esto parece menos desperdicio, pero no me sienta bien.La relación no es obvia.

Entonces, se lo digo a ustedes, gurús de las bases de datos de Stackoverflow.¿Qué haría usted en esta situación?

EDITAR:¡Gracias a todos por sus aportes!Me ha dado mucho en qué pensar.Por un lado, usaré un ORM la próxima vez que comience un proyecto como este.=) Para dos, como no estoy ahora, morderé los cuatro bytes y usaré dos campos.

¡Gracias a todos de nuevo!

¿Fue útil?

Solución

Estoy con Psychotic Venom y Mattlant.

Seguir la ruta polimórfica (tener que averiguar a qué tabla apunta su clave externa en función del contenido de otro campo) será una molestia.Codificar las restricciones para eso puede ser difícil (no estoy seguro de que la mayoría de las bases de datos lo admitan de forma nativa, creo que tendrías que usar un activador).

¿Alguna vez los objetos se mueven entre las mesas?Seguir dos tablas con definiciones idénticas, una para devoluciones y otra para envío, puede ser la ruta más fácil.Si desea seguir con la definición que propuso primero (con los dos campos separados) es perfectamente razonable.

"La optimización prematura es la raíz de todos los males" y todo eso.Aunque parezca un desperdicio, recuerda lo que estás almacenando.Dado que son ID, probablemente sean solo números enteros, tal vez 4 bytes.Desperdiciar cuatro bytes por registro no es básicamente nada.De hecho, debido al relleno para colocar cosas en direcciones pares u otras cosas similares, puede ser "gratis" colocar ese campo adicional allí.Todo depende del diseño de la base de datos.

A menos que tenga una muy buena razón para seguir la ruta polimórfica (como estar en un sistema integrado con poca memoria o tener que replicar a través de un enlace realmente lento de 9600 bps), probablemente no valdrá la pena los dolores de cabeza que pueda tener. .Tener que escribir todos esos casos especiales en sus consultas puede resultar molesto.

Ejemplo rápido:Hacer una unión entre dos tablas en las que si desea unirse se basa en si el indicador isDefective está configurado, será una molestia.Ser capaz de usar solo una de las dos columnas probablemente sea una molestia suficiente que puede ahorrar, al menos para mí.

Otros consejos

Consideraría hacer una tabla única para las cajas y que el tipo de caja sea una columna de la tabla de cajas.Esto simplificaría las relaciones y facilitaría la consulta del tipo de cuadro.Entonces, el elemento del cuadro solo tiene una clave externa para el ID del cuadro.

Yo usaría lo que llama Hibernate Tabla por subclase, entonces mi base de datos terminaría con 3 tablas para Cajas: Box, ShippingBox, y ReturnBox.El FK en BoxItem apuntaría a Box.

De lo que estás hablando es de relaciones polimórficas.Un ID único que puede hacer referencia a varias otras tablas.Hay varios marcos que admiten esto; sin embargo, es (potencialmente) malo para la integridad de la base de datos (esa podría ser otra discusión sobre si su base de datos o su aplicación deben mantener o no la integridad referencial).

¿Qué pasa con esto?

BoxItem:
BoxItemID, Description, IsDefective

Box:
BoxID, Description

BoxItemMap:
BoxID, BoxItemID, BoxItemType

Luego, puede hacer que BoxItemType sea una enumeración o un número entero donde define constantes en su aplicación como "Devolución" o "Envío" como tipo de caja.

De acuerdo con la discusión polimórfica anterior, aunque tiene potencial para usarse mal, sigue siendo una solución viable.

Básicamente tienes una tabla base llamada caja.Luego tienes otras dos tablas, caja de envío y caja de devolución.Esos dos agregan los campos adicionales que sean especiales para ellos.están relacionados con el cuadro con una tabla base fk.Boz 1:1 tiene los campos comunes de todos los tipos de cuadro.

Relacionas BoxItem con la tabla de cajas.La forma de obtener el tipo de cuadro adecuado es realizando una consulta que una el cuadro secundario con el cuadro raíz según la clave.El registro que tiene tanto en el cuadro base como en el cuadro hijo es de ese tipo.

Solo debes tener cuidado, como se mencionó, cuando creas un tipo de cuadro, se hace correctamente.PERO para eso están las pruebas.El código para agregarlos solo necesita escribirse una vez.O utilice un ORM.

Casi todos los ORM apoyan esta estrategia.

Yo elegiría una sola tabla BoxItems con IsDefective, ShippingBoxID, los campos relacionados con la caja de envío, ReturnBoxID y los campos relacionados con la caja de devolución.Algunos campos siempre serán NULL para cada registro.

Este es un diseño muy simple y evidente que probablemente no confundirá al próximo desarrollador.En teoría, este diseño es ineficiente debido a los campos vacíos garantizados para cada fila.En la práctica, las bases de datos tienden a tener un tamaño de almacenamiento mínimo requerido para cada fila de todos modos, por lo que (a menos que la cantidad de campos sea enorme) este diseño es lo más eficiente posible de todos modos y mucho más fácil de codificar.

Probablemente iría con:

BoxTable:
box_id, box_descrip, box_status_id ...
     1, Lovely Box, 1
     2, Borked box, 2
     3, Ugly Box, 3
     4, Flammable Box, 4

       BoxStatus:
       box_status_id, box_status_name, box_type_id, ....
                   1,Shippable, 1
                   2,Return, 2
                   3,Ugly, 2
                   4,Dangerous,3

                BoxType:
                box_type_id, box_type_name, ...
                          1, Shipping box, ...
                          2, Return box, ....
                          3, Hazmat box, ...

De esa manera, el Estado del cuadro define el tipo de cuadro y es flexible si necesita expandirse a algunos niveles de estado o tipos de cuadro más más adelante.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top