Normalization of database for timesheet tool and ensure data integrity - mysql

I'm creating a timesheet application. I have the following entities (amongst others):
Company
Employee = an employee associated with a company
Client = a client associated with a company
So far I have the following (abbreviated) database setup:
Company
- id
- name
Employee
- id
- companyId (FK to Company.id)
- name
Client
- id
- companyId (FK to Company.id)
- name
Now, I want an employee to be associated with a client, but only if that client is associated with the company the employee works for. How would you guarantee this data integrity on a database level? Or should I just depend on the application to guarantee this data integrity?
I thought about creating a many to many table like this:
EmployeeClient
- employeeId (FK to Employee.id)
- companyId \ (combined FK to Client.companyId, Client.id)
- clientId /
Thus, when I insert a client for an employee along with the employee's company id, the database should prevent this when the client is not associated with the employee's company id. Does this make sense? Because this still doesn't guarantee the employee is associated with the company. How do you deal with these things?
UPDATE
The scenario is as followed:
A company has multiple employees. Employees will only be linked to one company.
A company has multiple clients also. Clients will only be linked to one company.
(Company is a sandbox, so to speak).
An employee of a company can be linked to a client of it's company, but only if the client is part of the company's clientele.
In other words:
The application will allow a company to create/add employees and create/add clients (hence the companyId FK in the Employee and Client tables). Next, the company will be allowed to assign certain clients to certain of it's employees (EmployeeClient table).
Imagine an employee working on projects for a few clients for which s/he can write billable hours, but the employee must not be allowed to write billable hours for clients they are not assigned to by their employer (the company). So, employees will not automatically have access to all their company's clients, but only to those that the company has selected for them. Hopefully this has shed some more light on the matter.

If you want to do it from the database level then I would put the logic in a stored procedure. The stored proc code will then associate the two if applicable but this means that (given you put the foreign key to the employee in the client table) a client is only associated with one employee. Is this what you want?
Also take note though that an employee in your table is indirectly associated with all such clients via its company association. If all employees are automatically associated with all new clients of their company then perhaps you just want to write a query that checks for this.

(This is not an answer, but it didn't really fit in as a question comment.)
The data presented for your design question begs a number of questions:
Are employees to be associated with companies and clients? Or...
Are employees only associated with clients, and (thus) the company associated with that client?
If employess and clients are associated with companies, is an employee thus associated with all employees of that company, or must you pick and choose?
Update
As far as data modelling is concerned, it seems like all you need to do is expand the foreign key in EmployeeClient into Employee like so:
EmployeeClient
- companyId
- employeeId
- clientId
Compound primary key on all three columns.
Foreign key on (companyId, clientId) into Client
Foreign key on (companyId, employeeId) into Employee
Thus, all relations defined in EmployeeClient require both Client and Employee to share the same clientId.

Related

In access update contact information while retaining record of old in database

In Microsoft Access I have three tables: order table, customer table and product table. My order table pulls in both customer contact and product information. Every now and then I need to update either the customer address. When doing so, I only want the new address to appear on future orders. I don't want Access to update previous orders with an address that was not originally affiliated with that order. I also want to maintain a list of active and past addresses on the customer list. Please advise on the best ways for setting up the customer table and how to retain customer contact information on the order table.
To do this you need to take the customer address out of the Customer table and keep it in a separate CustomerAddress table. This new table has a primary key (of course), a foreign key back to the Customer table, all the address fields that you want to maintain history of and a Current flag (Yes/No). Your Order table then points directly to the CustomerAddress table instead of the Customer table (you can get from Order to Customer because of the FK link on CustomerAddress to Customer). Now your fun starts! You have to maintain your CustomerAddress table in such a way that for each Customer ID you should only have one Address record where Current is True.
The other alternative is to not have a Current flag on the CustomerAddress table, but instead have a CurrentAddress field in your Customer table - this ensures that only one Address can ever be the current one for a Customer. However you can't enforce both the CurrentAddress integrity and the CustomerAddress foreign key - you can't set the value of CurrentAddress until you've added the Address record, so Customer record has to be able to exist with NULL CurrentAddress (although I suppose you could have a dummy 'Not set' CustomerAddress record).
The simple method is to store the current customer information with the order.
The extended method is to store the customer table(s) as temporal tables, either using a custom method or a native as - for example - offered by the newest versions of SQL Server. Look up the term Temporal database for more information.

How do I link a single table to data in two different tables?

I'm running for office and have created a web app for tracking my door knocks to voters at their homes. The database contains a table called voters that contains all the necessary information about voters in my community.
I'd like to add a new feature to track donors to my campaign. Not all of these donors live in the community and do not vote in the district where I'm running for office. I do not need to track the same kind of info for these individuals as I do for the voters so I'm going to place these individuals into a table called nonvoters.
Now, the individuals in my "voters" table can also make donations, and I want to track those as well.
To track the donations from both voters and nonvoters, I'd like to set up a new table called "donations." This table would contain the appropriate details about the donation.
But I'm uncertain as to what the best structure is for linking the donations table to the "voters" and "nonvoters" table. If I create a column called voter_id in the table to key it to the donors information, there's no way to know which table that ID refers to. So do I set up two columns, nonvoter_id and voter_id and insert the ID into the applicable column depending on whether the donor is a voter? This seems weird.
Or maybe I create a column in both the voters and nonvoters table called donor_id that I can use to link my data in the donations table. If I went this route, it seems like I'd have to do a some behind the scenes work to ensure the donor_id was unique and was keyed to the data inside the donations table.
Or maybe there are other approaches I'm not familiar with. Any guidance is appreciated.
I would use a single table for voters and non-voters, let's say persons. You can have a flag in the persons table that indicates if the person is a voter or you may even derive this from their address (if that's possible).
I would create a donations table and link each donation to a person (or persons) in the persons table using the id in the persons table. If a donation can be given by multiple people, then you will need a 3rd connection table with person id and donation id as 2 fields. These 2 fields would be the primary key for the connection table.

Should i stock "quotation_request" as a table on my DB?

I'm working on a very simple DB.
Imagine I've table customer and table seller.
The customer is able to request a quotation for some products
There will be a simple form that allow to customers to select products and submit the quotation.
Now, should I create table : "Quotation" and store all quotations (with id_quotation..etc)?
Thank you all
Without knowing all of the business rules that govern the requirements of this database, perhaps the following design will help to answer your question and explain a few concepts in the process.
In database terms, an entity is a person, place, or thing about which we want to collect and store data. From your description we can already see two entities: seller and customer. This is important since the entities we identify conceptually become database tables in their own right.
The seller table should contain data applicable only to sellers. Thus, the qualities (attributes) about sellers that we want to store become columns in our seller table. Each row (record) in the seller table represents an individual seller. Each individual seller is uniquely identified in the seller table with a unique value stored in it's primary key column, which we can name seller_id.
A simplified version of such a table could look like this:
In a similar manner, the customer table should contain data only applicable to customers. The qualities (attributes) about customers that we wish to store become the columns in the customer table. Each row (record) in the customer table represents an individual customer. Each individual customer is uniquely identified in that table with a unique value in it's primary key column, which we can declare as customer_id.
A simplified version of this table:
I'm guessing the business rules state that any customer is able to request any number of products, from any seller, any number of times...since surely any seller would want as many sales and customers as possible!
How can we express and record the interactions (relationship) between seller and customer?
This is done with a new kind of entity: a composite entity. It becomes a new table, having it's own primary key, and contains seller_id and customer_id as foreign keys. The foreign keys in this table connect (relate) the seller table to the customer table.
We can name this new table quotation (if that is your preferred name). Each row of this table is intended to capture and record each and every individual transaction between a customer and a seller. The columns (attributes) of this table are the data that apply to a transaction between a customer and seller, such as amount or date of sale.
A very simplified version of this composite entity:
Note that the foreign key values that exist in this table must already exist in their respective tables as a primary key value. That is, a foreign key value cannot be entered into this table unless it exists already as a primary key value in it's own table. This is important, and it is called referential integrity - it ensures that there is no record of a customer purchasing from a non-existent seller, etc.
In the example above we can see that Builder B requested a quotation from Acme Construction in the amount of $3500.00. They then requested another quotation at another time for the amount of $1800.00. What else does it reveal? All existing customers have ordered something. Acme Lumber has not made a sale at all (yet), etc.
A design such as this enables the database to store any number of transactions between sellers and customers. Likewise, it supports the addition of any number of new customers and sellers, even if they have not sold or purchased anything yet. Queries can be run that reveal which sellers have sold the most or least, and so on.
Good luck with your studies!

Unique tables for specific customers in MySQL

I'm currently designing a billing app that can be used for a consultant to bill their customers. I currently have 3 tables in mysql for this the database to store information. The tables are activity, customer and expenses.
In the activity table I've got activity_id, activity_name, percent_rate, hours
In the customer table I've got customer_id, and all the information on the customer
In the expense table I've got expense_id, description, cost, quantity
I'm trying to figure out how to design the database that I can keep track of the hours spent on activity per customer. I want it to be used for multiple customers, but can't figure out how to structure the database for this.
Is it best to use a foreign key like custId in the activity table?
Yes.
But a lot depends on your overall structure. That's a pretty simple data model. If for instance you had something like "project", that the activities are related to, you'd put the customer id in the project table. Then again, if there were multiple customers for that activity, you'd have another table, with activity_id and customer_id in it, just to show that relationship. So, it depends on the problems you're trying to model.
Sounds like it. Does each activity have one (and only one) customer? Then you could have activity_id be the primary key of the activity table, and customer_id be a foreign key. For each customer you can get a list of activities, and for each activity you can figure out the # of hours the consultant worked for that customer on that activity.

Database design: many2many relationship for self referencing FK

My question can be demonstrated using the classic "employees" self referencing table, where manager_id is the FK related to the employee_id (PK). Another table is "authorizations".
What if authorizations are only relevant to managers and not to non-managers?
Assuming I create a junction table of "manager authorizations", can this table connect to employees.manager_id even though it's not unique?
Or must I separate managers to another table, even though they have the exact same attributes as non-managers?
Look at this structure Employees Structure. It manages a complex situation (a manager is responsible of one or more departement) and records are historical (from_date, to_date).
Try to modify this structure as follow:
departments becomes authorizations
dept_emp becomes the associative table auth_emp
remove dept_manager
A FK must always refer to a PK so connecting auth_emp to employee by manager_id is not possible (think to null references).
The decision to split or not employees that are manager to another table depends on your requirements (think about this: when a employee becomes a manager? An employee is a manager when at least another employee refers to him?).
If you want force the constraint that an employee_id registered in auth_emp refers to a manager you can use trigger on employee table. Obviously the trigger logic depends on your requirements.