检查表中是否存在值或处理MySQL的唯一约束异常?

时间:2014-02-24 21:07:08

标签: php mysql performance apple-push-notifications unique-constraint

我正在开发一款可让用户接收推送通知的iOS应用。因此,我必须为每个用户存储他们的APN设备令牌。我决定在每个API请求上捎带APN设备令牌,如果它还不存在,则将其存储在数据库中。

表设计非常简单,只有一列'device_token':

mysql> desc apn_devices;
+--------------+-------------+------+-----+---------+-------+
| Field        | Type        | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+-------+
| device_token | varchar(64) | NO   | PRI | NULL    |       |
+--------------+-------------+------+-----+---------+-------+

现在我想知道,确保所有令牌都是独一无二的会更贵吗?我看到两个选择:

  1. 在'device_token'上放置一个唯一约束,只需插入令牌并忽略可能发生的任何异常
  2. 首先,执行查询以检查令牌是否已存在,如果不存在,请插入它。
  3. 第一个似乎是一个更“干净”的解决方案,从某种意义上说,它需要更少的代码,更容易维护。第二个解决方案只会在令牌尚不存在时添加额外的查询,从而防止不可避免的约束违反第一个。逻辑思考,后者应该更便宜,但需要更多的代码来完成。

    这里的最佳做法是什么? MySQL抛出异常是否很昂贵?

1 个答案:

答案 0 :(得分:1)

或者,您可以简单地执行INSERT IGNORE ...(不需要唯一约束,因为它是主键,因此构造必须是唯一的)

来自MySQL Reference Manual

  

如果使用IGNORE关键字,则会忽略执行INSERT语句时发生的错误。例如,如果没有IGNORE,则复制表中现有UNIQUE索引或PRIMARY KEY值的行会导致重复键错误,并且语句将中止。使用IGNORE时,仍未插入行,但不会发生错误。忽略错误可能会生成警告,但重复键错误不会。

请注意,如果您的表中有其他列,则每次都要更新(例如“上次使用”的时间戳),您也可以使用INSERT ... ON DUPLICATE KEY UPDATE ...