2013-01-14 51 views
0

我有一個MySQL數據庫與4個表:應關係表包含重複的數據,以加快查詢速度

job 
job_application 
client 
candidate 

每個表都有它自己的主鍵,即job_idjob_application_idclient_idcandidate_id

僱主在client表中可以在job表中發佈作業。該job表包含一個client_id字段,識別客戶端在candidate

考生可以申請工作,到job_application表中插入一行。該job_application表包含job_id場和candidate_id場以確定哪些工作是和誰申請就

我已經在運行了一下寫了查詢的問題的用人單位來管理他們收到的求職申請。此處作爲一例是一個功能我寫的,從job_application

public function deleteJobApplications($job_application_ids) { 
    $this->db->query("DELETE ja.* FROM " . DB_PREFIX . "job_application ja LEFT JOIN " . DB_PREFIX . "job j ON (j.job_id = ja.job_id) WHERE ja.job_application_id IN ('" . implode("','", array_map('intval', $job_application_ids)) . "') AND j.client_id = '" . (int)$this->client->getClientId() . "'"); 
} 

刪除行因爲client_idjob表只是引用,我需要LEFT JOINjob表我想UPDATEDELETEjob_application每次表

我應該另一client_id字段添加到job_application表,基本上是複製在數據庫中已經保存的數據,或者繼續LEFT JOIN爲每UPDATEDELETE

+0

爲了速度和複雜度最小化而擁有冗餘數據並非與數據庫無關關鍵是平衡 – amar

+0

我會說重複外鍵是提高數據庫性能的適當做法,您必須確保保留表是一致的。嘗試一些性能測試(大量的數據集),看看它是否對你有很大幫助 – x4rf41

+1

我認爲你應該檢查indexex,做一些「解釋」,我在+100m行的表上留下了連接,少於一毫秒平均值爲〜4ms),在一個體面的服務器上,而不是高科技。我不認爲你有那麼多行,左連接應該工作得很好。 –

回答

2

您的問題是不是你需要通過引入「CLIENT_ID」作爲冗餘列進行非規範化「job_applications」。 (目前接受的答案在這方面事實上是不正確的。)你的問題是你沒有正確地正常化。如果你,那麼「client_id」列將已經在該表中,並且你的問題永遠不會出現在第一位。

讓我們假設候選名稱,客戶端名稱和作業名稱是全局唯一的。

看起來像這樣的表格將滿足名爲「candidate_name」的人員在公司「client_name」處適用於「job_name」的謂詞。

job_applicatons 
Person named <candidate_name> applies for <job_name> at company <client_name>. 

client_name job_name    candidate_name 
-- 
Microsoft C++ programmer, Excel Ed Wood 
Microsoft C++ programmer, Excel Dane Crute 
Microsoft C++ programmer, Excel Vim Winder 
Microsoft C++ programmer, Word Wil Krug 
Microsoft C++ programmer, Word Val Stein 
Google  Python coder, search Ed Wood 
Google  Programmer, compilers Ed Wood 
Google  Programmer, compilers Val Stein 

三列,沒有id號,沒有null,沒有nonprime屬性,所有的鍵。這種關係在6NF。

很明顯,您可以通過從前兩列中選擇不同的值來創建工作(或工作機會)表。外鍵引用是顯而易見的。

jobs 
Company named <client_name> offers <job_name>. 

client_name job_name 
-- 
Microsoft C++ programmer, Excel 
Microsoft C++ programmer, Word 
Google  Python coder, search 
Google  Programmer, compilers 

以類似的方式,可以爲一組公司的選擇僅在第一列不同的值,然後單獨從最後一列一組申請人。再次,外鍵引用應該是顯而易見的。

clients 
Company named <client_name> is a client. 

client_name 
-- 
Microsoft 
Google 

candidates 
Person named <candidate_name> is looking for a job. 

candidate_name 
-- 
Ed Wood 
Dane Crute 
Vim Winder 
Wil Krug 
Val Stein 

所有這些表都在6NF。

除了其自然鍵之外,使用代理鍵增大表格的大小並不會改變正常形式。讓我們用您的代理ID號替換「job_applications」中的自然鍵。做出更換將導致你的桌子看起來像這樣。 (實際上,你也可以在其他表格中做同樣的事情。)

job_applications 
-- 
client_id 
job_id 
candidate_id 
primary key (client_id, job_id, candidate_id) 
other columns go here... 

請注意,client_id已經在那裏。如果沒有其他列,你仍然至少有5NF。

+0

我很欣賞你爲此付出的時間和精力,但它並沒有回答我應該向job_application表中添加另一個client_id以改進UPDATE和DELETE性能的問題嗎? – Andy

+0

如果您已將表格標準化爲5NF,那麼它已經在那裏了。請參閱上面的表格「job_applications」。 –

+0

好的......雖然還沒有真正回答我的原始問題。無論如何謝謝 – Andy

0

要回答你的問題,這取決於你的情況,特別是如果它是值得的表的大小。 這個過程被稱爲非規範化。 例如,你可以在這裏信息: http://en.wikipedia.org/wiki/Denormalization

+0

OP的問題不在於他需要對性能進行非規範化。問題在於他首先無法正確標準化。你也是。 –

+0

是的我沒有回答,問題的標題「關係表中是否包含重複數據以加速查詢」對我來說是誤導性的,我回答了非特定問題的標題,因此我回答了一個非特定答案那裏不需要。 –