零或一到零或一

And*_*ykh 9 foreign-key sql-server sql-server-2008-r2

如何以最自然的方式在 Sql Server 中建模零或一到零或一的关系?

有一个“危害”表,列出了现场的危害。有一个“任务”表用于需要在站点上完成的工作。有些任务是为了修复一个危险,没有一个任务可以处理多个危险。有些危害有修复它们的任务。任何危险都不能有两项相关的任务。

以下是我能想到的最好的:

CREATE TABLE [dbo].[Hazard](
  [HazardId] [int] IDENTITY(1,1) NOT NULL,
  [TaskId] [int] NULL,
  [Details] [varchar](max) NULL,
 CONSTRAINT [PK_Hazard] PRIMARY KEY CLUSTERED 
(
  [HazardId] ASC
))

GO

ALTER TABLE [dbo].[Hazard]  WITH CHECK ADD  CONSTRAINT [FK_Hazard_Task] FOREIGN KEY([TaskId])
REFERENCES [dbo].[Task] ([TaskId])
GO


CREATE TABLE [dbo].[Task](
  [TaskId] [int] IDENTITY(1,1) NOT NULL,
  [HazardId] [int] NULL,
  [Details] [varchar](max) NULL,
 CONSTRAINT [PK_Task] PRIMARY KEY CLUSTERED 
(
  [TaskId] ASC
))

GO

ALTER TABLE [dbo].[Task]  WITH CHECK ADD  CONSTRAINT [FK_Task_Hazard] FOREIGN KEY([HazardId])
REFERENCES [dbo].[Hazard] ([HazardId])
GO
Run Code Online (Sandbox Code Playgroud)

你会这样做吗?我对这个设置不满意的原因是需要有应用程序逻辑来确保任务和危险相互指向而不是其他任务和危险,并且没有任务/危险指向相同的危险/任务另一个任务/危险指向。

有没有更好的办法?

在此处输入图片说明

And*_*y M 9

您可以通过从当前设置中删除一个外键来采用自己的非对称模式想法,或者,为了保持对称,您可以删除两个外键并引入一个对每个引用具有唯一约束的联结表.

所以,它会是这样的:

CREATE TABLE dbo.Hazard
(
  HazardId int IDENTITY(1,1) NOT NULL CONSTRAINT PK_Hazard PRIMARY KEY CLUSTERED,
  Details varchar(max) NULL
);

CREATE TABLE dbo.Task
(
  TaskId int IDENTITY(1,1) NOT NULL CONSTRAINT PK_Task PRIMARY KEY CLUSTERED,
  Details varchar(max) NULL,
);

CREATE TABLE dbo.HazardTask
(
  HazardId int NOT NULL
    CONSTRAINT FK_HazardTask_Hazard FOREIGN KEY REFERENCES dbo.Hazard (HazardId)
    CONSTRAINT UQ_HazardTask_Hazard UNIQUE,
  TaskId int NOT NULL
    CONSTRAINT FK_HazardTask_Task FOREIGN KEY REFERENCES dbo.Task (TaskId)
    CONSTRAINT UQ_HazardTask_Task UNIQUE
);
Run Code Online (Sandbox Code Playgroud)

(HazardId, TaskId)如果您需要从另一个表中引用这些组合,您可以另外声明为主键。然而,为了保持对的唯一性,主键是不必要的,每个 ID 是唯一的就足够了。