2011-09-05 138 views
6

您好,我有一个关于数据库设计的简短问题。我也试过搜索,但找不到我在找什么。所以这里是我的问题:1:N关系,其中N必须至少有一个条目

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

我希望有人能帮助我。

THX很多的帮助

UPDATE: 这是它看起来像此刻:在想法

enter image description here

+2

我不知道如何将'Media'保存在单独的表格中:如何插入数据?你必须首先插入一个表格,然后插入第二个表格。你可以尝试的是将第一个'Media'放入'Idea'(去规范化)并声明这些字段为'not null' - 但我不会推荐它。用代码中的某些逻辑而不是数据库可能会更好。 –

+0

我同意Aleks。我认为这是一个属于中间层的业务规则,不在数据库中。 – David

+0

@Aleks将FK NOT NULL从Idea添加到Media并不少见。这很简单,是的,他需要首先填充媒体。 – vol7ron

回答

2

首先,有一种设计经验法则,即表格模拟单个实体类型或实体类型之间的关系,但不是两者都建模。因此,我设想了三个表,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

理想的(基于集合的)解决方案将用于SQL标准以支持多种分配,例如,

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 ASSERTION也不CHECK约束可以参照其他表,也没有延迟约束!

  • 创建“帮手”存储的特效的添加,修改和删除Ideas及其各自 IdeasMedia关系:

    就个人而言,我会在SQL Server如下处理这个问题。

  • 删除表中的更新权限以强制用户使用 procs。
  • 当删除MediaIdea实体时,可能使用触发器来处理场景。 1..1关系,而是:

当然,这(再次程序)实现远基于集合的理想的方法,这或许可以解释为什么大多数SQL程序员视而不见的需求为1移除假设设计师意味着1:0..N!

+0

嘿onedaywhen谢谢你真的很棒的回答!您的答案非常广泛,并描述了针对我的问题实现解决方案的不同方法。我真的很感激。即使如此,所有的解决方案都非常难看。我决定在我的业务逻辑中处理这个问题。而thx为语法修正;) – MUG4N

1

您创建一个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 

我并不是说这是伟大的设计,我绝对不知道你是什么表正在存储(由我的不好的例子表示),但这个想法不能存在w/o媒体条目链接到。没有来回的链接,你要求1:N,而不是N:N,你可能想要。

想到表名时,好像你的想法倒退了。我想你会有1:媒体对N:想法而不是其他方式。


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 
); 

注:这不是标准化的,所以你需要第三个表以匹配联接。

+1

所以这两个表有彼此的外键?这可能会有点奇怪吗?它也遭受Aleks G.指定的“鸡和蛋”问题。 – David

+0

这意味着交叉引用...我听说过交叉引用的坏消息。这是一种常见的最佳做法吗?或者有这种情况的一些最佳实践? – MUG4N

+0

@David你是什么意思,你为什么要FK去海誓山盟,只有一个方法FK从想法到媒体 – vol7ron