Does adding information to this table makes it lose its 3NF - mysql

The table below is from a tutorial where the tables are in 3rd normal form. But if I insert information into the table PROJECT as follows:
projectCode projectDescr customerNo
1 Apples 21
1 Apples 22
Didn't I lose the 3NF cos the projectcode and projectdescr ends up repeating since 2 customers could possibly have the same project?
So my question is whether the table in the image below is in 3NF. And does the above problem even exists or I am looking at it wrongly? I am setting up my own table but before that I am trying to get the 3NF understanding right. Please help. Thanks.
The table from the tutorial:

The assumption in the example would be that the relationship between PROJECT and CUSTOMER is many to one. A customer may have multiple projects but each project applies to only one customer. If you want a project to apply to multiple customers, then you need to split out another project_customer table that just contains a project and customer key for each row.

Related

Database design for user experiences with various specialities

I’m doing a database design for user experience with specialties. A user can have experience months/ years for each specialty ( please see the attached images)
I’m planning to create a table to list all specialities, and a table to list experiences within years, and another table to list experiences with in months, and finally another table that will basically say “this user has this number of years / months experience for this speciality”
but having a table for experience is months and another table for experience in years kinda sounds redundant, but I can’t think of another way to do it. Is my design fine ?
Here's one idea:
User_ID Skill_ID Experience unit
1. 101 7. Year
1. 102. 4. Month
2. 101. 9. Month
You can simply make a table candidate_experience which has the following columns :
candidate_id which indicates the id of the candidate
specialty indicates the name of the specialty
in_years indicates the number of experience in years
in_months indicates the number of experience in months
You can just make a single table. Without the need to do 4 separate tables.
P.S: You may need to make a composite primary key (candidate_id , specialty) to avoid duplication of same specialty for the same candidate.
^^ This is of course if you are sure that there is no multiple specialties with the same name. Else, you can make a separate specialties table as you did and replace specialty with the specialty_id in the candidate_experience table

SQL Stock multiple information in a field or create tables

I'm having conception difficulties to implement something in a database. I have two solutions for a problem, and I was wondering which one is the best.
Problem :
Let's picture a table speciality with 2 fields : speciality_id and speciality_name.
So for example :
1 - Mage
2 - Warrior
3 - Priest
Now, I have a table user with fields such as user_id, name, firstname etc ...
In this table, there is a field called speciality. The speciality stores an integer, corresponding to the speciality_id of the table speciality.
That would be acceptable for users that have only one speciality. I want to improve the model to be able to have multiple specialities for a user.
Here are my two solutions :
Create a table 'solution1' which link the user_id with the speciality_id and remove the speciality field in the user table. So for a user which has 2 specialities, 2 rows will be created in the table 'solution1'.
Change the type of the field speciality in the user table to be able to write down the specialities, separated with commas.
For example 2;3
The problem I got with the second solution is for making foreign keys between my table user and my table specialities, to link them. I may have a bit more difficulties with the PHP in the future too, while wanting to get the specilities for a user (will need to use a parser I guess).
Which solution do you find is the best ?
Thanks.
Absolutely go with your first solution.
Create a third "Many-to-Many" table that allows you to relate a user to multiple specialties. This is the only way to go in your case.
When designing tables, you always want to have each column contain one and only one data element. Think about what querying your second solution would look like. What would you do when you wanted to see all users who had a given specialty?
You might try something like this:
select * from user where specialty like '%2%'
Well, what happens when you have specialties that go to 12? Now "2" matches multiple entities. You could devolve further and try to be tricky, but...you really should just make your data design as normal as possible to avoid all the mess, headache, and errors. Go with Solution 1.
i think the best way is to follow solution1 cause solution2 will end up will lot of complexity later on

SQL query - Two tables with relation many to one (Normalization issue)

I have this example tables:
table ORDERS
client orderno cant1 code1 notes1 cant2 code2 notes2 cant[i] code[i] [...]
--------------------------------------------------------------------------------------
1 1 3 AA01 Test 4 BB01 Testing
2 2 10 XX05 Test
table PRODUCTS
code prod price
---------------------
AA01 Engine 100
BB01 Wheel 50
table CLIENTS
client name address telephone
-----------------------------------------
1 Maxwell 24 1st st 0987654321
2 Hammer 77 main st 1234567890
I need to relate them to get the quantity, name of the product and price for each of the product lines (they are 30 cant[i], code[i] and notes[i]) and the customer's information (name, address, etc)
I found this case, but I don't understand how to apply it to mine: SQL query two tables with relation one-to-many
I hope it's not too complex.
Thanks in advance!
EDIT
Thanks to ElectricLlama I realized the problem here is the table where the order is storaged. According to his answer, the normalization of the database would improve the way I'm able to get the info.
For anyone interested in this solution, I found this great website: http://www.devshed.com/c/a/MySQL/An-Introduction-to-Database-Normalization/
This SO answer clears it ALL! Super clear and understandable!
https://stackoverflow.com/a/1258776/888292
Looking at what's in your link - yes it seems like a lot of nonsense, but it is probably the only way to get what you want.
The problem is that your table is not normalised. Specifically you should not have fields called code1 code2 code3 code4... code30
There are many flaws with this design including what happens when a client has 31 products?
In a normalised database you would have a table with one set of cant, code and notes, and you would have one row per product.
But I guess you are not in a position to normalise it.
So well done for coming up with your own answer, and you now you also have first hand experience of the repercussions of not normalising a database.
What you might want to consider is creating a view that will normalise this for you. It will introduce performance issues but it will give you an introduction to views, and give you an opportunity to see how the solution would look like against a normalised table.
Ditto #ElectricLlama & here are a few links that should help you learn SQL:
W3Schools: SQL Tutorial
SQLServerCentral.com Stairway Series
I think that your table should be look like
Table orders
-------------
orderno
client
code
cant
note
Here make orderno, client and code make a composite primary key of the table

Ideas for stock management using mysql

I am creating a database for a publishing company. The company has around 1300 books and around 6-7 offices. Now i have created a table that displays the stock items in all locations. The table should look like following to the user:
Book Name Location1 Location2 Location3 ......
History 20000 3000 4354
Computers 4000 688 344
Maths 3046 300 0
...
I already have a Books table which stores all the details of the books, i also have a office table which has the office information. Now if i create a stock management table which shows the information like above i will end up in a huge table with a lot of repetition if i store my data in the following way:
Column1- Book_ID Column2- Location_ID Column3- Quantity
1 1 20000
1 2 3000
1 3 4354
2 1 4000
2 2 688
...
So, i think this isn't the best way to store data as it would end up with 1300 (Books) X 7 (Locations) = 9100 rows. Is there a better way of storing data. Now i can have 7 additional columns in the Books stable but if i create a new location, i will have to add another column to the Books table.
I would appreciate any advice or if you think that the above method is suitable or not.
Nope, that's the best way to do it.
What you have is a Many-to-Many relationship between Books and Locations. This is, in almost all cases, stored in the database as an "associative" table between the two main entities. In your case, you also have additional information about that association, namely, it's "stock" or "quantity" (or, if you think about it like a Graph, the magnitude of the connection, or edge-weight).
So, it might seem like you have a lot of "duplication", but you don't really. If you were to try to do it any other way, it would be much less flexible. For example, with the design you have now, it doesn't require any database schema change to add another thousand different books or another 20 locations.
If you were to try to put the book quantities inside the Locations table, or the Locations inside the Books table, it would require you to change the layout of the database, and then re-test any code that might be use it.
Thats the most common (and effective) solution. Most frameworks like Django, Modx and several others implement Many2Many relations via an intermediate table only, using foreign key relations.
Make sure you index your table properly.
ALTER TABLE stock_management add index (Book_ID), add index (Location_ID)
That really the best way to do it; you have 9100 independent data to store, so you really do need 9100 rows (less, really; the rows where the quantity is 0 can be omitted.) Other way of arranging the data would require the structure of the table to change when a location was added.

Database Design for Rental Listings

I'm designing a simple database for a rental listings website,
sort of like classified ads but only for home/room rentals. This is what I've come up with thus far:
Question 1
For the "post" table, I actually wanted more information. For example, there would be a 'facilities' section where the users can select whether there's 'parking' available, do I need a separate table? Or just use 0 for no and 1 for yes?
Question 2
Here's what I did with the "category" table (sorry I don't know how to pretty print yet)
Category_ID 1 is Rent
Category_ID 2 is buildingType
For "categoryProperty" table
Category_ID 1 categoryPropertyID 1 House
Category_ID 1 categoryPropertyID 2 Room
Category_ID 2 categoryPropertyID 3 Apartment
Category_ID 2 categoryPropertyID 4 Condominium
Category_ID 2 categoryPropertyID 5 Detached
Does the above make sense?
Question 3
Users can post whether they are logged in or not. Just that logged in users/members have the advantage of tracking their ads/adjusting the availability.
How do I record the ads that a member has posted? Like their history.
Should I create a "postHistory" table and set the 'postHistory_ID' as FK to "member" table?
Thanks a lot in advance, I appreciate your help, especially just pointing me to the right direction.
Question 1:
make a separate table and make a One to One relation, that would be the simplest way:
POST -|-----|- EXTRAS
in EXTRAS you may have every extra field (parking=1/0, in_down_town=1/0,has_a_gost=1/0)
Question 2:
This does not make sense, you've two options:
in the Post table create a "type_of_operation", that can have two vales (building_type,rent). Or you can create different tables, but would make this more complicate (you should analyise if the same type can be in both states, etc).
Question 3:
I recommend you to make your users register. Even with a really simple form (email+password) .
Seems to be on the right track -- with respect to your specific questions:
Question #1: Assuming there's more than one type of facility (parking; swimming pool; gym) then you have a many-to-many relationship and you want 2 new tables: Facilities and PropertyFacilities. Each Property (or I guess "post") could have multiple rows in the PropertyFacilities table.
Question #2: Not really clear on what you're getting at -- is it that each property type can either be rented whole or rented per room?
Question #3: Good question, what you want to do is have an Active bit, or an ExpireDate, in your POST table -- then anything that becomes inactive or expired is automatically 'historical' data, no need to marshall it to a history table. Although you'll have to archive eventually of course.