简体   繁体   English

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

[英]Check if value exists in table or handle MySQL's unique constraint exception?

I'm developing an iOS app that will enable users to receive push notifications. 我正在开发一个iOS应用,该应用将使用户能够接收推送通知。 Therefore, I have to store for each user their APN device token. 因此,我必须为每个用户存储他们的APN设备令牌。 I have decided to piggy back the APN device token on each API request and store it in the database if it doesn't yet exist. 我已决定在每个API请求上都附带APN设备令牌,如果尚不存在,则将其存储在数据库中。

The table design is very simple, only one column 'device_token': 该表的设计非常简单,只有一列“ device_token”:

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

Now I'm wondering, what would be more expensive to ensure all tokens are unique? 现在我想知道,确保所有令牌都是唯一的会更昂贵吗? I see two options: 我看到两个选择:

  1. Put a unique constraint on 'device_token', just insert the token and ignore any exception that might occur 对“ device_token”施加唯一约束,只需插入令牌并忽略可能发生的任何异常
  2. First, perform a query to check if the token already exists and if not, insert it. 首先,执行查询以检查令牌是否已经存在,如果不存在,则将其插入。

The first seems to be a more 'clean' solution, in a sense that it takes less code, which is easier to maintain. 第一个似乎是一个更“干净”的解决方案,从某种意义上讲,它需要较少的代码,更易于维护。 The second solution will only add an additional query when the token does not yet exist, preventing the inevitable constraint violation of the first. 第二种解决方案将仅在令牌不存在时添加一个附加查询,以防止不可避免地违反第一种约束。 Logically thinking, the latter should be less expensive, but takes more code to accomplish. 从逻辑上考虑,后者应该较便宜,但需要更多代码来完成。

What is best practice here? 什么是最佳做法? Is it expensive for MySQL to throw exceptions? MySQL引发异常是否昂贵?

Or, you can simply do an INSERT IGNORE ... (no need for a unique constraint as it's the primary key, and hence by construction must be unique) 或者,您可以简单地执行INSERT IGNORE ... (因为它是主键,所以不需要唯一约束,因此构造必须是唯一的)

From MySQL Reference Manual : MySQL参考手册

If you use the IGNORE keyword, errors that occur while executing the INSERT statement are ignored. 如果使用IGNORE关键字,则在执行INSERT语句时发生的错误将被忽略。 For example, without IGNORE, a row that duplicates an existing UNIQUE index or PRIMARY KEY value in the table causes a duplicate-key error and the statement is aborted. 例如,如果没有IGNORE,则复制表中现有UNIQUE索引或PRIMARY KEY值的行会导致重复键错误,并且该语句将中止。 With IGNORE, the row still is not inserted, but no error occurs. 使用IGNORE,该行仍未插入,但不会发生错误。 Ignored errors may generate warnings instead, although duplicate-key errors do not. 被忽略的错误可能会生成警告,尽管不会出现重复键错误。

Note that if you had other columns in your table you'd want to update each time (eg a "last used" timestamp), you could also use INSERT ... ON DUPLICATE KEY UPDATE ... 请注意,如果表中还有其他列想要每次更新(例如“上次使用”时间戳),则还可以使用INSERT ... ON DUPLICATE KEY UPDATE ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM