Inventory/Stock Monitoring Database Schema - mysql

I tried my best, asked IRC for help but still kinda hard.
Here's what I only got so far
I don't know how would I link medicines to products.
Here's the logic:
Many brands can make many products.
Products can have many brands, has name, and image
Products have type (it may be Medicine, Soap, etc)
If product is medicine, I want to it to be attached to the medicines tables as it's attribute will be inserted there.
examples:
Brand A - Product A - image1 - Medicine - 250 - mg
Brand B - Product A - image2 - Medicine - 250 - mg
Brand B - Product A - image2 - Medicine - 500 - mg
Brand B - Product B - image 3 - Soap
Brand B - Product C - image 4- Soap
-- EDIT --
I thought of adding medicine_fk on the products table. It'll be null if it's not a medicine. But thinking about its flexibility, what if in the future there will be more product types?
A good example (bad type tho xD)
I'll be needing car_fk in the product table? that points to car table?
How should I do that?
-- EDIT --
My mind's is so stressed about this one I forgot I should put the product_id instead on car table and medicine table and any other types of products
-- EDIT --
At first I thought how to find all the tables that is related to the product if ever a user added a new product type.
And thought of making another table again, and also dynamically making new tables for each product types but that seems an ugly way.
With the help of IRC people I ended up with this:
Is there any possible errors with that?
-- EDIT --
My FINAL table structure is the same as above only without the sub tables.
I removed subattributes and sub categories.
Add a parent_id column on categories and attributes table instead.
Much better and I assumed this answered my question.

Firstly, in your diagram the relationship between PRODUCT_TYPES and PRODUCTS is depicted as one-to-one, shouldn't this relationship be one- to-many (One product type can have many products for example Medicine can have Asprin, Paracetamol etc).
Secondly, the approach you are following is correct. Just introduce your PRODUCT_ID in your medicines table and your CAR table. It should be NOT NULL. Since PRODUCTS is your parent table it should not have the keys from other tables.
Alternately, you could also make the ID in your medicines table as a foreign key to the ID column in your PRODUCTS table.

Keep in mind that relationships should be 1:many or many:many, never 1:1. Only in the many:many case do you need an extra table.
"Sub" attributes and categories will be a nightmare to deal with; can you get rid of them?
What will the SELECTs be? To some extend, they drive what the tables look like.
A table with a thousand rows does not need its fields "normalized".

Related

DB design for product pricing history for multiple suppliers

I am currently trying to design DB(mysql) structure for my project which is an online shop for wholesale company - I already created everything when it comes to products, it's multiple variants etc but I have problem with following which is price and historic data for multiple suppliers:
Please find below main assumptions for the project:
We are going to have several suppliers for products
Thanks to the above each product will have few different prices
We want to be able to have historic price data for each product with each supplier
Variant 1
At first I thought about adding 2 tables to my DB:
suppliers table: supplier_id, name
prices table: id, product_id, price_supplier1, price_supplier2, price_supplier3, timestamp
However in such example whenever we want to add another supplier we need to add row to the database (I am not a db expert but I guess that's not the best approach)
Variant 2
Another idea was just to have price table with following:
suppliers table: supplier_id, name
prices table: id, product_id, supplier_id, timestamp
However in this case if we have 5 suppliers we get 5 records created for 1 products every single day so let's imagine that we have only 1000 products and want to keep historic data for last 6 months - such table would grow very rapidly
So to summarize - which approach is better or maybe there is a different one that I could implement? Thanks a lot for any suggestions.
You should go with variant 2. It's best practice to avoid frequent table restructure, which you would have to do in variant 1 any time you add or remove a supplier (although MySQL is fairly fast at this in recent versions). Using a single column to identify the distinct supplier values is better. It also promotes query reuse when you don't have to worry about column values changing or being dropped altogether. Also, space shouldn't really be a concern. To give you an idea, if your prices table had 1,000,000 rows (6 months), it would be about 40-50M in size (assuming only a primary key index). MySQL also offers compression and partitioning to reduce storage as well, if that's really a concern.

Mysql tables link with each other

I will create 3 tables in mysql:
Movies: id-name-country
Tv-Series: id-name-country
Artists: id-name-country
Instead of entering country information into these tables seperately, i am planning to create another table:
Countries: id-country
And i will make my first three tables take country data from Countries table. (So that, if the name of one country is misspelled, it will be easy just to correct in one place. Data in other tables will be updated automatically.
Can i do this with "foreign keys"?
Is this the correct approach?
Your approach so far is correct, ONLY IF by "country" in Tv-Series and Artist you mean country ID and NOT a value. And yes you can use foreign keys (country id in tv-series and artist is a foreign key linking to Countries);
Edit:
Side note: looking at your edit I feel obliged to point out that If you are planning to link Movie/TV-Show with artist you need a 4th table to maintain normalization you've got so far.
Edit2:
The usual way to decide whether you need tables is to check what kind of connection 2 tables or values have.
If it's 1 to many (like artist to country of origin), you are fine.
If you have Many to many, like Movie with Artist where 1 artist can be in multiple movies and 1 movie can have multiple artists you need a linking table.
If you have 1 to 1 relation (like customer_ID and passport details in a banking system, where they could be stored separately in customer and Passport tables, but joining them makes more sense because a banks only hold details of 1 valid passport for each customer and 1 passport can only be used by 1 person) you can merge the tables (at the risk of not meeting Normalization 3 criteria)

Creating a relationship between three tables

There are many ways I can think of to hack this together, but I want to know what the best practice is here:
I have three tables. Products, Pricelists and Prices.
One product can belong to many pricelists.
One pricelist can belong to many products.
This is a many to many relationship and as far as I know requires a Junction table (pricelist_products). Which works well.
Now, one product within a pricelist can have multiple prices. A product is only ever given a price once its within a pricelist.
What I've thought about here is using the ID from the junction table 'pricelist_products' as a foreign key within the prices table, but this feels really.... hacky?
Fishy example:
Product 1 - Fishing Rod.
Pricelist A - Fishermen.
Pricelist B - Fishingshop.
Pricelist A, Product 1, price 1:
(Monthly repayments option 1 (no deposit))
Pricelist A, Product 1, price 2:
(Monthly repayments option 2 (with deposit))
Pricelist A, Product 1, price 3:
(Quaterly repayments)
Pricelist B, Product 1, price 1:
(Quaterly repayments)
What I've thought about here is using the ID from the junction table 'pricelist_products' as a foreign key within the prices table, but this feels really.... hacky?
Maybe the issue here is just one of perspective. The purpose of the junction table is to uniquely define each combination within your many-to-many relationship (initially: pricelist to product). This can be achieved in the junction table with the fields product_id and pricelist_id alone, and without the surrogate key id.
Of course, if you defined your junction table with PRIMARY KEY (product_id, pricelist_id), this table would lack the ability to uniquely define combinations when price is considered. So you add a third id to the junction table. It appears you were looking at this field as a necessary surrogate key when defining a relationship between only two tables. However, since the real utility of this field relates to the third table, you might name it price_id instead, name your junction table pricelist_product_price, and define the primary key on all three fields (for example). This more clearly demonstrates the purpose of each field, and so may not feel "hacky" in practice.
I don't know if this is a best practice for database design, but keep in mind that there is no reason you must fully normalize every database. You want good performance with reasonable amount of flexibility and scalability (this can mean one thing for a casual blog, and quite another thing for a small business), and that can often be achieved with some degree of non-normalized design.
Edited to add: Okay, there is one other change I forgot to mention that would fall under "good" design or best practices. In your picture, you have two ID fields in the price table where one would be sufficient. As #Gilbert Le Blanc pointed out, you should try to avoid ambiguous field names like having multiple id fields, even if they are in different tables. This will help you see the utility of your fields, identify natural keys, and eliminate redundancies.
If you would not use anywhere else the relation between products and price lists but for prices then an alternative design is like this:
-Table products with fields: id, others
-Table pricelists with fields: id, others
-Table prices with fields: id (autoincrement), product_id, pricelist_id, price
and you would define index (not unique) on the pair of fields product_id, pricelist_id

Did I overdesign my MySQL database (users/companies/products)?

I'm new to database design,
please give me advice about this.
1 When should I use a composite index?
im not sure what does index does, but
i do know we should put it when it
will be heavly loaded like for WHERE
verified = 1 and in search like
company.name = something. am i right ?
2 MySQL indexes - how many are enough?
is it just enough ?
3 Database Normalization
is it just right?
Thanks.
edit*
rules.
each users( company member or owners ) could be a member of a
company
each company have some member of users.
there are company admins ( ceo, admins) and there are company members
( inserts the products )
each company can have products.
for the number 3 i will add a bit at users_company
- 1 is for admin
- 0 is for members
Looks good, well normalised, to me at least.
I notice that each product can only belong to one company. If that's what you intended that's fine, otherwise you could have product have its own PID and have a product_company relation table, which would let more than one company sell a particular product. Depends who administers the products I guess.
I did notice that the user table is called 'users' (plural) and the others are singular ('company', 'product'). That's only a minor thing though.
The only comment I have is that you may want to consider just adding a mapping_id column to your users_company table and making CID and UID foreign keys, and add a UNIQUE constraint.
This way you can have a distinct Primary Key for records in that table which isn't dependent on the structure of your other tables or any of your business logic.

DB schema question, products types

My question is how to model transactions for different types of products.
So there is a Transactions table:
TransactionId(pk)
Amount
Method
AuthorisedBy(fk)
And there are different tables for different types of products.
Books table:
BookId(pk)
Name
Description
Price
And a Pens table:
PenId(pk)
Color
Description
Price
And a table for pencil sharpening services:
SharpenId(pk)
Description
Price
Now my question is linking the transactions with the particular id's of the different items.
One method was to have in the transaction table:
TransactionId(pk)
Amount
Method
AuthorisedBy
ProductType
ProductTypeId(fk)
Where product type would refer to the title of the table, eg Books and the product id would refer to the BookId in that case.
OR another method would be to have a linking table of 'products' that refer to each different id of the other tables, so the Transaction table would look like this:
TransactionId(pk)
Amount
Method
AuthorisedBy
ProductID(fk)
and the products table would look like this:
ProductId(pk)
PoductType
ProductTypeId(fk)
But then this is a table that is exactly the same as the transactions table. So my question is how do I efficiently link the different product type tables to the transactions?
Please note I am not modelling a school pencil sharpening service, they're just examples :P
First of all i dont like the DB model. You need only one table for product definition that can hold columns that describes every product:
(table)Products: ID - PK, Name, Description, Color, Price, ProductTypeID - FK
You need additional table that explain the type of the product, it's category let say:
(table)ProductTypes: ProductTypeID - PK, ProductTypeName
And for registering transactions you will need only one table:
(table)Transactions: TransactionID, ProductID - FK, Amount, Method, AuthorizedBy
I think this schema will be OK for you to resolve your issue.
Happy coding.