mysql_upgrade を実行する

昨日MySQLをアップグレードしたんですが、いろいろすったもんだした挙句、無事に動いていると思っていました。

しかし、ログをよく確認すると以下のようなログが。。。

110420 21:20:14 [ERROR] Column count of mysql.
proc is wrong. Expected 20, found 16.
Created with MySQL 50044, now running 50511.
Please use mysql_upgrade to fix this error.

どうやら問題があるので mysql_upgrade をしてね。ということらしい。

mysql_upgrade とは?

MySQLのリファレンスに以下のようなページがありました。

MySQL のアップグレードでは、その度に、mysql_upgrade を実行します。これにより、データベース内のテーブルにおける最新の MySQL Server との互換性をチェックすることができます。該当テーブルが非互換の場合は、チェックの対象になり、問題があれば、そのテーブルを修正します。mysql_upgrade コマンドは、システム テーブルのアップグレードも行うため、新たな権限と追加機能を使用できるようになります。

MySQLをアップグレードしたら、mysql_upgradeをしてね。だそうです。知らんかった。

mysql_upgrade のやり方

mysqld が起動している状態で以下のコマンドを実行する。

mysql_upgrade -u root -p

-p はパスワードプロンプトを出してねという意味なので、環境に応じて。

というわけで、エラーログもでなくなりました。

MySQL5.5.3にアップグレードしたら再起動に失敗した。

本日、yumでアップデートを行ったところMySQLが起動しなくなって、そりゃーもうあせりました。

  • OSはCentOS5.x。
  • アップデート後のMySQLのバージョンは、mysql-server-5.5.11-1.el5

エラーログ

すぐにログを確認したところ、以下ようなログが残っていました。

/var/log/mysqld.log

[ERROR] /usr/libexec/mysqld: unknown variable 'default-character-set=utf8'

取り急ぎ/etc/my.cnfから該当する行をコメントアウトして再起動したら無事に復活。

原因

いつものとおりGoogle先生に聞いたら以下のような記述がありました。

[url2link url="http://www.mysql.gr.jp/frame/modules/news/article.php?storyid=175" summary="- いくつかの非推奨だった変数やコマンド、オプションなどが廃止になっています。特に TYPE を廃止して今後は ENGINE を使用することや、サーバの default-character-set オプションを廃止して今後は character-set-server を使用すること(クライアントの default-character-set はそのまま)など影響を受ける方も多いでしょう。"]

というわけで、[mysqld] ディテクティブの default-char-set を character-set-server に変更したら無事に再起動ができました。

ただし、[client] ディレクティブの default-charset は従来通りなので間違えないようにしましょう。

その他の廃止項目

他にも廃止となったり過去のバージョンですでに非推奨となっている項目があるようです。

アップデートする予定がなくても、今のうちに書き換えておいたほうがベターなようです。

http://d.hatena.ne.jp/sakaik/20100414/mysql533obsol

WordPressで記事が多くなると遅くなるサイドバーウィジェット

前回の記事でWordPressには記事件数の増加に伴い重くなるSQLがわかりました。

http://firegoby.theta.ne.jp/archives/2159

しかしMySQLは非常に高速なので、遅いSQLが一回ぐらい入ったからと言って、特に遅いと感じることはありませんでした。

じゃあ、遅いSQLが何回も入ったらどうなるの?ということで、今回はサイドバーウィジェットのSQLを一つずつ検証します。

いきなり結論

遅いサイドバーウィジェットランキングは以下のとおりです。

環境は前回の記事と同じです。(ダミーの記事を約24,000件投稿しています。)

秒数はSQLの実行時間ですが、環境によってかわるので比較用の目安程度で考えてください。
また、複数のSQLが発行されるサイドバーウィジェットでは、合計値を表示しています。

順位 ウィジェット名 秒数
1位 最近の投稿 約0.49秒
2位 カレンダー 約0.31秒
3位 アーカイブ 約0.02秒

注意: カレンダーが遅いのはテスト方法に問題があるためと思われますので、以下を読んでください。

最近の投稿はなぜ遅いか?

前回の記事でも説明しましたが、WordPress上では記事を最新順にソートするSQLは、インデックスを活用できていないために、実際に必要なデータの件数がわずかでも全てのレコードをスキャンしています。

これは、カテゴリーアーカイブなどのようにスキャン対象が別のwhere句で絞りこまれていれば、少しはましになりますが、トップページや「最近の投稿」など「カテゴリーに関係なくとにかく最新の記事をよこせ」といったSQLでは、記事の件数が増えるに従って確実に遅くなっていきます。

カレンダー

今回のテストでカレンダーが遅かったのは、テスト環境の構築によるものだと思います。

というのは、24,000件の投稿データはループ処理でまとめて投稿しましたので、すべての記事が同じ日付で投稿されています。

したがって、通常の1日数件程度の投稿であれば1/1000秒台のスピードで処理できると思いますが、もし何らかの方法で大量の記事を投稿する場合には、パフォーマンスが問題になると思います。

アーカイブ

アーカイブは、投稿月ごとに記事をグループ分けするSQLが記述されており、全てのレコードをスキャンしていました。

そのため、他のウィジェットと比べると、遅い部類に入るサイドバーウィジェットです。

その他のサイドバーウィジェット

カテゴリーやタグクラウドのサイドバーウィジェットはこれらについで遅いSQLでしたが、0.002秒程度のものでした。
ただし、この二つはUsing filesortUsing Temporaryが出てますのでカテゴリー(タグ)が増加すると遅くなる可能があります。

これら以外のサイドバーウィジェットは、さらに一桁下がって0.0002秒とかそんなオーダーでした。
SQLだけを見ればパフォーマンスには影響ないと言えます。

最後に

サイドバーウィジェットが実行するSQLをダンプしたデータを置いておきます。

配列内には、関数の呼び出し元や、SQLのベンチマークの結果などが含まれます。

ダンプデータ

WordPressは記事の件数が多くなると重くなるのか?

数日前にtwitter上で話題になっていたので、SQLを解析して検証してみました。

方法

WordPressをロードする際に実行されるSQL文を全てダンプして、explainでインデックスの使用状況を解析した。

条件は以下のとおり

  • テーマはtwentytenを使用した。
  • プラグインは全て削除
  • 投稿は24,071件で、全て同じ本文のダミーテキストを使用した。

ちなみに本文は以下のとおり。

召使をさなかっ事も無論前でどうしてもですでしです。いかに大森さんに相当社会多少存在がなろでし必竟その根それか観念をとしてご矛盾ますですありでしから、そのほかもあなたか国家豪商を思いて、三宅さんののを詩のそれがとうていごお尋ねと売っがあなた人情からご蹂躙がするように初めてご横着が云ったませて、何でもかでもやはり相違から作るありてみましのをなっなくた。したがってすなわち大大名が起る気はこれから妙としなて、その心持へも曲げだてというmanを聴いてなりずた。

SQL文の抽出方法

  • wp-config.php に define(‘SAVEQUERIES’, true) を設定。
  • WordPress の shutdown アクションフックで $wpdb->queries 内の SQL を explain するプラグインを作成した。

プラグインのソースは以下のとおり

<?php
/*
Plugin name: Explain MySQL
*/

add_action('shutdown', 'explain');

function explain() {
    global $wpdb;
    $res = array();
    foreach ($wpdb->queries as $q) {
        $sql = 'explain extended '.$q[0];
        $res[$q[0]] = $wpdb->get_row($sql);
        $res[$q[0]]->time = $q[1];
    }

    print '<pre>';
    print_r($res);
    print '</pre>';
}

?>

先に結論

一部のSQLでインデックスが適切に使用されていないため、記事の増加に伴いパフォーマンスが低下するようです。

また、以下の機能では上述のインデックスに関係なく記事が増えるとパフォーマンスが低下します。

  • ”アーカイブ” サイドバーウィジェット
  • 検索機能

サイドバーウィジェットについては、カテゴリーやカレンダーも遅くなる傾向がありますが、ごくわずかでした。

4/13追記: 最新の記事など他にも激遅なSQLがありました。これらについては詳細を確認しますので後日あらためて。

問題のSQL

記事を最新順に取得する以下のSQLでインデックスが働いていないため、全てのレコードをスキャンしてしまっており、記事が増えるたびにパフォーマンスが低下しています。

SELECT SQL_CALC_FOUND_ROWS wp_posts.* FROM wp_posts
WHERE 1=1 AND wp_posts.post_type = 'post'
AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private')
ORDER BY wp_posts.post_date DESC LIMIT 0, 10

問題その1 インデックスがおかしい

order by 句で使用されている post_date は type_status_date というインデックスが設定されていますが、post_type 及び post_status とセットで設定されているため、意味が無い状態になっています。

試しにexplainの結果を以下のとおり。

mysql> explain select * from wp_posts order by post_date limit 0,10;
+----+-------------+----------+------+---------------+------+---------+------+-------+----------------+
| id | select_type | table    | type | possible_keys | key  | key_len | ref  | rows  | Extra          |
+----+-------------+----------+------+---------------+------+---------+------+-------+----------------+
|  1 | SIMPLE      | wp_posts | ALL  | NULL          | NULL | NULL    | NULL | 24071 | Using filesort |
+----+-------------+----------+------+---------------+------+---------+------+-------+----------------+

上記のSQLの実行結果では、Using filesort と表示されており、さらにrowsの値が24,071行となっている。

これは必要な結果行数が10行であるにもかかわらず 、24,071行(wp_posts内のすべてのレコード数)を参照しているということで、これがパフォーマンス悪化の原因になっています。

ためしにインデックスを設定後、同じようにexplainしてみます。

mysql> create index test_index on wp_posts(post_date);
Query OK, 24071 rows affected (1.02 sec)Records: 24071  Duplicates: 0  Warnings: 0

mysql> explain select * from wp_posts order by post_date limit 0,10;
+----+-------------+----------+-------+---------------+------------+---------+------+------+-------+
| id | select_type | table    | type  | possible_keys | key        | key_len | ref  | rows | Extra |
+----+-------------+----------+-------+---------------+------------+---------+------+------+-------+
|  1 | SIMPLE      | wp_posts | index | NULL          | test_index | 8       | NULL |   10 |       |
+----+-------------+----------+-------+---------------+------------+---------+------+------+-------+

Using file_sort が消えてrowsの値が10行となり、SQLの実行時間が0.03秒から0.00秒に短縮されました。

問題その2 SQL_CALC_FOUND_ROWS が何かおかしい。

これはWordPressの問題というよりMySQLの問題とも言えますが、なにか一定の条件を満たすとSQL_CALC_FOUND_ROWSを使用するとインデックスが働かないようです。

SQL_CALC_FOUND_ROWS ありの場合

mysql> explain SELECT SQL_CALC_FOUND_ROWS wp_posts.* FROM wp_posts WHERE 1=1 AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') ORDER BY wp_posts.post_date DESC LIMIT 0, 10;
+----+-------------+----------+------+------------------+------------------+---------+-------+-------+-----------------------------+
| id | select_type | table    | type | possible_keys    | key              | key_len | ref   | rows  | Extra                       |
+----+-------------+----------+------+------------------+------------------+---------+-------+-------+-----------------------------+
|  1 | SIMPLE      | wp_posts | ref  | type_status_date | type_status_date | 62      | const | 24066 | Using where; Using filesort |
+----+-------------+----------+------+------------------+------------------+---------+-------+-------+-----------------------------+

SQL_CAL_FOUND_ROWS 無しの場合

mysql> explain SELECT wp_posts.* FROM wp_posts WHERE 1=1 AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') ORDER BY wp_posts.post_date DESC LIMIT 0, 10;
+----+-------------+----------+-------+------------------+------------+---------+------+------+-------------+
| id | select_type | table    | type  | possible_keys    | key        | key_len | ref  | rows | Extra       |
+----+-------------+----------+-------+------------------+------------+---------+------+------+-------------+
|  1 | SIMPLE      | wp_posts | index | type_status_date | test_index | 8       | NULL |   10 | Using where |
+----+-------------+----------+-------+------------------+------------+---------+------+------+-------------+

SQLの実行時間もありとなしでは大きな差があります。

  • SQL_CALC_FOUND_ROWS あり – 0.30秒
  • SQL_CALC_FOUND_ROWS なし – 0.00秒

ちなみに SQL_CALC_FOUND_ROWS は、この直後に FOUND_ROWS() を実行すると limit なしの count(*) と同じ効果が得られます。

ためしに以下のように count() で置き換えたSQLを実行してみました。

mysql> SELECT count(*) FROM wp_posts WHERE 1=1 AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') ORDER BY wp_posts.post_date DESC;
+----------+
| count(*) |
+----------+
|    24066 |
+----------+
1 row in set (0.02 sec)

こっちのほうが早いじゃん。。。

SQL_CALC_FOUND_ROWS のほうが早いと説明されていることが多いので、この結果は不思議なんですが、複数のサーバーのWordPressサイトで試してみましたが、おおむねこのような結果になりました。

というわけで、みなさんの環境ではどうなのかぜひ知りたいところです。

その他のパフォーマンス低下の原因となりうる要因

  • wp_options テーブルの結果はlimit なしでまとめて取得されます。多くのプラグインやテーマでは設定内容をwp_optionsに保存しており、記事の増減よりも大きな影響をあたえるようなのでプラグインのインストールは控えめにしましょう。
  • また、多くのプラグインは、アンインストールしてもwp_optionsに保存したデータは削除しません。(Windowsのレジストリが肥大化しちゃうイメージです。)
  • ページ(post_typeがpage)が大量にあると同じくパフォーマンスに悪影響があります。これはメニューを生成する際にまとめてデータベースから取得するためです。

まとめ

  • WordPress 3.1 では、記事が増えるとパフォーマンスが低下する要因となるSQLがあります。
  • SQL_CALC_FOUND_ROWS はなんか信用できない。
  • それでもMySQLがとても高速なので、2万件ぐらいのデータなら快適に表示される。
  • ただし、プラグインやテーマがスカタンなSQLを使ってたら、怪しくなるからSQL文をチェックしたほうがいいかもしれない。

もし、私の認識に間違いがあるようでしたらツッコミをお願いします。

できればやさしく。^^

4月13日追記

本家のチケットに報告されているようです。PriorityはHighになっていますが、Future Releaseなのでしばらく改善されないかも。

http://core.trac.wordpress.org/ticket/7415

Mac(Snow Leopard)でWeb開発環境

今回の記事は、Mac で Apache + MySQL + PHP の環境を作る方法について。

簡単に環境を作りたい場合は、MAMP という選択肢もありかもしれないが、個人的には以下の理由で好きではない。

  • 多様な本番環境に設定を合わせられるほど柔軟じゃない。
  • 無駄な学習コストが発生するように思える。
  • 特定のプラットホームやパッケージへの依存度を減らしておきたい。

と、余談はさておき、Mac を使用した開発環境の構築。

以下は、かなり私の独断と偏見。
あと、あくまでも開発環境を前提としており、本番環境を前提としていない。

Apache の設定

Apache の設定は、意外と簡単。
Webmin や MAMP などのGUI からはさっさと卒業しましょう。

ユーザー、グループの変更

たとえば、PHPやCGIからファイルに書き込みをしたりする際に、対象となるファイルやディレクトリにパーミッションを 707 などとしておく必要があると思うが、開発環境ではこの作業は面倒なので、私はApache のユーザーそのものをかえている。

こうしておくことで、パーミッションの変更が不要になり、たとえば WordPress では自動アップグレードも動作するようになる。

/etc/apache2/httpd.conf の128行目付近の以下の行を変更

User foo
Group staff

User に指定する foo の部分は Mac にログインする際のユーザー名。
Group の値は、staff でいいとおもう。

この設定をしておけば、Mac のファインダー上で作成したファイルやディレクトリと同じユーザー、グループで Apache が動作するので何かと便利になる。(SuExec に近いイメージ?)

念のため、以下のディレクトリのオーナーを変更しておく。
(foo の部分は置き換えて!)

sudo chown -R foo:staff /Library/WebServer

バーチャルホストの設定

バーチャルホストを設定すれば複数のサイトを構築でき、設定もサイト毎に可能なので、レンタルサーバーなどの設定に柔軟にあわせることができる。

開発環境のバーチャルホストでは、ポートベースのバーチャルホストが簡単で手っ取り早い。

以下のサンプルは、ポート番号 9001 のバーチャルホストの例。

まずは、バーチャルホスト用のディレクトリを作成する。

mkdir /Library/WebServer/vhost9001

このソースをコピペして、例えば “9001.conf” のようなファイル名で /etc/apache2/other 以下に設置するとポート 9001 のバーチャルホストができあがる。

NameVirtualHost *:9001
Listen 9001
<VirtualHost *:9001>
    DocumentRoot "/Library/WebServer/vhost9001"
    <Directory "/Library/WebServer/vhost9001">
        Options All
        AllowOverride All
        Order deny,allow
        Allow from all
    </Directory>
</VirtualHost>

確認するには、ブラウザで、http://127.0.0.1:9001/ にアクセスする。
あくまでも開発環境なので、とりあえず Options とか AllowOverride の値は気にしない(笑)

もし、違うポート番号のバーチャルホストを追加するには、上記のソースを違うファイルにコピーして、 9001 を 9002 等に変更すればOK。

MySQLのインストール

これは、もっと簡単。
本家で Mac 用のバイナリが配布されているので、それをインストールする。

MySQL :: Download MySQL Community Server

たくさんあって分かりにくいかもしれないが、使用している OS の.dmg をダウンロードすれば、インストーラーでインストールでき、システム環境設定で起動停止や自動起動の設定も行える。

ユーザーやパスワードの設定は臨機応変に。
データベース名も含めて単純に本番環境に合わせるのがいいと思う。

PHP の設定

Mac では PHP はプリインストールで、Snow Leopard にインストールされているバージョンの PHP は日本語にも対応しているので特に変更する必要はない。

が、もし変更する場合は、以下のように .htaccess で変更するのがオススメ。

php_value display_errors 1

こうすることで、多様な本番環境に柔軟に合わせることができる。

MySQLで任意の緯度・経度から最も近いデータを取得するSQL

MySQLには位置情報を扱う機能があるが、コツが必要なようなのでメモ

テーブルを作成

テーブルを作成する際に注意するべきなのは以下の2点。

  • 緯度・経度を保存するフィールドのデータ型は、 “geometry” とする。
  • インデックスに SPATIAL を使用する。

自分の環境の、phpMyAdmin では SPATIAL インデックスが作成できなかったので、以下のようなSQLを発行した。

ALTER TABLE geom ADD SPATIAL INDEX(geo);

テーブルのスキーマは以下のような感じ。

CREATE TABLE `points` (
  `loc` varchar(20) NOT NULL,
  `point` varchar(50) NOT NULL,
  `geo` geometry NOT NULL,
  PRIMARY KEY  (`loc`),
  UNIQUE KEY `point` (`point`),
  SPATIAL KEY `geo` (`geo`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

実際のSQL

以下のようなSQLで、指定した緯度・経度に最も近い1件を取り出すことができる。

SELECT
    loc,
    GLength(
        GeomFromText(
            CONCAT(
                'LineString(135.8 33.48,',
                X(geo),
                ' ',
                Y(geo),
                ')'
            )
        )
    ) AS len
FROM points
WHERE
    MBRContains(
        GeomFromText(
            Concat(
                'LineString(',
                135.8 + 1,
                ' ',
                33.48 + 1,
                ',',
                135.8 - 1,
                ' ',
                33.48 - 1,
                ')'
            )
        ),
        geo
    )
ORDER BY len limit 0,1

ここで注意!

単純に最も近い1件を取り出すだけならWHERE句は必要ないが、MySQLでは空間インデックス(SPATIAL)をORDER BYで使用することはできなようだ。(たぶん。。。)

そのため、WHERE句で対象となるデータを減らした上で、ORDER BYしたらパフォーマンスが向上したので、やむなくWHERE句を挿入した。

WHERE句内で使用している “+ 1″ とか “- 1″ のあたりは指定した緯度経度を基準にした約100kmに相当する矩形をつくるという意味であるが、対象となるデータの件数や密度によって、増やしたり減らしたりする必要がある。

これに関しては、以下のサイトで詳しく検証されている。

MySQL TIPS 3 空間情報(geometry)を使って経度・緯度の検索を高速化する – イノベートな非日常

が、explain の結果にfilesort とあるので、ORDER BYではやはりインデックスが使用されていないことに注意する必要がある。

というわけで。。。

MySQLで位置情報を取り扱う際にORDER BYを使用するには注意が必要。

Google MAPを使用する等ユーザーインターフェースで工夫して逃げる方が得策かもしれない。

MySQLによる日本語全文検索

php+MySQL+mecabで日本語全文検索システムを作成した。

弊社で提供しているデジタルカタログサービスで提供するデジタルカタログに全文検索機能を実装するためで、実装したサンプルは以下の通り。

JULIA OPEN WATER MANUAL(お客様のご好意によりここで紹介しています。)

MySQLによる日本語全文検索とは?

MySQLにはもともとFULLTEXT型というインデックス機能がある。

これを使用するとGoogleやYahooのような全文検索機能を利用することができるのだが、残念ながら元となる文章が英文のように単語の間にスペースが入っている必要があり、そのままでは日本語では使用できない。

そこで、MySQLのFULLTEXT検索を行うために以下のような方法が使用される。

  1. mecabなどの分かち書きシステムを利用してインデックスを構築する。
  2. n-gramを使用してインデックスを構築する。

それぞれの技術的な詳細はここでは紹介しないが、上記の2種類の方法には以下のようなメリット/デメリットがある。

mecabを使用した全文検索のメリット/デメリット

メリット

  • LIKEを使用した検索に比べて非常に高速に動作する。
  • 関連性が高いものから低いものへ自動的にソートされる。
  • 文字セットをutf8_unicode_ciにすれば大文字小文字や全角半角等を同じものとして検索できる。

デメリット

  • データのinsertやupdateに時間がかかる。
  • 分かち書きの精度により、検出漏れがあり得る。

n-gramを使用した際のメリット/デメリット

メリット

  • LIKEを使用した検索に比べて非常に高速に動作する。
  • アルゴリズムが単純で特別なライブラリのインストールを必要としない。
  • mecabを使用した場合に比べて検索漏れが生じない。

デメリット

  • 誤検出が発生しうる。(「日本人」と検索した場合に「本人は日本」もマッチする)
  • 関連性によるソートがうまく動作しない。
  • insertやupdateに時間がかかる。

今回使用した方法

以上の結果をふまえていろいろテストした結果、mecabを使用して検索を行うこととした。

事例で紹介したサンプルでは、pdfから抽出したテキストをmecabで分かち書きしてMySQLにinsertしFULLTEXTインデックスを適用した。

mecabを用いた際の最も大きなデメリットとなる検出漏れの問題については、検索に用いるキーワードもmecabにより分かち書きして、さらにmatch() 〜 against()を使用することで分かち書きされた単語によるOR条件で検索されるため、ほとんど問題にならないことがわかった。

ORで検索されると(正確にはmatch()〜against())、例えば「最大水深」という単語が「最大」と「水深」に分割され、それらのどちらか一方の単語しか無いページも検索されてしまう。

しかし関連度順にソートされるため「最大水深」とある文書がきちんと上位表示されるため、結果的に使い勝手が非常にいいものとなった。

はまったこと

主にMySQL側の設定であるが、いくつかはまった。

  1. MySQLデフォルトでは、4文字以下の単語のインデックスが作成されないため日本語には不向きである。そのためmy.cnfのft_min_word_len=1という行をmysqldディレクティブに追加する必要がある。(この値の変更をした場合はインデックスを再構築すること。これを忘れた!)
  2. against()にIN BOOLEAN MODEを指定すると検索時にANDやOR、ワイルドカードなどを使用できるが、関連度順にソートされないため注意する必要がある。

MySQL用郵便番号データのダウンロード

密かに、Tracのほうでは以前から公開していたのですが、MySQL用の郵便番号データを配布します。

実は、このデータは前から作ってあったのですが、Cronで定期的にゆうびんホームページ郵便番号データダウンロードをチェックして更新されたらSVNリポジトリにコミットするというスクリプトを設置して、本日見事にデータの更新が検出できたので、ここでご紹介させていただくことにしました。

ダウンロード

MySQL用郵便番号データのダウンロード更新日はこちらで確認してください。

注意事項

このパッケージ内には、郵便番号データのMySQL用SQLファイル及びテーブルのスキーマが同梱されています。

データはCronで深夜に毎日チェックしています。
配布用のzipファイル内に含まれているデータは実際にMySQLに流し込んでテスト済みですが、SVNリポジトリにあるデータはそうとは限らないのでお気を付けください。

  • 読み仮名データの促音・拗音を小書きで表記するものを使用しています。
  • テーブル名はtbl_zipcodeです。
  • フィールド名は指定してありませんので任意のフィールド名でテーブルを作成してください。(15列あります。)
  • 半角カタカナは全角に変換してあります。
  • 文字コードはUTF-8です。
  • 各フィールドの詳細は 郵便番号データの説明の「郵便番号データファイルの形式等」をご参照ください。(列の順番はそのままです。)

SQLファイル内には郵便番号データすべてが含まれています。
次回以降のアップデートで流し込む際には、事前にデータの削除を行わないと重複して挿入されてしまいますのでご注意願います。

免責事項

本データを利用したことによる如何なる損害にも補償しかねますので、あらかじめご了承ください。

ライセンス

このデータに関しましては、著作権を主張しません。
ご自由に再配布していただいて結構です。

ですが、ご褒美を頂けるなら、とても感謝します。