2012-08-15 114 views
0

enter image description here公司數據庫

層次的數據訪問級別實行我要在數據庫中創建一個應用程序的給定公司的結構,並希望遍歷結構的基礎上的員工詳細信息。下面給出的問題。

當員工登錄到系統時,他應該能夠看到員工的詳細信息,他們在哪個級別工作。例如,如果「Executive B」登錄系統,他應該能夠看到員工A,員工B,員工C和員工C的下屬員工的詳細信息。

與此同時,工作人員C正在向科長C報告,科長C只能查看工作人員C的詳細信息,而不能查看其子工作人員。這意味着,當科長C登錄時,他可以查看其子員工以及員工C.

但科長D可以查看員工C的詳細信息和其子員工的詳細信息,因爲他具有對該分支的完全訪問權限這意味着他可以查看他的下屬員工以及員工C和他的下屬員工。

任何人都可以幫助我實現這個結構和數據庫中的訪問級別以及如何以有效的方式查詢它們嗎?

+1

喬爾布朗指出你的嵌套集合將幫助你瀏覽樹,但是你的層次結構有問題。如果'Staff C'報告給'Section C',爲什麼它低於'Executive B'? – 2012-08-15 12:17:56

+0

在架構中,員工C是多人交叉報告。根據公司結構,他在B組執行,但是對於一些特定的工作,他必須向科長C和科長D報告。 – Sutha 2012-08-17 02:48:35

回答

3

解決這種層次遍歷問題的常用方法是使用名爲的訪問號的技術,我在my answer to this question中詳細描述了這一技術。使用訪問號碼,您可以輕鬆找到層次結構中任何給定節點下的所有節點的列表。

請注意,您仍然使用員工表上的漸進式外鍵記錄每位員工的直接上級。

對於您的情況,您還在常規報告層次結構之外進行了虛線報告(員工C到科長C)。這意味着你需要兩種方法。首先是將訪問數字用於定期報告,其中管理人員可以查看他們的所有直接和間接報告,然後使用點線報告的其他內容。

看起來你有兩種虛線報告規則。一些虛線主管可以看到副員工,其他人只能看到他們的虛線直接報告。由於人們可以有多個虛線管理員,因此您需要添加一個交點表來記錄這些虛線關係。此交集表還可以包含標記屬性,該屬性指示虛線主管是否能夠看到唯一的直接虛線下屬或該人及其所有下屬。

無論哪種方式,虛線關係直接記錄在員工和他們的主管之間,並且定期報告關係(可能是間接的)由訪問數量管理。

+0

非常感謝您的回答,它確實有助於解決我遇到的問題。我在**訪問數字結構中更改/插入新員工時遇到了一個小問題。例如,如果我想在_Becutive B_和員工上方添加另一名員工,那麼員工應該向新添加的員工報告,他應該向_Executive B_報告。在這種情況下,我如何管理插入(SQL)以在流之間添加新員工。提前致謝。 – Sutha 2012-08-17 03:02:06

+0

@Sutha ... - 當層次結構發生變化時,訪問號碼將被重新計算。您可以使用強力方法,並在發生任何變化時重新計算所有數字,或者您可以進行更多手術。 Joe Celko的書「聰明人SQL:高級SQL編程」在樹的章節中詳細介紹了機制。 – 2012-08-17 11:13:33

0

您需要員工上的幾個自聯接表。 One代表監督員與員工的關係。 第二個代表員工之間的同伴關係。

這裏是否存在級聯計算器PostgreSQL的

的SQL

下降模式;

create schema stackoverflow;

將search_path設置爲stackoverflow,public;

創建表僱員

id serial not null unique, 

name text not null unique, 

title text not null, 

primary key (id) 

);

創建表報告

supervisorid integer not null references employee (id) on delete cascade , 

subordinateid integer not null references employee (id) 
     check (supervisorid != subordinateid), 

unique (supervisorid, subordinateid), 

unique(subordinateid) 

);

創建表等

supervisorid integer not null references employee (id) on delete cascade , 

peerid integer not null references employee (id) 

     check (supervisorid != peerid), 

unique (supervisorid, peerid) 

);

創建或替換視圖directreports作爲

select supervisor.id as "supervisor id", 

     supervisor.name as "supervisor name", 

    reporting.id as "employee id", reporting.name as "employee name" 

from 

    employee supervisor, employee reporting , reports 

where 

supervisor.id = reports.supervisorid 

and reporting.id = reports.subordinateid; 






create or replace view peerreports as 

SELECT * FROM directreports,對等體,僱員

where 

    employee.id = peer.peerid 

     and peer.supervisorid = directreports."supervisor id"; 

插入到僱員(姓名,頭銜)

values ('c head', 'c head'), 
     ('d head', 'd head'), 
     ('c emp1', 'c emp1') , 
     ('c emp2', 'c emp2') ; 




insert into reports 

select employee.id as "supervisorid", 
     reportsto.id as "subordinateid" 

    from employee, employee reportsto 

    where employee.name = 'c head' 

    and reportsto.name in ('c emp1', 'c emp2') 

    and reportsto.name != employee.name ; 




insert into peer  

    select employee.id as "supervisorid", 
      peerto.id as "peer.peerid" 

    from employee, employee peerto 

     where employee.name = 'c head' and peerto.name = 'd head' 

     and employee.id != peerto.id; 

這裏是典型查詢

select * from employee;

select * from reports;

select * from directreports;

select * from peer;

select * from peerreports,employee where employee.name ='d head';