php - MySql 如何插入或更新 IF 重复的 2 个字段?

标签 php mysql sql database performance

我正在尝试为此找到最佳解决方案,我知道 ON DUPLICATE KEY UPDATE 是处理此类问题的理想方式,但被检查的字段可能会出现多次,这是 userId 和唯一的 productId 字段,而不是字段本身..因为 userId 为 1 可以喜欢多个产品..

基本上,我想要完成的,最好是不删除和重新插入现有字段的是,如果用户喜欢特定产品,isActive 将等于 1,如果他们在喜欢之前不喜欢该产品,我们设置 isActive到 0。如果他们再次喜欢相同的产品并且满足 userId 和 productId 条件,则他们的 userId 重新喜欢他们过去已经喜欢过的产品(存在行)然后将 isActive 设置为 1。

我基本上想使用 isActive 作为切换来防止 Id 的碎片,据我所知,这比删除和重新插入更有效和更受欢迎?

我将如何编写 MySQL 查询来完成此操作?

这是表格架构

enter image description here

最佳答案

如果 (userId, productId) 的组合是唯一的,那么您可以在该元组上创建 UNIQUE 约束,例如

CREATE UNIQUE INDEX mytable_UX1 ON mytable (userId, productId)

然后您可以使用单个 INSERT ... ON DUPLICATE KEY 语法。 (请注意,即使由于“重复键”异常而未插入行,插入尝试也会烧毁 AUTO_INCREMENT 值。)


如果没有 UNIQUE 约束,您需要 INSERTUPDATE 语句的组合。

尝试更新,并检查来自 MySQL 的“找到的行”计数。在您的情况下,isActive 被定义为整数类型且 NOT NULL,并且赋值 isActive = !isActive,“受影响的行数”计数将与“找到的行数”计数相匹配;

注意对于 future 的读者,在更一般的情况下,我们不能保证找到的行实际上需要更新,当“找到的行”计数不为零时,“受影响的行”计数可能为零。 mysqli 和 PDO 都有设置(在连接上)可以覆盖默认行为,并指定“受影响的行”将返回“找到的行”。

通过检查 UPDATE 语句“匹配”的行数,您可以知道是否需要运行 INSERT 语句。

MySQL 不支持 ANSI "MERGE"语法。

因此,除了 INSERT ... ON DUPLICATE KEY 语句外,MySQL 将需要(至少)发出两个单独的 SQL 语句。

这两个单独的语句可以捆绑在一起成为一个存储过程,这样您就可以获得一个数据库调用来执行“upsert”类型的功能。但这会在您的应用程序和数据库之间传播逻辑,并且需要另一个需要维护的数据库对象。您可能会认为存储过程方法的额外复杂性超过了潜在的性能提升;并且您在提高性能方面的努力可能更好地瞄准其他地方。

关于php - MySql 如何插入或更新 IF 重复的 2 个字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24375145/

相关文章:

php - Laravel 验证中的 For 循环

php - Laravel 5 找不到 http ://localhost:8000/css/app. css

来自mysql的php名称拼写更正

Java hibernate org.hibernate.exception.SQLGrammarException : could not extract ResultSet on createSQLQuery

php - 使用 SHOW CREATE TABLE 使用 php 和 mysql 创建一个表

php - 尝试在 mysql 查询中使用多个 WHERE 命令 [不工作]

php - 如何获取本月记录?

mysql - 在 MySQL 中索引日期时间

sql - sql developer中的NLS设置以更改数字格式

java - 集群安全数据库在启动时填充