DBAccessはiOS用の新しいORMである。スレッドセーフ性とハイパフォーマンスを提供して,AppleのCore Dataを改善する。
DBAccessはCore Dataに対して,おもに3つのメリットを主張している。
- スレッドセーフである。
- ハイパフォーマンスであり,クエリのパフォーマンスの微調整をサポートする。
- データオブジェクトをUIコントロールにバインドすることで,データベースの更新を反映可能にするイベントモデルを備える。
DBAccessは自由に使用および配布可能である。最新バージョンには,ASYNCクエリのサポートや結果セットが大規模な場合のパフォーマンス向上,カラム数が多い場合のメモリ消費量の削減などの改良が含まれる。
DBAccessの提示する利用モデルは非常にシンプルだ。永続オブジェクトの宣言方法はCore Dataに極めて近い。
@interface Person : DBObject @property (strong) NSString* forename; @property (strong) NSString* surname; @property int age; @end
オブジェクトの生成と削除,データベースへのクエリなどは,一般的なパターンに従って行う。
Person* p = [Person new]; p.forename = @"Adrian"; p.surname = @"Herridge"; p.age = 35; [p commit]; // オブジェクトをテーブルに保存する [p remove]; // 保存したオブジェクトを削除する DBResultSet* r = [[[[[Person query] where:@"age > 30"] limit:10] orderBy:@"surname,forename"] fetch];
InfoQは,DBAccessの作者であるAdrian Herridge氏にコンタクトを取り,いくつかの質問をした。
Core Dataに代わるORMを開発した,もっとも大きな理由は何でしたか?
プロジェクトを開始した当時,iPresentはまだ,Compsoft plcという大規模なソフトウェアハウスの一部門でした。平均で5つの開発チームがいくつものアプリを同時開発している中で,その中のいくつかが永続性要件にCore Dataを使用していたのです。
オープンな共有環境だったので,パフォーマンスやスレッド,動作上の問題など,不足していたり,あるべきだと感じている機能(結合や集計関数などのように)について,皆が遠慮なく話し合っていました。
Core Dataを利用する最大のメリットは,テーブルやリレーションの設定がGUI形式で編集できることなのですが,モデルのバージョンが間違っていて編集に支障が生じることがたびたびありました。それが原因でバージョン管理システムがだめになったり,ある時にはリリース済みのアプリケーションへのフィールド追加に大きな問題が発生したりしていたのです。
個人的な観点から見たCore Dataは,5年ほど前に開発に使用していたSQLiteからコア機能のいくつかを取り除いたものでした。シンプルで極めてハイパフォーマンスなインターフェースがとても気に入っていました。
その一方で,ループ内でのクエリのネストを回避する目的からは,インラインのサブクエリやテーブルの結合が使えないことに強い制限を感じていました。結果的にルーチンが非常に重くなることも少なくなかったのです。そのために当時は,Core Dataについて,実用上のメリットの少なさ対して,あまりにも多くの落とし穴があるように感じていました。
開発チーム内の能力にばらつきがあるため,Predicate Queryのシンタックスを理解できない人たちもいましたし,スレッドを越えて呼び出されるメソッドにわずかなミスがある場合に発生するような,とても微妙なバグやクラッシュによって苦労することも少なくありませんでした。
ですから,要約すれば,私や他の開発者が感じていた,ネストしたクエリが必要な場合のあまりにも悪いパフォーマンスの改善や,スレッドの問題で悩まなければならないフラストレーションの軽減,表結合とサブクエリの実装,そういったものが,DBAccessを開発したもっとも大きな理由だったのです。
iOS開発者がCore Dataに代わってDBAccessを選択できるような,DBAccessの長所を説明して頂けますか?
- DBAccessの実装にあたっては,開発者ができる限り自然に利用できるように,可能な限りSQLiteの構文にこだわりました。ですから,最初に挙げられるのは使いやすさでしょう (少なくとも開発に参加している人たち,DBAccessの開発に感謝の連絡をくれた方々,丁重にお断りしなければならない寄付を申し出てくれた方々にとっては)。
- パフォーマンスも大きなメリットです。私たちはコードベース(現在はおよそ15kライン)のほとんどをプロファイルするように努力してきました。Core Dataは単純な読み出し処理では高速なのですが,データベースにデータを書き戻そうとすると問題が発生しやすいですし,ネストしたクエリとなるともうお手上げです。私たちは書き込みを最適化するとともに,可能な限りレコードキャッシュを行うことで,非常に”話し好き”なiOSアプリケーションでは大きな性能差を実現できました。
- クエリオブジェクトのシンプルかつ迅速な実装。ほとんどのアプリケーションでアプリケーション用のクエリ処理クラスが必要になるという状況に,私たちは納得できませんでした。同じクエリを何度も何度も繰り返すのであれば,この方法にも確かに意味はあります。ですが私たちは,読みやすさや時間的な観点から,もっとコンパクトで読みやすい,流ちょう(FLUENT)なインターフェースにしたいと思っていました。次の例のように,forループの中でインラインで項目を引き出すことができれば,開発者にとっては非常に便利だと思ったのです。
for (Person* in [[[[Person query] where:@“age >= 18”] orderBy:@“age”] fetch]) { ... }.COUNT, SUM, ID, GROUP
といった関数の実装。これらがSQLレベルで実行されることで,メモリを消費する重いクエリの必要がなくなりました。- 完全にスレッドセーフです。任意のタイミングで,どのスレッドからでもクエリやコミットが可能になりました。
- DBAccessにはイベントモデルがあって,特定のオブジェクトがシステムの他の部分で更新された場合や,ベースとなるテーブルに何らかの変更が加えられた場合に実行されるコードブロックを登録することができます。これを使えば,データレイヤとGUIを簡単にリンクすることができます。スレッドの問題やイベントの非同期性を扱う苦労を背負う必要はありません。
- オブジェクトが格納されるデータベースファイルを開発者が特定できる機能を実装しました。これによってデータレイヤを複数のファイルに分割することが可能になります。
- 列ベースのAES256暗号化。 8.Aのプロパティや列を,
NSKeyedArchiver
を使用したエンコードをサポートする任意のNSObject
継承クラスにすることができます。DBAccessはそれをBLOBとして格納した上で,元の項目に再拡張するために必要な情報をすべて含んだ独自のストレージタイプでラップします。
DBAccessは現在クローズドソースですが,その点がiOSコミュニティの採用を妨げる可能性はないでしょうか?オープンソース化する予定はありますか?
私たちは当初,DBAccessをオープンソースプロジェクトにするつもりでした。ですがその時点では,私の会社内にとても複雑な問題があって,それを実行することができませんでした。それで私は,フレームワークをクローズドソースとしてコンパイルしたものを無償公開する,ということに合意したのです。
コミュニティへの普及という意味では確かに障害になるかも知れませんが,残念なことに,クローズドソース配布の合意を取り付けるのにも1年を要してしまったのです。最初の目標に固執していたとすれば,さらに時間が必要だったでしょう。
真にオープンなライセンス契約を結んでこの制限を和らげたいと思っていますし,フレームワークに含まれるコードなどについて保証することで,ユーザに安心してもらえればと思います。
オープンソースプロジェクトとそのコントリビューションについては,ジレンマを感じることがよくあります。開発者たちが善かれと思って追加したり希望した特徴や機能によって,当初の計画やアイデアが台無しになってしまったプロジェクトはたくさんあります。DBAccesも現在すでに,多数のプロジェクト(私の知る限りでは18)で使用されていますから,同じことが問題になる可能性はあります。プロジェクトで行う修正が,すでに開発中のアプリケーションが採用した方法論に影響したり,損なったりすることのないように,十分な確認を行う必要があるでしょう。ですから私自身としては,オープンソースや開発者によるコントリビューションを支持はしますが,受け取ったものを管理したり,機能開発の同意を取り付けるような作業が,私たちのワークロードになるのではないかという懸念を多少持っています。
DBAccessでドキュメント化されて一般に公開されているのは,全体のおよそ3分の1に過ぎません (実際にはすべて揃っているのですが,ヘッダファイルには記述されていないので,GUIオブジェクトバインディングやデータアダプタ,高度なリレーションシップ,アップグレードあるいはマイグレーションスキーマシステムなどの特別な機能については誰も知らないのです)。最近では,連絡をくれた開発者に対して,フレームワークの機能のアンロックあるいは変更を行うためのエクステンションパックを送っています。この点はobjective-cのメリットのひとつで,コントリビュートあるいはカスタマイズを望むならば,エクステンションを作って機能セットを簡単に追加することができるのです。コアデータのストレージや検索が変わることはありません。
フレームワークのエクステンションを,Webサイトからダウンロード可能なオープンソースとしてリリースすることを勧めていますし,自分でもリリースしたいと思っています。この方法ならば,より広範な開発者コミュニティからのコントリビューションを簡単に取り込むことができるでしょう。つまり,現時点でドキュメント化されていないDBAccessの機能をオープンソースコンポーネントにする一方で,コアフレームワークについては,先ほど述べた理由からクローズドのままにする,ということです。
コアフレームワークをオープンソース化する計画ですか? 目標としては持っていますが,当面は実現しそうもありません。何といっても会社側には,DBAccessを完全なオープンソースプロジェクトにするメリットがありませんからね。