Normalizing database MySQL - mysql

Table values:
Tabel Desc:
Is it normalized to 1NF, 2NF, 3NF? To the best of my knowledge and if i understand Normalization it cannot be divided again. Am i correct?

We can still normalize the above structure as follows
udegid, userid, designationid,designatedon,revokedon,status
Where udegid is the guid for this table.
Similarly for the department we can have as
udeptid, userid, deptid, effectivefrom, effectiveto,status
This approach enables you to track the history of the employee designation and dept throughout the lifetime of the employee.
HTH

Related

During normalization of data, can I add my own attributes?

Can we add our own attributed to the main table during the normalization process.
For example, we have
custid, custname, invoice_date, invoice amount, prod_code, prod_description.
Can I add invoice_ID to the table ?
You have left out a lot of key details making this is a very poor question. Assuming you have have the correct permission/role in any DBMS you can alter any table attributes. The normalisation processes normally comes after you have a draft version of what information you want to represent in each table and then follow the steps of the normalisation process.
http://www.studytonight.com/dbms/database-normalization.php
(Also some advice, you haven't posed any of your DB or even what attributes belong to what table above, in which case if all of the attributes you have listed above belong to the single table this breaks the second/third normal form rule)
An example of a normalised environment:
customers
customer_id*, customer_name
invoices
invoice_id*,invoice_date, customer_id,invoice amount
products
product_id*,product_code, product_description
invoice_detail
invoice_id*,product_id*,quantity
* = (component of) primary key
This assumes that there is a 1:1 relationship between orders and invoices, and that invoices are generated on the date an order is placed.

Did I normalize correctly?

Doing some practice questions and just wanted to know if I normalized correctly. Thanks.
Un-normalized Table
INVOICE [Invoice#(pk), InvoiceDate, Sales, Cust#,
(EquipClass, EquipClassDesc, Equip#, EquipDesc, EquipCharge, EquipQTY)]
1NF Tables
INVOICE [Invoice#(pk), InvoiceDate, Sales, Cust#]
Equipment [ Invoice#(pk), Equip#,(pk), EquipClass, EquipClassDesc,
EquipDesc, EquipCharge, EquipQTY)]
2NF Tables
INVOICE [Invoice#(pk), InvoiceDate, Sales, Cust#]
Equipment [Equip#,(pk), EquipClass, EquipClassDesc, EquipDesc, EquipCharge]
INVOICE_Equipment [Invoice#(pk) (FK), Equip# (pk) (FK), EquipQTY]
3NF Tables
INVOICE [Invoice#(pk), InvoiceDate, Salesperson#(fk)]
Salesperson [Salesperson#(pk), SalespersonName]
Invoice_SalesPerson [Invoice#(pk)(fk), Salesperson#(pk)(fk), Cust#]
Equipment [Equip#,(pk), EquipClass(fk), EquipDesc, EquipCharge,]
Equipment_Class [EquipClass(pk), EquipClassDesc]
INVOICE_Equipment [Invoice#(pk) (FK), Equip# (pk) (FK), EquipQTY]
Since the Unnormalized, 1NF and 2NF tables never mention a sales person, there's no basis for the splits and additions that occur as you progress from 2NF to 3NF in the prior schemas.
Additionally, an invoice is more probably associated with a customer and a salesperson directly (it would have independent FK references to the customer table (which isn't identified in the schema) and the salesperson table). The Invoice_SalesPerson table looks spurious, and the removal of customer number from Invoice looks dubious. It could be done the way you've shown, but I'd never mark it as correct without a clear, verbose, cogent explanation of why that was necessary (and I'd still be sceptical that it was not necessary).

how to design: users with different roles see different records

I have a schema design question for my application, hope I can get advices from teachers. This is very alike of Role Based Access Controll, but a bit different in detail.
Spec:
For one company, there are 4 roles: Company (Boss) / Department (Manager) / Team (Leader) / Member (Sales), and there are about 1 million Customers records. Each customer record can be owned by someone, and he could be Boss or Manager or Leader or Sales. If the record's owner is some Sales, then his upper grade (say: his leader / manager / boss) can see this record as well (but others: say the same level of his workmates, cannot see, unless his upper grade manager share the customer to his workmates), but if the record's owner is boss, none except the boss himself can see it.
My Design is like this (I want to improve it to make it more simple and clear):
Table:
departments:
id (P.K. deparment id)
d_name (department name)
p_id (parent department id)
employees
id (P.K. employee id)
e_name (employee name)
employee_roles
id (P.K.)
e_id (employee id)
d_id (department id)
customers
id (P.K. customer id)
c_name (customer name)
c_phone (customer phone)
permissions
id (P.K.)
c_id (customer id)
e_id (owner employee id)
d_id (this customer belongs to which deparment)
share_to (this customer share to other's id)
P.S.: each employee can have multi roles, for example, employee A can be the manager of department_I and meanwhile he can also be one sales of deparment_II >> Team_X.
So, when an employee login to application, by querying from employee_roles table, we can get all of the department ids and sub department ids, and save them into an array.
Then I can use this array to query from permissions table and join it with customers table to get all the customers this employee should see. The SQL might look like this:
SELECT * FROM customers AS a INNER JOIN permissions AS b ON a.id =
b.c_id AND (b.d_id IN ${DEP_ARRAY} OR e_id = ${LOGIN_EMPLOYEE_ID} OR
share_to = ${LOGIN_EMPLOYEE_ID})
I don't really like the above SQL, especially the "IN" clause, since I am afraid it will slow down the query, since there are about 1 million records or even more in the customer table; and, there will be as many records as the customers table in the permissions table, the INNER JOIN might be very slow too. (So what I care about is the performance like everyone :))
To my best knowledge, this is the best design I can work out, could you teachers please help to give me some advice on this question? If you need anything more info, please let me know.
Any advice would be appreciated!
Thanks a million in advance!!
Do not use an array, use a table, ie the value of a select statement. And stop worrying about performance until you know more basics about thinking in terms of tables and queries.
The point of the relational model is that if you structure your data as tables then you can looplessly describe the output table and the DBMS figures out how to calculate it. See this. Do not think about "joining"; think about describing the result. Whatever the DBMS ends up doing is its business not yours. Only after you become knowledgeable about variations in descriptions and options for descriptions will you have basic knowledge to learn about performance.

In MySQL what's the correct way to map a "belongs-to" relationship when an item could belong to two or more types of item?

If this is standard knowledge, I apologize. Part of my problem is I'm not even sure what language to use to search.
If I have the tables Event, Department, Client and I want to denote a one-to-many relationship between Clients and Events but also between Departments and Events, what would I do?
If I had a one-to-many relationship with Clients to Events only, I'd simply have a client_id field in Event. I could have two columns: client_id and department_id, but is there a better approach or can you point me at resources or even proper terminology so I can find more and educate myself?
Thanks in advance.
By the RDBMS system, what you have is the best approach.
You would have a client_id column and a department_id column in the events table, which maps to a key in a client and department table respectively.
Edit: However, if you have a ton of data, and you have abundant storage space and would like to optimize for speed of operations, you might consider joining the columns of one or both of the tables to the events table. Storage is cheap nowadays.
Standard normalization is to have "membership" tables that are join tables.
Your tables then become:
Event (event_id)
Client (client_id)
Department (department_id)
Plus:
Client_Events (id, client_id, event_id)
Department_Events (id, department_id, event_id)
Then using JOIN, you can get what you want. MySQL/Postgre can handle JOINs of this sort very quickly.

creating relational tables within a database

I am having a major issue with relating the following tables together. It is a many to many relationship between Patient and Nurse.
Here is the relational table:
Patient (PatientID (PK), Forename, surname, gender, date of birth, address, illness, prioirty)
seen_by (ID(PK) PatientID(FK to Patient.PatientID), NurseID(FK to Nurse.NurseID) )
Nurse (NurseID(PK), Forename, surname)
The issue I am getting is that, I want the PatientId to be assigned to a NurseID so I know what patient is seen by what nurse. Please note that the ID are all auto_increment values.
Any suggesions, thanks in advance!
Why not create a join table that would be the relationship between the patient and the nurse?
Table: Appointment (AppointmentID (PK), PatientID, NurseID)
Then you can assign the patient and the nurse to the appointment record and keep track of the relationship. This also gives you the benefit of keeping track of additional information regarding the appointment such as dates, prescriptions, etc.
I'm not sure what development environment you're using but Rails has some nice patterns for accessing objects through these kinds of relationships.