<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
		xmlns:xhtml="http://www.w3.org/1999/xhtml"
>

<channel>
	<title>ueblog &#187; mysql</title>
	<atom:link href="http://ueblog.natural-wave.com/tag/mysql/feed/" rel="self" type="application/rss+xml" />
	<link>http://ueblog.natural-wave.com</link>
	<description>Web関連のネタを中心に役立つ情報を配信しています。</description>
	<lastBuildDate>Wed, 11 Jan 2012 00:51:56 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://ueblog.natural-wave.com/tag/mysql/feed/" />
		<item>
		<title>SQLで2点間の緯度経度から距離を測定する方法</title>
		<link>http://ueblog.natural-wave.com/2010/09/14/latitude-longitude-sql/</link>
		<comments>http://ueblog.natural-wave.com/2010/09/14/latitude-longitude-sql/#comments</comments>
		<pubDate>Tue, 14 Sep 2010 14:46:24 +0000</pubDate>
		<dc:creator>ueblog</dc:creator>
				<category><![CDATA[Programing]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://ueblog.natural-wave.com/?p=704</guid>
		<description><![CDATA[位置情報をmysqlなどのRDBMS上に保持して、2点間の距離を求めたり、ユーザの現在地とデータベース上にある位置データとの距離を求めるときにSQLで何とかしようという話です。 まず2点間の距離は、三平方の定理を使うと a^2 + b^2 = c^2（cが斜辺） という]]></description>
			<content:encoded><![CDATA[<p>位置情報をmysqlなどのRDBMS上に保持して、2点間の距離を求めたり、ユーザの現在地とデータベース上にある位置データとの距離を求めるときにSQLで何とかしようという話です。</p>
<p>まず2点間の距離は、<a href="http://ja.wikipedia.org/wiki/%E3%83%94%E3%82%BF%E3%82%B4%E3%83%A9%E3%82%B9%E3%81%AE%E5%AE%9A%E7%90%86" target="_blank">三平方の定理</a>を使うと</p>
<blockquote><p>a^2 + b^2 = c^2（cが斜辺）</p></blockquote>
<p>ということのようです。ただし地球は丸いので直線での公式とは違うため、長い距離になるとずれるようですが、その辺りは誤差として無視することとします。</p>
<p>そしてWikipediaから平均で<a href="http://ja.wikipedia.org/wiki/%E7%B7%AF%E5%BA%A6" target="_blank">緯度</a>1度あたり111km、<a href="http://ja.wikipedia.org/wiki/%E7%B5%8C%E5%BA%A6" target="_blank">経度</a>1度あたり91kmということなので、距離は</p>
<blockquote><p>距離(km) = √((緯度1 - 緯度2) / 0.0111)^2 + ( (経度1 - 経度2) / 0.0091)^2</p></blockquote>
<p>で求められるということになります。</p>
<p>mysqlのSQLで書くと下記のようになります。</p>
<blockquote><p>SELECT SQRT(POWER((緯度1 - 緯度2) / 0.0111, 2) + POWER((経度1 - 経度2) / 0.0091, 2)) AS distance</p></blockquote>
<p>渋谷駅(35.658482,139.701441)と新宿駅(35.690224,139.700089)の距離を求めると、</p>
<div class="igBar"><span id="lcode-3"><a href="#" onclick="javascript:showPlainTxt('code-3'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div id="code-3">
<div class="code">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mysql&gt; SELECT SQRT<span style="color:#006600; font-weight:bold;">&#40;</span>POWER<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#800000;color:#800000;">35</span>.<span style="color:#800000;color:#800000;">658482</span> - <span style="color:#800000;color:#800000;">35</span>.<span style="color:#800000;color:#800000;">690224</span><span style="color:#006600; font-weight:bold;">&#41;</span> / <span style="color:#800000;color:#800000;">0</span>.<span style="color:#800000;color:#800000;">0111</span>, <span style="color:#800000;color:#800000;">2</span><span style="color:#006600; font-weight:bold;">&#41;</span> + power<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#800000;color:#800000;">139</span>.<span style="color:#800000;color:#800000;">701441</span> - <span style="color:#800000;color:#800000;">139</span>.<span style="color:#800000;color:#800000;">70008</span><span style="color:#006600; font-weight:bold;">&#41;</span> / <span style="color:#800000;color:#800000;">0</span>.<span style="color:#800000;color:#800000;">0091</span>, <span style="color:#800000;color:#800000;">2</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> AS distance;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+------------------+</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">| distance&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+------------------+</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">| <span style="color:#800000;color:#800000;">2</span>.<span style="color:#800000;color:#800000;">86354800792301</span> | </div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+------------------+</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#800000;color:#800000;">1</span> row in set <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#800000;color:#800000;">0</span>.<span style="color:#800000;color:#800000;">01</span> sec<span style="color:#006600; font-weight:bold;">&#41;</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>2.8kmくらいになりました。これでデータと現在地の距離を求めて近い順に出すとかがSQLでできてしまいます。例えば下記のような雰囲気で。</p>
<div class="igBar"><span id="lcode-4"><a href="#" onclick="javascript:showPlainTxt('code-4'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div id="code-4">
<div class="code">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">SELECT SQRT<span style="color:#006600; font-weight:bold;">&#40;</span>POWER<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#40;</span>現在地緯度 - lat<span style="color:#006600; font-weight:bold;">&#41;</span> / <span style="color:#800000;color:#800000;">0</span>.<span style="color:#800000;color:#800000;">0111</span>, <span style="color:#800000;color:#800000;">2</span><span style="color:#006600; font-weight:bold;">&#41;</span> + power<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#40;</span>現在地経度 - lng<span style="color:#006600; font-weight:bold;">&#41;</span> / <span style="color:#800000;color:#800000;">0</span>.<span style="color:#800000;color:#800000;">0091</span>, <span style="color:#800000;color:#800000;">2</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> AS distance FROM geodata ORDER BY distance </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
]]></content:encoded>
			<wfw:commentRss>http://ueblog.natural-wave.com/2010/09/14/latitude-longitude-sql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://ueblog.natural-wave.com/2010/09/14/latitude-longitude-sql/" />
	</item>
		<item>
		<title>ライブドアのレコメンデーションエンジン「Cicindela」を試す</title>
		<link>http://ueblog.natural-wave.com/2009/01/25/livedoor-cicindela/</link>
		<comments>http://ueblog.natural-wave.com/2009/01/25/livedoor-cicindela/#comments</comments>
		<pubDate>Sun, 25 Jan 2009 13:42:06 +0000</pubDate>
		<dc:creator>ueblog</dc:creator>
				<category><![CDATA[Programing]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[Livedoor]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://ueblog.natural-wave.com/?p=325</guid>
		<description><![CDATA[livedoorのラボ「EDGE」からリリースされたレコメンデーションエンジン「Cicindela」を試してみた。 Cicindelaは何を提供するか Cicindelaが提供するものは主に下記のものだ。 WebAPIとなるWebプログラム（Handlers） データ解析プログラム（Recommender） データを加工するフィルタ（Filters） 制御、設]]></description>
			<content:encoded><![CDATA[<p>livedoorのラボ「<a href="http://labs.edge.jp/" target="_blank">EDGE</a>」からリリースされたレコメンデーションエンジン「<strong><a href="http://labs.edge.jp/cicindela/" target="_blank">Cicindela</a></strong>」を試してみた。</p>
<h3 class="PostLine">Cicindelaは何を提供するか</h3>
<p><strong><a href="http://labs.edge.jp/cicindela/" target="_blank">Cicindela</a></strong>が提供するものは主に下記のものだ。</p>
<ol>
<li>WebAPIとなるWebプログラム（Handlers）</li>
<li>データ解析プログラム（Recommender）</li>
<li>データを加工するフィルタ（Filters）</li>
<li>制御、設定部分（Config）</li>
<li>その他データ作成用の補助スクリプト等</li>
</ol>
<p>これらすべてが、perlのプログラムで作成されていて、Apache+mod_perl+mysqlな環境で動作する。</p>
<p>内部構造は柔軟な構造になっているらしく、自作のフィルタ（Filter）やレコメンダー（Recommender）を設定（Config）で自由に組み合わせて利用できるようだ。</p>
<p>機能的には、「データの蓄積」「データの操作」「データの取得」の3種類で、すべてWebAPI経由で操作可能だ。</p>
<p><a href="http://code.google.com/p/cicindela2/wiki/WebAPI" target="_blank">WebAPI - cicindela2 - web API 経由でデータを入出力するには / how to input or output data via web API - Google Code</a></p>
<p>アイテムを選択した情報だけでなく、アイテムの評価情報や、タグ情報を付加したり、カテゴリによるフィルタリングも可能なようだ。</p>
<h3 class="PostLine">インストールとセッティング</h3>
<p>さてさっそくインストールだが、基本的に</p>
<p><a href="http://code.google.com/p/cicindela2/wiki/Install" target="_blank">Install - cicindela2 - セットアップ方法 / How to setup - Google Code<br />
</a></p>
<p>こちらに従えばそれほど難しくないが、簡単にメモがてら記しておく。</p>
<blockquote><p># チェックアウト<br />
cd /usr/local<br />
svn checkout http://cicindela2.googlecode.com/svn/trunk/ cicindela<br />
# perlモジュールインストール<br />
perl -MCPAN -e "install DBI; install DBD::mysql; install Ima::DBI; install Time::Piece; install Log::Log4perl; install Module::Pluggable; install Class::Singleton;"</p></blockquote>
<p>Apacheの設定ファイル「<strong>$CICINDELA_HOME/etc/httpd/modperl.conf</strong>」を参考にhttpd.confなどを設定。</p>
<p>mysqlの設定ファイルmy.cnfはDemoをやる際に、メモリが足りなくなる可能性があるので、「<strong>$CICINDELA_HOME/etc/mysql/my.cnf</strong>」を参考に設定しよう。</p>
<p>Apache＋mod_perl＋mysqlのインストールは割愛。</p>
<p>daemontoolsでデータの再集計などをやってくれるようだが、今回は割愛。</p>
<p>デモはこちらを参考</p>
<p><a href="http://code.google.com/p/cicindela2/wiki/Demos" target="_blank">Demos - cicindela2 - デモ用データセットを用いたクイックスタート / quick start with demo datasets - Google Code</a></p>
<p>このデモは「データの蓄積」部分はデータのインポートを利用している。</p>
<blockquote><p># サンプル用のデータを取得(リポジトリのswitch)<br />
cd /usr/local/cicindela<br />
svn switch http://cicindela2.googlecode.com/svn/branches/demo_data/misc misc<br />
# データベース作成<br />
cd misc<br />
perl create_init_sql.pl --db_name=cicindela_clip_db | mysql -uroot<br />
# インポート用にperlのモジュールインストール<br />
perl -MCPAN -e "install Text::CSV_XS;"<br />
# データインポート<br />
cd clip_data<br />
gunzip -c ldclip_demo_dataset.csv.gz | perl importer.pl  --work_dir=`pwd` | mysql -uroot cicindela_clip_db</p></blockquote>
<p>そして、設定ファイル「<strong>$CICINDELA_HOME/lib/<span class="highlight">Cicindela</span>/Config/_common.pm</strong>」の</p>
<blockquote><p>## sample settings for ldclip_dataset</p></blockquote>
<p>以下の設定がコメントアウトになっているので、19行目から69行目あたりまでのコメントを外していく。</p>
<p>なおこのファイルで宣言されている、</p>
<blockquote><p>'clip_simple' =&gt; {<br />
datasource =&gt;  [ 'dbi:mysql:cicindela_clip_db;host=localhost', 'root', '' ],<br />
filters =&gt; [<br />
[ 'PicksExtractor', { interval =&gt; '20 year' } ],<br />
'InverseUserFrequency',<br />
'ItemSimilarities',<br />
],<br />
recommender =&gt; 'ItemSimilarities',<br />
calculation_track =&gt; 1,<br />
refresh_interval =&gt; 1,<br />
},</p></blockquote>
<p>このようなかたまりが、設定の一つ一つになっている。</p>
<p>上記の場合、「clip_simple」というフィルタやレコメンダーなどの設定がされている。（APIで「set=clip_simple」として呼び出される）</p>
<p>datasouceはmysqlに接続する設定なので、各行書き換えておく。</p>
<p>あとは集計バッチを実行する。</p>
<blockquote><p>bin/batch.pl --track=1<br />
bin/batch.pl --track=1</p></blockquote>
<p>初回は2回叩く。</p>
<p>これでApacheが動いているならば、Webブラウザで</p>
<blockquote><p>http://hostname/cicindela/recommend?op=for_item&amp;set=clip_simple&amp;item_id=39102</p></blockquote>
<p>このようにリクエストすると、改行区切りのデータが帰ってくるだろう。</p>
<blockquote><p>49425<br />
44936<br />
42886<br />
37580<br />
37710<br />
40699<br />
39574<br />
41925<br />
40012<br />
44423</p></blockquote>
<h3 class="PostLine">感想</h3>
<p>実際にデータを自分で入れていないので、精度などはまだわからないが、このような難しいロジックを擁するツールがオープンソースで公開されている意義はとても大きい。</p>
<p>また、<a href="http://ja.wikipedia.org/wiki/MIT_License" target="_blank">MITライセンス</a>というとても緩いライセンスなので、再利用等が可能だ。これから積極的に利用していきたいと思う。</p>
<p>個人的には、WebAPIにまで手を出さず、<strong>レコメンドエンジン＋ストレージくらいのシンプルなところで留めておいてもよかったのでは？</strong>と思ったりしますが、今後の動きに期待したい。</p>
<p><strong>mod_perl</strong>は、レンタルサーバじゃほとんど利用できないと思うので、<strong>敷居が高いかと</strong>・・・</p>
]]></content:encoded>
			<wfw:commentRss>http://ueblog.natural-wave.com/2009/01/25/livedoor-cicindela/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://ueblog.natural-wave.com/2009/01/25/livedoor-cicindela/" />
	</item>
	</channel>
</rss>

