Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
处理MYSQL表中的并行相同插入_Mysql_Sql_Multithreading_Stored Procedures_Sql Insert - Fatal编程技术网

处理MYSQL表中的并行相同插入

处理MYSQL表中的并行相同插入,mysql,sql,multithreading,stored-procedures,sql-insert,Mysql,Sql,Multithreading,Stored Procedures,Sql Insert,我们正在开发一个由MySQL数据库支持的Spring Boot应用程序,我有一个问题找不到答案,尽管这里有几个类似的问题。 问题是,如果运行了多个并行相同的insert语句,则在数据库中只保留一个insert 例如,如果我的实体具有属性(Id、parent\u Id和status),则我们不希望允许多个实体具有相同的parent\u Id和status=1——即使它们以这种形式来自客户端,客户端使用相同的请求向我们的端点发送垃圾邮件。我知道其他db供应商允许使用称为条件唯一键的东西,即类似(pa

我们正在开发一个由MySQL数据库支持的Spring Boot应用程序,我有一个问题找不到答案,尽管这里有几个类似的问题。 问题是,如果运行了多个并行相同的insert语句,则在数据库中只保留一个insert

例如,如果我的实体具有属性
(Id、parent\u Id和status)
,则我们不希望允许多个实体具有
相同的parent\u Id和status=1
——即使它们以这种形式来自客户端,客户端使用相同的请求向我们的端点发送垃圾邮件。我知道其他db供应商允许使用称为条件唯一键的东西,即类似
(parent\u id,status=1)
的唯一键,但MySql不允许。有没有办法通过索引甚至存储过程来实现这一点

类似问题(供参考):


  • 你可以用一个小技巧来做

    使用IF()函数再包含一个虚拟perstant列。 如果状态为1,则将存储父\u id,否则为空 因此,您可以在此字段上创建唯一键

    CREATE TABLE `cond` (
      `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
      `parent_id` int(11) DEFAULT NULL,
      `status` int(11) DEFAULT NULL,
      `cond_status` int(11) GENERATED ALWAYS AS (if(`status` = 1,`parent_id`,NULL)) STORED,
      PRIMARY KEY (`id`),
      UNIQUE KEY `idx_cond_status` (`cond_status`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    
    样本

    MariaDB [Bernd]> select * from cond;
    Empty set (0.10 sec)
    
    MariaDB [Bernd]> INSERT INTO cond (parent_id,`status`) VALUES(1234, 0);
    Query OK, 1 row affected (0.05 sec)
    
    MariaDB [Bernd]> INSERT INTO cond (parent_id,`status`) VALUES(1235, 0);
    Query OK, 1 row affected (0.01 sec)
    
    MariaDB [Bernd]> INSERT INTO cond (parent_id,`status`) VALUES(1235, 2);
    Query OK, 1 row affected (0.00 sec)
    
    MariaDB [Bernd]> INSERT INTO cond (parent_id,`status`) VALUES(1235, 2);
    Query OK, 1 row affected (0.02 sec)
    
    MariaDB [Bernd]> INSERT INTO cond (parent_id,`status`) VALUES(1235, 1);
    Query OK, 1 row affected (0.22 sec)
    
    MariaDB [Bernd]> INSERT INTO cond (parent_id,`status`) VALUES(1235, 4);
    Query OK, 1 row affected (0.01 sec)
    
    MariaDB [Bernd]> INSERT INTO cond (parent_id,`status`) VALUES(1235, 1);
    ERROR 1062 (23000): Duplicate entry '1235' for key 'idx_cond_status'
    MariaDB [Bernd]> 
    
    MariaDB [Bernd]> select * from cond;
    +----+-----------+--------+-------------+
    | id | parent_id | status | cond_status |
    +----+-----------+--------+-------------+
    |  1 |      1234 |      0 |        NULL |
    |  2 |      1235 |      0 |        NULL |
    |  3 |      1235 |      2 |        NULL |
    |  4 |      1235 |      2 |        NULL |
    |  5 |      1235 |      1 |        1235 |
    |  6 |      1235 |      4 |        NULL |
    +----+-----------+--------+-------------+
    6 rows in set (0.08 sec)
    
    MariaDB [Bernd]> 
    

    注意:create table是针对MariaDB的,但在MySQL中几乎是相同的

    这看起来是一个很好的解决方案,但确实有点“黑”。虽然有效负载没有真正增加,但我真正关心的是这种解决方案如何在具有大量列的生产数据库中扩展。您是否知道使用存储过程的解决方案,因此“状态”保持不变,而我们只更改“行为”?