2012-02-23 42 views
7

假设我们有以下实体:钻石模式:如何规范化?

  • 制作工作室
  • 记者
  • 摄像机操作
  • 新闻素材

在这个简单的世界,制作工作室有很多记者和许多相机操作员。每位记者都属于一个工作室。运营商也是如此。新闻片段是由一名记者和一名运营商制作的,这两名记者都来自同一工作室。

这里是我的幼稚的方法来把这个模型到关系数据库:

CREATE TABLE production_studios(
    id     SERIAL PRIMARY KEY, 
    title    TEXT NOT NULL 
); 

CREATE TABLE journalists(
    id     SERIAL PRIMARY KEY, 
    name     TEXT NOT NULL, 
    prodution_studio_id INTEGER NOT NULL REFERENCES production_studios 
); 

CREATE TABLE camera_operators(
    id     SERIAL PRIMARY KEY, 
    name     TEXT NOT NULL, 
    production_studio_id INTEGER NOT NULL REFERENCES production_studios 
); 

CREATE TABLE news_footages(
    id     SERIAL PRIMARY KEY, 
    description   TEXT NOT NULL, 
    journalist_id  INTEGER NOT NULL REFERENCES journalists, 
    camera_operator_id INTEGER NOT NULL REFERENCES camera_operators 
); 

此架构形式很好形钻石ERD和几个问题。

问题是,新闻片段可以将来自不同制作室的摄影师与记者联系在一起。我知道这可以通过编写相应的约束条件来解决,但为了实验的目的,我们假装我们在Normal Form数据库设计中进行了练习。

  1. 第一个问题是关于术语:是否正确地声明这个模式是非规范化的?如果是的话,哪种正常形式会破坏?或者是否有这个异常的更好名称,如记录间冗余,多路径关系等?

  2. 如何更改此模式以使描述的异常不可能?

当然,我非常感谢参考论文解决这个特定问题。

回答

3

天真的方式是让你的记者和摄影师操作员依赖实体,依赖于他们工作的工作室。这意味着制作室的外键成为其主键的一部分。你news_footage表则具有由4种成分组成的主键:

  • production_studio_id
  • journalist_id
  • camera_operator_id
  • footage_id

和两个外键:

  • journalist_id ,production_studio_id,po inting给记者发表,
  • camera_operator,production_studio_id,指着摄像机操作表

容易。

还是不是。现在,您已经在您的E-R模型中定义了相机操作员或记者的存在的概念取决于其工作室。这并不能很好地反映真实的工作:在这个模型中,人们不能改变他们的雇主。

我们不要那样做。

在你原来的模式,你混淆一个与他们玩一个_role(记者或相机操作),以及你缺少一个有点短暂的实体是用于生产的新闻素材的实际负责:在[特定工作室]制作团队。

我的ER模型将是这个样子:

create table studio 
(
    id int not null primary key , 
    title varchar(200) not null , 
) 

create table person 
(
    id int not null primary key , 
    title varchar(200) not null , 
) 

create table team 
(
    studio_id   int not null , 
    journalist_id  int not null , 
    camera_operator_id int not null , 

    primary key (studio_id , journalist_id , camera_operator) , 

    foreign key (studio_id   ) references studio (id) , 
    foreign key (journalist_id  ) references person (id) , 
    foreign key (camera_operator_id) references person (id) , 

) 

create table footage 
(
    studio_id   int not null , 
    journalist_id  int not null , 
    camera_operator_id int not null , 
    id     int not null , 
    description  varchar(200) not null , 

    primary key (studio_id , journalist_id , camera_operator_id , id) , 

    foreign key  (studio_id , journalist_id , camera_operator_id) 
    references team (studio_id , journalist_id , camera_operator_id) , 

) 

现在你有一个世界里,人们可以在不同的角色工作:同一个人可能在某些情况下和一名记者的相机操作在其他地方。人们可以改变雇主。特定工作室的团队由一名记者和一名摄影师组成。在某些情况下,同一个人可能在一个团队中扮演这两个角色。最后,一个新闻片段是由一个且只有一个工作室特定的团队制作的。

这反映了现实世界好得多,而且它更加灵活。

编辑补充样本查询:

要找到记者工作的特定演播室:

select p.* 
from studio s 
join team t on t.studio_id = s.id 
join person p on p.id  = t.journalist_id 
where s.title = 'my desired studio name' 

这将使你的一组人谁是(或有)已经用一个工作室相关在记者的角色。但应该注意的是,在现实世界中,人们在一段时间内为雇主工作:为了正确建模您需要一个开始/结束日期,并且您需要用现在的相对概念来限定查询。

+0

你正在创造完美点。事实上,我错过了人和他/她的角色。 – 2012-02-23 20:33:51

+0

你在说得很完美,谢谢。事实上,我错过了人和他/她的角色。但现在,记者属于一个工作室的唯一方法是与操作员组成一个团队。假设记者(和运营商)受制于工作室(在我的例子中,由FK表示)。鉴于这个新的模式,我如何找到哪些记者被特定工作室聘用? – 2012-02-23 20:47:36

+0

@SergeBalyuk:看到我修正的答案。 – 2012-02-23 21:11:57