エモンのブログ(スマホアプリ作成日記) -17ページ目

エモンのブログ(スマホアプリ作成日記)

エモンのブログです。

GooglePlayとAppStoreにアプリをリリースしてます。
「詰将棋パラダイス」4500問無料で公開。
「みんなのしょうぎ」投票型の将棋対局。いずれもソーシャルアプリなので、ソーシャルゲーム作成に興味があるかたは是非ご覧ください。

Android向けに「詰将棋パラダイス」をリリースしました。
詰将棋作家127名、作品数1700以上。詰将棋を解答してランキングを競ったり、作品を評価したりできます。また創作して発表することもできます。
iOSはうまくいけば9月1日くらいかな。

相互リンクは常に募集してます。アプリからリンクが可能ですので、是非ご連絡下さい。
詳しくはここの下部をご覧ください。
詰将棋パラダイス(空気ラボ)


詰将棋的なこと

詰将棋作家さんにとって、もっと発表の場を広く持たせたいということと、創作のハードルを下げたかったという狙いがあります。
詰将棋ってのは解くだけでなくて、創作するのも面白いのだということを知ってほしいですね。
みなさまの協力があって、すごい規模になりました。無料でこれだけの作品があるアプリはたぶん他にないでしょう。皆様ダウンロードをお願い致します。※できればレビューもしてほしいなーなんて。


制作的なこと

制作的にはかなり苦しい環境でした。
実はガラケー版の「詰将棋パラダイス」が既に存在していて、そこからの移行ユーザもケアしていく必要があるんです。しかし、ガラケー版のほうのプログラムが実にやっかい。いったいだれが作ったんだろう。

ガラケー版の環境がJava+tomcat+mysqlで、プログラム忘れ気味ってのと、DBの構成の仕方が、むかしむかしのOracleを引っ張っているので全部大文字だし、サロゲートキーが無い。
ユーザの識別が「なんとなく」ユニークという始末。

今回の制作環境をAIR&CakePHPにしました。環境は自分にとって使いやすいのが一番ですからね。
スマホでソーシャルゲームを作ろうとする人に参考にしていただければと思います。
それに関しては別記事にてまとめようかと思います。

MySQLでorder by句を使って検索する際、
select  * from test_table where date = '20120819' order by time limit 0, 10;

とかやってたら実に重くなってしまいました。
ところが、
select  * from test_table where date = '20120819' order by time limit 0, 3;

とすると軽くなったのです。
違いはlimit句のみなのになぜ?
ちなみにこのテーブルのdate='20120819'のレコードは4件しかありません。
INDEXはdateで貼ってあります。
重くなっていたときはまるで
test_table全てでorderしているかのような振る舞いであり、軽いときは検索条件をかけた上でのテーブルでorderしている振る舞いでした。
そこでこうしてみました。
select * from (select * from test_table where date='20120819' ) test_table order by time limit  0, 10

サブクエリを使って必ず検索条件をかけた上でorderします。すると軽くなりました。なんてこったい。まったく原因がわからない...。
また、別の場所で使っていたorder by句はちゃんと検索条件を見た上での並び替えでした。
調査中です。
「デコポニテの魔女エアホッケー編」コンピュータとの対戦型エアホッケーゲームです。
Android端末(google play)⇒  iOS端末(app store)⇒
Technology By: Adobe AIR



詰将棋サイトを運営してますが、タイムアタックランキングを実装してます。
昔の話ですがSQLでのスロークエリ解消法を記します。今はO/RマッパーがあるからSQLを書かなくなってきているのであまり使われないけれども備忘録を残します。
またmemcachedの利用やTokyoTyrantなどを使ったほうが早いので、ますますひねったSQLは使わなくなりました。
今回の手法の大枠は、ランキング表示時のスロークエリが出たときはJOIN時のスロークエリなどで、その場合サブクエリを使った上でのJOINをする感じです。ひねったSQLでんな。

※ちなみに、そのmemcachedなんですがどうやら自分が使っているキャッシュサーバが弱くてキャッシュヒット自体は早いのですが、連想配列などをシリアライズ化して投入しておいたら、
キャッシュサーバからのパケット容量が問題になりました。それでCPU負荷やレスポンスタイムが遅れては元も子もない。このあたりはちゃんとSQLで完結できるならSQLでなんとかしたいですよね。

簡単にテーブル定義を解説しますと※実際とは異なります
テーブル:answers
カラム:id, user_id, question_id, time
こんな感じ、どのユーザがどの問題でどれだけ秒数がかかったかというテーブルですな。
ランキングを表示するさいユーザテーブルとJOINしてユーザ名も表示させます。
テーブル:users
カラム:id, name

とあるページのランキングを表示させる際のSQL文です。?マークはプレースホルダです。
select 
Answer.question_id
, Answer.time
, User.name
from
answers Answer
, users User
where
Answer.user_id = User.id
order by
Answer.time asc
limit
?, ?


これだとスロークエリが出てました。answersっていうテーブルは時間が経つとふくれあがります。
なので一旦answersをlimitで切ってからusersとJOINしましょう。

select 
Answer.question_id
, Answer.time
, User.name
from
(select * from answers order by time asc limit ?, ?) Answer
, users User
where
Answer.user_id = User.id


これにてスロークエリがなくなりました。
前述の通りキャッシュサーバが強ければユーザ情報はmemcachedから拾ったほうが早いかもしれません。
しかし自分としてはDBの情報をシリアライズ化して入れておくってのは本筋じゃない気が...。
キャッシュってキーと値が1対1だから使えるんじゃないかと。
たとえばkey=1 : value="sql" みたいに単純な形。それ以上にふくれあがるなら、ちゃんとDBにいれたほうがいいように思えます。
この辺はベンチマークとって見ないとわかりませんけど。

一応JOIN構文を使ったSQL。SQL92でしたっけ?そちらが推奨しているんですけど、3つ以上JOINすると逆に見づらすぎるのが難点。
select 
Answer.question_id
, Answer.time
, User.name
from
(select * from answers order by time asc limit ?, ?) Answer
join
users User
on
Answer.user_id = User.id




「山川悟の詰将棋」はスマートフォン用詰将棋アプリです。
Android端末(google play)⇒  iOS端末(app store)⇒
Technology By: Adobe AIR