我正在使用 SQL Server 2012
我有两张 table ,Person
和 Couple
, Person
有来自 Couple
的外键和 Couple
有来自“人”的外键。
当我尝试将数据插入每个表时,会发生错误,因为每个表都有来自另一个表的 FK
表,并且最初都是空的。
CREATE TABLE [dbo].[Couple](
[CoupleId] [int] IDENTITY(1,1) NOT NULL,
[HusbandPersonId] [int] NOT NULL,
[WifePersonId] [int] NOT NULL,
[StartDate] [date] NOT NULL,
[EndDate] [date] NOT NULL,
CONSTRAINT [PK_Couple] PRIMARY KEY CLUSTERED
(
[CoupleId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[Person](
[PersonId] [int] IDENTITY(1,1) NOT NULL,
[ChildOfCoupleId] [int] NOT NULL,
[CityOfBirth] [int] NOT NULL,
[CityOfPermanentResidence] [int] NOT NULL,
[CityOfCurrentResidence] [int] NOT NULL,
[FirstName] [varchar](20) NOT NULL,
[LastName] [varchar](20) NOT NULL,
[BirthDate] [date] NOT NULL,
[DeathDate] [date] NOT NULL,
[IsMale] [bit] NOT NULL,
CONSTRAINT [PK_Person] PRIMARY KEY CLUSTERED
(
[PersonId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY
ALTER TABLE [dbo].[Couple] WITH CHECK ADD CONSTRAINT [FK_Couple_Person] FOREIGN KEY([HusbandPersonId])
REFERENCES [dbo].[Person] ([PersonId])
GO
ALTER TABLE [dbo].[Couple] CHECK CONSTRAINT [FK_Couple_Person]
GO
ALTER TABLE [dbo].[Couple] WITH CHECK ADD CONSTRAINT [FK_Couple_Person1] FOREIGN KEY([WifePersonId])
REFERENCES [dbo].[Person] ([PersonId])
GO
ALTER TABLE [dbo].[Couple] CHECK CONSTRAINT [FK_Couple_Person1]
GO
ALTER TABLE [dbo].[Person] WITH CHECK ADD CONSTRAINT [FK_Person_Couple] FOREIGN KEY([ChildOfCoupleId])
REFERENCES [dbo].[Couple] ([CoupleId])
GO
ALTER TABLE [dbo].[Person] CHECK CONSTRAINT [FK_Person_Couple]
GO
如何解决这个问题?
最佳答案
你不能要求所有人都有 parent ,因为你会遇到父递归的无限循环。也就是说,你必须有一对没有 parent 的“亚当和夏娃”夫妇才能成为所有 child 的 parent 。
现在,您可以制作您的 ChildOfCoupleId
列 NULLable 作为一种解决方案。但坦率地说,我认为使用 CoupleId
不是最优的。相反,使用 MotherId
和 FatherId
.这最终会更好,因为它:
Person
中制作 FK 来简化 FK 关系指向Person
而不是必须查询才能确定人员的另一个表。 Couple
的参与--我注意到你没有调用它 Marriage
但您正在使用 Husband
和 Wife
.因此,如果您想对真实的、 splinter 的世界进行建模,则不一定要了解这些信息。 最后,通常最好避免 NULLable 列。您可以通过创建一个新表(例如
Parentage
)来完成此操作。 :CREATE TABLE dbo.Parentage (
PersonID int NOT NULL
CONSTRAINT FK_Parentage_Person
FOREIGN KEY REFERENCES dbo.Person (PersonID),
ParentID int NOT NULL,
ParentIsMale bit NOT NULL,
CONSTRAINT PK_Parentage PRIMARY KEY CLUSTERED (PersonID, ParentIsMale),
CONSTRAINT FK_Parentage_Parent FOREIGN KEY (ParentID, ParentIsMale)
REFERENCES dbo.Person (ParentID, IsMale)
);
您必须在
(ParentId, IsMale)
上添加唯一约束或唯一索引。在 Person
表以便为其创建 FK。使用 IsMale
作为 PK/FK 的一部分,确保您只有一位母亲和一位父亲。虽然这种设计可能看起来很笨拙,但从长远来看,它会带来真正的好处。一个人的父亲或母亲的知识是通过插入一行而不是更新可空列来编码的。如果没有行,则父项未知。
这种设计也很容易适应记录不同类型的 parent :遗传、出生、收养。一个人可以有两个遗传 parent 和一个生母。然后通过一系列灾难性事件,所有 parent 都被杀害并被收养(甚至不止一次)。因此,您需要更改 PK 然后添加
ParentTypeID
, FromDate
, 和 ToDate
列到表中。需要进一步调整以限制不当关系的表述(例如“生父”)。
关于sql - 将数据插入 SQL Server 2012,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14018773/