web-dev-qa-db-ja.com

リレーショナルデータベースで列挙型をどのように表す必要がありますか?

私は、会社で作業しているデバイスで発生するトランザクションを追跡するリレーショナルデータベースの開発に取り組んでいます。デバイスで発生する可能性のあるトランザクションにはさまざまなタイプがあるため、メインのレコードテーブルの1つに「trans_type」フィールドがあります。私のグループは、このフィールドの型を整数にし、列挙型として扱うことにしました。私の直感では、このフィールドを文字列にして、データベースのデータを読みやすく、使いやすくすることをお勧めします。私の同僚は、これが価値よりも多くのトラブルを引き起こすのではないかと心配しているようです。その文字列の比較はコストがかかりすぎ、タイプミスの可能性は障壁が大きすぎます。

だから、あなたの意見では、本質的に列挙された値であるリレーショナルデータベースのフィールドを扱うとき、このフィールドを整数または文字列にするほうが良い設計上の決定でしょうか?または、私が見落とした他の代替案はありますか?

注:明示的な列挙型は、使用しているデータベースではサポートされていません。そして、このデータベースとインターフェースする私たちが開発しているソフトウェアは、C++で書かれています。

12
c.hughes

列挙型は、ID番号と文字列名、および役立つと思われるその他の列を持つ、データベース内の個別のテーブルである必要があります。次に、各タイプはこのテーブルの行として存在します。次に、トランザクションを記録するテーブルで、「trans_Type」フィールドはその参照テーブルのキーへの外部キーである必要があります。これは、データベースの正規化における標準的な方法です。

このようにして、1つの公式名文字列を格納し、パフォーマンスのために数値比較を使用できるようにし、すべてのトランザクションが有効なタイプを持つという参照整合性を確保します。

26
Ryathal

一般的な方法は、trans_typesテーブルを作成し、次にメインテーブルでtrans_type_idという名前の外部キーを使用して参照することです。これにより、レコードが有効な列挙型のみを参照するようになります。

例:

 trans_type 
 ---------- 
 id 
 name 
 
 transactions 
- ----------- 
 id 
 trans_date 
 details 
 trans_type_id(FK to trans_type.id)
 

データの例:

 
 trans_type 
 
 ID | NAME 
 ---------- 
 1 |送信
 2 |キャンセル
 
 
トランザクション
 
 ID | trans_date | trans_type_id 
 --------------------------------- 
 1 | 2012-12-31 | 1 
 2 | 2013-01-09 | 2 

値が整数としてデータベースに送られる場合は、そのように格納します。データベースへの書き込み中に文字列に変換するオーバーヘッドをかける必要はありません。文字列/テキスト値を持つルックアップテーブルにいつでも関連付けることができます(より正規化されています)。

これには、なんらかの更新ルーチンを実行する代わりに、単一の場所で文字列値を更新するという追加の利点があります。 1 = '赤'の代わりに '本当に赤'

これは、文字列値(非正規化)を含む1つのテーブルが必要な場合に比べて、レポートのパフォーマンスには理想的ではありません。このフィールドのインデックスにより、パフォーマンスが十分になります。

ほとんどのRDBMSは十分な馬力を可能にします。テーブルを単純なデータ形式で「読み取る」ことができるという考えはありますが、テーブルを結合することは大したことではありません。ビューまたは同様のオブジェクトを使用する習慣を身に付けてください。

3
JeffO

別の列挙型テーブルアプローチを支持するこの質問に対する他の回答に同意する必要があります。

しかし、私は確かにすでに言われたことを繰り返さないことに賛成です、それで私は単にスタックオーバーフローで同じ質問への(多かれ少なかれ)受け入れられた答えを参照します: https://stackoverflow.com/a/229919/114626

2
Eyal Roth