How to tie up MySQL tables properly - mysql

I have browsed a similar topics at Stackoverflow but haven't found the solution I'm looking for. Please give me an idea how to organise the tables relation. I have 2 tables: the one contains contractor's names and number of contracts for each contractor, the second have invoice's data (like number, amount, date) which relates to each contractor. How should I have to connect these two table correctly? I have an idea to store in the first table contartor's ID,contractor's name and number; in the second - contractor's ID and all invoces' details. But should I store all the invoices' data in one table or create separate table (with invoice's data) for each contractor? I'm newcomer in db-issues and have no enough experience in it. I would appreciate any suggestions.

You're doing it correctly. It'd be best to have two tables as the data will be less redundant giving your more efficient space usage.
As an example:
CONTRACTOR TABLE
ID NAME PHONE
----------------------------------
1 TEST1 619-123-4567
2 TEST2 619-234-5678
INVOICE TABLE
ID CONTRACTOR_ID AMOUNT DATE
----------------------------------------------------------------
1 1 150.00 2014-04-17 00:00:00
2 1 150.00 2014-04-18 00:00:00
So in the example table, I have two contractors. The first one, named TEST1, has two invoices linked to them in the INVOICE table.
If you're worried about performance, all I would suggest is to add indexes on both tables and foreign keys linking the contractors information with the invoices by the contractors ID.

The two tables should be correct
Contractor
NumberOfContact NameOfContact
Invoice Data
Number Amount Date
The Number of the invoice table would be a FK to contractor Number and if that person were to have multiple entries into the invoice table it would be identified by the date.

Your line of thinking is correct. The script would be like this:
CREATE TABLE `contractor` (
`id` INT NOT NULL,
`name` VARCHAR(45) NOT NULL,
PRIMARY KEY (`id`));
CREATE TABLE .`invoice` (
`number` INT NOT NULL,
`amout` INT NOT NULL,
`date` DATE NOT NULL,
`id_contractor` INT NOT NULL,
PRIMARY KEY (`number`),
INDEX `fk_invoice_1_idx` (`id_contractor` ASC),
CONSTRAINT `fk_invoice_1`
FOREIGN KEY (`id_contractor`)
REFERENCES `contractor` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION);

Related

many to many relationship in mysql have to be the foreign keys the primary keys from both tables connections tables?

Lets says that I have an order table and item table :
CREATE TABLE if not exists ORDERS (
ORDERID INTEGER AUTO_INCREMENT,
ORDERTYPE VARCHAR (20) NOT NULL,
ShippedTime VARCHAR(40),
ORDERDATE DATE,
PRIMARY KEY (ORDERID),
);
CREATE TABLE if not exists ITEM(
ITEMID INTEGER AUTO_INCREMENT,
NAME VARCHAR (20) NOT NULL,
PRICE INTEGER NOT NULL CHECK (PRICE > 0),
PRIMARY KEY (ITEMID)
);
and the relation between the both tables will be existof :
CREATE TABLE if not exists EXISTOF (
ORDERID INTEGER NOT NULL,
ITEMID INTEGER NOT NULL,
FOREIGN KEY (ORDERID) REFERENCES ORDERS(ORDERID) ON DELETE CASCADE,
FOREIGN KEY (ITEMID) REFERENCES ITEM(ITEMID) ON DELETE CASCADE,
PRIMARY KEY (ORDERID,ITEMID)
);
The explanation should be for each order has multiple item and each item belongs to many orders.
If I do like this it will not be work because the ids are primary keys and I can't insert for specific order multiple item and also it can not items belongs to multiple order.
Does anyone have any recommendation how to do that?
Your Existof Table is not flexible enough. The way most order processing systems deal with this situation is to add a column, which we can call Quantity, to the Existof table. The default value is 1, but other quantities can be put in as well.
So if a given order wants to order say 5 reams of paper,and ream of paper in a product, the entry for this item in Existof will have a quantity of 5.
This assumes that all 5 reams are interchangeable, and therefore described by the same data. If some of the paper reams are of different colors, than they ought to be different products.
Create an intermediate table OrderItems with foreign keys item_id and order_id. There are other options but this is the easiest way I find to break down many-many relationships!
"... have to be ..." -- no. FOREIGN KEYs are never "required".
A FK provides three things:
A dynamic check that there is a matching element. This is useful as an integrity check on the data, but is not mandatory.
An INDEX to make the above check significantly faster. Manually specifying an INDEX is just as good. Anyway, a PRIMARY KEY is an index.
"Casscading delete, etc". This is an option that few schemas use, or even need.
There are 3 main types of "relations" between tables:
1:1 -- But why bother having two tables? The columns could simply be in a single table. (There are exceptions.)
1:many -- (This sounds like "many items in one order"??) That is implemented by simply having order_id in the Items table. (And index that column.) Optionally, it can be a FK. Others call the table OrderItems. And it links to a Products table.
many:many -- This is when you need an extra table with (usually) exactly two columns, namely ids into the other two tables. (Eg, Student vs class) Each column could be an FK, but the optimal indexes are PRIMARY KEY(a_id, b_id) and INDEX(b_id, a_id). The FKs would see that you already have indexes starting with a_id and b_id, so it would not create an extra index. Do not have "a unique junction table ID"; it is less efficient than the PK I suggest here. (More discussion: http://mysql.rjweb.org/doc.php/index_cookbook_mysql#many_to_many_mapping_table)
Back to your proposed design. I suggest that "item" implies the product and quantity of that product and the price charged at that time. Hence it needs to be 1:many. And that "product" is what you are thinking of. Please change the table name so I am not confused.
Now, another issue... Price. Is the price fixed forever? Or is the price going to be different for today's Orders than for yesterday's? Again, the Item and Price are tied to one Order. There may be a Price on the Product table, and that may be "current_price", which gets used when creating new Orders.
ShippedTime VARCHAR(40) -- Perhaps should be DATETIME?

How can I store orders with multiple products and quantity of each product in a mysql database?

I've made a simple shopping cart with PHP and AJAX. You can add multiple products to it and you can set the quantity of each product.
It might be a silly question, but honestly, I don't really know how should I store these orders in the mysql database, with all the multiple products per order and the quantity of each product per order.
Can someone help me please?
EDIT: I learned a lot about databases, I know about relations, I just don't know how should I do this correctly.
You should use aggregation table
That means, you have to create a table where primary key is combination of 2 foreign keys, one is a primary key of order, 2nd is primary key of product
and then, you have extra fields in table like count
That means you have a unique key for each row in table, because it is combination of order and product
But I have to say, this is literally basic knowledge of SQL databases
1 Create a PRODUCTS table with a PRODUCT_ID as primary key.
2 Create a ORDERS table with a ORDER_ID as primary key.
3 Create a ORDER_LINES table with foreign keys ORDER_ID and PRODUCT_ID.
The latter will have a column QUANTITY.
Let's say you have Products Table that contains the following columns
(ProductID, ProductName, Qty). and you want to sell many products to many customers. a many-to-many relationship in the database, you just need to add two more tables to your database.
The first table and let's assume it's called [Cart] in which you're going to store the Cart ID, Customer ID.
CREATE TABLE [dbo].[Cart](
CartID int NOT NULL,
CreatedDate datetime NULL, --to get the current date and time
CustomerID int NULL,
PRIMARY KEY (CartID)
)
The second table and let's assume it's called Cart_Detail in which we're going to store the ordered products and the quantity of each product.
CREATE TABLE [dbo].[Cart_Detail](
LineID int IDENTITY(1,1) NOT NULL,
CartID int NULL,
ProductID int NULL,
Price decimal(18, 2) NULL,
Qty int NULL,
Amount decimal(18, 2) NULL
) ON [PRIMARY]
LineID column is to facilitate the creation of views and operations such as selecting, updating, or deleting a specific product

Relationships midst two tables?

I have table visitors and table users. Each visitor can be created by only one user and contains field visitors.userId.
So, any another user from table users can edit or delete one or more visitors.
I have created a third table events_log for logging actions like edit/delete:
Visitors_log
id | userId | visitorId | action
This table stores information about user who did actions over table visitors.
Which relationship should be between table visitors_log and rest two: users and visitors?
Now I have this Db scheme:
My opinion is: visitors_log can have one or more rows. So relations is one to many. In the same time visitors_log can contain one or more users. So, where I am wrong? Now it is one to one relation.
Is there a possibility that the user_id of a visitor could ever change ?
If the answer is yes, then you would better take the safe approach and have two foreign keys in the log, referencing the concerned visitor and the user that commited the action.
In MySQL :
CREATE TABLE visitors_log (
idVisitorLog INT AUTO_INCREMENT,
idVisitor INT NOT NULL,
idUser INT NOT NULL,
action VARCHAR(100) NOT NULL,
date_action DATETIME NOT NULL,
PRIMARY KEY (idVisitorLog),
FOREIGN KEY (visitor_log_idVisitor) REFERENCES visitors(idVisitor),
FOREIGN KEY (visitor_log_idUser) REFERENCES users(idUser)
);
PS : you probably want a date column too in the log table, I added one.
On the other hand, if the user a visitor is assigned to can never change over time, then your design can be simplified. In the log table, you could just store a foreign key to the visitors table. As the visitor stores a (fixed) user id, you do not need to duplicate that information in the log.

How can the data on the transaction still be used when the product has been deleted

enter image description here
I have a problem regarding transaction data in the reports of products that have been sold. Constraints that occur if the product has entered the transaction / order but the product in question has been deleted.
How do I make the transaction report can still be used with the product that was deleted earlier?
Thanks.
Perhaps the best way to handle this possibility would be to add constraints to the tables involved which would make it not possible to delete a product row if an extant order exists which uses that product. Here is what the table definitions for Products and Order_Items might look like:
CREATE TABLE Order_Items (
order_item_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
order_id INT NOT NULL,
product_id INT NOT NULL,
...
FOREIGN KEY fk_prod (product_id) REFERENCES Products (product_id)
)
CREATE TABLE Products (
product_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
product_name VARCHAR(255) NOT NULL,
...
)
With this design in place, should someone attempt to delete a product record from the Products table while there exists on or more order item records referring to that product, the delete attempt would fail.
If a row in the Products table is used for two things, namely for purchasing the product and for reporting on a historical transaction, then you can never actually delete the row.
You might flag it in various ways: "available_for_purchase", "inventory = 0", "no_longer_produced", etc.

many to many table relationship dilemma

by constructing a brigde table I would link many salesman and group together
I've made three table like below
salesman
========
uId
salesGroupLinked
================
uId
groupId
group
======
groupId
so it should be able to allow 1 salesman can have many groups and also many groups can own by 1 salesman. But now I thought of expand the relationship.
Says I want each salesman can have their performances score for each group. Where should I put the column? If it's at group table then it's obsoleted, because groupId is unique, so it may give a score to many salesman.
Just by thinking about the problem: What is the key of the performance score? It is settings of one salesman's group. So, the settings should be on the table where they are linked. It will be unique for each pair of (salesman, group).
So the table would look like
salesGroupLinked
================
uId
groupId
PerformanceScore
put the score in the link table.
The pk on that table should still be uId and groupId, but it should also have a column for the score.
EDITED to shopw DDL statements to Create table with Primary Key
create table salesGroupLinked
( uId integer not null,
groupId integer not null,
performanceScore integer null,
Constraint PK_salesGroupLinked Primary Key clustered (uId, groupId)
)
The composite PK for this table itself guarantees that there can never be more than one row in this table with the same values for uId and groupId.