tablas - ¿Cómo creo una verdadera relación uno a uno en SQL Server?
relaciones en mysql (6)
1 a 1 ¡Las relaciones en SQL se crean fusionando el campo de ambas tablas en una!
Sé que puedes dividir una Tabla en dos entidades con una relación de 1 a 1. La mayoría de las veces lo usa porque quiere usar la carga diferida en "campo pesado de datos binarios en una tabla".
Ejemplo: tiene una tabla que contiene imágenes con una columna de nombre (cadena), tal vez alguna columna de metadatos, una columna en miniatura y la imagen misma varbinary (max). En su aplicación, seguramente mostrará primero solo el nombre y la miniatura en un control de recopilación y luego cargará los "datos de imagen completa" solo si es necesario.
Si es lo que estás buscando. Es algo llamado "división de tabla" o "división horizontal".
https://visualstudiomagazine.com/articles/2014/09/01/splitting-tables.aspx
Quiero crear una relación uno a uno en SQL Server 2008 R2.
Tengo dos tablas tableA
y tableB
, establezco la clave primaria de tableB
como clave foránea que hace referencia a la primaria de tableA
. Pero cuando uso la base de datos de Entity Framework primero, el modelo es de 1 a 0..1.
¿Alguien sabe cómo crear una relación real de 1 a 1 en la base de datos?
¡Gracias por adelantado!
Establezca la clave externa como clave principal y luego establezca la relación en ambos campos de clave primaria. ¡Eso es! Debería ver un signo de tecla en ambos extremos de la línea de relación. Esto representa uno a uno.
Compruebe esto: Diseño de la base de datos de SQL Server con una relación de uno a uno
Esto puede hacerse creando una relación de clave externa simple simple y configurando la columna de clave externa como única de la siguiente manera:
CREATE TABLE [Employee] (
[ID] INT PRIMARY KEY
, [Name] VARCHAR(50)
);
CREATE TABLE [Salary] (
[EmployeeID] INT UNIQUE NOT NULL
, [SalaryAmount] INT
);
ALTER TABLE [Salary]
ADD CONSTRAINT FK_Salary_Employee FOREIGN KEY([EmployeeID])
REFERENCES [Employee]([ID]);
INSERT INTO [Employee] (
[ID]
, [Name]
)
VALUES
(1, ''Ram'')
, (2, ''Rahim'')
, (3, ''Pankaj'')
, (4, ''Mohan'');
INSERT INTO [Salary] (
[EmployeeID]
, [SalaryAmount]
)
VALUES
(1, 2000)
, (2, 3000)
, (3, 2500)
, (4, 3000);
Verifique si todo está bien
SELECT * FROM [Employee];
SELECT * FROM [Salary];
Ahora, por lo general, en Relaciones Extranjeras Primarias (de uno a varios), puede ingresar varias veces EmployeeID
, pero aquí se arrojará un error
INSERT INTO [Salary] (
[EmployeeID]
, [SalaryAmount]
)
VALUES
(1, 3000);
La declaración anterior mostrará el error como
Violation of UNIQUE KEY constraint ''UQ__Salary__7AD04FF0C044141D''.
Cannot insert duplicate key in object ''dbo.Salary''. The duplicate key value is (1).
Estoy bastante seguro de que es técnicamente imposible en SQL Server tener una verdadera relación 1 a 1, ya que eso significaría que tendría que insertar ambos registros al mismo tiempo (de lo contrario, obtendría un error de restricción al insertar), en ambas tablas, con ambas tablas teniendo una relación de clave externa entre sí.
Dicho esto, el diseño de su base de datos descrito con una clave externa es una relación de 1 a 0. 1. No hay restricciones posibles que requieran un registro en la tabla B. Puede tener una pseudo relación con un disparador que crea el registro en la tabla B.
Entonces hay algunas pseudo soluciones
Primero, almacene todos los datos en una sola tabla. Entonces no tendrás problemas en EF.
O En segundo lugar, su entidad debe ser lo suficientemente inteligente como para no permitir un inserto a menos que tenga un registro asociado.
O en tercer lugar, y lo más probable es que tenga un problema que está tratando de resolver, y nos está preguntando por qué su solución no funciona en lugar del problema real que está tratando de resolver (un problema XY) .
ACTUALIZAR
Para explicar en REALIDAD cómo las relaciones 1 a 1 no funcionan, usaré la analogía del dilema del pollo o el huevo . No tengo la intención de resolver este dilema, pero si tuviera una restricción que dice que para agregar un Huevo a la tabla de Huevos, la relación del Pollo debe existir, y el pollo debe existir en la mesa, entonces no podrías agregar un Huevo a la tabla de Huevos. Lo opuesto también es cierto. No puede agregar un pollo a la tabla de pollo sin la relación con el huevo y el huevo existente en la tabla de huevos. Por lo tanto, no se pueden realizar todos los registros en una base de datos sin romper una de las reglas / restricciones.
La nomenclatura de la base de datos de una relación de uno a uno es engañosa. Todas las relaciones que he visto (por lo tanto, mi experiencia) serían más descriptivas como relaciones de uno a uno (cero o uno).
Hay una manera en que sé cómo lograr una relación estrictamente * uno-a-uno sin usar desencadenantes, columnas calculadas, tablas adicionales u otros trucos "exóticos" (solo claves externas y restricciones únicas), con una pequeña advertencia.
Pediré prestado el concepto de pollo y huevo de la respuesta aceptada para ayudarme a explicar la advertencia.
Es un hecho que un huevo o una gallina debe ser lo primero (en los DB actuales de todos modos). Afortunadamente, esta solución no se vuelve política y no prescribe cuál debe ser el primero, sino que lo deja en manos del implementador.
La advertencia es que la tabla que permite que un registro "llegue primero" técnicamente puede tener un registro creado sin el registro correspondiente en la otra tabla; sin embargo, en esta solución, solo se permite uno de esos registros. Cuando solo se crea un registro (solo pollo o huevo), no se pueden agregar más registros a ninguna de las dos tablas hasta que se elimine el registro "solitario" o se cree un registro coincidente en la otra tabla.
Solución:
Añada claves foráneas a cada tabla, haciendo referencia a la otra, agregue restricciones exclusivas a cada clave externa, y haga que una clave foránea sea nulable, la otra no nulable y también una clave principal. Para que esto funcione, la restricción única en la columna que admite nulos solo debe permitir un valor nulo (este es el caso en SQL Server, no está seguro acerca de otras bases de datos).
CREATE TABLE dbo.Egg (
ID int identity(1,1) not null,
Chicken int null,
CONSTRAINT [PK_Egg] PRIMARY KEY CLUSTERED ([ID] ASC) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE dbo.Chicken (
Egg int not null,
CONSTRAINT [PK_Chicken] PRIMARY KEY CLUSTERED ([Egg] ASC) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE dbo.Egg WITH NOCHECK ADD CONSTRAINT [FK_Egg_Chicken] FOREIGN KEY([Chicken]) REFERENCES [dbo].[Chicken] ([Egg])
GO
ALTER TABLE dbo.Chicken WITH NOCHECK ADD CONSTRAINT [FK_Chicken_Egg] FOREIGN KEY([Egg]) REFERENCES [dbo].[Egg] ([ID])
GO
ALTER TABLE dbo.Egg WITH NOCHECK ADD CONSTRAINT [UQ_Egg_Chicken] UNIQUE([Chicken])
GO
ALTER TABLE dbo.Chicken WITH NOCHECK ADD CONSTRAINT [UQ_Chicken_Egg] UNIQUE([Egg])
GO
Para insertar, primero se debe insertar un huevo (con nulo para pollo). Ahora, solo se puede insertar un pollo y debe hacer referencia al huevo "no reclamado". Finalmente, el huevo agregado se puede actualizar y debe hacer referencia al pollo ''no reclamado''. En ningún momento se pueden hacer dos pollos para hacer referencia al mismo huevo o viceversa.
Para eliminar, se puede seguir la misma lógica: actualice Chicken''s egg para null, elimine el pollo nuevo ''no reclamado'', elimine el huevo.
Esta solución también permite intercambiar fácilmente. Curiosamente, el intercambio podría ser el argumento más fuerte para usar tal solución, ya que tiene un uso práctico potencial. Normalmente, en la mayoría de los casos, una relación uno a uno de dos tablas se implementa mejor simplemente refactorizando las dos tablas en una; sin embargo, en un escenario potencial, las dos tablas pueden representar entidades verdaderamente distintas, que requieren una relación uno a uno estricta, pero necesitan intercambiar ''socios'' con frecuencia o reorganizarse en general, mientras se mantiene el one-to. -una relación después de la reorganización. Si se utilizara la solución más común, todas las columnas de datos de una de las entidades tendrían que actualizarse / sobrescribirse para todos los pares que se reorganizan, a diferencia de esta solución, donde solo se necesita reorganizar una columna de claves externas. (la columna de clave externa anulable).
Bueno, esto es lo mejor que puedo hacer usando restricciones estándar (no juzgues :) Tal vez alguien lo encuentre útil.
La forma más sencilla de lograr esto es crear solo 1 tabla con los campos de la Tabla A y B NOT NULL. De esta manera es imposible tener uno sin el otro.