【问题标题】:split keywords for post php mysql拆分post php mysql的关键字
【发布时间】:2010-10-13 21:48:00
【问题描述】:

我有一个表存储帖子 ID,它的标签如下:

Post_id |  Tags
--------------------------------------
1       |  keyword1,keyword2,keyword3

我想遍历该表的每一行并执行以下操作:

  • 把keyword1,keyword2,keyword3放到新表中:

    word_id    |  word_value
    -------------------------
       1       |  keyword1
       2       |  keyword2    
       3       |  keyword3
    
  • get mysql_insert_id() foreach(如果 word_value 已经存在,则存在 word_id),然后像这样放入新表中:

    post_id |  word_id
    ------------------
    1       |   1    
    1       |   2    
    1       |   3
    

我使用 php 和 mysql 来完成这项任务,但这很慢。有人有好主意吗?

【问题讨论】:

  • 你能在这里发布你的脚本来完成这个任务吗?还有原表有多少条记录?
  • OP 自从 =/

标签: php mysql split


【解决方案1】:

做这样的事情:

-- 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;

【讨论】:

  • 这很好用。它为我节省了很多时间,我希望我能更多地投票......
【解决方案2】:

对于每个关键字,做

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

如果是 SET 类型。

【讨论】:

    猜你喜欢
    • 2015-07-25
    • 2018-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-17
    • 1970-01-01
    • 2015-08-24
    相关资源
    最近更新 更多