c# - MySQL - 升级主键?

标签 c# mysql sql database

我真的不知道怎么给它起标题。问题是我是一般数据库的初学者,我想知道这是否是一个好习惯。

所以我的数据库中有一些与此类似的表:

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

因为我可以通过 BBB 访问,所以可以在 CCC 中添加 AAA 的主键以“更快地访问”吗?

最佳答案

简短的回答是:不要这样做。您会冗余地存储数据,这有时可能会导致错误 - 如果 id_aaa_AAA = 1 的 CCC 记录突然指向 id_aaa_AAA = 2 的 BBB 记录怎么办?

长答案是:有自然键和人工(技术)键...

通常您有识别实体的自然键(例如员工编号、国际项目编号等)。这是公司、员工和销售的数据库。粗体列是自然键,可以用作表的主键:

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

ILN(国际位置编号)是一家公司的唯一标识。

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

员工在其公司中有一个员工编号。但它只有在与公司结合时才是独一无二的。 (也就是说,A 公司的 #123 员工当然不是 B 公司的 #123 员工。)

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

一名员工一年的销售额是多少?记录由 ILN + 员工编号标识,以标识员工加上年份。

现在很多人更喜欢用技术 ID 来设计数据库,因为他们发现这个概念更灵活,而且经常有一些实体根本没有自然键(例如,地址仅由其所有组件的总和来标识,所以您更愿意创建一个人工 ID 以在其他表中引用它)。这是具有技术 ID 的同一个数据库:

  • 公司(company_id, iln, company_name, ...)
  • 员工(employee_id,employee_no,employee_name,company_id,...)
  • 销售额(sales_id、employee_id、年份、总计)

这里每个表都有一个唯一的技术ID,通常是主键。 (当然,您还会对 company(iln)employee(employee_no, company_id)sales(employee_id, year) 设置唯一约束code> still.) 没有冗余,因此 ILN 仅存储在表 company 中。如果您想要一家公司 2015 年的销售额总和,则必须相应地浏览所有表格。

使用上述自然键,您不会。您在所有表中都有 ILN,它仍然不会是多余的,因为它是所有表的键的一部分(即,如果您从 employee 或 sales 中删除 ILN,您将不知道记录指的是哪个员工到)。在这里,您只需访问销售额表即可获得一家公司 2015 年的销售额总和。

我发现使用自然键更舒服,但是正确设计这样的数据库需要一些时间,而且您通常仍然需要发明键,就像前面提到的地址一样。但数据访问通常更直接,即使在深层层次结构下也能保证数据一致性,而技术 ID 无法提供这一点。

所以长答案是:决定是否要使用自然键。

关于c# - MySQL - 升级主键?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35401148/

相关文章:

MySQL - 计算按国家分组的男性和女性人数

sql - 如何通过db.query在sqlite中使用BETWEEN

c# - C# sqlite 中的多线程

mysql - SQL : selection of specific value outputs

php - print_r() 函数返回 diff 算法的简单结果 "Array"

mysql - 将多行合并为一列

sql - 在 postgresql JSON 中添加列

c# - 为什么具有可为空返回类型的 Func 不适合保存具有对象返回类型的 Func 的字典?

c# - 返回实现相同接口(interface)的不同泛型

c# - 将长度不等的列写入 CSV