:dashmark日本語ページをアップ
[-]:dashmarkの日本語ページをアップしました。
[-]:dashmark
DevノートとかHistoryとかまだ翻訳していないけど、ユーザーガイドは日本語で書き始めることにしました。
ついでに、0.4にバージョンアップ
昨日、[-]:dashmarkを0.4にバージョンアップしています。今回は検索範囲のスコープ設定を追加したのが最も大きな変更点。スターランクと修正日時で絞り込んだ範囲内で、タグとキーワード検索を行う機能です。
このスコープ機能はxddさんに示唆いただいたSQLのビューを用いて実装しています。
0.3までの[-]:dashmarkでは以下のような二つのtableに対してSQLを発酵して、ブックマークの表示、検索やタグ表示を行っていました。
ELEMENT_DBテーブル
uid | title | text | tag | modified | created | referer | ... |
---|---|---|---|---|---|---|---|
0000-xxx... | dashmark | コメント文 | safari sql webkit | 20080515... | 20080501... | http://d.hatena... | ... |
TAGテーブル
uid | tagstring | count | modified |
---|---|---|---|
0000-xxx... | safari | 3 | 20080515... |
0000-xxx... | sql | 5 | 20080515... |
0000-xxx... | webkit | 12 | 20080515... |
上記のような設計の一番の問題点は、検索範囲が広がると検索速度が低下するリスクがあることです。いくらClient-side database storageが早いからといっても、Javascriptでループをまわして拾ってくるコストはそれほど小さくないため、数千件のブックマークからの抽出でも、それなりに速度低下が感じられる状態になっていました。
次に問題であったのは、TAGテーブル内でのcountの存在。これは私の設計ミスで、Javascriptで集計した結果をテーブルに挿入していたのですが、SQLiteの高速な集計機能を使っていなかったわけです。なんのためのSQLよ。
で、今回の0.4ではデータベースのバージョンを変更して、以下のようなテーブルを使ってスコープ機能と従来の機能を実装することにしました。データベースの構造が全く異なってはいるのですが、入り口と出口は変わっていないのでJavascript部分の修正は軽微に済んでいます。
ELEMENT_DBテーブル(変更なし)
uid | title | text | tag | modified | created | referer | ... |
---|---|---|---|---|---|---|---|
0000-xxx... | dashmark | コメント文 | safari sql webkit | 20080515... | 20080501... | http://d.hatena... | ... |
PRIMARY_SCOPE VIEW
VIEWを生成しているSQLの例
CREATE VIEW PRIMARY_SCOPE AS
SELECT * FROM ELEMENT_DB
WHERE (star >= 0) AND modified > datetime('now', '-24 hour')
AND modified < datetime('now')
uid | title | text | tag | modified | created | referer | ... |
---|---|---|---|---|---|---|---|
0000-xxx... | dashmark | コメント文 | safari sql webkit | 20080515... | 20080501... | http://d.hatena... | ... |
ELEMENT_DBからスターランキングと日付で検索した結果を丸ごと保持したVIEW。このVIEWは、スコープが変更されるたびに作り直す。
TAG_ELEMENT テーブル
mark_uid | tagstring | modified |
---|---|---|
0000-xxx... | safari | 20080515... |
0000-xxx... | sql | 20080515... |
すべてのタグが一つ一つ記録されたテーブル。
TAG ビュー
VIEWを生成しているSQL
CREATE VIEW TAG AS
SELECT (mark_uid || _rowid_) AS uid,
tagname,
count() AS count,
max(modified) AS modified
FROM TAG_ELEMENT WHERE mark_uid IN (SELECT uid FROM PRIMARY_SCOPE)
GROUP BY tagname
uid | tagstring | count | modified |
---|---|---|---|
0000-xxx... | safari | 3 | 20080515... |
0000-xxx... | sql | 5 | 20080515... |
0000-xxx... | webkit | 12 | 20080515... |
TAG_ELEMENTから、PRIMARY_SCOPEで絞り込まれているuidを持つ要素を抜き出して集計するVIEW。このVIEWは一度作ったらPRIMARY_SCOPEが変更されるたびに内容が自動的に更新される。しかも高速。
データベースを変更してみて……
文章で書くと、ELEMENT_DBとTAG_ELEMENTに全部のデータを保存しておき、表示するデータだけをPRIMARY_SCOPEで絞り込んで、タグの表示に使っているTAGの内容は自動更新させる、とでもなりますか。
集計は高速に行われるしメモリは食わないし、今後、スコープ用のVIEWをネストしていけば絞り込み検索もできるし、スコープ用のVIEWを保存しちゃえばスマートフォルダにもなるという優れもの設計。*1設計はそれなりにまとまってきたけど実装はまだまだっていうかonClick使ってたりするのwので、ま、がんばってきれいにしていきます。