Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Wie gestaltet man ein Datenmodell, das sich mit den aktuellen Mitarbeitern und prognostizierten Mitarbeitern befasst?

Ich sehe ein paar Gründe, warum Sie dafür zwei Tabellen brauchen:

  • Echte Mitarbeiter müssen einen Namen, eine Abteilung usw. haben, während prognostizierte Mitarbeiter nur diese Attribute haben dürfen
  • Es wird Verantwortlichkeiten geben, die nur echte Mitarbeiter haben können, also möchten Sie in der Lage sein, sich separat auf sie zu beziehen

Gleichzeitig möchten Sie jedoch sicherstellen, dass die IDs in den beiden Tabellen nicht kollidieren, da aus (hoffentlich) prognostizierten Mitarbeitern tatsächliche Mitarbeiter werden.

Der Weg, dies zu tun, besteht darin, eine Supertyp/Subtyp-Struktur zu implementieren. Sie haben also eine Tabelle, EMPLOYEES, die einzelne Primärschlüssel garantiert, und zwei abhängige Tabellen für tatsächliche und prognostizierte Mitarbeiter. Die Verwendung der Typspalte ist entscheidend, da sie sicherstellt, dass ein bestimmter Mitarbeiter nur in einer Untertabelle erscheint.

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 ;

Die Tasten könnten also etwas seltsam aussehen. Die übergeordnete Tabelle hat sowohl einen Primärschlüssel als auch einen zusammengesetzten eindeutigen Schlüssel. Der Primärschlüssel garantiert eine einzelne Instanz der EMP_ID. Der eindeutige Schlüssel ermöglicht es uns, Fremdschlüssel für die untergeordneten Tabellen zu erstellen, die sowohl auf EMP_ID als auch auf EMP_TYPE verweisen. Kombiniert mit den Check Contraints für das untergeordnete tThis liegt daran, dass sie auf den eindeutigen Schlüssel der übergeordneten Tabelle und nicht auf ihren Primärschlüssel verweisen. Diese Anordnung stellt sicher, dass ein Mitarbeiter entweder in FORECAST_EMPLOYEES oder ACTUAL_EMPLOYEES sein kann, aber nicht in beiden.

Die Fremdschlüssel sind aufschiebbar, um die Umwandlung von prognostizierten Mitarbeitern in tatsächliche Mitarbeiter zu ermöglichen. Dies erfordert drei Aktivitäten:

  1. Löschen des Datensatzes aus FORECAST_EMPLOYEES
  2. Einfügen eines Datensatzes in ACTUAL_EMPLOYEES
  3. Ändern des EMP_TYPE (aber nicht die EMP_ID) in MITARBEITER.

Das Synchronisieren der Aktionen 2 und 3 ist mit zurückgestellten Einschränkungen einfacher.

Beachten Sie außerdem, dass andere Fremdschlüsseleinschränkungen, die auf MITARBEITER verweisen, den Primärschlüssel und nicht den eindeutigen Schlüssel verwenden sollten. Wenn die Beziehung sich um die Art des Mitarbeiters kümmert, sollte sie wahrscheinlich stattdessen auf die untergeordneten Tabellen verweisen.

Willkommen in der Welt der Datenmodellierung. Es ist ein großes Kopfzerbrechen. Denn der Versuch, die chaotische Realität in ein sauberes Datenmodell einzupassen, ist schwierig :Sie brauchen klare Anforderungen, um es richtig zu machen, und ein Verständnis dafür, was am wichtigsten ist, damit Sie vernünftige Kompromisse eingehen können.

Ich habe einen Supertyp/Subtyp-Ansatz auf der Grundlage Ihrer anderen Frage vorgeschlagen, und weil dies der beste Weg zu sein scheint, mit zwei Datensätzen umzugehen:echte Mitarbeiter und fiktive Mitarbeiter. Ich denke, diese beiden Gruppen müssen unterschiedlich behandelt werden. Zum Beispiel würde ich darauf bestehen, dass Manager echte Mitarbeiter sind. Dies ist mit einer Integritätsbeschränkung für ACTUAL_EMPLOYEES einfach und mit einer einzigen Tabelle, die beide Arten von Mitarbeitern enthält, viel schwieriger zu erreichen.

Sicher, zwei Tabellen zu haben, bedeutet möglicherweise mehr Arbeit in Bezug auf die Synchronisierung ihrer Strukturen. Na und? Es ist weitgehend trivial, da es kaum mehr Arbeit macht, zwei ALTER TABLE-Anweisungen zu schreiben als eine. Außerdem ist es durchaus möglich, dass die neue Spalte nur für tatsächliche Mitarbeiter gilt und für prognostizierte Mitarbeiter keine Bedeutung hat (z. B. EARNED_COMMISSION, LAST_REVIEW_RATING). Vor diesem Hintergrund wird das Datenmodell durch getrennte Tabellen genauer.

In Bezug auf das Duplizieren abhängiger Tabellen ist dies, wie Ollie betont, ein Missverständnis. Tabellen, die unabhängig von ihrer Aktualität für alle Mitarbeiter gelten, sollten auf die Tabelle EMPLOYEES verweisen, nicht auf ihre untergeordneten Tabellen.

Schließlich verstehe ich nicht, warum die Pflege historischer Daten mit zwei Tabellen schwieriger ist als mit einer. Der meiste Journalcode sollte vollständig aus dem Datenwörterbuch generiert werden.

Es gibt drei Tabellen:

  • EMPLOYEES - eine Haupttabelle, um eindeutige EMP_IDs zu garantieren
  • ACTUAL_EMPLOYEES - eine untergeordnete Tabelle für Personen, die für Ihr Unternehmen arbeiten
  • FORECAST_EMPLOYEES – eine untergeordnete Tabelle für Personen, die Sie für Ihr Unternehmen gewinnen möchten

Bitte beachten Sie, dass ich anhand der wenigen von Ihnen bereitgestellten Details Annahmen über Ihre Geschäftslogik treffe.

Nun scheint es mir, dass Menschen, die noch nicht für Ihr Unternehmen arbeiten, keine damit verbundenen Aktivitäten haben sollten. In diesem Szenario hätten Sie eine Tabelle, EMPLOYEE_ACTIVITIES, die ein Kind von ACTUAL_EMPLOYEES ist.

Aber vielleicht haben Sie wirklich Aktivitäten für Menschen, die es nicht gibt. Also hier ist eine Wahl:ein Tisch oder zwei? Das One-Table-Design hat EMPLOYEE_TASKS als untergeordnetes Element der Master-Tabelle EMPLOYEES. Das Zwei-Tabellen-Design hat ACTUAL_EMPLOYEE_TASKS und FORECAST_EMPLOYEE_TASKS als Kinder der Tabellen ACTUAL_EMPLOYEES bzw. FORECAST_EMPLOYEES.

Welches Design das richtige ist, hängt davon ab, ob Sie Regeln zur Aufgabenverteilung durchsetzen müssen. Beispielsweise könnte Ihr Unternehmen eine Regel haben, die besagt, dass nur echte Personen neue Mitarbeiter einstellen können. Es wäre also sinnvoll, ein Modell zu haben, das die Zuweisung von Personalbeschaffungsaufgaben nur an TATSÄCHLICHE_MITARBEITER zulässt.

Okay, ich habe den beiden Tabellen Datumsspalten hinzugefügt. Dadurch können Sie den gewünschten Bericht ausführen.