【问题标题】:Maintaining a large table of unique values in MySQL在 MySQL 中维护一个包含唯一值的大表
【发布时间】:2011-05-08 08:09:23
【问题描述】:

这可能是一种常见情况,但我在 SO 或 Google 上找不到具体答案。

我在 MySQL 数据库上有一张包含好友关系的大表(>1000 万行),该表非常重要,需要维护以确保没有重复的行。该表存储用户的 uid。该表的 SQL 是:

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

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

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

维护这个独特表的最佳(即最快)方法是什么?

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

如果没有,长期使用此表的最佳方式是什么?

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

【问题讨论】:

  • 问题,你需要查询表possiblefriends吗?我只是想你可能可以根据用户拆分表,当你查询时它会受益,但从长远来看它可能会变成维护灾难
  • @ajreal:你的意思是每个用户都有自己的桌子吗?将有接近一百万用户左右,所以这可能会使事情变得非常复杂。
  • 是的,我提到它可能会变成维护灾难,每个表使用 1k 个用户怎么样?想象一下你把所有数据放到一张表中,发生表崩溃无法恢复,甚至是可恢复的情况,你能忍受多长时间的宕机?

标签: mysql large-data


【解决方案1】:

(user, possiblefriend) 上添加唯一索引,然后使用以下之一:

确保您在尝试插入重复行时不会出错。

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

另见:

【讨论】:

  • 我读过这个问题。 INSERT IGNORE 或 INSERT...ON DUPLICATE KEY UPDATE 对于一般具有数百万行的表是否有效?
  • @eric:我想INSERT IGNORE 是最快的,但我只是猜测。确保您可以对所有三种方法进行性能测试。我链接到的问题的最高投票答案建议使用INSERT...ON DUPLICATE KEY UPDATE
  • @symcbean:感谢您指出这一点。不知怎的,我忘了提及这个非常重要的细节!
【解决方案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 DUPLICATE KEY UPDATE 功能:

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;

【讨论】:

  • 谢谢。使用索引总是更好吗?我应该考虑为较大的表使用索引是否会产生任何成本?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-26
  • 1970-01-01
  • 1970-01-01
  • 2012-09-05
  • 2015-04-23
  • 1970-01-01
  • 2012-09-09
相关资源
最近更新 更多