我有一个数据库有两个表,每个当前有3列。主键自动增量
表-A:id
,uid
,url
表-B:id
,uid
,url
的id
是自动递增1
上每一个新的行插入的主键。
我有的问题是我还需要一个主键。我永远不会查询数据库的id
。 uid
列简单地分隔每个用户,因此它不是每行唯一的。 Table_A
and Table_B
经常会被uid
比较。 我有uid
,url
索引,我希望桌子在数十亿中可能增长,我不想在id
上浪费空间。
我有一个数据库有两个表,每个当前有3列。主键自动增量
表-A:id
,uid
,url
表-B:id
,uid
,url
的id
是自动递增1
上每一个新的行插入的主键。
我有的问题是我还需要一个主键。我永远不会查询数据库的id
。 uid
列简单地分隔每个用户,因此它不是每行唯一的。 Table_A
and Table_B
经常会被uid
比较。 我有uid
,url
索引,我希望桌子在数十亿中可能增长,我不想在id
上浪费空间。
如果您使用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
优秀的比尔,感谢技术细节 – Madbreaks
谢谢+1的例子。我在辩论使用innodb或myisam。将会有很多uid比较数据。我注意到,如果我使用myisam,桌子大小会下降3分钟然后innodb。 –
@Madbreaks我还应该添加索引到uid和url吗? –
你不需要id
列,但在我看来,你的“主”关键是uid-url
我将使用像这样的查询'WHERE uid ='$ uid'AND url ='$ url''你是正确的,那么永远不会有两行由uid-url相同,我将如何使这个主键? –
@AbbyE在create语句中:'PRIMARY KEY(uid,url)' – Neal
技术上来讲是没有,但它是很好的做法,你永远不知道你的未来的需求是什么。如果你最终需要一个独特的id
列,并且没有一个,它可能是一个主要的头痛。在我看来,id
专栏的“浪费”的开销量绝对值得。
此外,取决于Table_A
和Table_b
之间的关系,则最终可能会具有中介表以限定它们之间的(例如one-to-nany
,many-to-many
)的关系。对于这种情况下的高效查询,独特的id
列成为必需。
那么id被设置为'255'字符,所以十亿行将会占用一些空间。我知道innodb创建一个,如果你没有。 –
在RDBMS中的所有表需要一个主键。然而,它不需要是一个专用的('代理'),自动递增的id。它可以是在表中的一列或多列上形成的“自然”键,或者(取决于数据库引擎)两者的组合! – Strawberry