这是我的数据库结构:
ID NAME SOMEVAL API_ID
1 TEST 123456 A123
2 TEST2 223232 A123
3 TEST3 918922 A999
4 TEST4 118922 A999
我正在使用调用API并从外部服务获取一些数据的函数来填充它。
第一次运行,我想插入从API返回的所有数据。之后,每次运行该函数时,我只想更新当前行并添加行,以防我从API调用中获取它们并且不在数据库中。
因此,我对更新过程的初步想法是浏览我从API和SELECT
获取的每一行,看看它是否已经存在。
我只是想知道这是否是最有效的方法,或者最好是DELETE
来自数据库的相关行,然后重新插入它们。
注意:我从API获得的每批行都有一个API_ID,因此当我说delete
行时,我的意思是DELETE FROM table WHERE API_ID = 'A999'
。
答案 0 :(得分:0)
如果您从服务中检索所有行,我建议您删除所有索引,截断表,然后插入所有数据并重新创建索引。
如果从服务中检索一些数据,我将删除所有索引,删除所有相关行,插入所有行,然后重新创建所有索引。
答案 1 :(得分:0)
如果您从API返回的所有数据在删除后需要完全重建行,那么请继续删除它们,然后插入。
但是,请确保您在事务中执行此操作,并且您正在使用正确支持事务的引擎,例如InnoDB,以便数据库的其他客户端不会看到表中缺少的行它们将会更新。
为了提高效率,您应该在单个查询中插入尽可能多的行。这样快得多。
BEGIN;
DELETE FROM table WHERE API_ID = 'A987';
INSERT INTO table (NAME, SOMEVAL, API_ID) VALUES
('TEST5', 12345, 'A987'),
('TEST6', 23456, 'A987'),
('TEST7', 34567, 'A987'),
...
('TEST123', 123321, 'A987');
COMMIT;
答案 2 :(得分:0)
在这种情况下,我通常会选择:
为什么呢?因为通常我有其他表引用的本地行,并且删除它们都会破坏引用(更不用说deletete cascade)。
答案 3 :(得分:0)
我在执行SELECT
时没有看到任何问题,然后在INSERT
或UPDATE
之间做出决定。但是,MySQL能够执行所谓的“upserts”,如果它不存在则会插入一行,否则会更新现有行。
This SO answer显示了如何做到这一点。
答案 4 :(得分:0)
我建议使用INSERT...ON DUPLICATE KEY UPDATE
。
如果您使用INSERT IGNORE
,则实际上不会插入该行,如果它导致API_ID上出现重复的密钥。
在API_ID列上添加unique key index
。