0

4 つのテーブルを持つ MySQL データベースがあります。

job
job_application
client
candidate

job_id各テーブルには独自の主キーがありjob_application_idますclient_idcandidate_id

テーブル内の雇用者は、clientテーブルに求人を掲載できjobます。jobテーブルには、クライアントを識別するフィールドが含まれclient_idています

テーブル内の候補者は、candidateテーブルに行を挿入して仕事に応募できますjob_applicationjob_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_idはテーブルでのみ参照されるため、テーブルにアクセスするたびにテーブルにjobアクセスする必要がありますLEFT JOINjobUPDATEDELETEjob_application

client_idテーブルに別のフィールドを追加してjob_application、基本的にデータベースに既に保持されているデータを複製する必要がありますか、それともLEFT JOINfor everyUPDATEとを続行する必要がありDELETEますか?

4

2 に答える 2

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

3 つの列、ID 番号なし、NULL なし、非プライム属性なし、すべてキー。この関係は 6NF にあります。

最初の 2 つの列から個別の値を選択することで、求人 (または求人) のテーブルを作成できることは明らかです。外部キー参照は明らかです。

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 にあります。

自然キーに加えて代理キーを使用してテーブルを拡張しても、正しく行うと通常の形式は変わりません。「job_applications」の自然キーをサロゲート ID 番号に置き換えましょう。その置換を行うと、テーブルは次のようになります。(実際には、他のテーブルでも同じことを行います。)

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

client_id がすでにそこにあることに注意してください。他の列がない場合でも、少なくとも 5NF にいます。

于 2013-01-16T15:01:26.733 に答える
0

あなたの質問に答えるには、あなたのケース、特にテーブルのサイズが価値があるかどうかによって異なります。このプロセスは非正規化と呼ばれます。たとえば、ここで情報を得ることができます: http://en.wikipedia.org/wiki/Denormalization

于 2013-01-14T13:28:38.620 に答える