拆分关键字后的PHP MySQL
我有一个表存储邮政编号,它的标签如:
Post_id | Tags -------------------------------------- 1 | keyword1,keyword2,keyword3
我想循环这个表格中的每一行,并执行:
-
把关键字1,关键字2,关键字3放在新表中:
word_id | word_value ------------------------- 1 | keyword1 2 | keyword2 3 | keyword3
-
得到mysql_insert_id()foreach(或者如果word_value已经存在,则存在word_id),然后放入新表中,如:
post_id | word_id ------------------ 1 | 1 1 | 2 1 | 3
我已经使用PHP和MySQL做这个任务,但这是慢慢的。 任何人有好主意?
做这样的事情:
-- TABLES drop table if exists post_tags; create table post_tags ( post_id int unsigned not null auto_increment primary key, tags_csv varchar(1024) not null ) engine=innodb; drop table if exists keywords; create table keywords ( keyword_id mediumint unsigned not null auto_increment primary key, name varchar(255) unique not null ) engine=innodb; -- optimised for queries such as - select all posts that have keyword 3 drop table if exists post_keywords; create table post_keywords ( keyword_id mediumint unsigned not null, post_id int unsigned not null, primary key (keyword_id, post_id), -- clustered composite PK ! key (post_id) ) engine=innodb; -- STORED PROCEDURES drop procedure if exists normalise_post_tags; delimiter # create procedure normalise_post_tags() proc_main:begin declare v_cursor_done tinyint unsigned default 0; -- watch out for variable names that have the same names as fields !! declare v_post_id int unsigned; declare v_tags_csv varchar(1024); declare v_keyword varchar(255); declare v_keyword_id mediumint unsigned; declare v_tags_done tinyint unsigned; declare v_tags_idx int unsigned; declare v_cursor cursor for select post_id, tags_csv from post_tags order by post_id; declare continue handler for not found set v_cursor_done = 1; set autocommit = 0; open v_cursor; repeat fetch v_cursor into v_post_id, v_tags_csv; -- split the out the v_tags_csv and insert set v_tags_done = 0; set v_tags_idx = 1; while not v_tags_done do set v_keyword = substring(v_tags_csv, v_tags_idx, if(locate(',', v_tags_csv, v_tags_idx) > 0, locate(',', v_tags_csv, v_tags_idx) - v_tags_idx, length(v_tags_csv))); if length(v_keyword) > 0 then set v_tags_idx = v_tags_idx + length(v_keyword) + 1; set v_keyword = trim(v_keyword); -- add the keyword if it doesnt already exist insert ignore into keywords (name) values (v_keyword); select keyword_id into v_keyword_id from keywords where name = v_keyword; -- add the post_keywords insert ignore into post_keywords (keyword_id, post_id) values (v_keyword_id, v_post_id); else set v_tags_done = 1; end if; end while; until v_cursor_done end repeat; close v_cursor; commit; end proc_main # delimiter ; -- TEST DATA insert into post_tags (tags_csv) values ('keyword1,keyword2,keyword3'), ('keyword1,keyword5'), ('keyword4,keyword3,keyword6,keyword1'); -- TESTING call normalise_post_tags(); select * from post_tags order by post_id; select * from keywords order by keyword_id; select * from post_keywords order by keyword_id, post_id;
为每个关键字,做
insert into newtable (id, keyword) select id, 'aKeyword' from oldtable where oldtable.keywords like '%aKeyword%'
如果oldtable.keywords只是一个VARCHAR,或者
insert into newtable (id, keyword) select id, 'aKeyword' from oldtable where FIND_IN_SET('aKeyword',keywords)>0
如果它是一个SETtypes。