我们在设计新数据密集型项目的主键时遇到了技术问题。
请解释一下我们的数据密集型数据库哪种PK设计更好。
请从技术上告诉我们哪种类型的PK对我们的数据库更好,并且表格在将来不太可能改变。
1.INT/BIGINT自动增量列为PK
2.Composite keys。
3.Unique varchar PK。
答案 0 :(得分:3)
我会选择1,使用BIGINT自动增量柱作为PK。原因很简单,每次写入都会写到当前页面的末尾,这意味着插入新行非常快。如果您使用复合键,那么您需要一个订单,除非您按照复合键的顺序插入,否则您需要拆分要插入的页面,例如想象一下这张桌子:
A | B | C
---+---+---
1 | 1 | 4
1 | 4 | 5
5 | 1 | 2
如果主键是(A,B,C)上的复合键,假设我要插入(2,2,2),则需要按如下方式插入:
A | B | C
---+---+---
1 | 1 | 4
1 | 4 | 5
2 | 2 | 2 <----
5 | 1 | 2
这样群集密钥维持其顺序。如果您已经插入的页面已经填满,那么MySQL将需要拆分页面,将一些数据移动到新页面以便为新数据腾出空间。这些页面拆分非常昂贵,所以除非你知道你正在插入顺序数据,然后使用自动增量列作为聚类键意味着除非你搞乱增量,否则你不应该拆分页面。
您仍然可以为将成为维护完整性的主键的列添加唯一索引,但是对于索引上的拆分仍然存在相同的问题,但由于索引将比聚簇索引更窄,因此拆分将随着更多数据适合页面而不那么频繁。
或多或少相同的参数适用于唯一的varchar列,除非您有某种过程确保varchar是顺序的,但生成顺序varchar比自动增量列更昂贵,我看不到直接的优势
答案 1 :(得分:1)
这不容易回答。
首先,使用复合键作为主键是直截了当的方式。当数据库结构发生变化时,ID会派上用场。
假设您在不同国家/地区销售不同尺寸的产品。主键是粗体。
数据非常容易,因为您正在处理自然键,这是用户使用的。 dbms保证了数据的一致性。
现在与技术ID相同:
在插入数据时,获取ID是现在需要的额外步骤。您仍然必须确保product_no是唯一的。因此,product_id上的唯一约束不会替换product_no上的约束,但会增加它。对于product_size,product_country和product_size_country也是如此。此外,product_size_country现在可以链接到不同产品的product_country和product_size_country。 dbms不能再保证数据的一致性。
但是,必须在更改数据库结构时,自然键有其弱点。让我们说数据库中引入了一家新公司,产品编号只对每家公司都是唯一的。使用基于ID的数据库,您只需将公司ID添加到products表中即可完成。在基于自然密钥的数据库中,您必须将公司添加到所有主键。还有更多工作要做。 (但是,必须经常对数据库进行此类更改。在许多数据库中永远不会。)
还有什么需要考虑的?当数据库变大时,您可能希望对表进行分区。使用自然键,您可以对所述公司进行分区,假设您通常希望从一个公司或另一个公司中选择数据。使用ID,您将对表进行分区以增强访问权限?
嗯,这两个概念肯定都有利有弊。关于创建唯一varchar的第三个选项,我认为使用整数ID没有任何好处。