维护排名表的最佳做法?

时间:2010-09-19 02:25:07

标签: mysql ranking insert-update

使用MySQL和PHP,我有一个简单的排名表,其中包含2列userscore

每周一次,我重新运行排名脚本,并计算每个用户的分数。

  • 许多用户都有新的分数
  • 有些人不
  • 有时会有新用户添加到表格

使用MySQL解决这个问题的最佳方法是什么?如果我需要添加新行,update是否有效? insert会覆盖现有行,以便我可以再次插入整个表吗?最好放下桌子并从头开始重写它?

**Sample Data**

User01   2500
User02   3000
User03    100

**New Data to be Added**

User01   2700
User02   4000
User04   1000 // new account

除了数以千计的用户......

3 个答案:

答案 0 :(得分:1)

REPLACE ... INTO语法将在需要时插入新行,并为现有行删除+插入:

# deletes existing and inserts new row:
REPLACE INTO users SET score = 2000, username = 'User01';
# deletes existing and inserts new row
REPLACE INTO users SET score = 3000, username = 'User02';
# inserts new row
REPLACE INTO users SET score = 4000, username = 'User04';  

http://dev.mysql.com/doc/refman/5.0/en/replace.html

我最喜欢的方法是使用ON DUPLICATE KEY语法 - 主要是因为我总是假设删除一行然后重新插入它会更“昂贵”然后只更新现有行。假设username字段是UNIQUEPRIMARY KEY索引,您可以执行以下操作:

# Updates existing User01 row
INSERT INTO users SET score = 2000, username = 'User01' ON DUPLICATE KEY UPDATE score = 2000;
# Updates existing User02 row
INSERT INTO users SET score = 3000, username = 'User02' ON DUPLICATE KEY UPDATE score = 2000;
# Inserts new User04 row
INSERT INTO users SET score = 4000, username = 'User04' ON DUPLICATE KEY UPDATE score = 2000;

http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html

答案 1 :(得分:0)

INSERT不会覆盖现有行,而是会产生错误(例如,如果您将用户列标记为唯一,并尝试添加已存在的用户)。同样,UPDATE不会插入新行,只会更改现有行。

如果大多数用户需要更新并且应该删除用户,即不再包含在新的分数表中,则删除和重写整个表似乎是一个可接受的解决方案。

否则,我会更新表格:

便携式解决方案是检查表中是否已经包含密钥(即用户)(通过SELECT),然后使用INSERT表示不存在的密钥或UPDATE表示已存在的密钥。当然,如果出现约束违规错误,您也可以尝试INSERT并检查错误代码,然后回退到UPDATE。

在MySQL上,您还可以使用以下语法,该语法仅允许您使用单个查询进行操作:

INSERT INTO ... ON DUPLICATE KEY UPDATE score = ...

但是,这不可移植,不能与其他RDBMS一起使用,只能使用MySQL。

答案 2 :(得分:0)

正如你提到的那样

更新或插入

我认为INSERT会比更新更好。对于插入,您添加一个查询。对于更新,您必须为每个用户运行2个查询。首先选择用户,然后根据userId进行更新。

插入速度最快,你可以随时使用sql查询求和。