xml2sqlでmysqldump形式に変換
wikipediaのコンテンツは、600MB以上ある。それなりに時間が掛かるので、落としている間にデータベースへのインポートの準備。データの提供形態はxmlなので、データベースに入れるにはそれなりの工夫が必要である。幸いwikipedia自体が2種類の方法を提供してくれている。MediaWikiに付属しているimportDump.phpを使うか、xml2sqlというツールをインストールするかが選べる。
他でも使えそうなので、xml2sqlを使うことにした。
xml2sql
$wget ftp://ftp.tietew.jp/pub/wikipedia/xml2sql-0.5.tar.gz $tar xzvf xml2sql-0.5.tar.gz $cd xml2sql-0.5 $./configure $make $sudo make install
xml2sqlを使ってxmlをmysqldump形式に変換。
$bunzip2 -c jawiki-latest-pages-meta-current.xml.bz2 | xml2sql
2.5GB位のtext.txtと、80MB程度のrevision.txt,page.txtが出来る。
ちなみにxml2sqlのオプションは以下の通り。-iがデフォルトで、mysqldumpのフォーマットで出力してくれる。
Options -i, --import mysqlimport format. (default) Output filenames are page.txt, revision.txt, and text.txt. You can use mysqlimport program to import this format. -m, --mysql MySQL's INSERT format. Output filenames are page.sql, revision.sql, and text.sql. You can use mysql program to import this format. -p, --postgresql[=version] PostgreSQL's COPY format. Output filenames are page.sql, revision.sql, and text.sql. If the version is omitted, 8.0 and earlier is assumed. You can use psql program to import this format. -c, --compress[={old,full}] Compress text table with deflate. (default: old) When output format is postgresql, this option is ignored because PostgreSQL will compress table data itself. -r, --renumber Renumber page id and revision id. -N, --namespace=ns,ns,... Output only specifig namespaces. Namespaces can be specified by both namespace number and namespace name. -t, --no-text Exclude text table -o, --output-dir=OUTDIR Specifies output directory (default: current directory) -t, --tmpdir=TMPDIR Specifies temporary directory (default: OUTDIR) Temporary file is used only if --compress=old. -v, --verbose Show progress -h, --help Display help and exit --version Display version information and exit
データベースの準備
残念ながらテーブル作成のSQLまでは作ってくれないので、自前でテーブルを作成する。tables.sqlのページに必要なDDLが書いてある。今回必要なのは、page,revision,textの3つのテーブルだけ。(コーパスと言う意味では、textだけだが。)
create database corpus; use corpus; CREATE TABLE page ( page_id int unsigned NOT NULL auto_increment, page_namespace int NOT NULL, page_title varchar(255) binary NOT NULL, page_restrictions tinyblob NOT NULL, page_counter bigint unsigned NOT NULL default '0', page_is_redirect tinyint unsigned NOT NULL default '0', page_is_new tinyint unsigned NOT NULL default '0', page_random real unsigned NOT NULL, page_touched binary(14) NOT NULL default '', page_latest int unsigned NOT NULL, page_len int unsigned NOT NULL, PRIMARY KEY page_id (page_id), UNIQUE INDEX name_title (page_namespace,page_title), -- Special-purpose indexes INDEX (page_random), INDEX (page_len) ); CREATE TABLE revision ( rev_id int unsigned NOT NULL auto_increment, rev_page int unsigned NOT NULL, rev_text_id int unsigned NOT NULL, rev_comment tinyblob NOT NULL, rev_user int unsigned NOT NULL default '0', rev_user_text varchar(255) binary NOT NULL default '', rev_timestamp binary(14) NOT NULL default '', rev_minor_edit tinyint unsigned NOT NULL default '0', rev_deleted tinyint unsigned NOT NULL default '0', rev_len int unsigned, rev_parent_id int unsigned default NULL, PRIMARY KEY rev_page_id (rev_page, rev_id), UNIQUE INDEX rev_id (rev_id), INDEX rev_timestamp (rev_timestamp), INDEX page_timestamp (rev_page,rev_timestamp), INDEX user_timestamp (rev_user,rev_timestamp), INDEX usertext_timestamp (rev_user_text,rev_timestamp) ) MAX_ROWS=10000000 AVG_ROW_LENGTH=1024; CREATE TABLE text ( old_id int unsigned NOT NULL auto_increment, old_text mediumblob NOT NULL, old_flags tinyblob NOT NULL, PRIMARY KEY old_id (old_id) ) MAX_ROWS=10000000 AVG_ROW_LENGTH=10240;
データのインポート
準備が整ったので、いよいよデータのインポート
mysqlimport -u username corpus /dir/data/*.txt
エラーが出た。pageテーブルがuniq制約で引っ掛かってるとのこと。なんでやねん。
mysqlimport: Error: Duplicate entry '0-辰' for key 2, when using table: page
他の二つのテーブルは問題なく上手くいくので、とりあえずuniq制約を外してインポートしてみる。
無事成功。どのレコードが問題なのか調べてみる。
select page_namespace,page_title,count(*) from page group by page_namespace,page_title having count(*) > 1; +----------------+------------+----------+ | page_namespace | page_title | count(*) | +----------------+------------+----------+ | 0 | | 2 | | 0 | 辰 | 2 | | 2 | | 2 | +----------------+------------+----------+ 3 rows in set (10.60 sec)
放置決定。これにて、データベースへのインポートは終了。次は、これからコーパスの作成へ