1

使用 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

除了成千上万的用户...

4

3 回答 3

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字段是 aUNIQUEPRIMARY 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

于 2010-09-19T03:20:03.263 回答
0

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

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

否则,我会更新表格:

可移植的解决方案是检查表中是否已经包含一个键(即用户)(通过 SELECT),然后对不存在的键使用 INSERT 或对已经存在的键使用 UPDATE。当然,您也可以尝试 INSERT 并检查错误代码,如果遇到约束违规错误,则返回到 UPDATE。

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

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

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

于 2010-09-19T02:35:24.710 回答
0

正如你提到的两种方式

更新或插入

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

所以最快的是插入,您可以随时使用 sql 查询对其求和。

于 2010-09-19T02:38:35.493 回答