我试图为此找出最佳解决方案,我知道在DUPLICATE KEY UPDATE是处理这类事情的理想方式,但是被检查的字段可能会多次出现,它是之间的关系userId和productId字段是唯一的,而不是字段本身..因为userId为1可以像多个产品..
基本上,我想要完成的事情,最好不要删除和重新插入现有字段,如果用户喜欢特定产品,isActive将等于1,如果他们在喜欢之后不喜欢产品,我们将isActive设置为0.如果他们再次喜欢同一产品并且满足userId和productId条件,那么他们的userId会重新提供他们过去已经喜欢过的产品(现有行),然后将isActive设置为1。
我基本上想要使用isActive作为切换来防止Id的碎片化,因为我理解它与删除和重新插入相比更有效率和首选?
我如何编写MySQL查询来完成此任务?
这是表Schema
答案 0 :(得分:0)
如果 (userId, productId)
的组合是唯一的,那么您可以在该元组上创建一个UNIQUE约束,例如
CREATE UNIQUE INDEX mytable_UX1 ON mytable (userId, productId)
然后您可以使用单个INSERT ... ON DUPLICATE KEY
语法。 (请注意,插入尝试将刻录AUTO_INCREMENT值,即使由于"重复键"异常而未插入行也是如此。)
如果没有UNIQUE
约束,您需要INSERT
和UPDATE
语句的组合。
尝试更新,并检查"找到的行"从MySQL算起。在您的情况下,将isActive定义为整数类型且NOT NULL,并且使用赋值isActive = !isActive
,"行受影响" count将匹配找到的"行"计数;
N.B。对于未来的读者,在更一般的情况下,我们不能保证找到的行实际上需要更新,"行受影响"找到"行时,count可能为零。 count不为零。 mysqli和PDO都有设置(在连接上),可以覆盖默认行为,并指定"行受影响"将返回"找到的行"。
通过检查行数"匹配"通过UPDATE语句,您可以知道是否需要运行INSERT
语句。
MySQL并不支持ANSI" MERGE
"语法。
因此,除了INSERT ... ON DUPLICATE KEY
语句之外,MySQL将要求(至少)发布两个单独的SQL语句。
这两个单独的语句可以捆绑在一起存储过程,因此您可以通过单个数据库调用来执行" upsert"类型功能。但是,这会在应用程序和数据库之间传播逻辑,并且需要另一个需要维护的数据库对象。您可能会认为存储过程方法的额外复杂性超过了潜在的性能增益;而你在提高绩效方面的努力可能更好地针对其他地方。