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.
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).
I've run into a bit of a pickle during my development of a web application. I've boiled down the complexity of the application for sake of simplicity in this question.
The purpose of this web application is to sell insurance. Insurance can be purchased through an agent (Agency) or over the phone directly (Customer). Insurance policies can be paid through the agency or the customer can pay for the policy directly. So money is owed (invoiced) and received (payments) from multiple sources (Agencies/Customers).
Billing Options:
Agency (Agency collects from customer outside of app)
Customer
Here's where it gets complicated. Agencies are stored in a separate database table than customers (for obvious reasons). However, both agencies and customers need to be able to make payments and have invoices assigned to them. I'm having difficulty figuring out how to create the proper database schema to allow for both types of database records to be connected to their invoices and payments.
My initial plan was to set up separate relationship (joining) tables that link the agencies and customers to invoices/payments.
However, now that I've been thinking about the problem more, I think it might be beneficial to merge both agencies and customers into a single "Payee" table which would then be associated with payments/invoices. The payee table would only store a primary key. It would not contain actual names or info for the payee - instead I would pull that data via a JOIN with either the agencies or customers tables.
Regardless of whatever solution I choose I am still faced with the problem when creating a new payment record is that I need to scan both the agencies and customers table for possible payees. I'm wondering if there's a proper way to approach this from a database schema standpoint (or from an accounting/e-commerce standpoint).
What is the correct way to handle this type of situation? All ideas and possible solutions are most welcome!
Update 01:
After a few helpful suggestions (see below) I've come up with a possible solution that may solve this issue while keeping the data normalized.
The one thing about this method that rubs me the wrong way is that I will have to make multiple table selects to get a list of all the people who can potentially make payments and/or have invoices assigned to them.
Perhaps this is unavoidable though in this situation since indeed there are different "types" of people that can be associated with payments and invoices. I'm stuck with a situation where I have two different types of records that need to be associated to the same thing. In the above approach I'm using the FKs to link each table (Agencies/Customers) to a Payee record (the table that unifies both Agencies/Customers) and then ultimately links them to Payments and Invoices.
Is this the proper solution? Or is there something I've overlooked?
There are several options:
You might put this like you'd do it with OOP programming and inheritance.
There is one table Person which holds an uniqueID and a type (Agency, Customer, more in Future). Additionally you might add columns with meta-data like who inserted/when/why and columns for status/soft-delete/???
There are two tables Agency and Customer, both holding a PersonID as FK.
Your Payee is the Person
You might use a schema-bound VIEW with a UNION ALL to return both tables of your modell in one result. A unique index on this view should ensure, that you'll have a unique key, at least as combination of the table-source and the ID there.
You might use a middle table with the table-source and the ID there as unique Key and use this two-column-id in you payment process
For sure there are several more...
My best friend was the first option...
My suggestion would be: instead of Payees table - to have two linking tables:
PayeeInvoices {
Id, --PK
PayeeId,
PayeeType,
InvoiceId --FK to Invoices tabse
}
and
PayeePayments {
Id, --PK
PayeeId,
PayeeType,
PaymentId --FK to Payments table.
}.
PayeeType is an option of two: Customer or Agency. When creating a new payment record you can query PayeeInvoices by InvoiceId to get PayeeType and corresponding PayeeId, and then lookup the rest of the data in corresponding tables.
EDIT:
Having second thoughts now. Instead of two extra tables PayeeInvoices and PayeePayments, you can just have PayeeId and PayeeType columns right in Invocies and Payments tables, assuming that Invoice or Payment belongs only to one Payee (Customer or Agency). Both my solutions are not really normalized, though.
I'm creating this little Access DB, for the HR department to store all data related to all the training sessions that the company organizes for all the employees.
So, I have a Training Session table with information like date, subject, place, observations, trainer, etc, and the unique ID number.
Then there's the Personnel table, with employer ID (which is also the unique table number), names and working department.
So, after that I need another table that keeps a record of all the attendants of each training session. And here's the question, should I use a table for that in the first place? Does it have to be one table for each training session to store the attendants?
I've used excel for quite some time now, but I'm very new to Access and databases (even small ones like this). Any information will be highly appreciated.
Thanks in advance!
It should be one table for persons, one table for trainings, and one for participation/attendance, to minimize (or best: avoid) repetition. Your tables should use primary and foreign keys, so that there are one-to-many relationships between trainings and attendances as well as people and attendances (the attendances table would then have a column referring to the person who attended, and another column referring to the training session).
Google "database normalization" for more detail and variations of that principle (https://en.wikipedia.org/wiki/Database_normalization).
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.
Consider the following scenario:
Tables:
Employee (EmpId(PK), Name)
TeamMembers(TeamId(PK), EmpId(PK))
Project(ProjId(PK), TeamId)
I really want to avoid using composite PK, but the only way I see out of the problem is creating a Team table with only 1 column TeamId(PK) (i do not want to store any info associated with the team other than its members) (EDIT: if I create a team table, i'll add TeamMeberId to TeamMembers table and make it a PK)
Another problem with current setup is that I can't set a relationship for TeamId between Project and TeamMebers tables
Should I just create a 1 column Team table? What's the best approach in this case?
EDIT
just to clear things up, the only thing I want to know about that team is its existance, no additional info of any kind
EDIT2
Tables New Design (anything wrong with it?):
Employee (EmpId(PK), Name)
Team(TeamId(PK))
TeamMembers(TeamMemberId(PK), TeamId(FK), EmpId(FK))
Project(ProjId(PK), TeamId(FK))
If the only thing interesting about a team is the fact that it exists, then there is nothing wrong with a Team table with just one column: TeamId. It ensures referential integrity from the TeamMembers and Project tables.
But I do not understand your objection against a composite PK. The columns TeamId and EmpId in the TeamMembers table are alreay a composite primary key.
There is nothing wrong with this scenario. I'd do it.
On the other hand, you could hold other information in your Team table like a team Name or something.
There is nothing wrong with a 1 column table. However you might want to consider what other attributes your Team table could have. For instance, a team name?
For the relationship between project and employees, you merely have to join through the TeamMembers table.
does EmpId really need to be a primary key in your TeamMembers table? you could just say that each team has many employees, and the relationships work out.
Since it looks like there is a 1-to-1 relationship (correct me if I'm wrong) between Project and TeamMembers and you don't want to store additional info about the team, wouldn't it be easier to get rid of the TeamMembers table and go with a many-to-many linking table between Project and Employee
Employee (EmpId(PK), Name)
EmployeeProjects(EmpId(PK), ProjId(PK))
Project(ProjId(PK), <other project info>)
but to answer your original question. There is nothing particularly wrong with having a single column table.
This is how I would structure the tables
Employee (EmployeeId(PK), Name)
Team (TeamID(PK))
TeamMembers(TeamMembersID(PK), TeamId, EmployeeId)
Project(ProjectID(PK), TeamId)
I like to have a PK being the table name, suffixed with ID.
This convention does have the side affect of sometimes creating seemingly redundant primary keys (as TeamMembersID) but it solves your composite key problem.