1:N关系,其中N必须至少为一个条目

MUG*_*G4N 6 sql database sql-server-2008

您好,我有一个关于数据库设计的简短问题.我也试过搜索但找不到我要找的东西.所以这是我的问题:

我有两个数据库表IdeaMedia(1:N).所以基本上这意味着一个想法可以没有,一个或几个媒体.但我问自己是否有可能定义每个想法必须至少有一个媒体的表格.如果可以,我怎样才能用MS SQL Server 2008实现这一目标?

我希望有人可以帮助我.

很多你的帮助

更新: 这就是目前的样子:

在此输入图像描述

one*_*hen 3

首先,有一个设计经验法则,即表可以对单个实体类型或实体类型之间的关系进行建模,但不能对两者进行建模。因此,我设想三个表,Media(实体)、Idea(实体)和IdeasMedia(关系)。PS你知道“media”的单数是“medium”,对吧?:)

以下是一些仅关注键的标准 SQL-92 DDL:

CREATE TABLE Media (MediaID INTEGER NOT NULL UNIQUE);
CREATE TABLE Idea (IdeaID INTEGER NOT NULL UNIQUE);
CREATE TABLE IdeasMedia 
(
 MediaID INTEGER NOT NULL REFERENCES Media (MediaID), 
 IdeaID INTEGER NOT NULL REFERENCES Idea (IdeaID)
);
CREATE ASSERTION Idea_must_have_media DEFERRABLE 
   CHECK (
          NOT EXISTS (
                      SELECT * 
                        FROM Idea AS i 
                       WHERE NOT EXISTS (
                                         SELECT * 
                                           FROM IdeasMedia AS im 
                                          WHERE im.MediaID = i.IdeaID
                                        )
                     )
         );
Run Code Online (Sandbox Code Playgroud)

这里有一个“先有鸡还是先有蛋”的情况:如果没有引用就无法创建想法IdeasMedia,但如果没有创建就无法IdeasMedia创建Idea

理想的(基于集合的)解决方案是 SQL 标准支持多重赋值,例如

INSERT INTO Media (MediaID) VALUES (22), 
   INSERT INTO Idea (IdeaID) VALUES (55), 
   INSERT INTO IdeasMedia (MediaID, IdeaID) VALUES (22, 55);
Run Code Online (Sandbox Code Playgroud)

其中分号表示检查约束的 SQL 语句边界,逗号表示子语句。

遗憾的是,没有计划将这种基于集合的范例添加到 SQL 标准中。

SQL-92(过程)解决方案如下:

BEGIN TRANSACTION;
INSERT INTO Media (MediaID) VALUES (22);
SET CONSTRAINTS Idea_must_have_media DEFERRED;
-- omit the above if the constraint was declared as INITIALLY DEFERRED.
INSERT INTO Idea (IdeaID) VALUES (55);
INSERT INTO IdeasMedia (MediaID, IdeaID) VALUES (55, 22);
SET CONSTRAINTS Idea_must_have_media IMMEDIATE;
-- above may be omitted: constraints are checked at commit anyhow.
COMMIT TRANSACTION;
Run Code Online (Sandbox Code Playgroud)

遗憾的是,SQL Server 不支持CREATE ASSERTIONCHECK引用其他表的约束,也不支持可延迟的约束!

就我个人而言,我会在 SQL Server 中按如下方式处理此问题:

  • 创建“helper”存储过程以添加、修改和删除Ideas及其各自的 IdeasMedia关系。
  • 从表中删除更新权限以强制用户使用过程。
  • 可能使用触发器来处理删除实体时的Media场景 Idea

当然,这种(又是过程性的)实现与理想的基于集合的方法相去甚远,这可能解释了为什么大多数 SQL 编码人员对 1:1..N 关系的要求视而不见,而是假设设计者的意思是 1: 0..N!!