El otro día estaba pensando en la normalización, y se me ocurrió, no puedo pensar en un momento en el que debería haber una relación 1: 1 en una base de datos.
Name:SSN
? Los tendría en la misma mesa.PersonID:AddressID
? De nuevo, la misma mesa.
Se me ocurren millones de ejemplos de 1: muchos o muchos: muchos (con tablas intermedias apropiadas), pero nunca un 1: 1.
¿Me estoy perdiendo algo obvio?
sql
database-design
one-to-one
database-normalization
Cabeza de pulso
fuente
fuente
Respuestas:
Una relación 1: 1 generalmente indica que ha particionado una entidad más grande por alguna razón. A menudo se debe a razones de rendimiento en el esquema físico, pero también puede ocurrir en el lado lógico si se espera que una gran parte de los datos sea "desconocida" al mismo tiempo (en cuyo caso tiene un 1: 0 o 1: 1, pero no más).
Como ejemplo de una partición lógica: tiene datos sobre un empleado, pero hay un conjunto más grande de datos que deben recopilarse, si y solo si seleccionan tener cobertura de salud. Mantendría los datos demográficos con respecto a la cobertura de salud en una tabla diferente para dar una partición de seguridad más fácil y para evitar transportar esos datos en consultas no relacionadas con el seguro.
Un ejemplo de una partición física sería la misma información alojada en múltiples servidores. Puedo mantener los datos demográficos de la cobertura de salud en otro estado (donde está la oficina de recursos humanos, por ejemplo) y la base de datos primaria solo puede vincularse a ella a través de un servidor vinculado ... evitando replicar datos confidenciales en otras ubicaciones, sin embargo, estar disponible para (suponiendo que aquí es raro) consultas que lo necesitan.
La partición física puede ser útil siempre que tenga consultas que necesiten subconjuntos consistentes de una entidad más grande.
fuente
Una razón es la eficiencia de la base de datos. Tener una relación 1: 1 le permite dividir los campos que se verán afectados durante un bloqueo de fila / tabla. Si la tabla A tiene muchas actualizaciones y la tabla b tiene muchas lecturas (o tiene muchas actualizaciones de otra aplicación), el bloqueo de la tabla A no afectará lo que sucede en la tabla B.
Otros traen un buen punto. La seguridad también puede ser una buena razón dependiendo de cómo las aplicaciones, etc., están afectando el sistema. Tendería a adoptar un enfoque diferente, pero puede ser una forma fácil de restringir el acceso a ciertos datos. Es realmente fácil negar el acceso a una determinada tabla en caso de necesidad.
Mi entrada de blog al respecto.
fuente
Escasez. La relación de datos puede ser técnicamente 1: 1, pero las filas correspondientes no tienen que existir para cada fila. Entonces, si tiene veinte millones de filas y hay un conjunto de valores que solo existe para el 0.5% de ellos, el ahorro de espacio es enorme si empuja esas columnas hacia una tabla que puede estar escasamente poblada.
fuente
La mayoría de las respuestas altamente clasificadas brindan razones de optimización y optimización de bases de datos muy útiles para las relaciones 1: 1, pero quiero centrarme en nada más que ejemplos "en la naturaleza" donde las relaciones 1: 1 ocurren naturalmente.
Tenga en cuenta una característica importante de la implementación de la base de datos de la mayoría de estos ejemplos: no se retiene información histórica sobre la relación 1: 1. Es decir, estas relaciones son 1: 1 en cualquier momento dado. Si el diseñador de la base de datos desea registrar cambios en los participantes de la relación a lo largo del tiempo, las relaciones se convierten en 1: M o M: M; pierden su naturaleza 1: 1. Con eso entendido, aquí va:
Relaciones "Is-A" o supertipo / subtipo o herencia / clasificación: Esta categoría es cuando una entidad es un tipo específico de otra entidad. Por ejemplo, podría haber una entidad Empleado con atributos que se apliquen a todos los empleados, y luego diferentes entidades para indicar tipos específicos de empleados con atributos únicos para ese tipo de empleado, por ejemplo, Doctor, Contador, Piloto, etc. Este diseño evita múltiples nulos ya que muchos empleados no tendrían los atributos especializados de un subtipo específico. Otros ejemplos en esta categoría podrían ser Producto como supertipo y Manufactura Producto y Suministro de mantenimiento como subtipos; Animal como supertipo y Perro y Gato como subtipos; etc. Tenga en cuenta que siempre que intente asignar una jerarquía de herencia orientada a objetos en una base de datos relacional (como en un modelo relacional de objetos), este es el tipo de relación que representa tales escenarios.
Relaciones de "jefe" , como gerente, presidente, presidente, etc., donde una unidad organizativa puede tener un solo jefe, y una persona puede ser jefe de una sola unidad organizativa. Si se aplican esas reglas, entonces tiene una relación 1: 1, como un gerente de un departamento, un CEO de una empresa, etc. Las relaciones "jefes" no solo se aplican a las personas. El mismo tipo de relación se produce si solo hay una tienda como sede de una empresa, o si solo una ciudad es la capital de un país, por ejemplo.
Algunos tipos de asignación de recursos escasos , por ejemplo, a un empleado se le puede asignar solo un automóvil de la compañía a la vez (por ejemplo, un camión por camionero, un taxi por taxista, etc.). Un colega me dio este ejemplo recientemente.
Matrimonio (al menos en jurisdicciones legales donde la poligamia es ilegal): una persona puede casarse con solo otra persona a la vez. Obtuve este ejemplo de un libro de texto que lo usó como un ejemplo de una relación unaria 1: 1 cuando una compañía registra matrimonios entre sus empleados.
Reservas coincidentes : cuando se hace una reserva única y luego se cumple como dos entidades separadas. Por ejemplo, un sistema de alquiler de automóviles puede registrar una reserva en una entidad y luego un alquiler real en una entidad separada. Aunque tal situación podría diseñarse alternativamente como una entidad, podría tener sentido separar las entidades ya que no se cumplen todas las reservas, y no todos los alquileres requieren reservas, y ambas situaciones son muy comunes.
Repito la advertencia que hice anteriormente de que la mayoría de estas son relaciones 1: 1 solo si no se registra información histórica. Entonces, si un empleado cambia su rol en una organización, o un gerente se responsabiliza de un departamento diferente, o un empleado es reasignado a un vehículo, o alguien queda viudo y se vuelve a casar, entonces la relación que los participantes pueden cambiar. Si la base de datos no almacena ningún historial anterior sobre estas relaciones 1: 1, entonces siguen siendo relaciones legítimas 1: 1. Pero si la base de datos registra información histórica (como agregar fechas de inicio y finalización para cada relación), entonces casi todas se convierten en relaciones M: M.
Hay dos excepciones notables a la nota histórica: Primero, algunas relaciones cambian tan raramente que la información histórica normalmente no se almacenaría. Por ejemplo, la mayoría de las relaciones IS-A (por ejemplo, tipo de producto) son inmutables; es decir, nunca pueden cambiar. Por lo tanto, el punto de registro histórico es discutible; estos siempre se implementarían como relaciones naturales 1: 1. En segundo lugar, la tienda de la relación reserva-alquiler data por separado, ya que la reserva y el alquiler son eventos independientes, cada uno con sus propias fechas. Dado que las entidades tienen sus propias fechas, en lugar de que la relación 1: 1 en sí tenga una fecha de inicio, estas permanecerían como relaciones 1: 1 a pesar de que se almacena información histórica.
fuente
Su pregunta puede interpretarse de varias maneras, debido a la forma en que la redactó. Las respuestas muestran esto.
Definitivamente puede haber relaciones 1: 1 entre elementos de datos en el mundo real. No hay duda al respecto. La relación "es un" es generalmente uno a uno. Un carro es un vehículo. Un auto es un vehículo. Un vehículo puede ser un auto. Algunos vehículos son camiones, en cuyo caso un vehículo no es un automóvil. Varias respuestas abordan esta interpretación.
Pero creo que lo que realmente está preguntando es ... cuando existen relaciones 1: 1, ¿deberían dividirse las tablas alguna vez? En otras palabras, ¿alguna vez debería tener dos tablas que contengan exactamente las mismas claves? En la práctica, la mayoría de nosotros analizamos solo las claves primarias, y no otras claves candidatas, pero esa pregunta es ligeramente diferente.
Las reglas de normalización para 1NF, 2NF y 3NF nunca requieren descomponer (dividir) una tabla en dos tablas con la misma clave primaria. No he resuelto si poner un esquema en BCNF, 4NF o 5NF puede resultar en dos tablas con las mismas claves. Fuera de mi cabeza, voy a adivinar que la respuesta es no.
Hay un nivel de normalización llamado 6NF. La regla de normalización para 6NF definitivamente puede dar como resultado dos tablas con la misma clave primaria. 6NF tiene la ventaja sobre 5NF de que los NULLS pueden evitarse por completo. Esto es importante para algunos, pero no para todos, los diseñadores de bases de datos. Nunca me he molestado en poner un esquema en 6NF.
En 6NF, los datos faltantes se pueden representar mediante una fila omitida, en lugar de una fila con un NULL en alguna columna.
Hay otras razones además de la normalización para dividir tablas. A veces las tablas divididas dan como resultado un mejor rendimiento. Con algunos motores de base de datos, puede obtener los mismos beneficios de rendimiento al particionar la tabla en lugar de dividirla realmente. Esto puede tener la ventaja de mantener el diseño lógico fácil de entender, al tiempo que proporciona al motor de la base de datos las herramientas necesarias para acelerar las cosas.
fuente
Los uso principalmente por algunas razones. Una es la diferencia significativa en la tasa de cambio de datos. Algunas de mis tablas pueden tener pistas de auditoría en las que rastreo versiones anteriores de registros, si solo me interesa rastrear versiones anteriores de 5 de cada 10 columnas, dividir esas 5 columnas en una tabla separada con un mecanismo de pista de auditoría es más eficiente. Además, es posible que tenga registros (por ejemplo, para una aplicación de contabilidad) que son solo de escritura. No puede cambiar los montos en dólares, o la cuenta para la que eran, si cometió un error, entonces necesita hacer un registro correspondiente para escribir, ajustar el registro incorrecto y luego crear una entrada de corrección. Tengo restricciones en la tabla que imponen el hecho de que no se pueden actualizar o eliminar, pero puedo tener un par de atributos para ese objeto que son maleables, estos se guardan en una tabla separada sin restricción de modificación. Otra vez que hago esto es en aplicaciones de registros médicos. Hay datos relacionados con una visita que no se pueden cambiar una vez que se cierra la sesión, y otros datos relacionados con una visita que se pueden cambiar después del cierre de sesión. En ese caso, dividiré los datos y pondré un disparador en la tabla bloqueada, rechazando las actualizaciones de la tabla bloqueada cuando cierre la sesión, pero permitiendo las actualizaciones de los datos que el médico no está firmando.
Otro póster comentaba que 1: 1 no se normaliza, no estaría de acuerdo con eso en algunas situaciones, especialmente en el subtipo. Digamos que tengo una tabla de empleados y la clave principal es su SSN (es un ejemplo, guardemos el debate sobre si esta es una buena clave o no para otro hilo). Los empleados pueden ser de diferentes tipos, por ejemplo, temporales o permanentes, y si son permanentes, tienen más campos para completar, como el número de teléfono de la oficina, que solo no debe ser nulo si el tipo = 'Permanente'. En una tercera base de datos de forma normal, la columna debe depender solo de la clave, es decir, el empleado, pero en realidad depende del empleado y el tipo, por lo que una relación 1: 1 es perfectamente normal y deseable en este caso. También evita tablas demasiado dispersas, si tengo 10 columnas que normalmente se llenan,
fuente
El escenario más común en el que puedo pensar es cuando tienes BLOB. Digamos que desea almacenar imágenes grandes en una base de datos (por lo general, no es la mejor manera de almacenarlas, pero a veces las restricciones lo hacen más conveniente). Normalmente, desearía que el blob esté en una tabla separada para mejorar las búsquedas de los datos que no son del blob.
fuente
En términos de ciencia pura, sí, son inútiles.
En bases de datos reales, a veces es útil mantener un campo poco utilizado en una tabla separada: para acelerar las consultas utilizando este y solo este campo; para evitar cerraduras, etc.
fuente
En lugar de usar vistas para restringir el acceso a los campos, a veces tiene sentido mantener los campos restringidos en una tabla separada a la que solo ciertos usuarios tienen acceso.
fuente
También puedo pensar en situaciones en las que tiene un modelo OO en el que usa la herencia, y el árbol de la herencia debe persistir en la base de datos.
Por ejemplo, tienes una clase Bird y Fish que ambos heredan de Animal. En su base de datos, podría tener una tabla 'Animal', que contiene los campos comunes de la clase Animal, y la tabla Animal tiene una relación uno a uno con la tabla Bird, y una relación uno a uno con Fish mesa.
En este caso, no tiene que tener una tabla Animal que contenga muchas columnas anulables para contener las propiedades Bird y Fish, donde todas las columnas que contienen datos Fish se configuran en NULL cuando el registro representa un pájaro.
En cambio, tiene un registro en la tabla Birds que tiene una relación uno a uno con el registro en la tabla Animal.
fuente
1-1 relaciones también son necesarias si tienes demasiada información. Hay una limitación de tamaño de registro en cada registro de la tabla. A veces, las tablas se dividen en dos (con la información más consultada en la tabla principal) solo para que el tamaño del registro no sea demasiado grande. Las bases de datos también son más eficientes para consultar si las tablas son estrechas.
fuente
También es una forma de extender una tabla que ya está en producción con menos riesgo (percibido) que un cambio de base de datos "real". Ver una relación 1: 1 en un sistema heredado suele ser un buen indicador de que los campos se agregaron después del diseño inicial.
fuente
En SQL es imposible imponer una relación 1: 1 entre dos tablas que es obligatoria en ambos lados (a menos que las tablas sean de solo lectura). Para los propósitos más prácticos, una relación "1: 1" en SQL realmente significa 1: 0 | 1.
La incapacidad de admitir la cardinalidad obligatoria en las restricciones referenciales es una de las serias limitaciones de SQL. Las restricciones "diferibles" en realidad no cuentan porque son solo una forma de decir que la restricción no se aplica algunas veces.
fuente
Si está utilizando los datos con uno de los ORM populares, es posible que desee dividir una tabla en varias tablas para que coincida con su Jerarquía de objetos.
fuente
He descubierto que cuando hago una relación 1: 1 es totalmente por una razón sistémica, no una razón relacional.
Por ejemplo, descubrí que poner los aspectos reservados de un usuario en una tabla y poner los campos editables del usuario en una tabla diferente permite escribir lógicamente esas reglas sobre permisos en esos campos mucho más fácilmente.
Pero tiene razón, en teoría, las relaciones 1: 1 están completamente inventadas y son casi un fenómeno. Sin embargo, lógicamente permite que los programas y optimizaciones abstraigan la base de datos más fácilmente.
fuente
La mayoría de las veces, se piensa que los diseños son 1: 1 hasta que alguien pregunta "bueno, ¿por qué no puede ser 1: muchos"? La división prematura de los conceptos se anticipa a este escenario común. Persona y dirección no se unen tan fuertemente. Mucha gente tiene múltiples direcciones. Y así...
Por lo general, dos espacios de objetos separados implican que uno o ambos pueden multiplicarse (x: muchos). Si dos objetos eran verdaderamente, verdaderamente 1: 1, incluso filosóficamente, entonces es más una relación de is. Estos dos "objetos" son en realidad partes de un objeto completo.
fuente
información extendida que solo es necesaria en ciertos escenarios. en aplicaciones heredadas y lenguajes de programación (como RPG) donde los programas se compilan sobre las tablas (por lo tanto, si la tabla cambia, debe volver a compilar los programas). Etiquetar archivos también puede ser útil en casos en los que tiene que preocuparse por el tamaño de la tabla.
fuente
Con mayor frecuencia es más una construcción física que lógica. Se usa comúnmente para dividir verticalmente una tabla para aprovechar la división de E / S en dispositivos físicos u otras optimizaciones de consulta asociadas con la segregación de datos a los que se accede con menos frecuencia o datos que deben mantenerse más seguros que el resto de los atributos en el mismo objeto (SSN, salario, etc.).
La única consideración lógica que prescribe una relación 1-1 es cuando ciertos atributos solo se aplican a algunas de las entidades. Sin embargo, en la mayoría de los casos hay una forma mejor / más normalizada de modelar los datos a través de la extracción de entidades.
fuente
La mejor razón que puedo ver para una relación 1: 1 es un SuperType SubType de diseño de base de datos. Creé una estructura de datos Real Estate MLS basada en este modelo. Hubo cinco feeds de datos diferentes; Residencial, comercial, multifamiliar, hoteles y terrenos.
Creé una propiedad llamada SuperType que contenía datos que eran comunes a cada una de las cinco fuentes de datos separadas. Esto permitió búsquedas "simples" muy rápidas en todos los tipos de datos.
Creo cinco subtipos separados que almacenan los elementos de datos únicos para cada una de las cinco fuentes de datos. Cada registro SuperType tenía una relación 1: 1 con el registro SubType apropiado.
Si un cliente deseaba una búsqueda detallada, tenía que seleccionar un tipo Super-Sub, por ejemplo, PropertyResidential.
fuente
En mi opinión, una relación 1: 1 mapea una herencia de clase en un RDBMS. Hay una tabla A que contiene los atributos comunes, es decir, el estado de clase de parte. Cada estado de clase heredado se asigna en el RDBMS con una tabla B con una relación 1: 1 con la tabla A, que contiene los atributos especializados. El nombre de la tabla y A contienen también un campo "tipo" que representa la funcionalidad de "conversión"
Adios Mario
fuente
Puede crear una tabla de relación uno a uno si hay algún beneficio de rendimiento significativo. Puede poner los campos raramente utilizados en una tabla separada.
fuente
Las relaciones 1: 1 realmente no tienen sentido si te gusta la normalización, ya que todo lo que sería 1: 1 se mantendría en la misma tabla.
Sin embargo, en el mundo real, a menudo es diferente. Es posible que desee dividir sus datos para que coincidan con la interfaz de sus aplicaciones.
fuente
Posiblemente si tiene algún tipo de objeto escrito en su base de datos.
Digamos en una tabla, T1, que tiene las columnas C1, C2, C3 ... con una relación uno a uno. Está bien, está en forma normalizada. Ahora, en una tabla T2, tiene las columnas C1, C2, C3, ... (los nombres pueden diferir, pero los tipos y el rol son los mismos) con una relación uno a uno también. Está bien para T2 por las mismas razones que con T1.
En este caso, sin embargo, veo un ajuste para una tabla separada T3, que contiene C1, C2, C3 ... y una relación uno a uno de T1 a T3 y de T2 a T3. Aún más veo un ajuste si existe otra tabla, con la que ya existe uno a múltiples C1, C2, C3 ... digamos de la tabla A a varias filas en la tabla B. Luego, en lugar de T3, usa B y tiene una relación uno a uno de T1 a B, lo mismo para T2 a B, y aún la misma relación múltiple a A a B.
Creo que la normalización no está de acuerdo con esto, y esa puede ser una idea fuera de ella: identificar tipos de objetos y mover objetos del mismo tipo a su propio grupo de almacenamiento, utilizando una relación uno a uno de algunas tablas y uno a múltiples relación de algunas otras tablas.
fuente
Es innecesario para fines de seguridad, pero existen mejores formas de realizar controles de seguridad. Imagina que creas una llave que solo puede abrir una puerta. Si la llave puede abrir cualquier otra puerta, debe hacer sonar la alarma. En esencia, puede tener "CitizenTable" y "VotingTable". Citizen One vota por Candidate One que se almacena en la tabla de votación. Si el ciudadano uno vuelve a aparecer en la mesa de votación, entonces debería ser una alarma. Tenga en cuenta que esta es una relación uno a uno porque no nos referimos al campo de candidatos, nos referimos a la mesa de votación y la mesa de ciudadanos.
Ejemplo:
Entonces, si vemos la mesa de votación así:
Podríamos decir que el ciudadano número 3 es un mentiroso en llamas que engañó a Bern Nie. Solo un ejemplo.
fuente
Cuando se trata de una base de datos de un producto de terceros, entonces probablemente no desee alterar su base de datos para evitar un acoplamiento estrecho. pero puede tener datos que correspondan 1: 1 con sus datos
fuente
En cualquier lugar, dos entidades completamente independientes comparten una relación uno a uno. Debe haber muchos ejemplos:
persona <-> dentista (es 1: N, ¡así que está mal!)
persona <-> médico (es 1: N, ¡así que también está mal!)
persona <-> cónyuge (es 1: 0 | 1, ¡así que está mal!)
EDITAR: Sí, esos fueron ejemplos bastante malos, particularmente si siempre estaba buscando un 1: 1, no un 0 o 1 en ambos lados. Supongo que mi cerebro estaba disparando mal :-)
Entonces, lo intentaré de nuevo. Resulta, después de un poco de reflexión, que la única forma en que puede tener dos entidades separadas que deben estar juntas (en lo que respecta al software) todo el tiempo es que existan juntas en una categorización más alta. Entonces, si y solo si caes en una descomposición más baja, las cosas están y deberían estar separadas, pero en el nivel más alto no pueden vivir sin la otra. Contexto, entonces es la clave.
Para una base de datos médica, es posible que desee almacenar información diferente sobre regiones específicas del cuerpo, manteniéndolas como una entidad separada. En ese caso, un paciente tiene solo una cabeza, y necesitan tenerla, o no son pacientes. (También tienen un corazón y otros órganos individuales necesarios). Si está interesado en el seguimiento de cirugías, por ejemplo, cada región debe ser una entidad separada única.
En un sistema de producción / inventario, si está rastreando el ensamblaje de vehículos, entonces ciertamente desea ver el progreso del motor de manera diferente a la carrocería del automóvil, sin embargo, existe una relación uno a uno. Un cuidado debe tener un motor, y solo uno (o ya no sería un 'auto'). Un motor pertenece a un solo automóvil.
En cada caso, podría producir las entidades separadas como un gran registro, pero dado el nivel de descomposición, sería incorrecto. Son, en estos contextos específicos, entidades verdaderamente independientes, aunque podrían no parecerlo en un nivel superior.
Pablo.
fuente