PHP MySQL add another row function - php

I am starting to learn PHP;
i have two tables in my database:
the Brands List that contains Brand_ID, Brand_Name, and
Brand_Description.
the Product Lines List that contains Line_ID, Line_Name.
i want to create a third table named Offered Products that contains Offer_Id, Brand_ID, Line_Name - how can i manage this using Foreign Keys?
After creating the table, i want to create a php page that will let users to populate the third table by
Selecting a brand from a dropdown list
Selecting a Line Name from a drop down List
Beside it has a button "Add Row" - which when click will display
another row below the first one in order to do number 1 and 2 again
and so on
A save button is also present which when clicked will finally save
the record on my database.
how can i exactlydo this? please help

Creating the table.
Your third table would only need to store Line_ID and Brand_ID and (for whatever reason) you also want Offer_ID.
CREATE TABLE `Offered Products` (
/* define columns */
Offer_ID INT NOT NULL AUTO_INCREMENT,
Brand_ID INT NOT NULL,
Line_ID INT NOT NULL,
/* define primary key */
PRIMARY KEY (Offer_ID)
/* define foreign keys */
FOREIGN KEY Brand_ID (Brand_ID)
REFERENCES `Brands List` (Brand_ID)
FOREIGN KEY Line_ID (Line_ID)
REFERENCES `Lines List` (Line_ID)
);
This assumes that the Lines List table (with a space) and Brand List table have Line_ID and Brand_ID respectively defined as primary keys.
Creating the form.
Design the form with HTML and PHP. Have each list populated from the corresponding table. I'm not going to provide code for this; it should be straight forward.
Inserting into the table.
INSERT INTO `Offered Products` (Brand_ID, Line_ID) VALUES (###, ###)
The ### represents the ID numbers from the HTML form.
Joining the tables.
To obtain information from all of the tables you can join as below.
SELECT * FROM `Offered Products` as op
JOIN `Brand List` as bl ON bl.Brand_ID = op.Brand_ID
JOIN `Line List` as ll on ll.Line_ID = op.Line_ID
Other Notes.
To use foreign keys in MySQL you need to be using the InnoDB engine. Using myisam will not allow foreign keys, but you can still join the tables as demonstrated to achieve a similar result.
Avoid using spaces in your table names if you actually did that.

Related

To get 2 primary keys from different tables in mysql

I'm doing my final year project and planning to do comment feature on my system. The customer that have purchased the meal only can comment or give feedback about that particular meal. So, I need to get the Meal_ID and Cust_ID from table 1 and table 2 in order to keep track who's comment on what meal. I just want to ask is it possible to select multiple primary keys from different tables in one sql query? Thanks in advance!
I have 3 table as shown below.
Foreign Key:
Example:
CREATE TABLE Orders
(
O_Id int NOT NULL,
OrderNo int NOT NULL,
P_Id int,
PRIMARY KEY (O_Id),
FOREIGN KEY (P_Id) REFERENCES Persons(P_Id)
)
Description: The following SQL creates a FOREIGN KEY on the "P_Id" column when the "Orders" table is created:
Fetching Data:
Ya it it possible to select two Primary keys from a single select statement with the help of JOIN Query so that you can combine both the tables and you can get the result with the help of single query.
There are different types of Join available and you can use any such method:
JOIN
Left JOIN
Right JOIN

How to create a database model with multiple products in one order

I'm setting up a model of an SQL database that keeps track of an order with multiple products that have a certain quantity.
The table has to have a key value that is specific for that order and never repeats anywhere else in the table.
I'm thinking of making a row that has an orderID as key value, then an Order tab that has the productID and quantity like this "ProductID-Quantity" so that it can be placed in one cell. The tricky part is taking multiple different products in this row. It can be done inserting all the products with their quantities in one cell like this:
"1100-3, 1500-1, 1600-8"
So this is one cell with three products ordered 3, 1 and 8 times. Reading it in in PHP seperating them with a comma and a dash.
Is there any way to do this more effectively?
What you describe sounds like a "many to many" relationship. One order can hold many products but one product can be part of many rows as well.
For this you can create a table orders (in which additional info may be stored, eg. the userid it belongs to) and have your products table as well.
Now you connect them via something like this
CREATE TABLE order_products (
orderid INT NOT NULL,
productid INT NOT NULL,
quantity INT NOT NULL,
PRIMARY KEY (orderid, productid),
FOREIGN KEY (orderid) REFERENCES orders (id),
FOREIGN KEY (productid) REFERENCES products (id)
);
To select get all rows with their products, simply use a JOIN.

New table or field with array in field (php/mysql)

I need to store multiple id's in either a field in the table or add another table to store the id's in.
Each member will basically have favourite articles. Each article has an id which is stored when the user clicks on a Add to favourites button.
My question is:
Do I create a field and in this field add the multiple id's or do I create a table to add those id's?
What is the best way to do this?
This is a many-to-many relationship, you need an additional table storing pairs of user_id and article_id (primary keys of user and article tables, respectively).
You should create a new table instead of having comma seperated values in a single column.
Keep your database normalized.
You create a separate table, this is how things work in a relational database. The other solution (comma separated list of ids in one column) will lead to an unmaintainable database. For example, what if you want to know how many times an article was favorited? You cannot write queries on a column like this.
Your table will need to store the user's id and the article's id - these refer to the primary keys of the corresponding tables. For querying, you can either use JOINs or nested SELECT queries.
As lafor already pointed out this is a many-to-many relationship and you'll end up with three tables: user, article, and favorite:
CREATE TABLE user(
id INT NOT NULL,
...
PRIMARY KEY (id)
) ENGINE=INNODB;
CREATE TABLE article (
id INT NOT NULL,
...
PRIMARY KEY (id)
) ENGINE=INNODB;
CREATE TABLE favorite (
userID INT NOT NULL,
articleID INT NOT NULL,
FOREIGN KEY (userID) REFERENCES user(id) ON DELETE CASCADE,
FOREIGN KEY (articleID) REFERENCES article(id) ON DELETE CASCADE,
PRIMARY KEY (userID, articleID)
) ENGINE=INNODB;
If you then want to select all user's favorite articles you use a JOIN:
SELECT * FROM favorite f JOIN article a ON f.articleID = a.id WHERE f.userID = ?
If you want to know why you should use this schema, I recommend reading about database normilization. With multiple IDs in a single field you would even violate the first normal form and thus land in a world of pain...

MySQL auto-increment between tables

In MySQL, is it possible to have a column in two different tables that auto-increment? Example: table1 has a column of 'secondaryid' and table2 also has a column of 'secondaryid'. Is it possible to have table1.secondaryid and table2.secondaryid hold the same information? Like table1.secondaryid could hold values 1, 2, 4, 6, 7, 8, etc and table2.secondaryid could hold values 3, 5, 9, 10? The reason for this is twofold: 1) the two tables will be referenced in a separate table of 'likes' (similar to users liking a page on facebook) and 2) the data in table2 is a subset of table1 using a primary key. So the information housed in table2 is dependent on table1 as they are the topics of different categories. (categories being table1 and topics being table2). Is it possible to do something described above or is there some other structural work around that im not aware of?
It seems you want to differentiate categories and topics in two separate tables, but have the ids of both of them be referenced in another table likes to facilitate users liking either a category or a topic.
What you can do is create a super-entity table with subtypes categories and topics. The auto-incremented key would be generated in the super-entity table and inserted into only one of the two subtype tables (based on whether it's a category or a topic).
The subtype tables reference this super-entity via the auto-incremented field in a 1:1 relationship.
This way, you can simply link the super-entity table to the likes table just based on one column (which can represent either a category or a topic), and no id in the subtype tables will be present in both.
Here is a simplified example of how you can model this out:
This model would allow you to maintain the relationship between categories and topics, but having both entities generalized in the superentity table.
Another advantage to this model is you can abstract out common fields in the subtype tables into the superentity table. Say for example that categories and topics both contained the fields title and url: you could put these fields in the superentity table because they are common attributes of its subtypes. Only put fields which are specific to the subtype tables IN the subtype tables.
If you just want the ID's in the two tables to be different you can initially set table2's AUTO_INCREMENT to some big number.
ALTER TABLE `table2` AUTO_INCREMENT=1000000000;
You can't have an auto_increment value shared between tables, but you can make it appear that it is:
set ##auto_increment_increment=2; // change autoinrement to increase by 2
create table evens (
id int auto_increment primary key
);
alter table evens auto_increment = 0;
create table odds (
id int auto_increment primary key
);
alter table odds auto_increment = 1;
The downside to this is that you're changing a global setting, so ALL auto_inc fields will now be growing by 2 instead of 1.
It sounds like you want a MySQL equivalent of sequences, which can be found in DBMS's like PosgreSQL. There are a few known recipes for this, most of which involve creating table(s) that track the name of the sequence and an integer field that keeps the current value. This approach allows you to query the table that contains the sequence and use that on one or more tables, if necessary.
There's a post here that has an interesting approach on this problem. I have also seen this approach used in the DB PEAR module that's now obsolete.
You need to set the other table's increment value manually either by the client or inside mysql via an sql function:
ALTER TABLE users AUTO_INCREMENT = 3
So after inserting into table1 you get back the last auto increment then modify the other table's auto increment field by that.
I'm confused by your question. If table 2 is a subset of table 3, why would you have it share the primary key values. Do you mean that the categories are split between table 2 and table 3?
If so, I would question the design choice of putting them into separate tables. It sounds like you have one of two different situations. The first is that you have a "category" entity that comes in two flavors. In this case, you should have a single category table, perhaps with a type column that specifies the type of category.
The second is that your users can "like" things that are different. In this case, the "user likes" table should have a separate foreign key for each object. You could pull off a trick using a composite foreign key, where you have the type of object and a regular numeric id afterwards. So, the like table would have "type" and "id". The person table would have a column filled with "PERSON" and another with the numeric id. And the join would say "on a.type = b.type and a.id = b.id". (Or the part on the "type" could be implicit, in the choice of the table).
You could do it with triggers:
-- see http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_last-insert-id
CREATE TABLE sequence (id INT NOT NULL);
INSERT INTO sequence VALUES (0);
CREATE TABLE table1 (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
secondardid INT UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (id)
);
CREATE TABLE table2 (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
secondardid INT UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (id)
);
DROP TRIGGER IF EXISTS table1_before_insert;
DROP TRIGGER IF EXISTS table2_before_insert;
DELIMITER //
CREATE
TRIGGER table1_before_insert
BEFORE INSERT ON
table1
FOR EACH ROW
BEGIN
UPDATE sequence SET id=LAST_INSERT_ID(id+1);
NEW.secondardid = LAST_INSERT_ID();
END;
//
CREATE
TRIGGER table2_before_insert
BEFORE INSERT ON
table2
FOR EACH ROW
BEGIN
UPDATE sequence SET id=LAST_INSERT_ID(id+1);
NEW.secondardid = LAST_INSERT_ID();
END;
//

Choose an index for mysql table

The table
I got a table that contains price for some 1 000 000 articles. The articles got a uniques ID-number but the table contains prices from multiple stores. Thus if two stores got the same article the uniques ID will not be unique for the table.
Table Structure
table articles
id INT
price IN
store VARCHAR(40)
Daily use
Except for queries using the ID-number by users I need to run daily updates where data from csv-files insert/update each article in the table. The choosen procedure is to try to select an article and then perform either an insert or an update.
Question
With this in mind, which key should I choose?
Here are some solutions that Ive been considering:
FULLTEXT index of the fields isbn and store
Add a field with a value generated by isbn and store that is set as PRIMARY key
One table per store and use isbn as PRIMARY key
Use a compound primary key consisting of the store ID and the article ID - that'll give you a unique primary key for each item on a per-store basis and you don't need a separate field for it (assuming the store id and article id are already in the table).
Ideally you should have 3 tables... something like:
article
--------------------------------------------
id | isbn | ... etc ...
store
--------------------------------------------
id | description | ... etc ...
pricelist
--------------------------------------------
article_id | store_id | price | ... etc ...
With the PRIMARY KEY for pricelist being a compound key made up of article_id and store_id.
EDIT : (updated to incorporate an answer from the comment)
Even on a million rows the UPDATE should be OK (for a certain definition of OK, it might still take a little while with 1 million+ rows) since the article_id and store_id comprise the PRIMARY KEY - they'll both be indexed.
You'll just need to write your query so that it's along the lines of:
UPDATE pricelist SET price = {$fNewPrice}
WHERE article_id = {$iArticleId}
AND store_id =` '{$sStoreId}'
Though you may want to consider converting the PRIMARY KEY in the store table (store.id - and therefore also pricelist.store_id in the pricelist table) to either an unsigned INT or something like CHAR(30).
Whilst VARCHAR is more efficient when it comes to disk space it has a couple of drawbacks:
1: MySQL isn't too keen on updating VARCHAR values and it can make the indexes bloat a bit so you may need to occasionally run OPTIMIZE TABLE on it (I've found this on an order_header table before).
2: Any (MyISAM) table with non-fixed length fields (such as VARCHAR) will have to have a DYNAMIC row format which is slightly less efficient when it comes to querying it - there's more information about that on this SO post: MySQL Row Format: Difference between fixed and dynamic?
Your indexes should be aligned with your queries. Certainly there should be a primary key on the articles table using STORE and ID - but the order in which they are declared will affect performance - depending on the data in the related tables and the queries applied. Indeed the simplest solution might be PRIMARY KEY(STORE, ID) and UNIQUE KEY(ID, STORE) along with foreign key constraints on the two fields.
i.e. since it makes NO SENSE to call this table 'articles', I'll use the same schema as CD001:
CREATE TABLE pricelist (
id INT NOT NULL ,
price INT,
store VARCHAR(40) NOT NULL
PRIMARY KEY(store,id),
UNIQUE KEY rlookup (id, store)
CONSTRAINT id FOREIGN KEY articles.id,
CONSRAINT store FOREIGN KEY store.name
);
Which also entails having a primary key on store using name.
The difference between checking a key based on a single column and one based on 2 columns is negligible - and normalising your database properyl will save you a LOT of pain.

Categories