我有一个包含4个表的MySQL数据库:
job
job_application
client
candidate
每个表都有自己的主键,即job_id
,job_application_id
,client_id
,candidate_id
client
表中的雇主可以在job
表中发布职位。 job
表包含标识客户端的client_id
字段
candidate
表中的候选人可以申请工作,在job_application
表中插入一行。 job_application
表格包含job_id
字段和candidate_id
字段,用于标识作业是什么以及申请者是谁
我在为Employers编写查询以管理他们收到的作业应用程序时遇到了一些问题。作为一个例子,这里是我写的一个从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 JOIN
或{{job
时,我需要UPDATE
DELETE
表1}}来自job_application
表
我是否应该向client_id
表添加另一个job_application
字段,基本上复制数据库中已有的数据,或者为LEFT JOIN
和{{UPDATE
继续DELETE
1}}?
答案 0 :(得分: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号,没有空值,没有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。
答案 1 :(得分:0)
要回答你的问题,这取决于你的情况,特别是表的大小,如果它是值得的话。 此过程称为非规范化。 例如,你可以在这里获得信息: http://en.wikipedia.org/wiki/Denormalization