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.
Related
I have two tables. One is Employee and another is Role. The Employee table contains EmployeeId and EmployeeName. Similarly, the Role table will contain RoleId and RoleName column. An employee will belong to one of several different roles.
I am new to database design and having problem figuring out if it's better to have a RoleId column in the Employee table or to create another table called EmployeeRoleMapping which will contain rows indicating this employee is mapped to this role. What are the pros and cons of both approach?
the most important thing is that you must sure of the relationship between Employee and Role in your application.
In my point of view, an Employee may have one or many roles and vise versa one role may belong to one or many Employees. So that, we have to create a new table called EmployeeRoles and this table has employeed_id and Role_id.
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).
In a new database model that I am designing, I have a company table that has a contacts table related to it using a foreign key companyID field.
I have a branch table with PK branchId and FK companyId.
The problem is: Sometimes contacts can move from the company or branch they are in to a different one. And I need to know all the former companies and branches the contact was in.
What is the best way to do this?
I can't figure out anything that makes sense. If I insert another record into contacts with the different details, There will be a duplicate record, and if I just change the details, how will I know what the former details were?
I would suggest a table that joins your contacts table to your company table. This new table would have a contactsid, a companyid, a date (or date range, depending on your needs) and any other info that you would need to describe the relationship between the contact and the company. The contacts table would then no longer need an FK companyID.
A company is hired by another company for helping in a certain field.
So I created the following tables:
Companies: id, company name, company address
Administrators: (in relation with companies) id, company_id, username, email, password, fullname
Then, each company has some workers in it, I store data about workers.
Hence, workers has a profession, Agreement Type signed and some other common things.
Now, the parent tables and data in it for workers (Agreement Types, Professions, Other Common Things) are going to be the same for each company.
Should I create 1 new database for each company? Or store All data into the same database?
Thanks.
Since "Agreement Types", "Professions" are going to be same for each company, I would suggest to have a lookup table like "AgreementTypes" with columns such as "ID", "Type" and refer "ID" column in "Workers" table. I don't think new database is required, relational databases are used to eliminate data redundancy and create appropriate relationships between entities.
By imagining having one database for one company, it ends up with having one record in "Company" table in each database. "Administrators" & "Workers" are associated with that single record. And other common entities such as "AgreementTypes" will be in other tables.
So, if there is any addition/modification to agreement type, it is difficult to do it in all databases. Similarly, if there is any new entity to be linked to "Company" entity, again all databases needs to be revisited based on assumption that these entities belong to ONE application.
You should have one single database, with a structure something like this (this is somewhat over-simplified, but you get the idea):
Companies
CompanyID PK
CompanyName
CompanyAddress
OtherCompanySpecificData
Workers
WorkerID PK
CompanyID FK
LastName
FirstName
DOB
AgreementTypeID FK
ProfessionID FK
UserID FK - A worker may need more than one user account
Other UserSpecificData
Professions
ProfessionID PK
Profession
OtherProfessionStuff
AgreementType
AgreementTypeID PK
AgreementTypeName
Description
OtherAgreementStuff
Users
UserID PK -- A Worker may need more than 1 user account
WorkerID FK
UserName
Password
AccountStatus
Groups
GroupID PK
GroupName
OtherGroupSpecificData
UserGroups --Composite Key with UserID and GroupID
UserID PK
GroupID PK
Obviously, things will grow a little more complex, and I don't know your requirements or business model. For example, if companies can have different departments, you may wish to create a CompanyDepartment table, and then be able to assign workers to various departments.
And so on.
The more atomic you can make your data structures, the more flexible your database will be as it grows. Google the term Database Normalization, and specifically the Third Normal Form (3NF) for a database (Considered the minimum for efficient database design).
Hope that helps. Feel free to elaborate if you are stuck - there is a lot of great help here on SO.
Lets say we have three tables: Cars, People, Companies.
We want the owner of the car to be a people or a company. The structure of the Cars table is: Car_id, Car_model, Owner_id
What is the best way to do that?
If you can't change the current structure of the cars table, then you could add new table called owners with the following columns:
number id -- unique key
number owner_id -- this is the actual owner id
char owner_type -- this is a value indicating whether the owner is a person or a company
You will then need to cross reference cars with owners and look at the value of owner_type to determine which table to get your owner data from.
EDIT
Forgot to mention (rather important):
In the cars table, populate the owner_id with the owners.id column.
What about having another field in Cars table as "Owner_type_id" which will determine if owner is a person or a company or any other thing. Of course, you should keep another table "Owner_Types" for this scenario to work.
As Igby mentioned, your existing structure is far from ideal, but if you're stuck with it, one option is to have a new Owner table that has the owner_id from the Car table as well as a person_id and a company_id, only one of which would need to be populated.