Jeg kan se et par grunde til, at du har brug for to tabeller til dette:
- rigtige medarbejdere skal have et navn, en afdeling osv., mens prognosemedarbejdere kun må have disse attributter
- der vil være ansvar, som kun rigtige medarbejdere kan have, så du ønsker at kunne henvise til dem separat
Men samtidig vil du sikre dig, at der ikke er nogen sammenstød mellem id'er på tværs af de to tabeller, fordi (forhåbentlig) forventede medarbejdere bliver faktiske medarbejdere.
Måden at gøre dette på er at implementere en supertype/subtypestruktur. Så du har én tabel, MEDARBEJDERE, som garanterer enkelte primære nøgler, og to afhængige tabeller for faktiske og forventede medarbejdere. Brugen af typekolonnen er afgørende, da den sikrer, at en given medarbejder kun optræder i én undertabel.
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 ;
Så tasterne ser måske lidt mærkelige ud. Den overordnede tabel har både en primær nøgle og en sammensat unik nøgle. Den primære nøgle garanterer en enkelt forekomst af EMP_ID. Den unikke nøgle giver os mulighed for at bygge fremmednøgler på de underordnede tabeller, som refererer til både EMP_ID og EMP_TYPE. Kombineret med kontrolkontrainterne på barnet tDette skyldes, at de refererer til den unikke nøgle på den overordnede tabel i stedet for dens primære nøgle. Denne ordning sikrer, at en medarbejder kan være i enten FORECAST_EMPLOYEES eller ACTUAL_EMPLOYEES, men ikke begge dele.
Fremmednøglerne kan udskydes for at tillade konvertering af prognosemedarbejdere til faktiske ansatte. Dette kræver tre aktiviteter:
- sletter posten fra FORECAST_EMPLOYEES
- indsætter en post i ACTUAL_EMPLOYEES
- ændring af EMP_TYPE (men ikke). EMP_ID) i EMPLOYEES.
Synkronisering af handling 2 og 3 er nemmere med udskudte begrænsninger.
Bemærk også, at andre fremmednøglebegrænsninger, der refererer til MEDARBEJDERE, bør bruge den primære nøgle frem for den unikke nøgle. Hvis forholdet bekymrer sig om typen af medarbejder, bør det sandsynligvis linke til de underordnede tabeller i stedet.
Velkommen til en verden af datamodellering. Det er én stor hovedpine. Fordi det er hårdt at prøve at passe rodet virkelighed ind i en ren datamodel :du har brug for klare krav for at få det rigtigt og en forståelse af, hvad der betyder mest, så du kan indgå fornuftige kompromiser.
Jeg foreslog en super-type/sub-type tilgang på baggrund af dit andet spørgsmål, og fordi det ser ud til at være den bedste måde at håndtere to sæt data på:rigtige medarbejdere og fiktive medarbejdere. Jeg synes, de to grupper skal behandles forskelligt. For eksempel ville jeg insistere på, at ledere er rigtige medarbejdere. Dette er nemt at gøre med en integritetsbegrænsning mod ACTUAL_EMPLOYEES og meget sværere at opnå med en enkelt tabel, som indeholder begge typer medarbejdere.
At have to tabeller betyder sikkert, at det genererer mere arbejde med hensyn til at synkronisere deres strukturer. Og hvad så? Det er stort set trivielt, da det knapt er mere arbejde at skrive to ALTER TABLE-udsagn end én. Derudover er det meget muligt, at den nye kolonne kun gælder for faktiske medarbejdere og ikke har nogen betydning for prognoser for medarbejdere (f.eks. EARNED_COMMISSION, LAST_REVIEW_RATING). I det lys gør det at have separate tabeller datamodellen mere nøjagtig.
Med hensyn til at skulle duplikere afhængige tabeller, som Ollie påpeger, er det en misforståelse. Tabeller, der gælder for alle medarbejdere uanset deres aktualitet, skal referere til MEDARBEJDER-tabellen og ikke dens børn.
Endelig forstår jeg ikke, hvorfor det er sværere at vedligeholde historiske data med to tabeller end for én. Det meste af journaliseringskoden bør udelukkende genereres fra dataordbogen.
Der er tre tabeller:
- EMPLOYEES - en mastertabel for at garantere unikke EMP_ID'er
- ACTUAL_EMPLOYEES - et underordnet bord for folk, der arbejder for din virksomhed
- FORECAST_EMPLOYEES - et underordnet bord for personer, som du håber at rekruttere til din virksomhed
Vær venligst opmærksom på, at jeg gør antagelser om din forretningslogik ud fra de sparsomme detaljer, du har angivet.
Nu forekommer det mig, at folk, der endnu ikke arbejder for din virksomhed, ikke skal have nogen tilknyttede aktiviteter. I det scenarie ville du have én tabel, EMPLOYEE_ACTIVITIES, som er et underordnet af ACTUAL_EMPLOYEES.
Men måske har du virkelig aktiviteter for folk, der ikke eksisterer. Så her er et valg:et bord eller to? One table-designet har EMPLOYEE_TASKS som et underordnet af master-EMPLOYEES-tabellen. De to tabeldesign har ACTUAL_EMPLOYEE_TASKS og FORECAST_EMPLOYEE_TASKS som børn af henholdsvis ACTUAL_EMPLOYEES og FORECAST_EMPLOYEES tabellerne.
Hvilket design der er det rigtige afhænger af, om du skal håndhæve regler vedrørende tildeling af opgaver. For eksempel kan din virksomhed have en regel, der siger, at kun rigtige mennesker kan ansætte nyt personale. Så det ville være nyttigt at have en model, der kun tillader rekrutteringsopgaver at blive tildelt ACTUAL_EMPLOYEES.
Okay, jeg har tilføjet datokolonner til de to tabeller. Det giver dig mulighed for at køre den rapport, du ønsker.