让我们举一个.on('changeDate', function(ev) {
checkout.hide();
})
表的示例,其中包含以下列:login
(主键),id
,username
,password
status
是主键,但我们仍然通过id
+ username
搜索表来验证用户身份。它是否违反了规范化规则?
另一个例子:假设我们有两个表,password
和employer
job
表的id在employer
表中用作外键,但job
表本身有自己的job
id
现在,当我们搜索雇主发布的职位时,我们使用job table
---------
id (primary key) || employer_id (foreign key) || etc etc
,但此表有主键吗?
答案 0 :(得分:0)
任何表上的主键都是唯一标识符,默认情况下编入索引。这并不意味着将始终通过该字段本身搜索记录。现在,当您要将父记录链接到子记录时,可以使用主键建立关系。
在尝试获取记录时,您将使用主键作为不同表之间的链接。例如,您有雇主和雇员。搜索可能看起来像:“让我这个雇主的所有员工”。现在,雇主是这里的主要实体,我们正在寻找相关的员工记录。在这里,雇主id将帮助我们获取相关记录。查询相同的内容可能会显示如下:
SELECT [COLUMN NAMES HERE]
FROM EMPLOYER INNER JOIN EMPLOYEE ON
EMPLOYER.ID = EMPLOYEE.EMPLOYERID
答案 1 :(得分:0)
我建议你阅读一些教程,但是,很快......主键是一个唯一且不为空的id,并在表中标识一个条目。外键是对另一个表中的id的引用。正如你所说,员工和工作表。在大多数情况下,id由序列生成,在插入记录之前您不知道它的值。 您通常通过用户名称的用户名,名称,...数据执行seraches。在您的情况下,当您搜索作业时,您可能会执行加入。连接是表之间的关系(并且有更多类型)。在你的情况下,你会做
select *
from employer emp inner join job jjj on emp.id = jjj.employer _id
当您必须更新/删除记录时,ID在代码方面是有用的。在这种情况下,通常你知道关于你的记录的所有内容,包括id,然后你将使用id(也因为id通常有索引,所以查询更快)。您通常可以在过滤器中使用的列中创建索引,以减少查询的执行时间。
答案 2 :(得分:0)
我们需要区分业务(或候选)密钥和技术(或代理)密钥。业务键是在现实世界中唯一标识此行的数据项。技术密钥是数据管理的便利,由某些计算机进程生成,例如序列或sys_guid()
。
是的,使用技术密钥意味着存储冗余信息,但这是实用性胜过理论的情况。主键不应该改变,但在现实生活中它们可以改变(例如,由于各种生活事件,人们改变了他们的名字)。技术密钥没有意义所以不要改变。业务密钥通常是复合密钥,这通常不便于强制执行外键(有时候非常不受欢迎,例如当业务密钥是敏感数据项,例如社会安全号码时)。
因此,表通常有一个ID列作为主键,用于外键关系,以及一个唯一约束来强制执行业务键。
在您的第一个示例中,username
是业务密钥,id
是技术密钥。这就是为什么我们应该有两个数据模型的原因之一。逻辑数据模型有一个名为user
的实体,其候选键为username
。物理数据模型有一个名为user
的表,主键为id
,唯一键为username
。
对于您的第二个示例,您似乎正在为Situations Vacant工作板建模。雇主和工作之间的关系是一对多的,雇主可以宣传许多工作。因此Job
表有自己的主键id
,外加一个引用employer_id
表主键的外键Employer
。这意味着我们可以找到特定雇主的所有工作。但由于job
表有自己的主键,我们可以识别每个作业,以便我们可以区分 Harrisons Pharmaceuticals 中的 Janitor 作业与 Janitor 在 Ravi's Cash'n'Carry 工作。 (顺便说一下我们需要技术密钥的原因:想象一下employer_id
外键是varchar2(128)
表中每一行的Job
字符串。)
在逻辑数据模型中,employer_id
在实体job
上通过指向实体employee
的链接暗示,但会显示(实际上是可能,这取决于工具)。在物理模型中,必须将列添加到从属表中,因为数据库约束(和连接!)在物理上需要列才能工作。
因此我们可以看到规范化适用于业务数据的表示和存储,但数据库引擎的实用性意味着我们需要额外的列来管理数据。