私が提供する4種類のサービスがあると仮定します(それらは頻繁に変わることはほとんどありません):
- テスト中
- 設計
- プログラミング
- その他
上記のカテゴリのいずれかに該当する実際のサービスが60〜80個あるとします。たとえば、「サービス」は「テクニックAを使用したプログラムのテスト」で、タイプは「テスト」です。
それらをデータベースにエンコードしたいです。私はいくつかのオプションを思いつきました:
オプション0:
VARCHAR
直接使用して、サービスタイプを文字列として直接エンコードします
オプション1:
データベースを使用しますenum
。しかし、enumは悪です
オプション2:
2つのテーブルを使用します。
service_line_item (id, service_type_id INT, description VARCHAR);
service_type (id, service_type VARCHAR);
参照整合性も楽しむことができます:
ALTER service_line_item
ADD FOREIGN KEY (service_type_id) REFERENCES service_type (id);
いいですね。
しかし、私はまだ物事をエンコードし、整数を処理する必要があります。つまり、テーブルにデータを入力するときです。または、テーブルにデータを入力または処理するときに、手の込んだプログラミングまたはDB構造を作成する必要があります。つまり、データベースを直接扱うとき、またはプログラミング側で新しいオブジェクト指向エンティティを作成するときにJOINし、それらを正しく操作することを確認します。
オプション3:
使用しないでくださいenum
。2つのテーブルを使用せず、整数列を使用してください。
service_line_item (
id,
service_type INT, -- use 0, 1, 2, 3 (for service types)
description VARCHAR
);
これは、物事のコード側により多くのオーバーヘッドを必要とする「偽の列挙」のようなもの{2 == 'Programming'}
です。
質問:
現在、私はコンセプトの下でガイドされているオプション2を使用してそれを実装しました
- enumを使用しないでください(オプション1)
- データベースをスプレッドシートとして使用しないでください(オプション0)
しかし、プログラミングと認知のオーバーヘッドの点で私にとって無駄だと感じるのは仕方がありません。2つのテーブルを認識し、2つのテーブルを処理する必要があります。
「無駄の少ない方法」のために、私は見ていOption 3
ます。ITは軽量であり、動作するために本質的に同じコード構成が必要です(わずかな変更がありますが、複雑さと構造は基本的に同じですが、単一のテーブルを使用します)
私は理想的には常に無駄ではなく、どちらのオプションにも良いケースがあると思いますが、オプション2とオプション3をいつ使用するかについての良いガイドラインはありますか?
タイプが2つしかない場合(バイナリ)
この質問にもう少し追加するために...同じ会場で、「標準」または「例外」サービスのバイナリオプションがあります。これはサービス広告申込情報に適用できます。オプション3を使用してエンコードしました。
値{"Standard"、 "Exception"}を保持するためだけに新しいテーブルを作成しないことにしました。したがって、私の列は{0、1}を保持し、列名はが呼び出されexception
、コードは{0, 1} => {STANDARD, EXCEPTION}
(プログラミング言語の定数としてエンコードされた)からの翻訳を行っています
これまでのところ、どちらも好きではない.....(オプション2もオプション3も好きではない)。3よりも優れたオプション2が見つかりますが、オーバーヘッドが大きくなります。2と3のうちどのオプションを使用しても、エンコード処理を整数としてエスケープすることはできません。
ORM
回答を読んだ後、コンテキストを追加するために、ORCを(最近)使用し始めました(私の場合はDoctrine 2です)。データセット全体が比較的小さいため、プログラミング構造を使用してその動作を確認したいと考えました。
実際のスプレッドシートから既存のリストがあったのでservice_type
、最初にsを入力し、次にservice_line_item
sを入力しました。したがって、「標準/例外」や「テスト」などはすべてスプレッドシート上の文字列であり、DBに保存する前に適切なタイプにエンコードする必要があります。
私はこのSOの答えを見つけました:doctrine2でENUMの代わりに何を使いますか?、DBのenumコンストラクトを使用せず、INT
フィールドを使用し、プログラミング言語の「const」コンストラクトを使用してタイプをエンコードすることを提案しました。
しかし、上記のSOの質問で指摘されているように、整数を直接使用することを避け、定義された言語構成要素(定数)を使用できます。
しかし、それでも....どのように回してstring
も、ORMを使用している場合でも、型として開始する場合は、最初に適切な型に変換する必要があります。
だから、言うなら$str = 'Testing';
、私はまだどこかのようなブロックをどこかに持っている必要があります:
switch($str):
{
case 'Testing': $type = MyEntity::TESTING; break;
case 'Other': $type = MyEntity::OTHER; break;
}
良いことは、整数/マジック番号を処理していないことです(代わりに、エンコードされた一定量を処理します)が、悪いことは、この変換ステップなしで、自動的にデータベースに物を出し入れできないことです。知識。
そして、それは、「物事をエンコードし、整数を処理しなければならない」などのことを言うことによって、私が部分的に意味したものです。(現在、Ocramiusのコメントの後、私は整数を直接扱う必要はありませんが、必要に応じて名前付き定数と定数との変換を処理します)。