2

次のように要約できる問題があります。

従業員データベースを実装しているとします。一人一人が自分の立場に依存するため、さまざまなフィールドに入力する必要があります。たとえば、従業員がソフトウェア エンジニアの場合、次の列があります。

Name
Family
Language
Technology
CanDevelopWeb 

従業員がビジネス マネージャーの場合、次の列があります。

Name
Family
FieldOfExpertise
MaximumContractValue
BonusRate

また、従業員が営業担当者の場合は、他の列などがあります。

これをデータベーススキーマに実装するにはどうすればよいですか?

私が考えた1つの方法は、いくつかの関連するテーブルを持つことです:

コアテーブル:

Name
Family
Type

type が 1 の場合、従業員はソフトウェア開発者であるため、残りの情報は table にあるはずですSoftwareDeveloper

Language
Technology
CanDevelopWeb 

ビジネス マネージャーの場合、列を持つ別のテーブルがあります。

FieldOfExpertise
MaximumContractValue
BonusRate

この構造の問題は、1 つのテーブルが 1 つの列で複数のテーブルと関係を持っているため、テーブル間の関係を作成する方法がわからないことです。

リレーショナル整合性を強制する方法は?

4

7 に答える 7

3

There are a few schools of thought here.

(1) store nullable columns in a single table and only populate the relevant ones (check constraints can enforce integrity here). Some people don't like this because they are afraid of NULLs.

(2) your multi-table design where each type gets its own table. Tougher to enforce with DRI but probably trivial with application or trigger logic.

The only problem with either of those, is as soon as you add a new property (like CanReadUpsideDown), you have to make schema changes to accommodate for that - in (1) you need to add a new column and a new constraint, in (2) you need to add a new table if that represents a new "type" of employee.

(3) EAV, where you have a single table that stores property name and value pairs. You have less control over data integrity here, but you can certainly constraint the property names to certain strings. I wrote about this here:

于 2012-06-05T20:59:51.313 に答える
2

カテゴリ(別名、継承、一般化、サブクラス)階層を実装するための3つの可能な戦略のうちの1つ(「テーブルごとのクラス」)を説明しています。

親テーブルから子テーブルへの PK の正しい「伝播」は、それらの間の単純な外部キーによって当然強制されますが、子行の存在と排他性の両方を保証することは別の問題です。(上記のリンクに記載されているように) 実行できますが、追加された複雑さはおそらく価値がないため、通常はアプリケーション レベルで処理することをお勧めします。

于 2012-06-05T21:02:34.213 に答える
1
  1. EmployeeIdで呼び出されるフィールドを追加しますEmployeeTable
  2. 私は取り除くだろうType
  3. BusinessManagerテーブルの場合、たとえばSoftwareDeveloper、追加しますEmployeeId
  4. BusinessManagerここから、SoftwareDeveloperテーブルから外部キーの作成に進むことができますEmployee
于 2012-06-05T20:59:14.030 に答える
1

コア テーブルを使用して 1 つの方法をさらに拡張するには、ID 列に基づいて代理キーを作成します。これにより、各従業員に一意の従業員 ID が作成されます (これは、同じ名前の従業員を区別するのにも役立ちます)。

外部キーは参照整合性を保持します。SoftwareDeveloper または BusinessManagers テーブル内の存在をフィルタリングできるため、誰かが言及したように EmployeeTypeId は必ずしも必要ではありません。列は代わりに、クエリを簡単にするためにキャッシュされたデータ ポイントとして機能します。

以下のサンプル コードに型を入力し、外部キーの名前を変更する必要があります。

create table EmployeeType(
    EmployeeTypeId
,   EmployeeTypeName
,   constraint PK_EmployeeType primary key (EmployeeTypeId)
)

create table Employees(
    EmployeeId int identity(1,1)
,   Name
,   Family
,   EmployeeTypeId
,   constraint PK_Employees primary key (EmployeeId)
,   constraint FK_blahblah foreign key (EmployeeTypeId) references EmployeeType(EmployeeTypeId)
)

create table SoftwareDeveloper(
    EmployeeId
,   Language
,   Technology
,   CanDevelopWeb
,   constraint FK_blahblah foreign key (EmployeeId) references Employees(EmployeeId)
)

create table BusinessManagers(
    EmployeeId
,   FieldOfExpertise
,   MaximumContractValue
,   BonusRate
,   constraint FK_blahblah foreign key (EmployeeId) references Employees(EmployeeId)
)
于 2012-06-05T21:04:51.577 に答える
1

既存の SQL エンジンには、この状況での作業を容易にするソリューションはありません。

あなたの問題は、「エンティティのサブタイピング」の章の「データベース管理の実際的な問題」でかなり大きく議論されています。この特定の章だけでなく、称賛に値する読み物です。

論理設計の観点からの適切な解決策は、あなたのものと似ていますが、コアテーブルの「タイプ」列に対するものです。従業員が表示される非コアテーブルから「タイプ」を導出できるため、それは必要ありません。

確認する必要があるのは、データの全体的な整合性 (一貫性) を保証するビジネス ルール (別名データ制約) です (もちろん、これらのいずれかが実際に適用されるかどうかは、私ではなくビジネス ユーザーが教えてくれるはずです)。 :

指定された各従業員は、正確に 1 つの仕事を持っている必要があるため、どこかに仕事の詳細があります。iow : (1) 職務の詳細をまったく持たない名前付きの従業員はなく、(2) 1 つ以上の職務の詳細を持つ名前付きの従業員はいません。

(3) すべての仕事の詳細は、指名された従業員のものでなければなりません。

これらのうち、(3) は、SQL エンジンを使用している場合に宣言的に実装できる唯一のものです。非コア テーブルからコア テーブルへの通常の FK です。

(1) および (2) は、CREATE ASSERTION または CHECK CONSTRAINT が定義されているテーブル以外のテーブルへの参照を含む CHECK CONSTRAINT のいずれかを使用して、標準 SQL で宣言的に定義できますが、これらの構造はいずれもどの SQL エンジンでもサポートされていません。知る。

「タイプ」列を選択するのが適切でない理由についてもう 1 つ: 制約 (3) の定式化方法が変更されます。たとえば、「すべてのビジネス マネージャーは従業員という名前にする必要があります」と言うのではなく、「すべてのビジネス マネージャーは従業員という名前で、そのタイプは <ここに入力> です」と言う必要があります。つまり、コア テーブルへの「通常の FK」は、コア テーブルのVIEWへの参照になりました。

CREATE TABLE BUSMANS ... REFERENCES (SELECT ... FROM CORE WHERE TYPE='BM');

また

CREATE VIEW BM AS (SELECT ... FROM CORE WHERE TYPE='BM'); テーブル BUSMANS の作成 ... 参照 BM;

繰り返しになりますが、SQL では実行できないことがあります。

于 2012-06-06T08:23:00.343 に答える
0

You are on the right track. You can set up PK/FK relationships from the general person table to each of the specialized tables. You should add a personID to all the tables to use for the relationship as you do not want to set up a relationship on name because it cannot be a PK as it is not unique. Also names change, they are a very poor choice for an FK relationship as a name change could cause many records to need to change. It is important to use separate tables rather than one because some of those things are in a one to many relationship. A Developer for instnce may have many differnt technologies and that sort of thing should NEVER be stored in a comma delimted list.

You could also set up trigger to enforce that records can only be added to a specialty table if the main record has a particular personType. However, be wary of doing this as you wil have peopl who change roles over time. Do you want to lose the history of wha the person knew when he was a developer when he gets promoted to a manager. Then if he decides to step back down to development (A frequent occurance) you would have to recreate his old record.

于 2012-06-05T21:00:41.197 に答える
0

同じテーブル内のすべてのフィールドを使用できますが、Employee_Type(たとえば) という名前の追加のテーブルが必要になり、ここに配置する必要がありますDeveloper, Business Manager,... もちろん、一意の ID を使用します。したがって、あなたの関係は になりemployee_type_idますEmployee table

employee_type_idPHP または ASP を使用すると、ドロップダウン メニューの (またはテキスト) に応じて、表示するフィールドを制御できます。

于 2012-06-05T20:57:13.207 に答える