我真的不知道如何标题。事情是,我是一个数据库的初学者,我想知道这是否是一个好习惯。
所以我的数据库中有一些类似于这些的表:
create table AAA(
id_aaa int not null auto_increment,
primary key (id_aaa)
);
create table BBB(
id_bbb int not null auto_increment,
id_aaa_AAA int not null,
primary key (id_bbb),
foreign key (id_aaa_AAA) references AAA (id_aaa)
);
create table CCC(
id_ccc int not null auto_increment,
id_aaa_AAA int not null,
id_bbb_BBB int not null,
primary key (id_ccc),
foreign key (id_aaa_AAA) references AAA (id_aaa),
foreign key (id_bbb_BBB) references BBB (id_bbb)
);
ERD:
AAA (1-n) BBB (1-n) CCC
可以在CCC中添加AAA的主键以获得“更快的可访问性”,因为我可以通过BBB访问吗?
答案 0 :(得分:1)
简短的回答是:不要这样做。你会冗余地存储数据,这可能会导致错误 - 如果id_aaa_AAA = 1的CCC记录指向id_aaa_AAA = 2的BBB记录,该怎么办?
答案很长:有自然键和人工(技术)键......
通常,您拥有识别实体的自然密钥(例如员工编号,国际项目编号等)。这是一个公司,员工和销售数据库。粗体列是自然键,可用作表的主键:
ILN(国际位置编号)唯一标识公司。
员工在公司中有员工编号。但它只与公司合并。 (即,A公司#123的员工当然是B公司员工#123以外的其他员工。)
员工一年的销售额是多少?记录由ILN +员工编号标识,以识别员工加上年份。
现在很多人更喜欢设计带有技术ID的数据库,因为他们发现这个概念更灵活,而且通常有些实体根本没有自然键(例如,地址只能通过其所有组件的总和来识别,所以你更喜欢创建一个人工ID来在其他表中引用它。这是具有技术ID的相同数据库:
此处每个表都有一个唯一的技术ID,通常是主键。 (当然,您对company(iln)
,employee(employee_no, company_id)
和sales(employee_id, year)
上的唯一约束仍然存在。)没有冗余,因此ILN仅存储在表公司中。如果您想在2015年获得公司的销售总额,则必须相应地查看所有表格。
使用上述自然键,你不会。您在所有表中都有ILN并且它仍然不会是多余的,因为它是所有表的密钥的一部分(即,如果您从员工或销售中删除了ILN,您将不知道记录所指的是哪个员工至)。在这里,您只能访问销售表,以获得2015年公司的销售总额。
我觉得使用自然键更舒服,但是正确设计这样一个数据库需要一些时间,而且如上所述,通常你仍然需要发明密钥,就像地址一样。但是数据访问通常更直接,即使使用深层次结构也无法保证数据一致性,而技术ID无法提供。
所以答案很长:决定是否要使用自然键。
答案 1 :(得分:0)
尽量在数据库中存储尽可能少的数据(即规范化您的数据)。
表CCC中的冗余信息只会让你困扰。如果更新BBB中的行以引用AAA中的新值,则您将有义务更新CCC中引用BBB中的行的所有行。在这个简单的例子中没有太大的交易,但是一旦你超过5个表格,这可能变得非常混乱,很难跟踪。