How to include these requirements in my database design? - sql

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.

Related

SQL database structure with two changing properties

Let's assume I am building the backend of a university management software.
I have a users table with the following columns:
id
name
birthday
last_english_grade
last_it_grade
profs table columns:
id
name
birthday
I'd like to have a third table with which I can determine all professors teaching a student.
So I'd like to assign multiple teachers to each student.
Those Professors may change any time.
New students may be added any time too.
What's the best way to achieve this?
The canonical way to do this would be to introduce a third junction table, which exists mainly to relate users to professors:
users_profs (
user_id,
prof_id,
PRIMARY KEY (user_id, prof_id)
)
The primary key of this junction table is the combination of a user and professor ID. Note that this table is fairly lean, and avoids the problem of repeating metadata for a given user or professor. Rather, user/professor information remains in your two original tables, and does not get repeated.

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.

Best database schema for country, region, county, town

I have country, region, county, town data and I'm currently deciding between 2 schema designs (if there's a better one, do tell).
I first thought
Country
Id
Name
Region
Id
CountryId
Name
County
Id
RegionId
Name
Town
Id
CountyId
Name
Does the job however to get all towns in a country you have to 3 inner joins to do the filtering. I guess this could be ok but potentially expensive?
The other design was:
Country
Id
Name
Region
Id
Name
County
Id
Name
Town
Id
CountryId
RegionId
CountyId
Name
This way all hierarchical data so to speak is at the bottom and you can go back up however if you want all regions in a country you're a bit screwed which makes we wonder whether the first design is best.
What do you think is the best schema design?
The best database design depends on how the data is being used.
If this is pretty static data that will all be updated at one time and external references are all to towns, then I would probably go for a denormalized dimension. That is, store the information all in one row:
Town Id
Town name
County name
Region name
Country name
Under the above scenario, the ids for county, region, and country are not necessary (by assumption).
If the data is being provided as separate tables with separate ids, and these tables can be updated independently or row-by-row, then a separate table for each makes sense. Putting all the ids into the towns table may or may not be a good idea. You will have to verify and maintain the hierarchies when data is inserted and updated.
If ids for each level are necessary for your, then you should have appropriate table structure for declaring foreign key constraints. But, this can get complicated. Will an external entity have a "geography" attribute that can be at any level? Will an external always know what level it is going to refer to as?
In other words, you need to know how the data is going to be used in order to define an appropriate data model.

How would you model the following database relationship?

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'.

Question on Database Modeling

Tables:
Students
Professors
Entries (there’s no physical table intry in the database for entries yet, this table is on the front-end, so it is probably composed from multiple helper tables if we need them. Just need to create valid erd)
Preambula:
One student can have an association to many professors
One professor can have an association to many students
One entry can have 0,1 or more Students or professors in it.
Professor is required to be associated with one or more students
Student is not required to have an association with any professor
It should be more like this (front-end entry table):
Any professor in this table must have an associated name in the table.( For example Wandy is associated to Alex)
It is not required for student (but possible) to have associated professors in this table
One row (for example Linda (Student), Kelly (Professor),Victor (Professor))
Cannot be associated between each other in any manner.
But it is absolutely fine if Linda associated with David.
The problem is that I do not quite understand how one column can have ids of different tables (And those are multiple!) And do not quite understand how to build valid erd for that.
I will answer any additional questions you need. Thanks a lot!
If you simply want an association between Students and Professors - just make a many-to-many relationship in ERD. In logical (relational) schema it will make an intermediate table with foreign keys to Student and Professor tables.
But from your example it looks like you need to design the DB for your "PeopleEntries", which is not straightforward. ERD seems to have the following entities:
Students(ID, name)
Professors(ID,
name)
PeopleEntries(ID, LoveCats,
LoveDogs, LoveAnts)
Relationships (considering people cannot appear in entries more than once):
Students Many - 1 PeopleEntries
Professors Many - 1 PeopleEntries
Students Many - Many Professors
Relational schema would contain tables (foreign keys according to erd relationships):
Students(ID, name, PeopleEntryID FK)
Professors(ID, name, PeopleEntryID
FK)
PeopleEntries(ID, LoveCats, LoveDogs,
LoveAnts)
StudentProfessor(StudentID FK,
ProfessorID FK)
I don't know how to implement the constraint, disallowing association between people from the same entry, on conceptual level (ER-diagram). On physical level you can implement the logic in triggers or update procedures to check this.
As per my quick understanding,
Create a table with following columns
PersonName
Designation
.....
Create one more table
PersonName
LinksTo
In the second table each person entry will have multiple records based on the relation
You want a junction table:
ID StudentID ProfessorID
0 23 34
1 22 34
2 12 33
3 12 34
In the table above, one professor has 3 students, one student has two professors.
StudentID and ProfessorID should together be a unique index to avoid duplicate relationships.