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
Related
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.
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".
Lets consider three tables :
1.Companies
id
company_name
...
2. Employees
id
employee_name
...
3. Payment
id
pay_by
pay_to
...
Now the problem is here pay_to can be id of a Company or an Employee (fk). So I have added a Boolean column "is_company" in the Payment Table. So my solution is if is_company is True then its Company otherwise its Employee.
But I am not satisfied with this solution. I mean I don't want to have a column which has multi table foreign key. I think there has a better solution but I could not find that. Please help to find a better solution. Thanks in advance.
You could, depending on what you using to interact with the database, prefix the pay_to with a letter, e for employee or c for company however then you can't specify that the field is an int etc which may cause issues.
One alternative is to use different ranges (this would obviously limit the number of each you could have) but you could say 0-9999999 is employees and 10000000+ is company ID's.
Another alternative would be to have an interim table (called payees for example) where pay_to references a row in that table which gives you a payee type and then the payee's ID in their respective table.
--EDIT--
You could create a table called payees with columns such as payee_id, payee_type, id. payee_id would be an auto increment column that you would then reference in the payment.pay_to field. payee_type would be company/employee and then id would either be company.id or employee.id depending on the type. It would mean using 2 queries rather than using a join but that is true with any of the possibilites unless you could combine companies and employees in to one table - this would depend on the other columns beyond what you have detailed in your original question.
None of them are necessarily elegant (and there may and probably are other) solutions, but they would be the 3 I would look at using in your situation!
to build on what Ed Wade said, you could prefix all companies with a 1 and all employees with a 2. This would help with keeping the field as an integer while not limiting the number you could store
How do I represent invoices into an MySQL table structure?
The invoice table has the following fields:
id
customer_id
services
tax
total_price
date
...
Now the services can contain one or more articles and, what makes it complicated, various prices. The actual price of a service is negotiated, there are seldom fixed prices because each customer has individual requirements. These items have to be listed on the invoice and the prices of each have to be listed and summarized + tax.
What is the best practice for this purpose? I want to make it normalized if possible, something more sophisticated than just saving an (serialized) array of service => price into the service field, if this is possible at all. Do I use a second table for each service + price and hold a list of IDs with foreign keys?
I think you should follow Has And Belongs To Many relationship. Fr that you use two more tables for this one is 'services' and other is 'invoice_services'
'services' table contain service info and its price etc.
'invoice_services' table will be the join table for 'invoice' and 'services' tables. 'invoice_services' table will contain 'service_id' and 'invoice_id'.
Then you can remove the column 'services' from 'invoice' table.
If you want to maintain negotiable price for each service, then you can add one more field 'custom_price' in 'invoice_services' table.
Then using joins you can fetch the relative data of any invoice.
Hope this may help :)
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.