我正在与合同开发人员合作,他们开始创建表(MySQL)而没有定义主键。相反,他正在使用带有AUTO_INCREMENT的UNIQUE约束来定义列。我以前从未见过这个,所以我想了解以这种方式定义表的含义。 如果需要,一个缺点就是无法创建外键。以这种方式创建表有什么其他影响,无论好坏。也许我在这里错过了一个概念...
答案 0 :(得分:6)
在没有显式主键的情况下定义MySQL是一个非常糟糕的主意 如果缺少PK,MySQL将创建一个隐式(但非常真实)整数自动递增主键 此PK将包含在InnoDB中的每个辅助密钥中,并将确定MyISAM中的主要排序顺序。
<强>后果强>
您刚刚放慢了每个选择,插入和更新的性能
无所不能。
InnoDB:获取表数据需要额外查找
在InnoDB中,需要进行额外的查找,因为所有二级索引都引用PK而不是行本身。
MyISAM:浪费空间
在MyISAM中,惩罚并不是那么好,但是你仍然拖着一个未被使用的4字节未使用字段。
InnoDB + MyISAM:无用的自动增量字段生成
因为创建了隐式自动增量PK,并且还需要额外的自动增量键来进行连接;为了防止重复的自动增量字段,您现在每个插入没有1个,而是2个表锁。
InnoDB:加入上面提到的查找探测器加倍
如果使用不是PK的字段进行连接,InnoDB需要额外查找每个连接以获取该另一个表的记录。
InnoDB:最糟糕的是你失去了覆盖索引的好处
您已禁用InnoDB中最佳优化之一,涵盖索引
如果MySQL只使用索引中的数据来解析查询,它将永远不会读取表,这将导致显着的速度增益。现在,InnoDB中每个索引的50%都是未使用的空间,您只是没有使用该优化的机会。
请用线索棒击败这个承包商!
链接:
http://www.xaprb.com/blog/2006/07/04/how-to-exploit-mysql-index-optimizations/(慢速链接,但建议阅读)
O'Reilly on InnoDB's covering indexes
http://tag1consulting.com/MySQL_Engines_MyISAM_vs_InnoDB
BTW ,如果你的承包商说,这没关系,因为他正在使用MyISAM,再次击败他,除非你有充分的理由,否则你应该总是使用InnoDB。
InnoDB在生产方面更加安全,MyISAM有其用途,但很容易被破坏。
答案 1 :(得分:0)
这不会阻止外键,但会影响使用该字段的查询的性能。只要您必须查询表并指定一些条件来根据列的值(例如WHERE子句)过滤记录,就应该使用索引。
答案 2 :(得分:-1)
主键只是一个结合NOT NULL约束的唯一索引,如果你在没有PK的情况下满足这些要求,那么在性能方面没有任何损害,当然它仍然没有多大意义,因为它将是混乱。