mysql主键问题

时间:2011-02-20 02:48:33

标签: mysql

在3个或4个字段上拥有主键的最佳效果如何?如果表中有数百万条记录,那么在运行查询的服务器上是否会很重:例如:

Select * from my_table where field1='123' and field_2='123' and field_3='hours'

在这些字段上创建主键: field_1 int(11) field_2 int(11) field_3 varchar(20)

我正在考虑做的另一种选择是让这些字段将数据与主键存储在一个单独的字段上,该字段具有数据的md5哈希值,例如“md5(field_1 +' - '+ field_2 +' - '+ field_3)然后我的脚本只查询一个字段,如:

Select * from my_table where field_hash=MD5('123-123-hours')

所以基本上我只是想知道方法1是否与方法2一样最优,并且表中包含数百万条记录。

3 个答案:

答案 0 :(得分:1)

我说你最好的选择是使用代理自动递增字段作为PK。如果没有,我只会使用这三个字段。

md5哈希似乎不值得复杂。在任何情况下,我都没有看到该方法的好处。不要试图超越数据库引擎。如果散列确实更快,那么索引引擎将在内部以复合键的方式实现。它不是,应该告诉你一些事情。

使用代理键可以获得更快的连接,当您的查询只返回属于主键(覆盖索引)的字段时,使用复合键可以获得一些性能优势。

答案 1 :(得分:0)

您可以从问题Composite Primary Key performance drawback in MySQL

的答案中了解复合键的效果

在进行这种优化之前,您应该始终测量效果。也就是说,创建两个具有相同数据的表,一个使用复合键,另一个使用散列,并尝试哪一个在您的用例中更好用。

一般来说,如果不是绝对必要,我不喜欢使用荒谬的键值。如果将哈希用作主键,则意味着数据库的用户必须知道ID生成过程。这会导致更多文档,无法读取,以及长期错误。

如果有可能进一步规范化您的数据库,而不是使用您可能想要查看的复合键。复合键是否表示不同的实体,它是否应该实际形成第二个表,您可以在其中将代理键附加到列集?

另一种选择是在当前表中使用代理键,然后将唯一约束放在当前复合键上,例如

create table 
   id int(11) primary key,
   field1 int(11), 
   field_2 int(11), 
   field_3 varchar(20), 
   constraint uq_composite unique (field1, field_2, field_3);

答案 2 :(得分:0)

我会尽量避免使用非顺序主键(即字符串或随机生成的数字),因为这会导致磁盘上的I / O更多,并降低某些存储引擎(尤其是MyISAM)的性能。