単純なデータベースの正規化の問題
-
27-09-2019 - |
質問
私は、私が設計し、それを正規化...
であることを確認することだとデータベースに関する簡単な質問を持っています私ははcustomerIdの主キーを持つ、顧客テーブルを持っています。これは、顧客がすなわち、ステータスアカウントに反映コードを持っているのStatusCode列があります。 1 =オープン、2 =クローズ、3 =などの中断...
今、私は、彼らがそこに取引条件を破る場合は、アカウントを一時停止することを許可するかしないフラグか...特定の顧客が自動的に停止されることを顧客テーブル内の別のフィールドを持っていると...他の人ではないでしょう...
:関連テーブルのフィールドはようになりますので、お客様(CustomerIdの(PK):のStatusCode:IsSuspensionAllowed)
これで、両方のフィールドがIsSuspensionAllowedフィールドがYESに設定されているときに、顧客が特定の顧客を知っている限り懸濁液はもちろんのを除いて、特定の顧客に許可されているかどうかの状態を判断できないとして、主キーに依存しています(一時停止)3ののStatusCodeを持つべきではありません。
それは、チェックcontraintが私のテーブルに追加されない限り、この現象が発生することが可能である上記の表の設計かららしいです。私は別のテーブルには、それが唯一のIsSuspensionAllowedがYESに設定され、両者がお互いに依存していたときのStatusCodeが3に設定されている場合にだとしてのにこれを強制するために、リレーショナル設計に加えることができるか見ることができません。
だから私の長いったらしい説明した後、私の質問はこれです:これは、正規化の問題であり、私はこれを強制しますリレーショナルデザインを見ていないよ...またはそれは実際にチェックして施行しなければならないだけでビジネスルールですcontraintとテーブルが実際にはまだ正規化されます。
乾杯、
スティーブ
解決
はい、それは可能です。あなたがチェック制約とCaseステートメントでそれを行うことができます:
Create Table Customer (
CustomerId <datatype> not null Primary Key
, StatusCode int not null
, IsSuspensionAllowed int not null Default( 1 )
, Constraint CK_Customer_IsSuspensionAllowed
Check ( IsSuspensionAllowed In(0,1) )
, Constraint CK_Customer_StatusCodeRange
Check ( StatusCode Between 0 And ?? )
, Constraint CK_Customer_StausCodeValid
Check ( Case
When StatusCode = 3 And IsSuspensionAllowed = 1 Then 0
Else 1
End = 1 )
, ....
)
私は単にプレースホルダを挿入してあなたはPKのデータ型については言及しませんでした。あなたは、SQL Serverを使用している場合は、(int
は、ANSI仕様の一部ではない)私は上記のbit
とチェック制約の代わりにビット列を使用することができます。
これは、ステータスコードのようなもののための代理キーが常にうまく動作しない場所の良い例です。文字列値は、CaseステートメントはWhen StatusCode = 'Suspended' And IsSuspendedAllowed = 0...
を読んでいました。その場合にはステータスコードを表す持っている方が良いでしょう。
正規化の観点から、私は何も間違って表示されません。サスペンションが許可されているかどうかは、お客様ではなく、別の属性に属性固有のものです。あなたは属性値の特定の状態は大丈夫ですが存在することができないことを、検査制約で何を言っている。
ところで、ときIsSuspensionAllowed = 0「一時停止」のステータスが許可されていないと言うことはより多くの意味がありませんか? 、StatusCode = 3 and IsSuspensionAllowed = 0
ことが許可されていない状態のデータを使用してはならない?