Handle (non)existing data - mysql

I have a table which consists of columns for users, categories and amount.
A user can buy an amount products from each category. I want to store only the very last purchase.
User Category Amount
1 100 15
1 103 25
Imagine that this user has just bought 30 pieces from 100 or from 110. Either additional category or a new category. This can be handled using following pseudo code:
SELECT amount FROM table WHERE user=1 AND category=100
if row exists
UPDATE table SET amount=30 WHERE user=1 AND category=100
else
INSERT INTO table (user, category, amount) VALUES(1, 100, 30)
The other way to do is, just always deleting the old value (ignoring the error message when not exists( and always inserting a new one.
DELETE FROM table WHERE user=1 AND category=100
INSERT INTO table VALUES(1, 100, 30)
Which of these patterns is preferred from performance point of view?
Does it matter which PK and FK exists?

mysql supports replace, so no need of delete insert or update. But this one assumes a unique key or primary key on your table as reference
REPLACE
INTO yourtable (user, category, amount)
VALUES (1, 100, 30);

Related

insert into 2column table, avoiding duplicate records

I have a table with 2 columns, userid and messageid. I am updating it automatically through a php script, but I can't get a working insert statement. I don't mind if there are duplicates of userid, or duplicates of messageid (in fact there should be duplicates of both), I just don't want any duplicate of the same combination of userid and messageid. Is there any way to write a query that will do this for me, or do I have to handle it at the php level?
I've probably tried 20 different queries that I found on here and google, but have not gotten it right. This was the last thing I tried:
INSERT INTO interests_join (userid, interestid)
VALUES (1, 4)
WHERE NOT EXISTS
(SELECT userid, interestid FROM interests_join WHERE userid = 1 AND interestid = 4)
You can add a UNIQUE KEY, sql will refuse to insert a new row that is a duplicate of an existing one.
ALTER TABLE `interests_join` ADD UNIQUE `row` (`userid`, `interestid`);
Then you'll have to check from PHP if the query was successful or not (error #1062). You can't apply the key if there are duplicate rows, you have to remove them first .

MYSQL auto_increment insert statement from two foreign keys

.
I'm making a database for my final year project at my University and i'm currently stuck.
I have three tables :product, customer and product_order.
product has an auto_incremented primary key product_ID
and customer also has an auto_incremented primary key customer_ID.
product_order table is where my problem lies( iknow that mysql doesn't support #insert and #scope_identity, also #last_insert_id doesn't work for me )
I have two foreign keys both from product and customer table inside here (which are auto_increment ids and using the variable I saw online
SELECT #last := LAST_INSERT_ID();
only returns the last id from the product_ID and customer_ID.
I have these insert statements:
insert into Product values(1000 ,'Logitech Webcam C270 HD mic USB', 260, 5, 'Accessory');
insert into customer VALUES(2000, 'Rachel ' , 'Mc Roy' , 'Rach#gmail.com', 'female','1985/06/05','wlovely8', '41, Cantubury Lane, San Franscique', 2938493);
insert into product_order values(#last_id_in_Customer, #last_id_in_Product, 'Logitech Webcam C270 HD mic USB', 260, 1);
i am inserting the id's to set the range of where i want the id's to fall into; hence the reason why i put 2000 and 1000; in the other inserts I utilized null to insert the data into the table automatically
select * from product_order;
2001 2001 Logitech Webcam C270 HD mic USB 260 1
My output from the query i only get to insert once because the #last variable only returns once.
So my question : is there a better way of doing this?
Btw this is for a customer login webpage, so the customer wouldn't have to enter a unique primary key.
Yes ,there is a better way of doing this Assuming that when customer is registered he will get customer_id auto-incremented ,when customer log in to system store that in session variable and whenever he selects any product ,retrieve the customer_id from session and product_id from product table and add it in order_product table

How do I keep the same auto-incrementing ids when inserting data into the same table across servers/databases in MySQL?

I have a lookup table that has 3 rows:
id | name
=== =======
1 Pendig
2 Sent
3 Failed
When I insert this data into the another table on another server/database, how can I ensure the same values (names) are created with the same auto-incrementing ids?
Since it is a lookup table, can I just insert into the table and specify the id?
You can always overwrite the insert ID in an auto_increment table by specifying it:
INSERT INTO yourtable (id, name) VALUES (2, 'Sent');
and 2 will be stuff into the table as the ID value. This works perfectly until any OTHER inserts are performed and the table's built-in auto_increment value happens to come up to a value that you yourself inserted, e.g, assuming a brand new freshly created table:
INSERT INTO yourtable (id, name) VALUES (2, 'Sent'); // force an ID
INSERT INTO yourtable (id, name) VALUES (NULL, 'foo'); // DB assigns 1
INSERT INTO yourtable (name) VALUES ('foo'); // DB assigns 2
The first query succeeds, the second query succeeds, the third query fails with a primary key violation, because the DB-generated '2' id now conflicts with the one you inserted manually.
If you want to ensure ID and auto_increment compatibility between different DB instances, then use mysql_dump to spit out the table for you. It'll ensure that all the IDs in the table are preserved, and that the internal auto_increment pointer is also sent across properly.
Since you have the lookup table to begin with it should be irrelevant what the id actually is. That is to say that you should never look at the id itself and only use it for joins and the like. If you want to look up this transparent id, you should use the name.
To answer your specific question, yes you can specify auto increment IDs during inserts:
INSERT INTO t1 (id, name) VALUES (1, 'Pendig')

Multiple vote options storing in MySQL table

I have a poll which has an undefined number of options (it can have only 2 options, but it can also have 10 or 20 or more options to choose from). I need to store the current vote count in MySQL table. I can't think of a centralized way of storing them except:
Create a field vote_count and store a serialized array of voting options mapped to counts.
When new vote data comes in this field is read, unserialized, appropriate values are incremented, then field is written to. This needs 2 queries and there might be 5 or more votes incoming per second.
So I need a way to store voting counts for an unknown number of voting options and be able to quickly access it (I need up to date counts for every option displayed on the voting page) and quickly update it (when new votes come in). It has to be within MySQL table. There is no "upper" limit for the number of voting options.
The normative pattern for handling multi-valued attributes, or repeating values, is to add a second table.
Consider a purchase order that can have more than one line item on it. We represent the line items in a child table, with a foreign key to the parent in the purchase order table:
CREATE TABLE `purchase_order` (id int not null, foo varchar(200), ... );
CREATE TABLE `line_item` (id int not null, order_id int not null, ... );
ALTER TABLE `line_item` ADD FOREIGN KEY (order_id) REFERENCES order(id) ;
INSERT INTO purchase_order (id, foo) VALUES (101, 'bar');
INSERT INTO purchase_order (id, order_id) VALUES (783, 101);
INSERT INTO purchase_order (id, order_id) VALUES (784, 101);
INSERT INTO purchase_order (id, order_id) VALUES (785, 101);
We can get a count of the line items associated with a purchase order, like this:
SELECT COUNT(1)
FROM line_item
WHERE order_id = 101;
Or, we can get a count of line items for every purchase order, like this:
SELECT o.id, COUNT(l.id) AS count_line_itesm
FROM purchase_order o
LEFT
JOIN line_item l
ON l.order_id = o.id
GROUP BY o.id
In your case, what are the entities you need to represent (person, place, thing, concept or event; which can be uniquely identified and you need to store information about.
I'm having difficulty conceptualizing what entities it is you are need to represent.
poll -
poll_question - a single question on a given poll
poll_question_answer - a possible answer to a question to a given poll question
voter -
ballot - associated with one voter and one poll (?)
vote - the answer given to a particular poll question
Good database design comes from an understanding of the entities and the relationships, and developing a suitable model.
Can't you just have one table of questions, and another table of possible answers (multiple rows per question, as many as you want). Then either store the counts on the table of answers, or (better) have another table of actual entered answers (this way you can log the details of the person doing the answers, and easily use SUM / COUNT to work out how many votes each option has).

MySql Update first entry that has X and Y else insert new record

I have a chat user entry in a MySql table -
id (primary key, autoincrement) - the chat user id
user_id - the users id as it pertains to our product
room_id - the id of the room your in
If a chat operator enters the room, leaves, and then comes back - as it is now - will create two entries in the room (INSERT INTO chatuser ...)
I know INSERT IF NOT EXISTS syntax, however I want to IF NOT EXISTS not on the primary key, but WHERE user_id = x AND room_id = y (which will be the same if they re-enter a room they have been in)
something like INSERT INTO chatuser SET user_id=4, room_id=2 IF ENTRY DOESNT EXIST WITH THOSE VALUES ALREADY ;)
thank you
If you have a unique index on (user_id,room_id), you can do INSERT ... ON DUPLICATE KEY UPDATE (or INSERT IGNORE if you don't need to update anything when the record already exists):
INSERT INTO table_1 (user_id, room_id, enter_date)
VALUES (1,1, NOW())
ON DUPLICATE KEY UPDATE
enter_date = NOW()
// or
INSERT IGNORE INTO table_1 (user_id, room_id)
VALUES (1,1)
I think what we have here is a design issue. You have 3 tables, a user table, a room table and a table that links that two. The last one is what we're working with here. Now, if you want to log every time a user enters a room, the table design you have is ideal. However it seems that is not what you are doing. It seems you want an entry for just the last visit. In this case your table should not have an auto incrementing primary key, and instead should have userID and roomID to both be parts of a multi-column primary key.
Modify your table to that set-up then run your insert statement with ON DUPLICATE KEY UPDATE clause.