SQLiteデータベース管理システム-私が知っているデータベースエンジン


SQLiteは軽量級の組み込みシステムに設計された関連データベース管理システムです。SQLiteは、自己依存性、純粋なクライアント、ゼロ構成を実現し、事務をサポートするデータベースエンジンである。これはD.Richard Hippによって初めて開発されました。現在は世界で最も広く展開されているオープンソースデータベースエンジンです。
本稿では、以下の内容を紹介します。
SQLiteデータベース

SQLiteConnection conn = new SQLiteConnection("Data Source=mytest.s3db");
conn.Open();
SQLiteデータ挿入

/// <summary>
/// Allows the programmer to easily insert into the DB
/// </summary>
/// <param name="tableName">The table into which we insert the data.</param>
/// <param name="data">A dictionary containing the column names and data for the insert.</param>
/// <returns>A boolean true or false to signify success or failure.</returns>
public bool Insert(string tableName, Dictionary<string, string> data)
{
Boolean returnCode = true;
StringBuilder columnBuilder = new StringBuilder();
StringBuilder valueBuilder = new StringBuilder();
foreach (KeyValuePair<string, string> val in data)
{
columnBuilder.AppendFormat(" {0},", val.Key);
valueBuilder.AppendFormat(" '{0}',", val.Value);
}
columnBuilder.Remove(columnBuilder.Length - 1, 1);
valueBuilder.Remove(valueBuilder.Length - 1, 1);
try
{
this.ExecuteNonQuery(string.Format("INSERT INTO {0}({1}) VALUES({2});",
tableName, columnBuilder, valueBuilder));
}
catch (Exception ex)
{
mLog.Warn(ex.ToString());
returnCode = false;
}
return returnCode;
}

DateTime entryTime;
string name = string.Empty, title = string.Empty;
GetSampleData(out name, out title, out entryTime);
int id = random.Next();
insertParameterDic.Add("Id", id.ToString());
insertParameterDic.Add("Name", name);
insertParameterDic.Add("Title", title);
insertParameterDic.Add("EntryTime",
entryTime.ToString("yyyy-MM-dd HH:mm:ss"));

db.Insert("Person", insertParameterDic);
SQLiteの事務処理方式を作成します。
Begin Transation:
begin-stmt
Comit Transation:
commit-stmt
Rollback Transation:
rollback-stmt

try
{
db.OpenTransaction();
Insert4Native();
db.CommiteTransaction();
}
catch (System.Exception ex)
{
mLog.Error(ex.ToString());
db.RollbackTransaction();
}
SQLiteのインデックス
インデックスは、クエリの特性を最適化するために使用され、データではクラスタインデックスと非クラスタインデックスに分類されます。前者はデータベース中のデータ組織方式によって決められています。たとえば、私たちはデータベースの中に一つずつデータを挿入する時、クラスター索引は順序によって挿入され、挿入後のデータの位置と構造が変わりません。非クラスター索引とは、私たちが手動で作成した索引のことで、データベース内の各列にインデックスを作成することができ、辞書内の索引と類似しています。原則としては、分散性と結合型の列にインデックスを作成し、大きなデータと複雑な照会状況の下で検索効率を高めることができます。
create-index-stmt

/// <summary>
/// Create index
/// </summary>
/// <param name="tableName">table name</param>
/// <param name="columnName">column name</param>
/// <param name="indexName">index name</param>
public void CreateIndex(string tableName, string columnName, string indexName)
{
string createIndexText = string.Format("CREATE INDEX {0} ON {1} ({2});",
indexName, tableName, columnName);
ExecuteNonQuery(createIndexText);
}
簡単照会、データベースサイズに関係なく照会効率のテスト結果は以下の通りである(700,000データ):

string sql = "SELECT LeafName FROM File WHERE Length > 5000";
Capture
複雑なクエリの場合のクエリ効率に対するテスト結果は以下の通りです。
Capture2
SQLiteのトリガー
トリガーとは、特定のデータベースイベント(DELETE、INSERT、or UPDATE)が発生したときに自動的に実行されるデータベース操作を指します。  私たちは触発器を高度な言語でのイベントとして理解することができます。
二つの表があるとします。
Folder(Gid VCHAR(255)NOT NULL,Deleted BOOLEAN DEFALT 0)
File(PartGrid VCHAR(255)NOT NULL,Deleted BOOLEAN DEFALT 0)
Folder表にトリガーUpdate_を作成します。Folder_Deleted:

string sql = "SELECT folder.Location AS FilePath"
+ "FROM Folder folder LEFT JOIN File file ON file.ParentGuid=folder.Guid"
+"WHERE file.Length > 5000000 GROUP BY File.LeafName";
フリップフロップを作成した後、以下の文を実行します。

CREATE TRIGGER Update_Folder_Deleted UPDATE Deleted ON Folder
Begin
UPDATE File SET Deleted=new.Deleted WHERE ParentGuid=old.Guid;
END;
以上の文は以下の文の自動実行をもたらします。

UPDATE Folder SET Deleted=1 WHERE Guid='13051a74-a09c-4b71-ae6d-42d4b1a4a7ae'
SQLiteのビュー(View)
ビューは仮想テーブルとしてもいいです。中には一定の条件でフィルタリングされたデータセットが格納されています。このようにして、今度はこれらの特定のデータセットを取得したい時には複雑なクエリではなく、簡単なクエリーの指定ビューから必要なデータが得られます。
次の例では、簡単なビューを作成します。
Capture
上記のクエリの結果に基づいて、ビューを作成します。
Capture2
SQLiteコマンドラインツール
SQLiteライブラリにはSQLite 3.exeのコマンドラインツールが含まれています。SQLiteの各基本操作を実現できます。ここでは、私たちの調査結果を分析するためにそれを使う方法を紹介します。
1.CMD->sqlite 3.exe MySQLiteDbWithout Index.s 3 db
Capture
2.EXPLAN機能をオープンし、指定されたクエリ結果を分析する
Capture
3.コマンドラインを再使用してインデックスのあるデータベースを開き、前のステップを実行します。
Capture
4.二つの異なるクエリ文の分析結果を比較すると、検索過程でインデックスが使用されている場合、SQLiteはdetail列で提示されていることが分かります。
5.注意すべきは、各語句の後に「記号」をつけることです。
SQLiteのいくつかの一般的な使用制限
1.SQLiteはUnicode文字の大きさと比較に対応していません。以下のテスト結果を見てください。
Capture
2.SQLiteの変換文字をどのように扱うか:

UPDATE File SET Deleted=1 WHERE ParentGuid='13051a74-a09c-4b71-ae6d-42d4b1a4a7ae'
3.複合SELECT文の本数制限:一つの複合クエリ文は、複数のSELECT文がユニオン、ユニオン、EXCEPT、or INTERSECTで接続されています。SQLiteプロセスのコード生成器は、再帰的アルゴリズムを用いてSELECT文を結合します。スタックのサイズを下げるために、SQLiteの設計者たちは複合SELECT文のエントリ数を制限した。SQLITE_MAX_COMPOUND_SELECTのデフォルト値は500です。この値は厳密に制限されていません。実際には、複合クエリ文のエントリ数が500より大きいのはほとんど見られません。
ここで複合クエリの原因として言及したのは、大量のデータを迅速に挿入するためにそれを使用することができるからです。

INSERT INTO xyz VALUES('5 O''clock');