:dashmark日本語ページをアップ

[-]:dashmarkの日本語ページをアップしました。
screenshot
[-]: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ので、ま、がんばってきれいにしていきます。

*1:xddさん、アイデア頂き本当にありがとうございます。