我看到很多人都问起了升级(这个,这个,这个,这个,这个,这个,这个,还有更多,甚至是官方的文件)。
但是,对于新手来说,如何使用主键或唯一索引创建重复键还没有得到足够的解释。
我需要的是:
如果 table1
的独特组合3列( attributeId, entityId, carId
)中有一个副本 table2
,然后更新 value
列。否则就拿走 table1
的行并将其插入 table2
.
这个 attributeId, entityId, carId
每行的组合都是唯一的。
ie:如果一行有列作为 1,2,5
,则没有其他行 1,2,5
. 但另一排可能 5,1,2
或者 3,4,2
等。
这里的难题是创建唯一索引。这样做是否足够: CREATE INDEX PIndex ON table1 (attributeId, entityId, carId);
或者有必要删除所有其他索引,然后创建这个索引,然后运行这样的查询吗(以下为伪代码):
INSERT INTO table1 (attributeId, entityId, carId, value, name)
VALUES (table2.attributeId,table2.entityId,table2.carId,table2.value,table2.name)
ON DUPLICATE KEY UPDATE value=VALUES(value);
基本逻辑是:
如果是一排 table2
,中有相应的行 table1
如果attributeid、entityid和carid的值完全相同,则更新 value
中的列 table1
有价值的 value
中的列 table2
. 如果没有对应的行,则取 table2
并将其附加到 table1
.
2条答案
按热度按时间9rygscc11#
该规范似乎针对两种不同的操作:1)更新表1中的现有行,2)向表2中插入新行。
规范说“更新值列”。。。我们认为这意味着更新
table1
.说明书上还写着“插入。。。进入
table2
.令人困惑的是,该规范还显示了一个伪代码示例
INSERT INTO table1
.更新
table1
基于中的值table2
,假设我们要忽略三列中任何一列的值为空的行。。。如果文件中有“副本”
table2
(即多行)table2
如果attributeid、entityid和carid三列的值相同,则无法确定这些行中的哪一行value
将从中删除。要插入在表2中找到但在表1中“丢失”的行(再次假设这三列在表2中可能不是唯一的),我们可以使用反连接模式来消除表1中已经有“匹配”的行。
例如:
如果表2中有“重复项”(即表2中有多行的attributeid、entityid和carid三列值相同,则不确定是哪一行
value
将从中删除。如果在其他列或列的组合上定义了其他唯一约束,则该语句有可能抛出“复制键”错误(在不知道关键定义的情况下,我们有点盲目。)我们可以添加
IGNORE
关键字,只忽略由于“unique key”冲突而无法插入的行。)同样,如果
table2
如果三列中的值相同(没有迹象表明这三列的组合在表2中是唯一的),则无法确定这些行中的哪一行value
将从中删除。相同的操作可以在相反的方向上执行,交换表引用的所有引用
table1
以及table2
在查询中。执行这些操作时,不必向任何一个表添加唯一键。如果定义一个合适的索引,并且将这三列作为索引中的前导(第一)列,那么(很可能)会对性能有好处(对于此操作,它不一定需要是唯一的索引。)
如果该列的组合应该是唯一的,那么一定要在该列的组合上添加唯一键。但是指定的操作可以在没有定义唯一键的情况下执行。
mysql
INSERT ... ON DUPLICATE KEY
语法至少需要一个主键或唯一键才能操作。如果目标表上有多个唯一键约束,并且一个insert会违反两个或多个唯一键约束,那么我认为在update操作中使用哪一个键是不确定的。我个人倾向于避免在定义了多个唯一键的表上使用这种语法。mo49yndu2#
你可以使用语法
根据文件:
如果指定ignore,则在唯一键上具有重复项的行中只使用一行。其他冲突行将被删除。不正确的值将被截断为最接近匹配的可接受值。
不幸的是,它没有指定将保留哪个值。做一些测试,它似乎保持了第一次出现,但你永远不能确定。
如果哪个条目将被删除并不困扰您,这是最简单的解决方案,否则如果您想要更多的控制权,最好通过一个临时表。
命令
CREATE UNIQUE PIndex ON table1 (attributeId, entityId, carId);
(请注意,添加了UNIQUE
)只会在第一个重复密钥上失败,并且没有管理重复项的选项可用。