如何批量插入Mysql并取得各自的递增ID

我用 PHP 从文章中提取关键词,平均一篇文章大约产生 100 多个词,需要录入 Mysql 的三个表,一个文章表,这个好说,一个词语表,结构如下:
id 自动递增,主键
term 词语,唯一索引
第三个表就是词语和文章的关系表(哪个词出现在哪个文章里?)。

给定词语 T,要取得它在词语表里的 ID —— 如果尚不存在,则插入之。
最笨的办法是,先 SELECT id from 词语表 WHERE term = 'T',若没有就 insert into ,再获取 ID。

一个词好说,但问题是,现在一篇文章产生了 100 多个词,总不能也这么干吧。请问如何批量取得这些词的 ID —— 如果某个词不在就插入?

我想用存储过程来办,但 Mysql 的存储过程能接收数组吗?或者存储过程接收一个TEXT参数,把 100 多个词用特殊字符拼起来?

求思路,谢谢!!

阅读 5.8k
5 个回答

用存储过程搞定了,大家可以把下面代码粘到NAVICAT里试一下:

CREATE DEFINER=root@% PROCEDURE fTest(IN a_Terms TEXT)
BEGIN

DECLARE l_TermsLen, l_TermLen INT;
DECLARE l_Term VARCHAR(20);

-- 测试用的临时表
DROP TABLE IF EXISTS temp_terms;
CREATE TEMPORARY TABLE temp_terms (c_Term VARCHAR(20));

SET l_TermsLen = CHAR_LENGTH(a_Terms);
WHILE (l_TermsLen > 0) DO
    SET l_Term = SUBSTRING_INDEX(a_Terms, ',', 1);
    SET l_TermLen = CHAR_LENGTH(l_Term);
    SET a_Terms = SUBSTRING(a_Terms, l_TermLen + 2);
    SET l_TermsLen = l_TermsLen - (l_TermLen + 1);
    
    -- 按需把l_Term插入到词语表,取得ID;这里插入到临时表,最后显示出来
    INSERT INTO temp_terms VALUES (l_Term);
END WHILE;

-- 显示拆分出的词语
SELECT * FROM temp_terms;

END

然后新建查询,执行:
CALL fTest('abc,你们,好')
输出:
abc
你们

现在只需执行两个查询就能完成任务:
1 把文章插入到文章表,取得自动递增ID
2 把所有词用逗号连接成一个字符串,和文章ID一起作为参数,调用存储过程,由它负责解码各个词,查询它们的ID,按需插入到词语表,最后把每个词的ID和文章ID一起插入到关系表中。

与其这样,不如把自增的ID,改成自定义的ID。比如可以用 redis 的inc生成自增ID。

首先看看自己的需求什么样,主要存下来干什么,如果只是为了统计某个词的数,一个文章表,一个词语表就好了,
词语表,文章id 词,统计数的时候group by一下也就好了,也就不用管存不存在。

在不考虑性能的情况下,这个是最快的,数据量小的时候可以用的,in的条件小于3000个
把存在的一次筛出来,对比不存在的,批量插入,再把所有词的id一次拿出来

select id
from xxx
where term in ('xx','xx')

问主自己的存储过程中是一条一条插入的,我感觉还是比较慢,我的建议:

  1. 用 replace into 词语表 values (...), (...)来批量插入词语,并避免重复词语
  2. 然后用select id from 词语表 where term in (...)来获取所有词语的id
  3. 最后用insert into 关系表 values (...), (...)批量插入文章和词语的对应关系
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题