コードまたはルックアップ テーブルのベスト プラクティス
-
09-09-2019 - |
質問
[更新] この質問への回答として、選択されたアプローチは以下のとおりです
こんにちは、
この件についていろいろ調べてみたのですが、探しているものがなかなか見つかりません...
コードテーブルとは次のことを意味します。「婚姻状況」、性別、特定の法的または社会的状態など...より具体的には、これらのタイプには設定されたプロパティのみがあり、項目はすぐに変更される予定はありません (ただし、変更される可能性はあります)。プロパティは、ID、名前、説明です。
次のテクノロジーでこれらを最適に処理する方法を考えています。
データベース内 (複数のテーブル、異なるコードキーを持つ 1 つのテーブル...?)
クラスの作成 (おそらく ICode.Name と ICode.Description で ICode を継承するようなもの)
このためのビュー/プレゼンターを作成します。それらすべてを含む画面があるはずです。つまり、タイプのリスト (性別、婚姻状況など)、次にそのタイプの値のリストと、値リスト内の各項目の名前と説明が表示されます。
これらはすべてのプロジェクトに現れるものであるため、これらを処理する方法についてはいくつかのベスト プラクティスが必要です...
記録のために言っておきますが、私はこのような状況で列挙型を使用するのはあまり好きではありません...ここでの使用に関する議論も大歓迎です。
[フォローアップ]
わかりました。CodeToGlory と Ahsteele から素晴らしい回答が得られました。この質問を改良してみましょう。
私たちが話しているのは、性別や婚姻状況についてではなく、その価値観は間違いなく変わらないのですが、名前と説明はあるものの、それ以上のことは何もない「もの」について話しているとします。例えば:社会的地位、法的地位。
UI:これには 1 つの画面だけが必要です。可能な NameAndDescription タイプ (単にそう呼ぶことにします) を含むリストボックス、選択した NameAndDescription タイプの可能な値を含むリストボックス、選択した NameAndDescription タイプ項目の名前と説明フィールド。
これはビューとプレゼンターではどのように処理できますか?ここで難しいのは、NameAndDescription タイプをクラス名から抽出する必要があることです。
DB:複数のルックアップ テーブルと単一のルックアップ テーブルの長所と短所は何ですか?
解決 3
私はこのアプローチを採用することにしました。
CodeKeyManager mgr = new CodeKeyManager();
CodeKey maritalStatuses = mgr.ReadByCodeName(Code.MaritalStatus);
どこ:
- CodeKeyManager は DB から CodeKey を取得できます (CodeKey=MaritalStatus)
- コードは定数で満たされたクラスであり、Code.MaritalStatus = "maritalStatus" となる文字列を返します。これらの定数は、CodeKey テーブル > CodeKeyName にマップされます。
- データベースには 2 つのテーブルがあります。
- ID 付きの CodeKey、CodeKeyName
- CodeKeyId、ValueName、ValueDescription を含む CodeValue
DB:
代替テキスト http://lh3.ggpht.com/_cNmigBr3EkA/SeZnmHcgHZI/AAAAAAAAAFU/2OTzmtMNqFw/codetables_1.JPG
クラスコード:
public class Code
{
public const string Gender = "gender";
public const string MaritalStatus = "maritalStatus";
}
クラスコードキー:
public class CodeKey
{
public Guid Id { get; set; }
public string CodeName { get; set; }
public IList<CodeValue> CodeValues { get; set; }
}
クラスコード値:
public class CodeValue
{
public Guid Id { get; set; }
public CodeKey Code { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
私が見つけた最も簡単で効率的な方法は次のとおりです。
- すべてのコードデータを同じ方法で (同じビュー/プレゼンター内で) 表示できます。
- 今後登場するすべてのコードテーブルに対してテーブルやクラスを作成する必要はありません
- しかし、データベースからそれらを簡単に取得し、CodeKey 定数を使用して簡単に使用することはできます...
- Hibernate もこれを簡単に処理できます
私がまだ検討している唯一のことは、ビジネス ロジックでの使いやすさのために GUID ID を破棄し、文字列 (nchar) コードを使用することです。
ご回答ありがとうございます!このアプローチについてご意見があれば、ぜひお願いします。
他のヒント
非常に便利なデータベース駆動型コード表を使用することができます。あなたは、(開始日と終了日を使用して)データの生活を定義しますが、コードを展開する必要はありません、あなたは(当然の権利権限を持つ)ユーザーを許可することができますので、リアルタイムでのテーブルにデータを追加するようなことを行うことができます管理画面を介してデータを追加します。
私はいつもオートナンバー、主キーではなく、コードや説明を使用することをお勧めします。あなたは、時間の異なる期間にわたって(同じ名前が異なる記述の)複数のコードを使用するためにこれができます。プラス(私の経験では)ほとんどのDBAはむしろ、テキストベースの主キーの上にオートナンバー型を使用します。
私はコード化されたリストごとに単一のテーブルを使用します。あなたは、すべての(種類のマトリックスを使用して)関係のない1台に複数のコードを置くことができますが、それは厄介取得し、それも有用であったところ、私は夫婦のみの状況を発見した。
ここでいくつかのこと:
明示的に明確で変更されない列挙型を使用してください。たとえば、婚姻状況、性別などです。
上記のように固定されておらず、時間の経過とともに変化、増減する可能性がある項目にはルックアップ テーブルを使用します。
データベース内にルックアップ テーブルがあるのは非常に一般的です。ビジネス層でビュー/プレゼンテーションと連携できるキー/値オブジェクトを定義します。
私はこのタイプのデータのテーブル表現を使用しての方に傾きます。あなたがデータをキャプチャする必要がある場合は最終的に、あなたはそれを格納する必要があるでしょう。報告目的のために、あなたがキーを経由してからそのデータを引き出すことができる場所を持っている方が良いです。正規化の目的のために、私は、単一目的のルックアップテーブルは、多目的ルックアップテーブルよりも簡単であることがわかります。
列挙は、ジェンダーなどのように変更されないもののためにかなりよく働く言った。
なぜ誰もがコード表を複雑にしたいですか?はいそこにそれらの多くがありますが、それらはシンプルなので、そのように保管してください。ただ、これまでに他のオブジェクトと同様に扱います。あなたは、ドメインの一部であるので、ドメインの一部で、何も特別なとしてそれらをモデル化します。あなたは、彼らがinevitibly以上の属性や機能を必要としないときならば、あなたは現在、それを使用するすべてのコードを元に戻すと、それを手直しする必要があります。
当然のごとに1つのテーブル(参照整合性のために、彼らは報告のために利用できるように)。
私は「性別」オブジェクトを受け取るための方法を記述する場合は、クラスについては、当然のあたり再び1、私は誤って「MarritalStatus」それを渡すことができるようにしたくないので!あなたはランタイムエラーを取り除くコンパイルのヘルプをしてみましょう、それはなぜそのあります。各クラスは、単に継承するか、コードテーブルクラスまたは何が含まれているが、それは単に実装ヘルパーですができます。
それは実際には継承されたコードテーブルを使用しない場合は、UIについては、私はあなたを助けるとちょうど1つのUIでそれを維持することを使用することができたとします。
は、原則として、台無しビジネスモデルない、台無しデータベースモデルをしませんが、それはUIモデル内のビットの周りにネジにあなたのwnt、それは悪くないのです。
私はさらに、このアプローチを簡素化を検討したいと思います。代わりに、どのようにコードタイプとコード値の両方が含まれているだけのテーブル約コード(コード、コードキーおよびコード値)を規定する3つのテーブルの?すべての後のコードの種類は、コードのちょうど別のリストです。
このようなおそらく、テーブルの定義:
CREATE TABLE [dbo].[Code](
[CodeType] [int] NOT NULL,
[Code] [int] NOT NULL,
[CodeDescription] [nvarchar](40) NOT NULL,
[CodeAbreviation] [nvarchar](10) NULL,
[DateEffective] [datetime] NULL,
[DateExpired] [datetime] NULL,
CONSTRAINT [PK_Code] PRIMARY KEY CLUSTERED
(
[CodeType] ASC,
[Code] ASC
)
GO
CODETYPEのための型を表すCODETYPE = 0、コード= 0の根レコードがあるかもしれません。 CODETYPEレコードのすべてがCODETYPE = 0とコード> = 1を持つことになります。ここでは、物事を明確に役立つかもしれないいくつかのサンプルデータがあります:
SELECT CodeType, Code, Description FROM Code
Results:
CodeType Code Description
-------- ---- -----------
0 0 Type
0 1 Gender
0 2 Hair Color
1 1 Male
1 2 Female
2 1 Blonde
2 2 Brunette
2 3 Redhead
チェック制約が有効なCODETYPEがテーブルに入力されていることを確認するために、コードテーブルに追加することができます:
ALTER TABLE [dbo].[Code] WITH CHECK ADD CONSTRAINT [CK_Code_CodeType]
CHECK (([dbo].[IsValidCodeType]([CodeType])=(1)))
GO
関数IsValidCodeTypeは、次のように定義することができます:
CREATE FUNCTION [dbo].[IsValidCodeType]
(
@Code INT
)
RETURNS BIT
AS
BEGIN
DECLARE @Result BIT
IF EXISTS(SELECT * FROM dbo.Code WHERE CodeType = 0 AND Code = @Code)
SET @Result = 1
ELSE
SET @Result = 0
RETURN @Result
END
GO
提起されてきた1つの問題は、コード列を持つ表は、そのコードタイプのための適切な値を持っていることを確実にする方法です。これは、あまりにも機能を使用して、チェック制約によって強制することができます。
ここで男女列を持つPersonテーブルです。単語コードに続くコードタイプ(この例では、性別)の説明をすべてのコードの列に名前を付けることをお勧めすることができます:
CREATE TABLE [dbo].[Person](
[PersonID] [int] IDENTITY(1,1) NOT NULL,
[LastName] [nvarchar](40) NULL,
[FirstName] [nvarchar](40) NULL,
[GenderCode] [int] NULL,
CONSTRAINT [PK_Person] PRIMARY KEY CLUSTERED ([PersonID] ASC)
GO
ALTER TABLE [dbo].[Person] WITH CHECK ADD CONSTRAINT [CK_Person_GenderCode]
CHECK (([dbo].[IsValidCode]('Gender',[Gendercode])=(1)))
GO
IsValidCodeは、このように定義することができます:
CREATE FUNCTION [dbo].[IsValidCode]
(
@CodeTypeDescription NVARCHAR(40),
@Code INT
)
RETURNS BIT
AS
BEGIN
DECLARE @CodeType INT
DECLARE @Result BIT
SELECT @CodeType = Code
FROM dbo.Code
WHERE CodeType = 0 AND CodeDescription = @CodeTypeDescription
IF (@CodeType IS NULL)
BEGIN
SET @Result = 0
END
ELSE
BEGiN
IF EXISTS(SELECT * FROM dbo.Code WHERE CodeType = @CodeType AND Code = @Code)
SET @Result = 1
ELSE
SET @Result = 0
END
RETURN @Result
END
GO
別の機能は、コード列を持つテーブルを照会するときに、コードの記述を提供するために作成することができます。ここにあります Personテーブルを照会する例:
SELECT PersonID,
LastName,
FirstName,
GetCodeDescription('Gender',GenderCode) AS Gender
FROM Person
これは、すべてのデータベース内のルックアップテーブルの増殖を防止する一つのルックアップテーブルを提供するという観点から考えました。私は、このデザインは、実際にうまく行うかどうかはわかりません。