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

时间:2011-09-05 15:36:22

标签: sql database sql-server-2008

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

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

我希望有人可以帮助我。

很多你的帮助

更新 这就是目前的样子:

enter image description here

2 个答案:

答案 0 :(得分:3)

首先,有一个设计经验法则,表格可以模拟单个实体类型或实体类型之间的关系,但不能同时模拟两者。因此,我设想了三个表,Media(实体),Idea(实体)和IdeasMedia(关系)。附:你知道'媒体'的单数是'中等',对吧? :)

以下是一些仅关注密钥的标准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
                                        )
                     )
         );

这里有一个'鸡肉和鸡蛋'场景:如果没有引用IdeasMedia就无法创建一个想法,但如果没有创建IdeasMedia则无法创建Idea!< / p>

理想的(基于集合的)解决方案适用于SQL Standard以支持多个分配,例如

INSERT INTO Media (MediaID) VALUES (22), 
   INSERT INTO Idea (IdeaID) VALUES (55), 
   INSERT INTO IdeasMedia (MediaID, IdeaID) VALUES (22, 55);

其中分号表示检查约束点的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;

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

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

  • 创建'帮助'存储过程以添加,修改和删除Ideas及其各自的 IdeasMedia关系。
  • 从表中删除更新权限以强制用户使用 特效。
  • 删除Media和时,可能会使用触发器来处理方案 Idea个实体。

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

答案 1 :(得分:1)

您在 Media 中的{em> Idea 中为FK(主键)创建了PK(外键)。同时对FK应用NOT NULL约束。

如果表格中已有数据see here


举例说明:

Media               Idea
-----               ----
 id | type           id | description       | media_id
----+-----          ----+-------------------+----------
 1  | TV             90 |  advertise        | 2
 2  | Magazine       90 |  advertise        | 1
 3  | Mail           91 |  superbowl party  | 1
                     91 |  superbowl party  | 3

我不是说这是一个很棒的设计,我绝对不知道你的桌子存储的是什么(用我糟糕的例子表示),但这个想法不存在没有媒体条目链接到。没有来回连接,你要求的是1:N,而不是N:N,你可能想要它。

在考虑表名时,似乎你的想法是倒退的。我认为你会有1:Media to N:Ideas而不是相反。


CREATE TABLE idea (
    id        integer 
  , media_id  integer NOT NULL REFERENCES media
)  

--or--

CREATE TABLE idea (
    id         integer
  , media_id   NOT NULL
  , FOREIGN KEY (media_id) REFERENCES media
);

注意: 这不是规范化的,因此您需要第三个表来匹配联接。