简体   繁体   English

MySQL-升级主键?

[英]MySQL - Escalate Primary Keys?

I don't really know how to title this. 我真的不知道该如何命名。 The thing is i'm a begginer with databases in general and i was wondering if this is a good habit. 问题是我通常是数据库的入门者,我想知道这是否是一个好习惯。

So i have some tables in my DB similar to this ones: 所以我的数据库中有一些类似于此的表:

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: ERD:

AAA (1-n) BBB (1-n) CCC

Is it ok to add AAA's primary key in CCC for "faster accessibility" since i could access through BBB? 可以在CCC中添加AAA的主键以实现“更快的访问性”,因为我可以通过BBB进行访问吗?

The short answer is: Don't do this. 简短的答案是:不要这样做。 You would store data redundantly which may some time lead to errors - what if sudenly a CCC record with id_aaa_AAA = 1 points to a BBB record with id_aaa_AAA = 2? 您将冗余地存储数据,这可能会导致一段时间的错误-如果突然将id_aaa_AAA = 1的CCC记录指向id_aaa_AAA = 2的BBB记录怎么办?

The long answer is: There are natural keys and artificial (technical) keys... 长答案是:有自然键和人工(技术)键...

Often you have natural keys identifying an entity (such as an employee number, an international item number, etc.). 通常,您具有用于标识实体的自然键(例如员工编号,国际物料编号等)。 Here is a database of companies, employees and sales. 这是公司,员工和销售的数据库。 The bold columns are the natural keys, which can be used as primary keys for the tables: 粗体列是自然键,可用作表的主键:

  • company ( iln , company_name, ...) 公司( iln ,company_name,...)

The ILN (International Location Number) uniquely identifies a company. ILN(国际位置编号)唯一标识一家公司。

  • employee ( iln, employee_no , employee_name, ...) 员工( iln,employee_no ,employee_name等)

An employee has an employee number in their company. 员工在公司中有员工编号。 But it's only unique in combination with the company. 但是,只有与公司结合才能实现。 (Ie an employee with #123 in company A is someone else than employee #123 in company B of course.) (也就是说,公司A中拥有#123的员工当然不是公司B中具有#123的员工。)

  • sales ( iln, employee_no, year , total) 销售( iln,employee_no,year ,total)

How much did an employee sell in a year? 一名员工一年卖多少钱? A record is identified by ILN + employee number to identify the employee plus the year. ILN +员工编号标识一条记录,以标识该员工加上年份。

Now many people prefer to design a database with technical IDs, because they find the concept more flexible, and often there are entities that simply have no natural key (eg an address is only identified by the sum of all its components, so you'd prefer to create an artificial ID to reference it in other tables). 现在,许多人喜欢设计带有技术ID的数据库,因为他们发现概念更灵活,而且通常有些实体根本没有自然键(例如,地址仅由其所有组成部分的总和来标识,因此您会倾向于创建一个人工ID以在其他表格中引用它)。 Here is the same database with technical IDs: 这是具有技术ID的相同数据库:

  • company ( company_id , iln, company_name, ...) 公司( company_id ,iln,company_name,...)
  • employee ( employee_id , employee_no, employee_name, company_id, ...) 员工( employee_id ,employee_no,employee_name,company_id等)
  • sales ( sales_id , employee_id, year, total) 销售( sales_id ,employee_id,年份,总计)

Here each table has a unique technical ID, which is usually the primary key. 在这里,每个表都有一个唯一的技术ID,通常是主键。 (Of course you would also have a unique constraint on company(iln) , on employee(employee_no, company_id) and on sales(employee_id, year) still.) There is no redundancy, so the ILN is stored in table company only. (当然,您对company(iln)employee(employee_no, company_id)sales(employee_id, year)都有唯一的约束。)没有冗余,因此ILN仅存储在表company中。 If you want the sum of sales for a company in 2015, you'll have to go through all the tables accordingly. 如果要获得一家公司2015年的销售总额,则必须相应地浏览所有表格。

With the aforementioned natural keys you wouldn't. 使用上述自然键,您将不会。 You'd have the ILN in all tables and it still wouldn't be redundant, as it is part of the key of all tables (ie if you removed the ILN from employee or sales, you wouldn't know which employee a record refers to). 您将在所有表中都有ILN,并且它仍然不是多余的,因为它是所有表键的一部分(即,如果您从员工或销售人员中删除了ILN,您将不知道记录引用的是哪个员工至)。 Here you'd only access the sales table in order to get the sum of sales for a company in 2015. 在这里,您仅访问sales表以获取公司2015年的销售总额。

I find working with natural keys more comfortable, but it takes some time to design such a database properly, and often you'd still have to invent keys, as for adresses, as mentioned. 我发现使用自然键会更舒适,但是正确地设计这样的数据库需要花费一些时间,而且如上所述,经常您仍然需要发明密钥,例如地址。 But data access is often more straight-forward and data consistency is guaranteed even with deep hierarchies, which technical IDs cannot provide. 但是,即使使用技术ID无法提供的深层次结构,数据访问也通常更为直接,并且可以保证数据的一致性。

So the long answer is: Decide whether you want to use natural keys. 所以长的答案是:决定是否要使用自然键。

Try to store as little data a possible in your data base (ie normalize your data). 尝试在数据库中存储尽可能少的数据(即规范化数据)。

Having the redundant information in table CCC will only come back to haunt you. 在表CCC中具有冗余信息只会再次困扰您。 If you update a row in BBB to reference a new value in AAA you will then be obliged to update all rows in CCC that reference the row in BBB as well. 如果您更新BBB中的行以引用AAA中的新值,则必须更新CCC中所有引用BBB中的行的所有行。 In this simple example not too big a deal, but once you grow beyond 5 tables this can become very messy and hard to keep track of. 在这个简单的示例中,没什么大不了的,但是一旦您超过了5张桌子,这将变得非常混乱且难以跟踪。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM