sqlite データベースを使用して、埋め込み C++ アプリケーションに結果を保存しています。
「ドメイン」テーブルと呼ぶ単一列のテーブルがいくつかあり、他のテーブルの列はそれらを外部キーとして参照します。これらは基本的に、初期化時に一度だけ変更される列挙型のテーブルです。たとえば、ステータス データ タイプを格納する 1 つのテーブルを次に示します。
CREATE TABLE status_domain (status TEXT PRIMARY KEY NOT NULL UNIQUE);
INSERT INTO status_domain VALUES ('pending');
INSERT INTO status_domain VALUES ('in_progress');
INSERT INTO status_domain VALUES ('error');
INSERT INTO status_domain VALUES ('complete');
.
.
CREATE TABLE my_other_table (
.
.
status TEXT NOT NULL,
.
.
FOREIGN KEY (status) REFERENCES status_domain(status)
);
ドメイン テーブルの目的は、sqlite の外部キー制約 (参照整合性) を利用することです。
これらのテーブルに書き込む C++ コードは、スキーマを認識しません。これらのテーブルを C++ で複製するのは悪い設計ではないかと思います。例えば:
enum StatusEnum { pending, in_progress, error, complete };
次の 4 つのオプションが表示されます。
- 挿入して
my_other_table
いるステータス値が有効かどうかを知らずに挿入します。ステータス値が無効な場合、これは実行時に失敗します。 - を C++ 列挙型で複製し
status_domain
て、コンパイラが無効なステータスで挿入を実行できないようにします。スキーマが変更された場合、両方の場所で変更を行う必要があるため、これは DRY の原則に違反しています。 - テーブルを破棄
status_domain
し、C++ 列挙型に有効なデータ型を適用させます。C++ コードは、これらのテーブルに挿入する唯一の場所になるため、これは妥当と思われます。ただし、スキーマで明示的に宣言されたステータス タイプがあると便利です。 - sqlite ラッパー コードをよりデータベース/スキーマに対応させます。これは努力する価値がないと思います。
私はオプション 2 に傾いていますが、2 つの異なる場所で変更される可能性のあるものを保存しているため、躊躇しています。
注: 私が共有していない、このような (より長い) テーブルが他にもいくつかあります。