我正在尝试找到一种方法来向表中插入一行或多行,而不会超过查询定义的那个时间点的最大行数。我需要有效地做到这一点并安全地进行线程化。
比方说,我有一个表格,其中包含有关不同水果的信息。我需要能够同时插入一片或多片水果(所有相同类型的水果),而不会超过桌上任何类型水果的总数。我的意思是不超过100个苹果,250个橙子等。
⁃ Insert 5 oranges into fruits unless there are more than 245 (250 - 5) oranges already.
⁃ Insert 1 apple into fruits unless there are more than 99 (100 - 1) apples already.
我知道我可以先选择确定是否有空格,然后插入我的数据,然后再次选择以确保我已超过该类型的“配额”,但这似乎效率不高。当谈到多个线程时,它似乎更像是一个黑客/锤击方法来完成它。我关注的原因是我“回头”检查是否插入了太多是在第一个选择和插入之间的另一个连接可能会出现并在我有机会使插入溢出这些限制之前插入行。
我还在学习MySQL,如果我没有提供足够的信息,请告诉我。
有什么想法吗?
答案 0 :(得分:0)
有两种方法可以做到这一点。
方法1 -
在将数据插入表格之前检查每个水果的数量,并仅插入差异记录。
例如,让我们说你的桌子是这样的。
id|fruit
1 |apple
2 |apple
3 |orange
4 |banana
然后你可以先查询一下,检查每个水果的数量
select fruit, count(*) from `table`
group by 1
//which gives you result like
apple | 2
orange | 1
banana | 1
现在说你要插入5个苹果,3个橙子和2个香蕉,你有8个苹果,5个橙子和4个香蕉。然后你只插入差异,即(5-2 = 3个苹果),4个橙子和3个香蕉。
但是,对于多个客户端同时执行此操作将要求您锁定表或阻止代码同时为多个客户端运行。
方法2 -
您可以检查每个插入处的计数,并仅在计数小于允许的最大值时插入。像这样。
insert into `table`(fruit)
select (case when count(fruit) < 1 then fruit end) as fruit
from `table`
where type="Apple"
having fruit is not null; //this having condition will prevent null values from getting inserted
这两种方法同样效率低下。如果客户端数量少于所需的插入数量,则可以使用方法1,因为您不必经常锁定并且可以一起处理大量插入。
如果插入次数少于客户端数量,则转到方法2。
答案 1 :(得分:0)
您可以在select case
语句中使用insert
个表达式。假设您的表名为food
,它接受两列name
和quantity
。您可以检查是否存在具有指定计数的苹果。如果没有,则插入如图所示。
insert into food(name, quantity)
select (case when count(name) <1 then "apple" end) as name, 1 as quantity
from food
where name="apple"
此处 as 关键字是最重要的。 为后的名称应与列名匹配。