1

従業員を管理するためのアプリケーションを作成しています。従業員は、現在の従業員または将来入社する予定の従業員 (予測) です。

従業員の管理とは別に、毎月の予測も管理する必要があります。

今日が4月だとすると、

現在の従業員の戦力は 4 月 26 日時点で 100 です。

今日、8月に10人が参加すると予想しています。20 11月入社予定。

私が予測すると言うと、実際にはシステムに 10 人から 20 人の従業員を追加します。私は完全な情報を持っているかもしれないし、持っていないかもしれません。彼らはまだ雇われていないので、名前さえないかもしれません。ただ、4 月と同様に、8 月に 10 人、11 月に 20 人の採用があると予測しています。

間に脱退者または参加者がこれ以上いないと仮定します。私の従業員の戦力は、8月末までに110、11月末までに130になります。

つまり、8 月に 110、11 月に 130 が 4 月の私の予測です。

さて、5 月には、8 月には 10 人ではなく 5 人だけが入社し、11 月には 20 人ではなく 25 人が入社し、12 月には既存の従業員 10 人が解雇されることがわかりました。

したがって、私の従業員数は、5 月には 8 月には 105 人、11 月には 130 人、12 月には 120 人になると予測されています。

したがって、従業員データを毎月保持する必要があります。つまり、5 月から 12 月までのすべての将来の月について、4 月の私の予測は何でしたか。

繰り返しますが、8 月から 12 月までの 5 月の私の予測は何でしたか。

等々。

また、既存の従業員のデータが毎分変化し続ける可能性があることにも留意する必要があります。

役職、住所、部署などが変わる可能性があります。

したがって、従業員 A が 4 月に部門 D1 に所属し、4 月以降は D2 に所属するとします。

4 月のレポートを引き出すと、私が D1 として表示され、6 月のレポートを引き出すと、彼の部署が D2 として表示されるはずです。

助けてください。


この前の質問には、追加の背景があります。

編集 :

次の画像をご覧ください。

3 月 (月 = 3 月) に予測された従業員の数を、その後の各月で知りたいと思います。つまり、月 = 3 月、3 月の数 = 400、4 月の数 = 405 です。

括弧内の数字は、その月に入社する新入社員を示します。たとえば、(+10) & (-5) はその月に退職する社員を示します。したがって、3 月の総従業員数が 400 人で、4 月に 10 人が入社し、5 人が退職する場合、4 月の総従業員数は 405 人になります。

ここに画像の説明を入力

4

3 に答える 3

2

このために 2 つのテーブルが必要な理由がいくつかわかります。

  • 実際の従業員は名前、部署などを持っている必要がありますが、予測従業員のみがこれらの属性を持つことができます
  • 実際の従業員のみが持つことができる責任があるため、それらを個別に参照できるようにする必要があります

しかし同時に、2 つのテーブル間で ID が衝突しないようにする必要があります。これは、(できれば) 従業員の予測が実際の従業員になるためです。

これを行う方法は、スーパータイプ/サブタイプ構造を実装することです。つまり、1 つの主キーを保証する EMPLOYEES テーブルと、実際の従業員と予測従業員用の 2 つの従属テーブルがあります。特定の従業員が 1 つのサブテーブルにのみ表示されるようにするため、type 列の使用は非常に重要です。

create table employees
    ( emp_id number not null
      , emp_type varchar2(8) not null
      , constraint emp_pk primary key (emp_id)
      , constraint emp_uk unique (emp_id, emp_type)
      , constraint emp_type_ck check (emp_type in ('FORECAST', 'ACTUAL'));

create table actual_employees
    ( emp_id number not null
      , emp_type varchar2(8) not null
      , name varchar2(30) not null
      , deptno number(2,0) not null
      , sal number(7,2) not null
      , hiredate date not null
      , constraint actemp_pk primary key (emp_id)
      , constraint actemp_type_ck check (emp_type = 'ACTUAL')
      , constraint actemp_emp_fk foreign key (emp_id, emp_type)
                   references emp (emp_id, emp_type) 
                   deferrable initially deferred ;

create table forecast_employees
    ( emp_id number not null
      , emp_type varchar2(8) not null
      , name varchar2(30) 
      , deptno number(2,0) 
      , sal number(7,2) 
      , predicted_joining_date date
      , constraint foremp_pk primary key (emp_id)
      , constraint foremp_type_ck check (emp_type = 'FORECAST')
      , constraint foremp_emp_fk foreign key (emp_id, emp_type)
                   references emp (emp_id, emp_type) 
                   deferrable initially deferred ;

そのため、キーが少し奇妙に見えるかもしれません。親テーブルには、主キーと複合一意キーの両方があります。主キーは、EMP_ID の単一インスタンスを保証します。一意のキーにより、EMP_ID と EMP_TYPE の両方を参照する子テーブルに外部キーを作成できます。子 t のチェック制約と組み合わせる これは、親テーブルの主キーではなく、親テーブルの一意のキーを参照するためです。この取り決めにより、従業員は FORECAST_EMPLOYEES または ACTUAL_EMPLOYEES のいずれかに所属できますが、両方に所属することはできません。

外部キーは、予測従業員を実際の従業員に変換できるように遅延可能です。これには、次の 3 つのアクティビティが必要です。

  1. FORECAST_EMPLOYEES からのレコードの削除
  2. ACTUAL_EMPLOYEES へのレコードの挿入
  3. EMPLOYEES のEMP_TYPE ( EMP_ID ではない) を変更します。

アクション 2 と 3 の同期は、遅延制約を使用すると簡単です。

また、EMPLOYEES を参照する他の外部キー制約では、一意キーではなく主キーを使用する必要があることに注意してください。リレーションシップが従業員のタイプを気にする場合は、代わりに子テーブルにリンクする必要があります。


「ちょっと頭が痛い」

データモデリングの世界へようこそ。それは一つの大きな頭痛の種です。乱雑な現実をクリーンなデータ モデルに当てはめようとするのは難しいため、それを正しく行うには明確な要件が必要であり、賢明な妥協ができるように最も重要なことを理解する必要があります。

他の質問に基づいて、スーパータイプ/サブタイプのアプローチを提案しました。これは、実際の従業員と概念上の従業員という 2 つのデータセットを処理する最良の方法と思われるためです。この 2 つのグループは、異なる扱いを受ける必要があると思います。たとえば、私はマネージャーが実際の従業員であることを主張します。これは、ACTUAL_EMPLOYEES に対する整合性制約で簡単に実行できますが、両方のタイプの従業員を含む単一のテーブルで達成するのははるかに困難です。

確かに、テーブルが 2 つあるということは、それらの構造の同期に関して、より多くの作業が発生する可能性があることを意味します。だから何?1 つよりも 2 つの ALTER TABLE ステートメントを作成する方がほとんど作業がかからないため、これはほとんど簡単です。さらに、新しい列が実際の従業員にのみ適用され、従業員の予測には意味がない可能性は十分にあります (例: EARNED_COMMISSION、LAST_REVIEW_RATING)。その観点から、個別のテーブルを使用すると、データ モデルがより正確になります。

Ollie が指摘するように、従属テーブルを複製しなければならないことに関しては、それは誤解です。実際の従業員に関係なくすべての従業員に適用されるテーブルは、その子ではなく EMPLOYEES テーブルを参照する必要があります。

最後に、1 つよりも 2 つのテーブルの方が履歴データの維持が難しい理由がわかりません。ほとんどのジャーナリング コードは、データ ディクショナリから完全に生成する必要があります。


"Employee テーブルと Employee_forecast テーブルがある場合 ..."

次の 3 つのテーブルがあります。

  • EMPLOYEES - 一意の EMP_ID を保証するマスター テーブル
  • ACTUAL_EMPLOYEES - 会社で働く人々の子テーブル
  • FORECAST_EMPLOYEES - あなたの会社に採用したい人の子テーブル

「...製品または活動の両方が 1 つの製品/活動テーブルに保存されますか?」

あなたが提供したわずかな詳細から、あなたのビジネス ロジックについて推測していることに注意してください。

現在、あなたの会社でまだ働いていない人は、関連する活動を行うべきではないように思えます。このシナリオでは、ACTUAL_EMPLOYEES の子である EMPLOYEE_ACTIVITIES という 1 つのテーブルを作成します。

しかし、あなたは存在しない人々のために本当に活動をしているのかもしれません。ここに選択肢があります。1 つまたは 2 つのテーブルでしょうか。1 つのテーブルの設計には、マスター EMPLOYEES テーブルの子として EMPLOYEE_TASKS があります。2 つのテーブルの設計には、それぞれ ACTUAL_EMPLOYEES および FORECAST_EMPLOYEES テーブルの子として ACTUAL_EMPLOYEE_TASKS および FORECAST_EMPLOYEE_TASKS があります。

どの設計が正しいかは、タスクの割り当てに関する規則を適用する必要があるかどうかによって異なります。たとえば、あなたの会社には、実在の人物だけが新しいスタッフを雇うことができるというルールがあるとします。したがって、採用タスクのみを ACTUAL_EMPLOYEES に割り当てることができるモデルがあると便利です。


「この設計では、月ごとの予測は考慮されていません」

さて、2 つのテーブルに日付列を追加しました。これにより、必要なレポートを実行できます。

于 2012-04-26T12:22:32.693 に答える
1

データモデルは、レポートする必要がある情報に依存すると思います。たとえば、標準EMPLOYEEDEPARTMENTテーブル (Oracle の既定のSCOTTスキーマなど) を使用する傾向があります。

また、従業員が現在の従業員または将来の従業員であることを示すステータス列もあり、これにより、現在の雇用と雇用の予測についてレポートできます。従業員のステータスなどに応じて、どの列が必要かについて機能上の制約/ビジネス ルールを追加できます。そのため、現在の従業員には氏名、生年月日などがありますが、将来の従業員には含まれない場合があります。

次に、監査テーブルを作成して、EMPLOYEEレコードが受ける変更を追跡します。これにより、部門の変更、レコードの従業員が将来の従業員から現在の従業員などに変更された時期、およびレコード内の他のデータへの変更をさかのぼって見つけることができますEMPLOYEE
また、すべてのデータを 1 つの場所に保管できるという利点もあります。EMPLOYEE必要に応じて、ステータス列を使用してテーブルを分割することも検討できます。

これにより、アプリケーションでの雇用のさまざまな段階を通じて、プロセス全体で各従業員に 1 つの ID のみを発行するという利点が得られます。

ステータス列のもう 1 つの利点は、従業員が将来必要に応じて通過する可能性のある他の段階を紹介できることです。

編集:

これにより、言及したように将来列を追加する必要がある場合でも、1 つのテーブル構造のみをサポートする必要があることが保証されます。

于 2012-04-26T12:25:43.113 に答える
0

これが私がすることです:従業員と部門テーブルは典型的ですが、従業員と部門の間の多対多を表すemp_deptテーブルはありません。perspective_employees については、日付を含む別のテーブルを作成し、その情報が必要なときに従業員テーブルと結合することをお勧めします。

ここで詳しく説明するのは難しいですが、私が言っていることの基本を理解していただければ幸いです。

よろしく、ロジャー

于 2012-04-26T11:45:23.633 に答える