我有一对必须合理频繁出现的逻辑实体关系。
考虑两个实体Parent
和Child
。不可思议的是,每个Parent
至少有一个或多个Children
。
到目前为止显而易见。
此外,每个Parent
只有一个收藏 Child
。
我有一些限制或要求可以告知最佳解决方案,
Child
和Parent
都有一个主键,即一个Indentity列。
解决方案必须尽可能强化诚信。我不想让没有孩子的父母,没有最爱或孤儿的父母。
我想简单快捷地访问父母最喜欢的孩子。
我希望所有的孩子,包括最爱的孩子都在同一张桌子上,所以我可以在没有工会或加入的情况下搜索他们。
我需要能够在表格中插入数据。
这是我从fiddle here
开始的地方CREATE TABLE [Parent]
(
[Id] INT NOT NULL IDENTITY,
[FavouriteChildId] INT NOT NULL,
[Other] NVARCHAR(MAX) NOT NULL,
CONSTRAINT [PK_Parent] PRIMARY KEY ([Id])
);
CREATE TABLE [Child]
(
[Id] INT NOT NULL IDENTITY,
[ParentId] INT NOT NULL,
[Other] NVARCHAR(MAX) NOT NULL,
CONSTRAINT [PK_Child] PRIMARY KEY ([Id]),
CONSTRAINT [FK_Child_Parent]
FOREIGN KEY ([ParentId]) REFERENCES [Parent]([Id])
);
ALTER TABLE [Parent]
ADD CONSTRAINT [FK_Parent_FavouriteChild]
FOREIGN KEY ([FavouriteChildId]) REFERENCES [Child]([Id]);
除了我无法插入数据外,这满足了我的所有要求。
答案 0 :(得分:1)
这就是我要做的。对你的约束略微放松,但希望足够接近:
CREATE TABLE [Parent]
(
[Id] INT NOT NULL IDENTITY,
[Other] NVARCHAR(MAX) NOT NULL,
CONSTRAINT [PK_Parent] PRIMARY KEY ([Id])
);
CREATE TABLE [Child]
(
[Id] INT NOT NULL IDENTITY,
[ParentId] INT NOT NULL,
IsFavourite bit not null,
FavouriteMarker as CASE WHEN IsFavourite = 1 THEN 1 ELSE -Id END persisted,
FavouriteRef as CASE WHEN IsFavourite = 0 THEN 1 END persisted,
[Other] NVARCHAR(MAX) NOT NULL,
CONSTRAINT [PK_Child] PRIMARY KEY ([Id]),
CONSTRAINT [FK_Child_Parent]
FOREIGN KEY ([ParentId]) REFERENCES [Parent]([Id]),
CONSTRAINT UQ_Child_Favourite UNIQUE (ParentID,FavouriteMarker),
CONSTRAINT FK_Child_FavouriteReference FOREIGN KEY (ParentID,FavouriteRef)
references Child (ParentID,FavouriteMarker)
);
和一些陈述来运用这些表格:
insert into Parent (Other) values ('ABC'); --We'll assume this gets assigned ID 1
insert into Child (ParentId,IsFavourite,Other) values (1,0,'def') --Fails - no favourite child yet
insert into Child (ParentId,IsFavourite,Other) values (1,1,'ghi') --Succeeds
insert into Child (ParentId,IsFavourite,Other) values (1,1,'jkl') --Fails - no second favourite
insert into Child (ParentId,IsFavourite,Other) values (1,0,'mno') --Succeeds
insert into Child (ParentId,IsFavourite,Other) values (1,0,'pqr') --Succeeds
update Child set IsFavourite =
CASE WHEN Other = 'mno' THEN 1 ELSE 0 END
where Other in ('ghi','mno') --Succeeds, favourite changed
delete from Parent where Id = 1 --Fails - no orphans
所以它确实允许无子女的父母存在,并且没有最喜欢的孩子的唯一父母正是那些没有孩子的父母。为特定父级添加子级的第一个INSERT
可能是多行插入,但必须包含一个(并且恰好一个)标记为收藏的子级。此后,可以更改收藏夹。