C#でデータベースSQLiteによる設定ファイル読み込みとバージョンアップ

本記事は、[C#での設定ファイル管理とパラメータのバージョンアップ]の続きとして、データベースのSQLiteによるよる設定情報やパラメータの扱いについて記載します。設定ファイルを扱う方法として、データベースのなかでSQLiteのようなRDB(リレーショナルデータベース)を使うことは、コストのかかる方法になります。C#の知識だけではなく、データベースを使うためのデータベース設計やSQLなどの知識を必要です。さらに、複雑な構造をデータベースで構築するには、それにあった複雑な設計が必要になります。同時に、C#などのプログラミング言語でそのデータベースにアクセスし、設定情報を扱うためのコーディングも複雑になります。そのため、普通のアプリケーションなら、あまり勧めはしません。アプリケーションの事情により、どうしてもデータベースを使う必要がある場合を想定し、データベースのSQLiteを使った方法をまとめます。

SQLiteとは

一般的にデータベースは、一つのシステムになっていて、専用のサーバを必要とします。例えば、OracleやSql server、Mysql,PostgreSqlなどは、専用のサーバを起動し、そのサーバとのやり取りでデータベースを扱います。そのためには、データベースサーバの管理が必要になります。構築アプリケーションやシステムの規模・安定性・セキュリティ面で、上記のようなサーバ型を使わなければならない場合も多いでしょう。しかし、そこまで要求しない一般的アプリケーションでデータベースを使うのであれば、データベースサーバを必要としないサーバレースのSQLiteは力を発揮します。

SQLiteは、サーバが必要ないので、開発のアプリケーションの中から、SQLiteのDLLを読み込み、APIライブラリ(関数)を呼び出すだけでデータベースを構築できます。さらに、必要な時だけAPI経由で使うので、軽量でメモリ消費量も少なく、処理速度面で高速である長所を持っています。サーバがないので、複雑なデータベース設定も必要ありません。

なお、SQLiteは、オープンソース(ライセンスはPublic Domain)で公開されているので、商用利用も可能です。

SQLiteを使うためには

Visual Studioで開発するなら、以下のようにNugetから追加します。下の図のようにNugetからSystem.Dta.SQLiteを検索し、インストールしてください。

もし、Nugetから設置しない場合は、必要なDLLを参照追加すると使えます。

SQLiteを使ってみる

SQLiteをインストール(インストールと書きますが、実際は、DLLを参照に追加するだけです)したら、SQLiteは使うことができます。いつもの通り、サンプルを使って、説明します。

サンプルで使うデータクラス

データクラスは、他の設定ファイルのサンプルで使っているクラスと類似のクラスです。

SQLiteを使うためのAPI関数

SQLiteにアクセスするのは、SQLiteが提供するSQLiteConnectionクラスです。このクラスを使って、データベースファイルにアクセスし、読み書きができるようになります。SQLiteConnectionを扱う方法として2つの方法を書いてみました。基本は同じで、どちらの方法が良いかは、アプリケーションの設計によって変わるでしょう。

方法1.クラス内にで接続を維持する方法

設計ファイルを管理するので、設定情報(本記載ではデータクラスのこと)とデータベースを結ぶづけるための専用のクラスを作って、そのクラス内でSQLite接続を維持する方法です。

この方法だと、データベースのアクセスするための接続(Connection)のインスタンス(サンプルでは、_connメンバー)がすでに生成されており、その接続を経由してSQLiteを扱いますので、毎回、接続しなおす必要がないです。

サンプルでは、データクラスの情報を丸ごと変更するための方法として、SelectUserDataIncludeIdx()を作成しました。この方法により、データクラスの値がどのように変わったとして、柔軟性を持つことができます。たとえば、ユーザのIDが変わることはあまりありえませんが、もし、変わったとしても、変更可能にするための関数の例です。

方法2.毎回インスタンスを生成する方法

この方法は、クラスの中に接続を維持するのではなく、必要な時、その都度、SQLiteとの接続を作成し、データベースにアクセスする方法です。

呼び出し側のサンプル

 

実行した結果

上記のサンプルを実行した結果は以下のようになります。

SQLiteデータベースの中身を見たい場合はSQLite Browser

SQLiteのデータベースはファイルでデータを保存(サンプルでは、 para_db_sqlite.db)します。その保存したファイルを見たり、直接編集したい場合は、SQLite Browserからダウンロードして使います。

ダウンロードした後SQLite Browserをインストールし、データファイル(para_db_sqlite.db)を開くと、下のような画面になります。このツールを使って、データベースを直接作成したり、削除したり、編集することもできます。

SQLiteを使った場合の設定ファイルのバージョンアップ

SQLiteを使った場合の設定ファイルのバージョンアップは、一言では言えません。結局、データベースの設計内容によって、次のバージョンアップに影響するからです。上記のようにクラスと一致する形のデータベース設計にした場合、何らかの形で影響を受けるでしょう。クラスメンバが増えたら、データベースも変更しないといけなくなります。ただ、データクラスをそのままデータベースに書き込んでいるわけでなく、変換クラス(Conveterクラス)を利用するので、バージョンアップによってメンバが増えたとか変更されても、ある程度、柔軟に対応できます。

バージョンアップによる影響を少なくするための対策

上記で書いた通り、設定クラスとデータベースの各要素(カラムと言います)を1:1でマッチングした設計をすると、バージョンアップによる影響が大きいことから、かなり、柔軟な設計をする方法があります。要するに、設定クラス(データクラス)に依存しない、汎用データベーステーブルを設計し、汎用テープるを使う方法です。例えば、ブログやサイト構築で人気のあるWordpressの場合、このような汎用テーブル(例:wp_options)を作成し、設定情報は、なんでも、このテーブルに詰め込んでいます。Wordpress標準機能はもちろんのこと、ユーザが作成したプラグインの設定情報も、この汎用テーブルに保存します。以下、実際のWordpressのOptionsテーブルの構造です。

  • option_name:データクラスのメンバー名を保存します。
  • option_value:データクラスのメンバに該当する値です。

このように作っておくと、INIファイルのようにkey=value型で値を書き込み、読みだすこともできます。利用するクラスで、データをクラスメンバーに詰め替える必要はありますが、自由度はかなり高くなります。どんな構造のクラスであっても詰め込むことができます。

汎用テーブルを利用する場合の注意点

option_nameが重複することもありえるので、そのための対策を入れると良いです。例えば、このテーブルにカテゴリ(データクラス名のような値)を入れるとかの方法もあります。すると、メンバー名が重複するトラブル防止につながります。

また、汎用テーブルであることは、それをデータクラスに詰め込むための実装、実行時間に影響することです。設定クラスとデータベースの各要素(カラムと言います)を1:1でマッチングしているわけでないので、変換クラスが必ず必要になります。

まとめ

データベースSQLiteを使って設定ファイルを使うことは、勧めはしませんが、どうしても必要であれば、データベース中でもSQLiteは高速、APIによって楽に使えるなどの長所があるので、SQLiteを勧めします。

また、データベースは、上の「バージョンアップによる影響を少なくするための対策」に書いたことを参考に、注意点に書いた内容で問題なければ利用することで、バージョンアップによる影響を減らすことができます。