Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/40.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何用最常用的约束来物理地表示父子关系?_Sql_Sql Server_Database Design_Sql Server 2012 - Fatal编程技术网

Sql 如何用最常用的约束来物理地表示父子关系?

Sql 如何用最常用的约束来物理地表示父子关系?,sql,sql-server,database-design,sql-server-2012,Sql,Sql Server,Database Design,Sql Server 2012,我有一对逻辑实体关系,必须经常出现 考虑两个实体Parent和Child。令人惊讶的是,每个父项至少有一个或多个子项 到目前为止很明显 此外,每个父项都有一个最喜欢的子项 我有一些限制或要求告知最佳解决方案 Child和Parent都有一个主键,它是一个标识列 解决方案必须(尽可能)加强诚信。我不想让没有孩子的父母、没有最爱的父母或孤儿 我想简单快速地找到父母最喜欢的孩子 我希望所有的孩子,包括最喜欢的孩子都住在同一张表中,这样我就可以在没有联合或加入的情况下搜索他们 我需要能够将数据插入表中

我有一对逻辑实体关系,必须经常出现

考虑两个实体
Parent
Child
。令人惊讶的是,每个
父项
至少有一个或多个
子项

到目前为止很明显

此外,每个
父项
都有一个最喜欢的
子项

我有一些限制或要求告知最佳解决方案

  • Child
    Parent
    都有一个主键,它是一个标识列

  • 解决方案必须(尽可能)加强诚信。我不想让没有孩子的父母、没有最爱的父母或孤儿

  • 我想简单快速地找到父母最喜欢的孩子

  • 我希望所有的孩子,包括最喜欢的孩子都住在同一张表中,这样我就可以在没有联合或加入的情况下搜索他们

  • 我需要能够将数据插入表中


这就是我的出发点


这满足了我的所有要求,但我不能插入数据。

这就是我要做的。这稍微放松了你的约束,但希望足够接近:

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
语句只能影响单个表,并且SQL Server不支持延迟约束。因此,你在“没有孤儿”和“没有孩子的父母”这两个问题上有鸡和蛋的问题@Damien_不信者,这就是我的处境,解决这个问题最好的办法是什么?我试图思考其他模式可能提供一个好的解决方案,显然,能够插入是很重要的。我会允许并没有孩子的父母存在。剩下的一切都很简单,没有这个限制。@Damien_不信者,这就是我上次提到的,我需要帮助记忆。如果您愿意,请回答。您是否尝试过用一条语句将OUTPUT子句插入到两个表中?像插入到父对象中一样。。。输出。。对于计算列上的Child…约束,我喜欢这个想法,它使插入更容易,并加强完整性。@Jodrell-如果您不想强制执行“除非至少有一个是最喜欢的”约束,那么您根本不需要计算列-您可以在Child(ParentID)上应用:
创建唯一索引IX\u Child\u收藏夹其中isfavorite=1
,并删除两个计算列。令人高兴的是,在ssame的时候,计算列可以用来实现“一个最喜欢的”和“没有孩子,除非一个最喜欢的”。
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