WPF*_*Bie 64 mysql performance upsert
愚蠢而简单的例子:假设我有一个表'Item',其中我保存了收到的项目的总数.
Item_Name Items_In_Stock
Run Code Online (Sandbox Code Playgroud)
项目名称是主键.当我收到数量为X的项目A时,如何实现以下目标.
如果该项目不存在,我为项目A插入一个新的,并将库存中的项目设置为X,如果存在库存中的项目为Y的记录,则库存中的项目中的新值为(X + Y)
INSERT INTO `item`
(`item_name`, items_in_stock)
VALUES( 'A', 27)
ON DUPLICATE KEY UPDATE
`new_items_count` = 27 + (SELECT items_in_stock where item_name = 'A' )
Run Code Online (Sandbox Code Playgroud)
我的问题是我的实际表中有多列.在更新部分中编写多个select语句是个好主意吗?
当然我可以在代码中完成它,但有更好的方法吗?
Mic*_*.V. 134
正如我的评论中所提到的,您不必执行子选择来引用导致ON DUPLICATE KEY触发的行.因此,在您的示例中,您可以使用以下内容:
INSERT INTO `item`
(`item_name`, items_in_stock)
VALUES( 'A', 27)
ON DUPLICATE KEY UPDATE
`new_items_count` = `new_items_count` + 27
Run Code Online (Sandbox Code Playgroud)
请记住,大多数事情都非常简单,如果你发现自己过于复杂的事情应该很简单,那么你最有可能做错了:)
Sal*_*lim 11
你可以从这个例子中得到一个想法:
假设您要添加用户明智的七天数据
它应该具有userid和day的唯一值
UNIQUE KEY `seven_day` (`userid`,`day`)
Run Code Online (Sandbox Code Playgroud)
这是表格
CREATE TABLE `table_name` (
`userid` char(4) NOT NULL,
`day` char(3) NOT NULL,
`open` char(5) NOT NULL,
`close` char(5) NOT NULL,
UNIQUE KEY `seven_day` (`userid`,`day`)
);
Run Code Online (Sandbox Code Playgroud)
你的查询将是
INSERT INTO table_name (userid,day,open,close)
VALUES ('val1', 'val2','val3','val4')
ON DUPLICATE KEY UPDATE open='val3', close='val4';
Run Code Online (Sandbox Code Playgroud)
例:
<?php
//If your data is
$data= array(
'sat'=>array("userid"=>"1001", "open"=>"01.01", "close"=>"11.01"),
'sun'=>array("userid"=>"1001", "open"=>"02.01", "close"=>"22.01"),
'sat'=>array("userid"=>"1001", "open"=>"03.01", "close"=>"33.01"),
'mon'=>array("userid"=>"1002", "open"=>"08.01", "close"=>"08.01"),
'mon'=>array("userid"=>"1002", "open"=>"07.01", "close"=>"07.01")
);
//If you query this in a loop
//$conn = mysql_connect("localhost","root","");
//mysql_select_db("test", $conn);
foreach($data as $day=>$info) {
$sql = "INSERT INTO table_name (userid,day,open,close)
VALUES ('$info[userid]', '$day','$info[open]','$info[close]')
ON DUPLICATE KEY UPDATE open='$info[open]', close='$info[close]'";
mysql_query($sql);
}
?>
Run Code Online (Sandbox Code Playgroud)
您的数据将在表格中:
+--------+-----+-------+-------+
| userid | day | open | close |
+--------+-----+-------+-------+
| 1001 | sat | 03.01 | 33.01 |
| 1001 | sun | 02.01 | 22.01 |
| 1002 | mon | 07.01 | 07.01 |
+--------+-----+-------+-------+
Run Code Online (Sandbox Code Playgroud)
虽然Michael的答案是正确的,但您需要了解更多以编程方式执行upsert:
首先,创建表并指定您想要唯一索引的列:
CREATE TABLE IF NOT EXISTS Cell (
cellId BIGINT UNSIGNED,
attributeId BIGINT UNSIGNED,
entityRowId BIGINT UNSIGNED,
value DECIMAL(25,5),
UNIQUE KEY `id_ce` (`cellId`,`entityRowId`)
)
Run Code Online (Sandbox Code Playgroud)
然后在其中插入一些值:
INSERT INTO Cell VALUES( 1, 6, 199, 1.0 );
Run Code Online (Sandbox Code Playgroud)
尝试再做同样的事情,你会得到一个重复的键错误,因为cellId并且entityRowId是相同的:
INSERT INTO Cell VALUES( 1, 6, 199, 1.0 );
Run Code Online (Sandbox Code Playgroud)
键'id_ce'重复输入'1-199'
这就是我们使用upsert命令的原因:
INSERT INTO Cell ( cellId, attributeId, entityRowId, value)
VALUES( 1, 6, 199, 300.0 )
ON DUPLICATE KEY UPDATE `value` = `value` + VALUES(`value`)
Run Code Online (Sandbox Code Playgroud)
此命令将1.0已存在的值作为值并执行a value = value + 300.0.
因此,即使执行上述命令后,表中只有一行,值也是如此301.0.