2013-01-22 171 views
2

我有一个数据库有两个表,每个当前有3列。主键自动增量

表-Aiduidurl

表-Biduidurl

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

我有的问题是我还需要一个主键。我永远不会查询数据库的iduid列简单地分隔每个用户,因此它不是每行唯一的。 Table_A and Table_B经常会被uid比较。 我有uid,url索引,我希望桌子在数十亿中可能增长,我不想在id上浪费空间。

+0

在RDBMS中的所有表需要一个主键。然而,它不需要是一个专用的('代理'),自动递增的id。它可以是在表中的一列或多列上形成的“自然”键,或者(取决于数据库引擎)两者的组合! – Strawberry

回答

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。 MyISAM比InnoDB更容易遭受数据损坏,通常InnoDB的性能更好,因为它缓存了数据和索引。确实有些情况下MyISAM可以使用更少的磁盘空间,但是磁盘空间很便宜,我更愿意从InnoDB中获益。

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

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

我更多地谈论的索引设计在我的介绍:How to Design Indexes, Really

+0

优秀的比尔,感谢技术细节 – Madbreaks

+0

谢谢+1的例子。我在辩论使用innodb或myisam。将会有很多uid比较数据。我注意到,如果我使用myisam,桌子大小会下降3分钟然后innodb。 –

+0

@Madbreaks我还应该添加索引到uid和url吗? –

0

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

+0

我将使用像这样的查询'WHERE uid ='$ uid'AND url ='$ url''你是正确的,那么永远不会有两行由uid-url相同,我将如何使这个主键? –

+1

@AbbyE在create语句中:'PRIMARY KEY(uid,url)' – Neal

1

技术上来讲是没有,但它是很好的做法,你永远不知道你的未来的需求是什么。如果你最终需要一个独特的id列,并且没有一个,它可能是一个主要的头痛。在我看来,id专栏的“浪费”的开销量绝对值得。

此外,取决于Table_ATable_b之间的关系,则最终可能会具有中介表以限定它们之间的(例如one-to-nanymany-to-many)的关系。对于这种情况下的高效查询,独特的id列成为必需。

+0

那么id被设置为'255'字符,所以十亿行将会占用一些空间。我知道innodb创建一个,如果你没有。 –