2012-02-23 66 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