I showed my lecturer my database today (based on an Ecommerce site).
He was very quick to point out a few issues, such as data redundancy. For example I have User ID in five tables.
My database is based on my ERD: http://imgur.com/X02JlF3
I am just looking on some advice on cleaning up my ERD so that I can produce a more efficient database.
If I removed User ID from every table except Users, how could I provide a User ID with a transaction report for example? Or would User ID need to be a foreign key in every table?
Thanks, sorry if this is an inappropriate question! Just not sure the right way to clean up this ERD.
After a quick look, I think that the use of UserID as a foreign key is OK. The redunancy I see is more like Prodcut Name, product Description, Price and stock level occuring in the Wish List, for example. These values should only be in the Product table and the ProductID in Wish List used to join to that table as a FK. With that in mind, I'm sure you will see other examples in your ERD.
Related
I need to create a mySQL database that keeps information about vehicles. My instincts were to create one table with as many columns as I need, but then I read about the problems in doing so. After researching, I think I'm on the right track with the following structure:
Vehicles Database
Motorcycles Table
id|road|cruising|touring|
Cars Table
id|sedan|coupe|hatchback|
Colours Table
id|green|red|blue|black|silver|white|yellow|etc..
Make Table
id|ford|chevrolet|gm|toyota|bmw|etc..
Quadrant Table (1-4)
id|motorcycle|car|truck
So basically I have a table for the objects - cars, motorcycles, trucks - and then tables for the fields/properties - Colour, Make, etc. and then a table for the Quadrant the vehicle is seen in, with a value of 1-4 where each row is an instance of only one vehicle.
The problem I'm having is understanding where the primary and foreign keys need to be in order for me to be able to organize the data:
By each individual vehicle selected along with its fields
By quadrant, showing each vehicle and their respective fields
The user counting cars should be able to input the vehicle type, the field values and the quadrant it's seen in and the db gets populated - and then I need to call the data by quadrant to analyze the data.
I don't know if or how a JOIN statement will be used? How do I go about structuring this database to suit my needs?
FWIW, dba.stackexchange says basic SQL questions belong here, so I hope I'm in the right place.
Can you tell, what is your exact need for the database i.e what functionality you need.
I suggest tables like following:
1) Vehicle table:
id|type which might contain info like 1|Motorcycle, 2|Car
2) category table:
id(foreign key)|category|color which contain info like 1|touring|Black, 2|Car|Hatchback
3) Make table: (if you need to create another table)
id (foreign key to table 1)|Make
I have not understood the functionality of quadrant table but with these 3 table you can create views according to your needs and play around with it.
From my point of view:
I will create a table CarBrands, with columns Id, BrandName, Description, which will serve as a look up.
Then I will create another table Cars with Id, CarBrandId, ColorId (From Colors Table), Description, which is your table with user records.
Same with your other entities. I suggest you search about Entity Relationship Diagrams, a good way of helping you come up with a good design.
Also look at this old StackOverflow question, this will help you.
My experience with databases is limited so I am not sure of the best way to ask this question, so I am going to break it down as simply as possible. I've built an ASP.net application with a mySQL database using NHibernate that has multiple users that can log in and all work on the same table (let's say of forum posts). So we have our users table and our food table.
Now I am looking for the best way to split these users into groups, very much like different companies. So The users from the same "company" can log on and see all there other company users and edit/create posts view-able by said "company".
I am looking for the most scalable (fastest with 1000's of companies) way to do this. Should I
1: Have a universal table for users and posts with a foreign key? So everything is stored on the same SQL table but their view of this table is restricted by the company ID. I see this being the easiest one to build, but will 1000's of companies accessing the same table with this be slow/problematic?
2: Create a new posts table for every company? So every user from a company accesses their own table of posts. To scale up would this be more efficient/faster if there were thousands of companies?
A quick explanation of the best method would be really appreciated. But also pointing me to documentation/resources would be amazing! Cheers.
I strongly suggest option 1.
You should create company table with companyID as primary key. Use companyID as foreign key in users table and food table.
This is regular approach and works well in most of the cases.
It would be very complicated to maintain 1000's of tables in the application.
Users and food table will be already indexed by company ID so the filtering will be very fast.
i wanna have a Users details stored in the database.. with columns like firstname, last name, username, password, email, cellphone number, activation codes, gender, birthday, occupation, and a few other more. is it good to store all of these on the same table or should i split it between two users and profile ?
If those are attributes of a User (and they are 1-1) then they belong in the user table.
You would only normally split if there were many columns; then you might create another table in a 1-1 mapping.
Another table is obviously required if there are many profile rows per user.
One table should be good enough.
Two tables or more generally vertical portioning comes in when you want to scale out. So you split your tables in multiple tables where usually the partiotioning criteria is the usage i.e., the most common attributes which are used together are housed in one table and others in another table.
One table should be okay. I'd be storing a hash in the password column.
I suggest you read this article on Wikipedia. about database normalization.
It describes the different possibilities and the pros and cons of each. It really depends on what else you want to store and the relationship between the user and its properties.
Ideally one table should be used. If the number of columns becomes harder to manage only then you should move them to another table. In that case, ideally, the two tables should have a one-one relationship which you can easily establish by setting the foreign key in the related table as the primary key:
User
-------------------------------
UserID INT NOT NULL PRIMARY KEY
UserProfile
-------------------------------------------------------
UserID INT NOT NULL PRIMARY KEY REFERENCES User(UserID)
Depend on what kind of application it is, it might be different.
for an enterprise application that my users are the employees as well, I would suggest two tables.
tbl_UserPersonallInformation
(contains the personal information
like name, address, email,...)
tbl_UserSystemInformation (contains
other information like ( Title,
JoinedTheCompanyOn,
LeftTheCompanyOn)
In systems such as "Document Managements" , "Project Information Managements",... this might be necessary.
for example in a company the employees might leave and rejoin after few years and even they will have different job title. The employee had have some activities and records with his old title and he will have some more with the new one. So it should be recorded in the system that with which title (authority) he had done some stuff.
I am designing a relational database of products where there are products that are copies/bootlegs of each other, and I'd like to be able to show that through the system.
So initially during my first draft, I had a field in products called " isacopyof " thinking to just list a comma delimited list of productIDs that are copies of the current product.
Obviously once I started implementing, that wasn't going to work out.
So far, most many-to-many relationship solutions revolve around an associative table listing related id from table A and related id from table B. That works, but my situation involves related items from the SAME table of products...
How can I build a solution around that ? Or maybe I am thinking in the wrong direction ?
You're overthinking.
If you have a products table with a productid key, you can have a clones table with productid1 and productid2 fields mapping from products to products and a multi-key on both fields. No issue, and it's still 3NF.
Because something is a copy, that means you have a parent and child relationship... Hierarchical data.
You're on the right track for the data you want to model. Rather than have a separate table to hold the relationship, you can add a column to the existing table to hold the parent_id value--the primary key value indicating the parent to the current record. This is an excellent read about handling hierarchical data in MySQL...
Sadly, MySQL doesn't have hierarchical query syntax, which for things like these I highly recommend looking at those that do:
PostgreSQL (free)
SQL Server (Express is free)
Oracle (Express is also free)
There's no reason you can't have links to the same product table in your 'links' table.
There are a few ways to do this, but a basic design might simply be 2 columns:
ProductID1, ProductID2
Where both these columns link back to ProductID in your product table. If you know which is the 'real' product and which is the copy, you might have logic/constraints which place the 'real' productID in ProductID1 and the 'copy' productID in ProductID2.
The best way to describe this scenario is to use an example. Consider Netflix: do they
store their orders (DVD's they mail out) in a separate table from their member lists (NOT members table, but a joiner table of members and movies--a list of movies each member has created), or are orders distinguished by using additional information in the same row of the same table?
For those not familiar with Netflix, imagine a service that lets you create a wish list of movies. This wish list is subsequently sent to you incrementally, say two movies at a time.
I would like to implement a similar idea using a MySQL database, but I am unsure whether to create two tables (one for orders and one for lists) and dynamically move items from the lists table to the orders table (this process should be semi-automatic based on the member returning an item, where before a new one is sent out, a table with some controls will be checked to see if the user is still eligible/has not gone over his monthly limit)...
Thoughts and pros and cons would be fantastic!
EDIT: my current architecture is: member, items, members_items, what I am asking is if to store orders in the same table as members_items or create a separate table.
Moving things from one database table to another to change its status is simply bad practice. In a RDBMS, you relate rows from one table to other rows in other tables using primary and foreign key constraints.
As for your example, I see about four tables just to get started. Comparing this to Netflix, the grand-daddy of movie renting, is a far-cry from reality. Just keep that in mind.
A User table to house your members.
A Movie table that knows about all of the available movies.
A Wishlist or Queue table that has a one-to-many relationship between a User and Movies.
An Order or Rental table that maps users to the movies that are currently at home.
Statuses of the movies in the Movie table could be in yet another table where you relate a User to a Movie to a MovieStatus or something, which brings your table count to 6. To really lay this out and design it properly you may end up with even more, but hopefully this sort of gives you an idea of where to begin.
EDIT: Saw your update on exactly what you're looking for. I thought you were designing from scratch. The simple answer to your question is: have two tables. Wishlists (or member_items as you have them) and Orders (member_orders?) are fundamentally different so keeping them separated is my suggestion.
A problem with storing orders in the members table is that there's a variable number (0, 1, or several) of orders per member. The way to do this using a relational database is to have two separate tables.
I feel like they would store their movies as follows (simplified of course):
tables:
Titles
Members
Order
Order_Has_Titles
This way an order which has a foreign key to the Members would then have a pivot table as many orders could have many titles apart of them.
When you have a many to many realtionship in the database you then need to create a pivot table:
Order_Has_Titles:
ID (auto-inc)
Order_FkId (int 11)
Title_FkId (int 11)
This way you're able to put multiple movies apart of each order.
Of course this is simplified, and you would have many other components which would be apart of it, however at a basic level, you can see it here.