2010-11-11 44 views
6

这可能是一种常见情况,但我无法在SO或Google上找到具体的答案。在MySQL中维护一个唯一值的大表格

我有一个很大的表(> 1000万行)的MySQL数据库上的朋友关系,这是非常重要的,需要保持这样,没有重复的行。该表存储用户的uid。表的SQL是:

CREATE TABLE possiblefriends(
id INT NOT NULL AUTO_INCREMENT, 
PRIMARY KEY(id), 
user INT, 
possiblefriend INT) 

表的工作方式是每个用户大约有1000左右的“可能朋友”被发现并需要存储,但重复“可能朋友”需避免。

问题是,由于程序的设计,在一天的过程中,我需要向表中添加100万行或更多的行,可能或不是重复的行条目。简单的答案似乎是检查每一行以查看它是否重复,如果不是,则将其插入表中。但是,随着表格大小增加到1亿行,10亿行或更多(我预计它很快),这种技术可能会变得非常缓慢。

什么是最好的(即最快)的方式来维护这个独特的表?

我并不需要一张只有唯一值的表格。我只需要每天一次的批量作业。在这种情况下,我应该创建一个插入所有可能行(包含重复行和所有行)的单独表,然后在一天结束时创建第二个表来计算第一个表中的所有唯一行吗?

如果不是,该表格的长期最佳方式是什么?

(如果指标是最好的长期解决方案,请告诉我要使用的索引)

+0

问题,做u需要查询表'possiblefriends'?我只是想你可能会根据用户分割桌子,当你查询时它将会有所帮助,但是它可能会在长时间内变成维护灾难 – ajreal 2010-11-11 09:12:56

+0

@ajreal:你的意思是每个用户都有自己的桌子吗?将会有近一百万用户左右,所以这可能会使事情变得非常复杂。 – eric 2010-11-11 10:04:34

+0

是的,这是我提到它可能会变成维护灾难,如何使用每桌约1k用户?想象一下,你把所有的数据放在一张桌子上,发生桌子坠毁,无法恢复,甚至可以恢复,你能忍受多久的停机时间? – ajreal 2010-11-11 12:48:50

回答

7

添加一个唯一索引(user, possiblefriend)然后使用一个:

to en确保您在尝试插入重复行时不会收到错误。

您可能还想考虑是否可以放弃自动递增主键并使用(user, possiblefriend)作为主键。这将减少表的大小,并且主键也将用作索引,从而使您不必创建额外的索引。

参见:

+1

我读过这个问题。 INSERT IGNORE或INSERT ... ON DUPLICATE KEY UPDATE对于一般具有数百行数百行的表有效吗? – eric 2010-11-11 08:33:14

+1

@eric:我想象'INSERT IGNORE'是最快的,但我只是猜测。为了确保你可以对所有三种方法进行性能测试。对于我链接到的问题,顶级投票答案建议使用“INSERT ... ON DUPLICATE KEY UPDATE”。 – 2010-11-11 08:36:20

+1

注意 - 它必须是唯一索引! – symcbean 2010-11-11 12:33:27

2

唯一索引会让你确信领域的确是独一无二的,你可以添加一个唯一索引,像这样:

CREATE TABLE possiblefriends( 
id INT NOT NULL AUTO_INCREMENT, 
PRIMARY KEY(id), 
user INT, 
possiblefriend INT, 
PRIMARY KEY (id), 
UNIQUE INDEX DefUserID_UNIQUE (user ASC, possiblefriend ASC)) 

这也将显着提高您的表访问。

你的其他问题与大众插入有一点比较麻烦,你可以使用内置的ON下面重复键更新功能:

INSERT INTO table (a,b,c) VALUES (1,2,3) 
    ON DUPLICATE KEY UPDATE c=c+1; 

UPDATE table SET c=c+1 WHERE a=1; 
+0

谢谢。使用索引总是更好吗?使用我应该考虑的较大表格的索引会有什么代价吗? – eric 2010-11-11 08:47:28

相关问题