主键自动增量

时间:2013-01-22 17:46:36

标签: mysql

我有一个包含两个表的数据库,目前每个表有3列。

Table_A iduidurl

Table_B iduidurl

id是在插入的每个新行上按1自动递增的主键。

我的问题是我还需要主键吗?我永远不会在id查询数据库。 uid列只是为每个用户分隔,因此每行不是唯一的。 Table_A Table_B 经常会uid进行比较。 我已将uidurl编入索引,我希望该表能够以数十亿的速度增长,而且我不想在id上浪费空间。

3 个答案:

答案 0 :(得分:2)

如果您使用InnoDB,并且未声明主键列,InnoDB将使用6字节整数为您创建一个。因此,通过删除id列获得的唯一事情可能是为6字节隐式PK列交换8字节BIGINT。

原因是InnoDB表存储为B树,这是一个基于主键的聚簇索引。每个表必须有一个用于组织这个B树的列,即使它是一个隐式创建的列。

您还可以声明一个包含复合主键的表:

CREATE TABLE Table_A (
  uid INT NOT NULL,
  url VARCHAR(100) NOT NULL,
  PRIMARY KEY (uid, url)
);

在这种情况下,满足主键的要求,InnoDB不会创建隐式列。


重新评论:

我尽量不使用MyISAM。与InnoDB相比,MyISAM更容易受到数据损坏的影响,并且InnoDB通常表现更好,因为它会缓存数据和索引。确实有些情况下MyISAM可以使用更少的磁盘空间,但磁盘空间很便宜,而且我更愿意从InnoDB中获益。

关于索引,如果你有PRIMARY KEY(uid, url),那么你自动拥有这两列的复合索引。无需在uid上创建额外的索引。

但是如果你有查询单独搜索url而不查找特定的uid,那么你需要在url上有一个单独的索引。

我在演示文稿中详细介绍了索引设计:How to Design Indexes, Really

答案 1 :(得分:1)

技术上不行,虽然这是一种很好的做法,但你永远不知道未来的要求是什么。如果您最终需要一个唯一的id列而没有一列,则可能是一个令人头疼的问题。在我看来,id列上“浪费”的开销是绝对值得的。

此外,根据Table_ATable_b之间的关系,您最终可能会有一个中间表来定义它们之间的关系(例如one-to-nanymany-to-many )。对于此类方案中的高效查询,唯一的id列成为必需。

答案 2 :(得分:0)

您不需要id列,但在我看来,您的“主要”键是uid-url