handle在mysql表中的并行完全插入

ukxgm1gy  于 2021-07-26  发布在  Java
关注(0)|答案(1)|浏览(337)

我们正在开发一个由mysql数据库支持的spring-boot应用程序,我有一个问题找不到答案,尽管这里有几个类似的问题。问题是,如果运行多个并行的相同insert语句,则只在数据库中保留一个insert。
例如,如果我的实体具有 (Id, parent_id and status) ,我们不希望允许多个实体具有 same parent_id and status = 1 -即使它们以这种形式来自客户端,客户端用相同的请求对我们的端点进行垃圾邮件处理。我知道其他数据库供应商也允许使用条件唯一键,即 (parent_id, status = 1) ,但mysql没有。有没有办法通过索引甚至存储过程来实现这一点?
类似问题(供参考):
条件唯一约束
sql我可以在表上有一个“条件唯一”约束吗?
https://dba.stackexchange.com/questions/7443/function-based-index-as-a-conditional-unique-key
我可以有条件地强制唯一性约束吗?
https://dba.stackexchange.com/questions/43/how-to-create-a-conditional-index-in-mysql

pxy2qtax

pxy2qtax1#

你只要耍点小把戏就行了。
使用if()函数再包含一个虚拟变量列。如果status=1,这将存储父项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表用于mariadb,但在mysql中几乎相同

相关问题