2012-08-15 111 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';