I have an employees table and the ERD looks like this
I want to add more requirements. I want to add if the employees are seasonal or fulltime. I thought of adding an extra column on the duration table where I can track if employees are seasonal or fulltime. If seasonal, then some of the seasonal employees might be interns from colleges. For them, I want to add another table to track the university they are enrolled in. is this approach okay or should I create different table for status of employees?
If there are only two options available, i.e. whether an employee is
full time or
seasonal
then the simplest option is to add a "checkbox" column, e.g.
alter table employees add cb_seasonal number(1) default 0 not null;
which will be set to 0 (i.e. everyone is NOT seasonal which means that everyone IS full time employed). When someone switches to a seasonal status, you'd just "check" it by updating the row and setting the column value to 1.
However, if there were more statuses, then it would be better to use additional table. You'd still have to alter the employees table and add a foreign key constraint to that "additional" table you created.
Related
I am attempting to create an Employee table in SQL Server 2016 and I want to use EmpID as the Primary Key and Identity. Here is what I believe to be true and my question: When I create the Employee table with EmpID as the Primary Key and an Identity(100, 1) column, each time I add a new employee, SQL Server will auto create the EmpID starting with 100 and increment by 1 with each new employee. What happens if I want to import a list of existing employees from another company and those employees already have an existing EmpID? I haven't been able to figure out how I would import those employees with the existing EmpID. If there is a way to import the employee list with the existing EmpID, will SQL Server check to make sure the EmpID's from the new list does not exist for a current employee? Or is there some code I need to write in order to make that happen?
Thanks!
You are right about primary keys, but about importing employees from another company and Merging it with your employee list, you have to ask these things:
WHY? Sure there are ways to solve this problem, but why will you merge other company employees into your company employee?
Other company ID structure: Most of the time, companies have different ID structure, some have 4 characters others have only numbers so on and so forth. But you have to know the differences of the companies ID Structure.
If the merging can't be avoided, then you have to tell the higher ups about the concern, and you have to tell them that you have to give the merging company new employee ID's which is a must. With this in my, simply appending your database with the new data is the solution.
This is an extremely normal data warehousing issue where a table has data sources from multiple places. Also comes up in migration, acquisitions, etc.
There is no way to keep the existing IDs as a primary key if there are multiple people with the same ID.
In the data warehouse world we would always create a new surrogate key, which is the primary key to the table, and include the original key and a source system identifier as two attributes.
In your scenario you will probably keep the existing keys for the original company, and create new IDs for the new employees, and save the oldID in an additional column for historical use.
Either of these choices also means that as you migrate other associated data such as leave information imported from the old system, you can translate it to the new key by looking up OldID in the employee table, and finding the associated newID to associate it with when saving your lave records in the new system.
At the end of the day there is no alternative to this, as you simply cant have two employees with the same primary key.
I have never seen any company that migrate employees from another company and keep their existed employee id. Usually, they'll give them a new ID and keep the old one in the employee file for references uses. But they never uses the old one as an active ID ever.
Large companies usually uses serial of special identities that are already defined in the system to distinguish employees based on field, specialty..etc.
Most companies they don't do the same as large ones, but instead, they stick with one identifier, and uses dimensions as an identity. These dimensions specify areas of work for employees, projects, vendors ..etc. So, they're used in the system globally, and affected on company financial reports (which is the main point of using it).
So, what you need to do is to see the company ID sequence requirements, then, play your part on that. As depending on IDENTITY alone won't be enough for most companies. If you see that you can depend on identity alone, then use it, if not, then see if you can use dimensions as an identity (you could create five dimensions - Company, Project, Department, Area, Cost Center - it will be enough for any company).
if you used identity alone, and want to migrate, then in your insert statement do :
SET IDENTITY_INSERT tableName ON
INSRT INTO tableName (columns)
...
this will allow you to insert inside identity column, however, doing this might require you to reset the identity to a new value, to avoid having issues. read DBCC CHECKIDENT
If you end up using dimensions, you could make the dimension and ID both primary keys, which will make sure that both are unique in the table (treated as one set).
There are three tables linked to each other as in the diagram.
This Youtuber is using IsDeleted=0 or IsDeleted=1 column to indicate that the data in the table is deleted or not.
When one SQL table is linked to another table, is it impossible to delete the data from the database? If it is impossible, then I think its really bad. Isn't there any workarounds for completely deleting the data?
Also, maybe Facebook also does something like IsDeleted=1 and they don't let us see us our own data when we 'delete' it while they can still access our past interests. What do you think?
No, data can always be deleted from a database. There may be constraints what has to happen before the data gets deleted (permissions, foreign-key constraints, etc), but it eventually can be deleted.
A column such as that is frequently used for maintaining data history in the application. The "links" you refer to are called Foreign Key relationships and they are used to maintain integrity within relational data. The IsDeleted column in the resultset doesn't have anything to do with the FK.
Also, that column would not indicate that the table is deleted, but rather the row of data the values of the column belong to.
Well defined and static and structured arrangement of data is one of the most important things in relational databases. In the tables you show, Employee belongs to a department. Now if you delete the department, you have a broken record in the Employee table. This is why, SQL will not allow you to delete the department.
To solve this, you will need to either stop the deletion of department with message like "There are users in this department. Cannot be deleted." or remove the department id (set it to null) from the employee records which belong to this department.
There are situations, business needs where the data is to be retained for various reasons. In those cases, IsActive like flags come to rescue. The records can be filtered using them and thus are hidden on the screen. This is generally referred to as soft delete.
Actually, i think it is very good practice to do Soft Delete rather than hard delete because you can safely recover the data later. To your question you can only delete parent table data if there are no more child table data. Else you get this errror:
the delete statement conflicted with the reference constraint ...
for example in your database say you have data of employee and departments. e.g this is your department table:
ID DepartmentName
1 HR
2 marketing
and this is your employee table:
ID DepartmentId Name Address
1 1 Name1 address1
2 1 Name2 address2
3 1 Name3 address3
Now if you want to delete marketing department from Department table , you can delete it easily and there is no error. But now if you try to delete HR department you will get error as mentioned above because the HR department Id(i.e. 1) is already linked with another table called Employee table. So if you want to delete HR department anyhow, you must first delete all the record from employee table with DepartmentId=1 . otherwise you can use the approach as the youtuber you mentioned.
Hope it helps !
I was trying to set up a couple tables, and I noticed an error, so I created a blank database and tried to recreate the error.
The error reads "The columns in table "" do not match an existing primary key or UNIQUE constraint.
Now from what I've read from this site, it has to do with the primary key.
However what I want to do (my primary concern) is to have one table, have the roles, salaries and job description in one table, and in another table, have names, and roles. So for example, if there are two accountants in the 2nd table, I would like the 1 accountant entry in first table to apply twice to the second table. By doing this I have let's say 20 "roles" and 30 employees some with unique roles, some with the same roles.
How would I set it up so that the table would work this way?
PS:
I am using SQL Server Management Studio to create the database (which I am creating from scratch). How I created the problem, is I created a table and inserted two columns, column 1 is RolesID, and column two is Salary. In the second table is made up of two columns, Column 1 is Name, and column 2 is Position. I would like to add a 3rd column to Table 2, labelled Salary (or pay or something) in which if I had two of the same RoleID for two different Names, I would like the 3rd table to give the Salary. I haven't inserted any triggers yet.
For added Clarity: Is it possible, to simply have a table of all the possible roles + salaries, and ADD that to a different table automatically? If I put Name A, B, and C, and they have role A, A and B, I would like to have the salary automatically update for A, B and C accordingly, with only having to specify their role
I wasn't thinking clearly apparently.
The simple solution is to add Identifier Codes (IDs) for every table you want to represent.
For this, I had 1 table for Salary, and 1 table for roles and 1 table for contacts.
On a master table, you put a column for each of your IDs - contact ID, Salary ID, and Role ID. Fill in what those ID's are on the master table.
I simple put the ID numbers for each person on the table, and on my reporting software it placed the proper salaries and roles for me.
I am wondering if it is okay to have master and detail table for employees?
As per requirments, data can filtered by department by country and by employee code on report level.
If employee's department or country code is changed then the changes will go in detail table and old record will be set to IS_ACTIVE = 'T'.
---------------------Master Table--------------------------------------
**EMPLOYEE_CODE** VARCHAR2(20 BYTE) NOT NULL,
EMAIL VARCHAR2(100 BYTE)
FIRST_NAME VARCHAR2(50 BYTE)
LAST_NAME VARCHAR2(50 BYTE)
WORKING_HOURS NUMBER
---------------------Detail Table--------------------------------------
**PK_USER_DETAIL_ID** NUMBER,
FK_EMPLOYEE_CODE VARCHAR2(20 BYTE),
FK_GROUP NUMBER,
FK_DEPARTMENT_CODE NUMBER,
FK_EMPLOYER_COUNTRY_CODE VARCHAR2(5 BYTE),
FK_MANAGER_ID VARCHAR2(20 BYTE),
FK_ROLE_CODE VARCHAR2(6 BYTE),
START_DATE DATE,
END_DATE DATE,
IS_ACTIVE VARCHAR2(1 BYTE),
INACTIVE_DATE DATE
Employee table will be linked with Timesheet table and for timesheet reports data can be filtered by department, country and by employee code.
OPTION : I
Have one employee table with one Primary Key and create a new entry whenever department or role is updated for an employee.
Add country and department code in the timesheet table.
--> This way i don't need to search employee table.
OPTION : II
Have master and detail table.
Add country and department code in timesheet table.
--> This way i don't need to search employee table plus i will have master detail table
OPTION : NEW
Have master and detail table.
Timesheet table will have EmpCode.
If user move to new location or change department then Insert a new row in the detail table with the new dept Code and same Emp No.
Update an old row and set the End Date field so if he changes his location or department then the End Date field needs to be updated.
Which one is a best option and is there any other better option available?
This is one way of implementing this requirement, and it's an approach many people take. However, it has on emajor drawback: every time you query the current employee status you need to filter the details on start and end date. This may seem like a trivial thing, but you wouldn't believe how much confusion it can cause, and it has performance implications too.
These things matter, because most of the time you will want only the current details, with queries on history being a relatively rare occurence. Consequently you are hampering the implementation of your most common use case to make it easier to implement a less-used one. (Of course I am making assumptions about your business requirements, and perhaps yours is not a run-of-the-mill employee application...)
The better solution would be to have two tables, an EMPLOYEES table with all the detail columns too and an EMPLOYEES_HISTORY table with the same columns plus the start and end date. When you change an employee's record insert a copy of the old record in the History table, probably by a trigger. Your standard processes have just the one table to query, and your history needs are met fully.
By the way, your proposed data model is wrong. Working_hours, email_address and last_name are definitely things which can change and perhaps even first name (e.g. through changes in personal circumstances such as getting married). So all those columns should be held in your details name
Option 3 - Please note that this option is useful only for the reports Point of View.
Whenever you insert the data, create a De-Normalized entry in a new table.
Whenever an entry will be updated, the De-Normalized entry will be updated in the new table.
The New Table will have all De-Normalized columns of Employee.
So while Performing the search, this will benefit you as the results will be calculated without using Joins. Thus, the access time will be reduced.
Records in the new table will be Created/Updated in The Insert/Update Trigger.
Improvements in Option - 2 and Option 1
Don't create redundancy by adding duplicate columns.
In my database I got a list of companies with columns CompanyId and Name.
Further on there is users and those users can add products.
Tables: user and user_products
There is no product table defining products, they are unique per user therefore "user_product"
When a user adds a product he types a name of a company. If that company name exists in the company table I want to make a connection to the company table instead of saving only the name on the user_product. So far so good.. I just store CompanyId in the user_product table.
The problem is when the user enters a name that doesn't exists in the company table. Instead of saving the name as varchar, I want to create a new record in a table called user_company.
The table got columns: UserCompanyId (PK), UserId, Name. If the combination Name and UserId already exists i will of course not create a new row, just reference to this id.
What should I do to maintain a good database design here.. Should i add this record and also a new column in user_product called UserCompanyId. So that either CompanyId or UserCompanyId is always set when adding a new row. It feels like this could be done in a better way. Anyone got any ideas?
I could of course only have one table "company" and have a column UserId which is null when it's a global company added by the system, or the UserId is actually set when a user has added a company name that didn't existed globally. This doesn't feel good either...
Actually, I think you nailed it in your last paragraph. A company is either defined by a user or isn't, so the userId makes sense as a nullable column. This would also allow you to have a unique key on the company name, which allows you to use the database to enforce the fact that a company name can't be duplicated.
Your company table exists to define companies--which user (or whether a user) created the company is just information ABOUT a company.