MySQL的m:n关系的高效插入/更新

4
我正在开发一个HTML5的多人游戏,其中在"关键词(keyword)"和"模型(model)"的表之间有一个m:n的关系,如下图所示: keyword.idmodel.id是自增无符号整数, 而keyword.keyword是唯一索引。为了效率,我正在寻找一种管理这种关系的方法。一种简单的方式是:
  • 检查关键字是否已存在
  • 如果是:从model_has_keyword中更新timesCountroundCount
  • 如果不是:进行insert into keywordinsert into model_has_keyword
但随着同时在线用户数量的增加,我担心这种简单的方式会变得太慢。那么最有效的方法是什么呢?
当我在StackOverflow上搜索时,我遇到了两个想法,但我认为它们都不适合我的需求。
  1. INSERT INTO table ON DUPLICATE KEY UPDATE col=val 如果进行INSERT INTO操作,我需要触发另一个INSERT INTO语句来插入到keywordmodel_has_keyword这两个表。
  2. REPLACE语句:如果替换关键字表中的记录,id将被分配下一个自增值,这样就会丢失对表model_has_keyword的引用。
由于我不是专家,请在这里纠正我是否有什么误解。
1个回答

3
您需要检查关系是否存在,然后再进行插入/更新操作。
A.将INSERT查询语句放在try块中,在出现错误的情况下执行更新查询。这样可以避免在关系不存在时进行所有检查...
B.对所有INSERT ON DUPLICATE UPDATE。这将完全与“A”中相同,但是您不必担心异常。
毫无疑问,您的第二种想法完全错误。
我不会创建关键字表,因为您只需要关键字本身...然后我会像这样定义我的model_has_keyword:
CREATE TABLE model_has_keyword (
  model_id         INT NOT NULL,
  keyword          VARCHAR(50) NOT NULL,
  timesCount       INT NOT NULL,
  roundCount       INT NOT NULL,
  PRIMARY KEY (model_id,keyword)
);

然后像这样更新它:

INSERT INTO model_has_keyword 
  (model_id,keyword,timesCount,$myIntValue) 
VALUES 
  ($model_id,$keyword,0,0) 
ON DUPLICATE KEY UPDATE 
  timesCount=timesCount+1,roundCount=roundCount + $myIntValue

谢谢回复!您能否详细说明如何按照B中所述的方式实施呢?我不知道这应该如何工作。假设语句如下:INSERT INTO keyword(keyword)VALUES('myValue')ON DUPLICATE KEY UPDATE model_has_keyword.roundCount = model_has_keyword.roundCount+1,model_has_keyword.timesCount = model_has_keyword.timesCount+myIntValue 如果没有检测到重复键,则会错过插入到model_has_keyword中的内容! 如果存在重复键,则会按预期工作。最后一个问题:您是指使用存储过程还是从源(php/js)查询? - grange
但是你不需要table关键字! - Amarnasan
谢谢Yihad!你说得完全正确,但我没有提到我还需要关键字表来处理另一个m:n关系。这将导致关键字的冗余存储。 - grange

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接