Creating Sub-Tables within a Table in PHPMyAdmin - mysql

I have this Menu for a restaurant with food categorized into different groups i.e.:
For the Breakfast (food here)
Salads (food here)
Cold Beverages (drinks here)
Hot Beverages (drinks here)
etc. ...
I've already created a table for the menu, I want to list the food served under Breakfast, Lunch, Dinner, Deserts, Drinks (hot and cold), Alcoholics, Smokes (shisha, pipes, cigarettes , etc..)
SQL has no function to serve my needs so... who has a creative idea!.

Of course, this can be done by adding the category title to the table and making my way around with indexing skipping the index of the row holding the title, but if the restaurant edits the menu ONCE everything will be scrambled.
That sounds like you're thinking of an SQL table like it was a Word table with different kinds of rows (like heading rows and data rows). That's not the case; an SQL table's rows should all be alike.
If your menu table is something like
id
name
price
1
Omelette
8
2
Sandwich
6
3
Soup of the Day
8
the simplest way to categorize these is to add a new column for the category:
id
name
price
category
1
Omelette
8
Breakfast
2
Sandwich
6
Breakfast
3
Soup of the Day
8
Lunch
(though in a real database design the category would probably be a foreign key to a Categories table)
You can then use a WHERE category = ... clause to only show some entries, or do SELECT DISTINCT category FROM menu ORDER BY category to get all of the categories in alphabetical order.

Related

1NF, 2NF, AND 3NF Normalization?

I have a teacher who doesn't like to explain to the class but loves putting up review questions for upcoming tests. Can anyone explain the image above? My main concern in the red underline which shows that supplier and supplierPhone are repeated values. I thought that repeated values occurred when there were many occurrences of the same item in a column.
Another question I have is that if the Supplier is a repeating value, why isnt Part_Name a repeating value because they both have 2 items with same names in their columns.
Example:
It's repeated because the result of the tuple is always the same. E.g. ABC Plastics will always have the same phone number, therefore having 2 rows with ABC Plastics means that we have redundant information in the phone number.
Part1 Company1 12341234
Part2 Company1 12341234
We could represent the same information with:
Part1 Company1
Part2 Company1
And
Company1 12341234.
Therefore having two rows with the same phone number is redundant.
This should answer your second question as well.
Essentially you're looking for tuples such that given the tuple (X, Y) exists, if there exists another tuple (X, Y') then Y' = Y
Looks like five tables to me.
model (entity)
modelid description price
1 Laserjet 423.56
1 256 Colour 89.99
part (entity)
partid name
PF123 Paper Spool
LC423 Laserjet cartridge
MT123 Power supply
etc
bill_of_materials (many to many relationship model >--< part )
modelid partid qty
1 PF123 2
1 LC423 4
1 MT123 1
2 MT123 2
supplier (entity)
supplier_id phone name
1 416-234-2342 ABC Plastics
2 905.. Jetson Carbons
3 767... ACME Power Supply
etc.
part_supplier (many to many relationship part >--< supplier )
part_id supplier_id
PF123 1
LC423 2
MT123 3
etc.
You have one row in model, part, supplier for each distinct entity
You have rows in bill_of_materials for each part that goes into each model.
You have a row in part_supplier for each supplier that can furnish each part. Notice that more than one part can come from one supplier, and more than one supplier can furnish each part. That's a many-to-many relationship.
The trick: Figure out what physical things you have in your application domain. Then make a table for each one. Then figure out how they relate to each other (that's what makes it relational.)

Database implemenation for Grouped Tagging

I need to implement a tagging system which is something like this :-
Every user can be tagged on the basis of his education. ( Tags be : Primary, secondary, High School) and these Tags fall under the umbrella of "education".Similarly the user may also be tagged on his interest(Cricket, Football, Rock music, pop music...) Cricket and football come under "Sports", rock music and pop music come under "Music".
Current design is :
User Userid TagID TagName UserId TagID
=========== ============= ============
1 User1 1 Pop 1 1
2 user2 2 Rock 1 2
3 Techno 1 5
4 Cricket 1 6
5 Football 2 1
6 Primary Scl. 2 4
7 Secondary scl 2 7
These 3 form the major tables that allow many to many relationship between users and tags.
secondary tables are:
(Music) (Sports) (Education)
TagID MusicID MusicType TagID SportID Sport TagID EducationID Education
======================= ==================== ============================
1 1 Pop Music 4 1 Cricket 6 1 Primary
2 2 Rock Music 5 2 Football 7 2 Secondary
3 3 Techno Music
the problem in this structure is that a TagID from table TagTable can be referenced by both Music and Sports if care is not taken.There is a chance that pop music and cricket will refer to the same TagID if the developer doesn't take necessary care.
How do I avoid this possibility of multiple referencing ?
Note : The secondary tables have been used to check if the tags fall under the same umbrella. This is feature of grouping tags is necessary.
Looks like you need something similar to this:
NOTE: Tag names are globally unique in the model above. If you need to make them unique per category, just include TAG_CATEGORY_ID in the UNIQUE constraint TAG.U1.
BTW, do you need to limit user to only one tag from certain categories? For example, can user have both Primary and Secondary tags from the Education category, or not? If you need to limit this, you'll need to reference such tags in a different way (as opposed to the "simple" junction table USER_TAG) and there will be certain complications to prevent mixing "single" and "multi" tags...

When is it better to flatten out data using comma separated values to improve search query performance?

My question about SEARCH query performance.
I've flattened out data into a read-only Person table (MySQL) that exists purely for search. The table has about 20 columns of data (mostly limited text values, dates and booleans and a few columns containing unlimited text).
Person
=============================================================
id First Last DOB etc (20+ columns)...
1 John Doe 05/02/1969
2 Sara Jones 04/02/1982
3 Dave Moore 10/11/1984
Another two tables support the relationship between Person and Activity.
Activity
===================================
id activity
1 hiking
2 skiing
3 snowboarding
4 bird watching
5 etc...
PersonActivity
===================================
id PersonId ActivityId
1 2 1
2 2 3
3 2 10
4 2 16
5 2 34
6 2 37
7 2 38
8 etc…
Search considerations:
Person table has potentially 200-300k+ rows
Each person potentially has 50+ activities
Search may include Activity filter (e.g., select persons with one and/or more activities)
Returned results are displayed with person details and activities as bulleted list
If the Person table is used only for search, I'm wondering if I should add the activities as comma separated values to the Person table instead of joining to the Activity and PersonActivity tables:
Person
===========================================================================
id First Last DOB Activity
2 Sara Jones 04/02/1982 hiking, snowboarding, golf, etc.
Given the search considerations above, would this help or hurt search performance?
Thanks for the input.
Horrible idea. You will lose the ability to use indexes in querying. Do not under any circumstances store data in a comma delimited list if you ever want to search on that column. Realtional database are designed to have good performance with tables joined together. Your database is relatively small and should have no performance issues at all if you index properly.
You may still want to display the results in a comma delimted fashion. I think MYSQL has a function called GROUP_CONCAT for that.

How to design category and subcategories in MySQL?

I have a list of categories and number of sub categories associated to each category.
let say Category table is called Cat then I have hot and cold categories in it
I have another table called subcats then I have the following:
Cat:
ID Name
1 Hot
2 Cold
SubCats:
SubCatID CATID Name
1 1 soup
2 1 rice
3 1 pizza
4 2 salad
5 2 fruit
I should consider performance in my design, how do you rate my design? is there any better solution?
(Categories are just sample - I have heaps of categories and subcategories.)
You could have everything in one table, category. Then have a column for parentID. If parentID = 0, it is a master category, if its another ID, then it is a subcategory? This structure would support sub-sub categories... not sure if that's helpful to you.
Example fields:
Table: category
categoryID
parentID
name
Example data:
categoryID : 1
parentID : 0
name : hot
categoryID : 2
parentID : 0
name: cold
categoryID : 3
parentID : 2
name : a soup that's cold
categoryID : 4
parentID: 1
name: a soup that's hot
If you are using mysql and/or sqlite (which you both have in your tags), doesn't offer any constructs for recursive queries, chances are you will be better of with a nested set model rather than a parent/child relationship.
It might be massively overkill, or it might not be fit for purpose (if its more heavy on inserts than reads), but nevertheless, its fun to learn so give these a read
http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/
http://en.wikipedia.org/wiki/Nested_set_model
There's really nothing wrong with your table structure. It's well normalized and you've implemented it in a standard way. It would probably be a good idea to have a foreign key constraint across the tables (if you don't already).
As Zeke said, however, your design wouldn't support multiple levels of sub-categories, but as long as you know there will only be categories and sub-categories, it's fine.
If you did want "sub-sub-categories" (to an infinite degree), you may just want one table like this:
Cat:
CatID ParentCatID Name
1 null Hot
2 1 Soup
3 1 Coffee
4 3 Decaf Coffee
5 null Cold
6 5 Iced Tea
Notice that Coffee's parent ID is "Hot" and Decaf Coffee's ParentID is "Coffee". So Hot > Coffee > Decaf Coffee. Anything with a ParentCatID of null will be a top-level category.
You can have a Foreign Key that references it's own table. So you can create a foreign key between ParentCatID and CatID.

e-commerce structure for products (MySQL)

I am considering how to structure my MySQL database in e-commerce solution. To be more specific I am looking at the product structure.
These are the tables I have come up with so far. What do you think?
Explanation of structure
The application is multilingual. Therefore the product table are split in 2 tables.
If a products has e.g. 2 variants (Small, Medium) a total of 3 rows will be inserted. This is because each variant can have different information for each variant. When the product is shown on the webpage product 1 will be shown with a drop down box with Small & Medium. A product with no variants will naturally only insert 1 row.
products
id master product_number
1 0 123
2 1 456
3 1 678
products_descriptions
id product_id country_code image name description vat price
1 1 en-us image.jpg t-shirt Nice t-shirt 25 19.99
2 2 en-us image.jpg t-shirt Nice t-shirt 25 19.99
3 3 en-us image.jpg t-shirt Nice t-shirt 25 19.99
products_to_options
product_id option_id
2 1
3 2
options
id name
1 Small
2 Medium
Your Products table is schizophrenic, its entity is sometimes Product and sometimes Variant. This leads to very cumbersome behavior. For example, you'd like the question "how many different products do we have?" be answered by select count(*) from products, but here this gives the wrong answer, to get the correct answer you have to know the Magic Number 0 and query select count (*) from products where master=0. "List all products and how many variants we have for each" is another query that should be straightforward but now isn't. There are other anomalies, like the fact that the first line in products_descriptions is a shirt that has a price and a picture but no size (size is stored in the variants, but they have prices and pictures of their own).
Your problem sounds like you have products in two contexts: (1) something that can be displayed as an item in your store, and (2) something that can be ordered by your customer. (1) probably has a name like "Halloween T-Shirt" or so, and it probably has an image that the customer sees. (2) is what the customer orders, so it has a (1), but also a variant specification like "small" or maybe a color "red". It probably has a price, too, and an order_id so your shop can know what specific item to ship.
You should give each context an entity. Here's how i'd do it
displayable_product
id name
1 "Baseball Cap"
2 "T-Shirt"
orderable_product
id d_product_id order_id size color price
1 1 123 red 9.99
2 2 456 small 19.99
3 2 789 medium 21.99
displayable_content
id d_product_id locale name image
1 1 en_US "Baseball Cap" baseballcap.jpg
2 1 es_US "Gorra de Beisbol" baseballcap.jpg
3 2 en_US "Nice T-Shirt" nicetshirt.jpg
4 2 es_US "Camiseta" nicetshirt.jpg
You should probably use locale instead of country in the display tables to account for countries with more than one language (USA, Switzerland, and others), and you might separate the size and color into its own variants table. And if you need country-dependent data on the orderables (like different prices/currencies for shipping to different countries), you'd have to extract a country-dependent orderable_content table, too.