sql >> Databasteknik >  >> RDS >> Oracle

Hur utformar man en datamodell som handlar om nuvarande anställda och prognostiserade anställda?

Jag kan se ett par anledningar till att du behöver två tabeller för detta:

  • riktiga anställda måste ha ett namn, en avdelning etc medan prognosanställda endast kan ha dessa attribut
  • det kommer att finnas ansvar som bara riktiga anställda kan ha, så du vill kunna referera till dem separat

Men samtidigt vill du se till att det inte finns några krockar mellan ID:n över de två tabellerna, eftersom (förhoppningsvis) prognostiserade anställda kommer att bli faktiska anställda.

Sättet att göra detta är att implementera en supertyp/subtypstruktur. Så du har en tabell, ANSTÄLLDA som garanterar enstaka primärnycklar, och två beroende tabeller för faktiska och prognostiserade anställda. Användningen av typkolumnen är avgörande, eftersom den säkerställer att en viss anställd endast visas i en undertabell.

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å nycklarna kan se lite udda ut. Den överordnade tabellen har både en primärnyckel och en sammansatt unik nyckel. Den primära nyckeln garanterar en enda instans av EMP_ID. Den unika nyckeln tillåter oss att bygga främmande nycklar på de underordnade tabellerna som refererar till både EMP_ID och EMP_TYPE. Kombinerat med kontrollbegränsningarna på barnet tDetta beror på att de refererar till den unika nyckeln på den överordnade tabellen snarare än dess primära nyckel. kan detta arrangemang säkerställer att en anställd kan vara i antingen FORECAST_EMPLOYEES eller ACTUAL_EMPLOYEES men inte båda.

De främmande nycklarna kan skjutas upp för att möjliggöra omvandling av prognostiserade anställda till faktiska anställda. Detta kräver tre aktiviteter:

  1. tar bort posten från FORECAST_EMPLOYEES
  2. infogar en post i ACTUAL_EMPLOYEES
  3. ändrar EMP_TYPE (men inte EMP_ID) i EMPLOYEES.

Synkronisering av åtgärder 2 och 3 är lättare med uppskjutna begränsningar.

Observera också att andra begränsningar för främmande nyckel som refererar till ANSTÄLLDA bör använda primärnyckeln snarare än den unika nyckeln. Om relationen bryr sig om typen av anställd bör den förmodligen länka till underordnade tabeller istället.

Välkommen till en värld av datamodellering. Det är en enda stor huvudvärk. Eftersom det är svårt att försöka få in rörig verklighet i en ren datamodell :du behöver tydliga krav för att få det rätt, och en förståelse för vad som är viktigast så att du kan göra vettiga kompromisser.

Jag föreslog ett tillvägagångssätt av supertyp/subtyp på grundval av din andra fråga, och för att det verkar vara det bästa sättet att hantera två uppsättningar data:riktiga anställda och fiktiva anställda. Jag tror att de två grupperna måste behandlas olika. Till exempel skulle jag insistera på att chefer är riktiga anställda. Detta är lätt att göra med en integritetsbegränsning mot ACTUAL_EMPLOYEES och mycket svårare att uppnå med en enda tabell som innehåller båda typerna av anställda.

Visst, att ha två tabeller innebär möjligen mer arbete när det gäller att synkronisera deras strukturer. Än sen då? Det är till stor del trivialt, eftersom det knappt är mer arbete att skriva två ALTER TABLE-satser än ett. Dessutom är det mycket möjligt att den nya kolumnen endast gäller faktiska anställda och inte har någon betydelse för att prognostisera anställda (t.ex. EARNED_COMMISSION, LAST_REVIEW_RATING). I det ljuset gör separata tabeller datamodellen mer exakt.

När det gäller att behöva duplicera beroende tabeller, som Ollie påpekar, är det ett missförstånd. Tabeller som gäller alla anställda oavsett deras verklighet ska referera till tabellen MEDARBETARE, inte dess barn.

Slutligen förstår jag inte varför det är svårare att upprätthålla historiska data med två tabeller än för en. Det mesta av journalföringskoden bör genereras helt från dataordboken.

Det finns tre tabeller:

  • ANSTÄLLDA - en huvudtabell för att garantera unika EMP_ID:n
  • ACTUAL_EMPLOYEES - ett underordnat bord för personer som arbetar för ditt företag
  • FORECAST_EMPLOYEES - ett underordnat bord för personer som du hoppas kunna rekrytera till ditt företag

Kom ihåg att jag gör antaganden om din affärslogik utifrån de knappa uppgifterna du har angett.

Nu verkar det för mig att personer som ännu inte arbetar för ditt företag inte ska ha några associerade aktiviteter. I det scenariot skulle du ha en tabell, EMPLOYEE_ACTIVITIES, som är ett barn till ACTUAL_EMPLOYEES.

Men kanske har du verkligen aktiviteter för människor som inte finns. Så här är ett val:ett bord eller två? Designen med en tabell har EMPLOYEE_TASKS som ett underordnat av tabellen Master EMPLOYEES. De två tabelldesignerna har ACTUAL_EMPLOYEE_TASKS och FORECAST_EMPLOYEE_TASKS som underordnade ACTUAL_EMPLOYEES- respektive FORECAST_EMPLOYEES-tabeller.

Vilken design som är den korrekta beror på om du behöver tillämpa regler för tilldelning av uppgifter. Till exempel kan ditt företag ha en regel som säger att bara riktiga personer kan anställa ny personal. Så det skulle vara användbart att ha en modell som endast tillåter att rekryteringsuppgifter tilldelas ACTUAL_EMPLOYEES.

Okej, jag har lagt till datumkolumner i de två tabellerna. Det gör att du kan köra den rapport du vill ha.



  1. Hur man listar alla lagrade procedurer i MariaDB

  2. SQL-uppdatering, radera och infoga på samma gång

  3. Konfigurera en lokal SQL Server-databas

  4. Oracle - unika Listagg-värden