How would you model the following database relationship? - sql

There are departments and managers. A department has more managers, but only one manager is the chief manager of the department. A department must have only one chief manager. During holidays, a chief manager from a department can be the temporary chief manager of another department. How would you model this ?
Please explain your choice.

Assuming a single "ordinary" manager can manage at most one department, your data model should probably look something like this:
A CHIEF_MANAGER_ID can "point" either:
to a manager from the same department (i.e. whose MANAGER.DEPARTMENT_ID matches the DEPARTMENT.DEPARTMENT_ID of the row containing this CHIEF_MANAGER_ID), in which case it is the "primary" chief manager
or to a manager from the different department, in which case it is the "substitute" chief manager.
In case you want to ensure a same person cannot manage multiple departments in its role as a chief manager (while still being able to manage one more department as an ordinary manager), add a UNIQUE constraint on CHIEF_MANAGER_ID.
In case you need to memorize both primary and substitute chief managers at the same time, use two fields instead of just CHIEF_MANAGER_ID (in which case, you'd also have to enforce department matching non-declaratively).
In the model above, the DEPARTMENT.CHIEF_MANAGER_ID is NULL-able. This is done to break the cycle of foreign keys, so data could actually be inserted into the database without deferring foreign keys. If your DBMS supports deferrable constraints, you can make this field NOT NULL and defer one of the FKs, so it is checked at the end of the transaction (after both rows have been inserted).
I just realized there is an additional requirement: not every manager can be substitute. Only a chief can. You could do something like this to model it:
The SUBSTITUTE_DEPARTMENT_ID points to the department we are "borrowing" the chief manager substitute from. Since we are pointing to a department, and not directly manager, we know we must be getting the chief manager with it.

One table for departments, one table for managers, one table for chief managers.
A relational table for managers to departments, a relational table for chief managers to departments, a relational table for chief managers to other departments they are allowed to oversee (or instead, if it results in a smaller data set, the table should be relational for chief managers to departments they are NOT allowed to oversee).

you can use this model
Department
(
IdDepartment,
other properties ...
)
Manager
(
Idmanager,
other properties ...
)
DepartmentManager
(
IdDepartment,
IdManager,
IsTemporary
)
In your physical model
DepartmentTable
IdDepartment as primary key
ManagerTable
IdManager as primary key
DepartmentManagerTable
(IdDepartment + IdManager) as primary key
IsTemporaryChef as property

One table for departments (including chief manager ID)
One table for Managers (Per person)
One table for Department/Manager relationships (Department ID & Manager ID)
Example:

The main idea here is to separate hierarchy of an organizational chart from employees (manager is an employee). Like the difference between the President (position) and the person who holds the office.
For simplicity, the hierarchy is here modelled with the levelled-adjacency-list; not most efficient for SQL hierarchies, but good enough for this.
Note, chief manager of a department has a position that does not report to anyone in that department. CEO of the whole organization has ReportsTo = NULL, for everyone else it points to the boss-position.
Each employee can fulfill any role over time.
For more efficient hierarchy models, see Celko's book or just google 'SQL hierarchies'.

Related

Selecting those Affected by a 1:1 relationship

My teacher asked us to select from a 1:1 table called Employee; the supervisor and their role, and each employee they supervise with their role (employee is the primary key and those are the only 3 values in the table).
A 1:1 relationship are two tables with only one possible matching id.
It assumes that each supervisors only has one employee. so your query would look something like this.
SELECT Employee.Name, Employee.Role, supervise.Name, supervise.Role
FROM Employee
INNER JOIN supervise
ON Employee.EmployeeId = Supervise.EmployeeId
However, do note that in a real world context. This should have been a 1:N (One-To-Many) as each supervisors can have many employees.
Usually a 1:1 relationships are only used when you want to extended a table that you have no access or cannot modify. Otherwise, you would just add more columns to that original table. (or if you are working with a very old database system and you reach the max number of columns)

How to use FKs correctly in SQL Tables

Table Department:
DeptId
Name
Table Team
TeamId
*DeptId (FK)
Name
Table Employee
EmpId
*DeptId
*TeamId
I am making some updates on an old project, but I don't know why the old programmer designed those tables like this (like putting both DeptId and TeamId in the Employee table).
I find this useless because I can get the department from the Team table, and there's no need to put both FK IDs into the Employee table, TeamId is enough.
Is there any other reason that could force me to put both FKs in that table?
Thank you.
As the data model is written, an employee could be a member of a team that is not in his or her department.
That is probably possible, for instance, if the employee is temporarily on loan.
My bigger problem with the data model is that the relationships between employee and team and employee and department vary over time. So, I would have three tables for each entity. The only relationship in the tables would be between team and department (because that presumably does not change over time).
Then I would have two junction tables, one employeeDepartments and one employeeTeams that capture the changing relationships over time.

Generate connections table in SQL

I looked for this and did not find a solution that would apply to my scenario.
I'm building a database of game devs and I wish to generate a connections table:
I have the following:
Employee
(
name, date of birth, department they work at, task they do
)
Department
(
department name
)
Task
(
task name
)
and I need to generate a connections table that shows which department contributes to which task. I would do that by checking for each employee their department (only one) and task (also only one) and upon a match, the department contributes to that task.
That is the idea but I have to clue how to code it using Oracle
SELECT DISTINCT "department they work at", "task they do"
FROM Employee;
You should first work out an entity-relationship diagram, that lists the entities you use and with what attributes (and which primary keys), and the relations between those entities. Relationships can be: 1-to-1, 1-to-many and many-to-1, and many-to-many.
In the last case (M:N relation), the implementation in database tables requires an extra table to record such a M:N relationship.
The way to implement a 1:N relationship in a table is adding a foreign key in the child table to the primary key of the parent table.
EDIT: I see that you now supplied some details, and it is clear now that EMPLOYEE table is in fact the connection table, so you could simply query that table and show the DEPTID and TASKID (both the primary keys of their respective tables) to have a connection between departments and tasks. See the query in the other answer, and just add an ORDERBY on DEPTID, to show results in the order of DEPTID.

How to express these model relationships

I'm not sure about the best way to express a relationship between models in my Laravel 4 application. I have three models that I am using to store information in a database: Employer, Employee and User. Basically, the Employer and Employee models are just going to contain meta information about the User model. I think the following expression is the best I can think of:
Employer has many Employee
Employee belongs to one Employer
Employer belongs to one User
Employee belongs to one User
In the database, I am going to have a user_id foreign key in both the employers and employees tables that reference the id field in the users table. Is this the best way to model this domain?
It depends. Can an employee have more than one employer? Can an employee be employed at more than one place? Do you want to delete records if an employee leaves (and lose history)?
If you can delete the employee record when the employee leaves you can just have an employer_id field in the employee table. But just be prepared that you won't be able to easily add capabilities if you need them in the future.
If you want to prepare for the future: You might want to have a table that says
employer_id
employee_id
start_date
end_date
And even then if an employee comes and then leaves you have records with the same employer_id, employee_id. So that makes it look like you need an internal key and have say:
employment_record_id // this is the primary key
employer_id
employee_id
start_date
end_date
I'm not sure exactly what users are but ask yourself the same types of questions:
Can a user exist with an employee record
Can you have employees without a user record
Can a employees user record change
Can a users employee record change

How to include these requirements in my database design?

I am developing an intranet application for my company. The company has a complicated structure in which there are many business lines, departments, divisions, units and groups. I have to take care of all of these things. Some employees work under department level, some of them work under unit level and so on. The problem now is with database design. I am confused about how to design the database. At the beginning, I decided to design it as following:
Employees: Username, Name, Title, OrgCode
Departments: OrgCode, Name
Divisions: OrgCode, Name
Units: OrgCode, Name
but the problem as I said before, some employees are working under departments, so how to make relations between all of these tables. Is it possible to have OrgCode in Employees table as a foreign key to OrgCode in Departments, Divisions and Units tables?
Could you please recommend me how to design it?
UPDATE:
#wizzardz put a nice database design. All what I need now is to have an example of data that fit this database design
Here's a set of data that I am using in the database:
let us assume that we have Employee with the following information:
Username: JohnA
Name: John
Title: Engineer
OrgCode: AA
And let us assume we have department AA, how I will distribute this data into the database design?
You could do a design something like this
rather than going for separate tables for Departments, Divisions etc try to store them in a single table with a TypeId to distingush Departments , Divisitions etc.
Could you try a design like this
In the Level table you need to enter the values like 'Deparments,Divisions', Groups, etc (By keeping it in a separate table you can handle any future addition of new levels by your organisation.)
In the OrganisationLevels table you need to store Department Names,Division Name, GroupName etc.
The Employee table has a forigen key reference with the table Organisation level, that will store which Level an employee is working in the organisation.
If you wants to store the work history of a particular employee/ there is a chance that an employee can be moves to one level to another I would suggest you to go for this design
Sample data wrt the design
Level
Id LevelType
1 Department
2 Division
3 Group
OrganisationLevels
Id Name LevelId Parent*(Give a proper name to this column)*
13 AA 1 NULL
.
.
21 B 2 13 (This column refer to the Id of department it belongs to.)
Employees
Id UserName Name Title
110 JohnA John Engineer
EmployeeWorkDetails
Id EmployeeId OrganisationLevelId StartDate EndDate IsActive
271 110 13 20/09/2011 NULL true
OrgCode from the Employee Table can be removed, because I thought it is the employee code of the employee with that organisation.
I hope this helps.
Employees: Username, Name, Title, OrgCode
Departments: OrgCode, Name
Divisions: OrgCode, Name
Units: OrgCode, Name
To the above mentioned DB design, have one more table called Org containing OrgCode and another column as type (which we give insights on which type of org is it i.e. Departments,Divisions and Units)
then you can have employee table's OrgCode to have refer the OrgCode of Org table(parent-child relationship).
I suggest that you learn the difference between analysis and design. When you design a database, you are inventing tables, columns and constraints that will affect how the data is stored and retrieved. You are concerned with ease of update and query, including operations you will learn about later.
When you analyze the data requirements, you aren't engaged in inventing things, you are engaged in discovering things. And the things you are discovering are things about the "real world" the subject matter is supposed to represent. You break the subject matter down into "entities" and relationships among those entities. Then you relate every value stored in the database to an instance of an attribute, and every attribute to some aspect of either an entity or a relationship. This results in a conceptual model.
In your case, the relationships between employees, departments, units, etc. sound quite complex. It's worth quite a bit of effort to come up with a model that reflects this complex reality accurately.
Once you have a good conceptual model, you can create SQL tables, columns, and constraints that adequately represent the conceptual model. This involves design skills that can be learned. But if you have a lousy conceptual model, you're doomed, no matter how good you are at design.