¿Cuándo debería utilizar la relación uno a uno?

92

Perdón por esa pregunta de novato, pero ¿hay alguna necesidad real de usar una relación uno a uno con las tablas en su base de datos? Puede implementar todos los campos necesarios dentro de una tabla. Incluso si los datos se vuelven muy grandes, puede enumerar los nombres de columna que necesita en una SELECTdeclaración en lugar de usarlos SELECT *. ¿Cuándo realmente necesitas esta separación?

Pavel Shchegolevatykh
fuente

Respuestas:

105

1 a 0..1

  • El "1 a 0..1" entre las superclases y las subclases se utiliza como parte de la estrategia "todas las clases en tablas separadas" para implementar la herencia .

  • Un "1 a 0..1" se puede representar en una sola tabla con la parte "0..1" cubierta por campos NULL. Sin embargo, si la relación es mayoritariamente "1 a 0" con sólo unas pocas filas "1 a 1", dividir la parte "0..1" en una tabla separada podría ahorrar algunos beneficios de almacenamiento (y rendimiento de caché). Algunas bases de datos son más económicas para almacenar NULL que otras, por lo que un "punto de corte" en el que esta estrategia se vuelve viable puede variar considerablemente.

1 a 1

  • El "1 a 1" real divide verticalmente los datos, lo que puede tener implicaciones para el almacenamiento en caché. Las bases de datos suelen implementar cachés a nivel de página, no a nivel de campos individuales, por lo que incluso si selecciona solo unos pocos campos de una fila, normalmente se almacenará en caché toda la página a la que pertenece esa fila. Si una fila es muy ancha y los campos seleccionados relativamente estrechos, terminará almacenando en caché mucha información que en realidad no necesita. En una situación como esa, puede ser útil dividir los datos verticalmente, de modo que solo se almacenen en caché la porción o las filas más estrechas y utilizadas con más frecuencia, de modo que puedan caber más en la caché, haciendo que la caché sea efectivamente "más grande".

  • Otro uso de la partición vertical es cambiar el comportamiento de bloqueo: las bases de datos normalmente no se pueden bloquear a nivel de campos individuales, solo las filas completas. Al dividir la fila, permite que se produzca un bloqueo en solo una de sus mitades.

  • Los disparadores también suelen ser específicos de la tabla. Si bien teóricamente puede tener solo una tabla y hacer que el disparador ignore la "mitad incorrecta" de la fila, algunas bases de datos pueden imponer límites adicionales sobre lo que un disparador puede y no puede hacer, lo que podría hacer que esto no sea práctico. Por ejemplo, Oracle no le permite modificar la tabla de mutación; al tener tablas separadas, solo una de ellas puede estar mutando, por lo que aún puede modificar la otra desde su disparador.

  • Las tablas separadas pueden permitir una seguridad más granular.

Estas consideraciones son irrelevantes en la mayoría de los casos, por lo que en la mayoría de los casos debería considerar fusionar las tablas "1 a 1" en una sola tabla.

Branko Dimitrijevic
fuente
20

Si los datos de una tabla están relacionados con la entidad descrita por la otra, pero no 'pertenecen' a ella, entonces es un candidato para mantenerla separada.

Esto podría proporcionar ventajas en el futuro, si los datos separados también deben estar relacionados con alguna otra entidad.

Sepster
fuente
19

Si coloca dos tablas uno a uno en una, es probable que tenga problemas de semántica. Por ejemplo, si cada dispositivo tiene un control remoto, no suena muy bien colocar el dispositivo y el control remoto con sus características en una sola mesa. Incluso podría tener que dedicar tiempo a averiguar si un determinado atributo pertenece al dispositivo o al control remoto.

Puede haber casos en los que la mitad de las columnas permanezcan vacías durante mucho tiempo o nunca se llenen. Por ejemplo, un automóvil puede tener un remolque con un montón de características, o puede que no tenga ninguna. Entonces tendrás muchos atributos sin usar.

Si su tabla tiene 20 atributos y solo 4 de ellos se usan ocasionalmente, tiene sentido dividir la tabla en 2 tablas por problemas de rendimiento.

En tales casos, no es bueno tener todo en una mesa. Además, ¡no es fácil lidiar con una tabla que tiene 45 columnas!

superM
fuente
17

Mis 2 centavos.

Trabajo en un lugar donde todos desarrollamos en una gran aplicación, y todo es un módulo. Por ejemplo, tenemos una userstabla y tenemos un módulo que agrega detalles de Facebook para un usuario, otro módulo que agrega detalles de Twitter a un usuario. Podríamos decidir desconectar uno de esos módulos y eliminar toda su funcionalidad de nuestra aplicación. En este caso, cada módulo agrega su propia tabla con relaciones 1: 1 a la userstabla global , así:

create table users ( id int primary key, ...);
create table users_fbdata ( id int primary key, ..., constraint users foreighn key ...)
create table users_twdata ( id int primary key, ..., constraint users foreighn key ...)
santiago arizti
fuente
13

El momento más sensato para usar esto sería si hubiera dos conceptos separados que solo se relacionarían de esta manera. Por ejemplo, un automóvil solo puede tener un conductor actual, y el conductor solo puede conducir un automóvil a la vez, por lo que la relación entre los conceptos de automóvil y conductor sería de 1 a 1. Acepto que este es un ejemplo artificial para demostrar el punto.

Otra razón es que desea especializar un concepto de diferentes maneras. Si tiene una tabla de Persona y desea agregar el concepto de diferentes tipos de Persona, como Empleado, Cliente, Accionista, cada uno de ellos necesitaría diferentes conjuntos de datos. Los datos que son similares entre ellos estarían en la tabla Persona, la información especializada estaría en las tablas específicas para Cliente, Accionista, Empleado.

Algunos motores de base de datos luchan por agregar de manera eficiente una nueva columna a una tabla muy grande (muchas filas) y he visto tablas de extensión utilizadas para contener la nueva columna, en lugar de agregar la nueva columna a la tabla original. Este es uno de los usos más sospechosos de tablas adicionales.

También puede decidir dividir los datos para un solo concepto entre dos tablas diferentes por problemas de rendimiento o legibilidad, pero este es un caso razonablemente especial si está comenzando desde cero; estos problemas se mostrarán más adelante.

Fenton
fuente
5

no muy seguido.

puede encontrar algún beneficio si necesita implementar algo de seguridad, por lo que algunos usuarios pueden ver algunas de las columnas (tabla1) pero no otras (tabla2).

Por supuesto, algunas bases de datos (Oracle) le permiten hacer este tipo de seguridad en la misma tabla, pero es posible que otras no.

Cachondo
fuente
5

Se refiere a la normalización de la base de datos. Un ejemplo que se me ocurre en una aplicación que mantengo es Items. La aplicación permite al usuario vender muchos tipos diferentes de artículos (es decir, InventoryItems, NonInventoryItems, ServiceItems, etc.). Si bien podría almacenar todos los campos requeridos por cada artículo en una tabla de artículos, es mucho más fácil mantener una tabla de artículos base que contenga campos comunes a todos los artículos y luego tablas separadas para cada tipo de artículo (es decir, inventario, no inventario, etc.) que contienen campos específicos solo para ese tipo de elemento. Entonces, la tabla de elementos tendría una clave externa para el tipo de elemento específico que representa. La relación entre las tablas de elementos específicos y la tabla de elementos base sería uno a uno.

A continuación, se muestra un artículo sobre normalización.

http://support.microsoft.com/kb/283878

Saltamontes
fuente
3

Como ocurre con todas las preguntas de diseño, la respuesta es "depende".

Hay algunas consideraciones:

  • ¿Qué tan grande será la tabla (tanto en términos de campos como de filas)? Puede ser un inconveniente almacenar el nombre de usuario y la contraseña con otros datos de uso menos común, tanto desde el punto de vista del mantenimiento como de la programación.

  • Los campos de la tabla combinada que tienen restricciones pueden resultar engorrosos de administrar con el tiempo. por ejemplo, si un disparador debe activarse para un campo específico, eso sucederá para cada actualización de la tabla, independientemente de si ese campo se vio afectado.

  • ¿Qué tan seguro está de que la relación será 1: 1? Como señala esta pregunta, las cosas se pueden complicar rápidamente.

Rob Allen
fuente
3

Otro caso de uso puede ser el siguiente: puede importar datos de alguna fuente y actualizarlos diariamente, por ejemplo, información sobre libros. Luego, agrega datos usted mismo sobre algunos libros. Entonces tiene sentido colocar los datos importados en otra tabla que no sea su propia información.

Puñal
fuente
2

Normalmente encuentro dos tipos generales de relación 1: 1 en la práctica:

  1. Relaciones IS-A, también conocidas como relaciones de supertipo / subtipo. Esto es cuando un tipo de entidad es en realidad un tipo de otra entidad (EntityA IS A EntityB). Ejemplos:

    • Entidad persona, con entidades separadas para Contador, Ingeniero, Vendedor, dentro de la misma empresa.
    • Entidad de artículo, con entidades separadas para Widget, RawMaterial, FinishedGood, etc.
    • Entidad de automóvil, con entidades separadas para camión, sedán, etc.

    En todas estas situaciones, la entidad de supertipo (por ejemplo, Persona, Elemento o Coche) tendría los atributos comunes a todos los subtipos, y las entidades de subtipo tendrían atributos únicos para cada subtipo. La clave principal del subtipo sería la misma que la del supertipo.

  2. Relaciones de "jefe". Esto es cuando una persona es el jefe o gerente o supervisor único de una unidad organizativa (departamento, empresa, etc.). Cuando solo se permite un jefe para una unidad organizativa, existe una relación 1: 1 entre la entidad persona que representa al jefe y la entidad de la unidad organizativa.

Tripartio
fuente
1
Me gusta el segundo ejemplo. Puede tener entidad "Departamento" y entidad "Empleado". En un departamento tiene muchos empleados y un empleado solo puede trabajar en un departamento. Esto es 1: n. Un empleado puede ser supervisor de un departamento, solo de un departamento, y el departamento solo tiene un supervisor. Entonces terminas con dos tablas conectadas con dos relaciones: 1: n y 1: 1.
cezar
2

Primero, creo que se trata de modelar y definir qué consiste en una entidad separada. Suponga que tiene customerscon uno y solo uno address. Por supuesto, podría implementar todo en una sola tabla customer, pero si, en el futuro, le permite tener 2 o más direcciones, entonces deberá refactorizar eso (no es un problema, pero tome una decisión consciente).

También puedo pensar en un caso interesante que no se menciona en otras respuestas donde dividir la tabla podría ser útil:

Imagina, de nuevo, que tienes customerscon uno solo addresscada uno, pero esta vez es opcional tener una dirección. Por supuesto, podría implementar eso como un montón de NULLcolumnas -able como ZIP,state,street. Pero suponga que dado que tiene una dirección, el estado no es opcional, pero el ZIP sí lo es. ¿Cómo modelar eso en una sola tabla? Puede usar una restricción en la customertabla, pero es mucho más fácil dividir en otra tabla y hacer que la clave_externa sea NULL. De esa manera, su modelo es mucho más explícito al decir que la entidad address es opcional y que ZIPes un atributo opcional de esa entidad.

polvoazul
fuente
0

En mi época de programación, encontré esto solo en una situación. Que es cuando hay una relación de 1 a muchos y de 1 a 1 entre las mismas 2 entidades ("Entidad A" y "Entidad B").

Cuando la "Entidad A" tiene múltiples "Entidades B" y la "Entidad B" tiene solo 1 "Entidad A" y la "Entidad A" tiene solo 1 "Entidad B" actual y la "Entidad B" tiene solo 1 "Entidad A".

Por ejemplo, un automóvil solo puede tener un conductor actual, y el conductor solo puede conducir un automóvil a la vez, por lo que la relación entre los conceptos de automóvil y conductor sería de 1 a 1. - Tomé prestado este ejemplo de la respuesta de @Steve Fenton

Donde un conductor puede conducir varios coches, pero no al mismo tiempo. Entonces, las entidades Car y Driver son de 1 a muchos o de muchos a muchos. Pero si necesitamos saber quién es el controlador actual, también necesitamos la relación 1 a 1.

Jo Smo
fuente
0

Otro caso de uso podría ser si se excede el número máximo de columnas en la tabla de la base de datos. Entonces podrías unirte a otra mesa usando OneToOne

db303
fuente