I may have either misunderstood how to use the ON DUPLICATE KEY syntax, alternatively my database structure needs some work but here goes.
I have a table (bookings-meta) which represents meta data associated with another table (bookings) , different rows in the bookings table may or may not have specific meta data associated with them in the other table.
The bookings-meta table has the following columns, meta_id (primary key), booking_id, key and value.
From my understanding, to use ON DUPLICATE KEY I need to know what in this case is the meta_id, often this isn't the case, I'm trying to simply push a key, value pair to the table using the booking_id, so if the particular key exists then its replaced otherwise its inserted.
At the moment I have a seperate query to try to select the row, if its found then I UPDATE, if not then its an INSERT.
Is there a way of doing an insert/update in one query without using ON DUPLICATE KEY or have I missed a trick with this one?
If possible, I'd drop the meta_id column entirely and turn booking_id and key into a composite primary key. That'll save space in your table, allow use of ON DUPLICATE KEY, and be cleaner in general.
Related
I am trying to do a sql insert only if the data doesn't already exist in the table. I have a language table that has a auto incremented primary id field and a string description field to capture the name of the language(ex. English). I want to be able to insert into the database only if the description field is not already there. The primary id doesn't matter. So I only want to insert into the table if "English" isn't already a value in the table. Also, I am only given the description to check if it's already in the database (I mention this because the ON DUPLICATE KEY requires all fields to be matching and I don't have the id).
I have searched and tried so many queries without any of them producing the correct results. Any ideas would be helpful. Thanks.
You would simply add a UNIQUE constraint to the description field.
and then use "INSERT ... ON DUPLICATE KEY UPDATE" in your code. Refer this link.
if you need to update rows that have UNIQUE key conflict - you should use "meda" answer.
if you need only insert rows without duplicates you should also add UNIQUE constraint but with using query:
INSERT IGNORE INTO table SET ....
this query will insert row that have no conflict and ignore others without any mysql errors
I am having a table of the form ID, MID,PID. Now, for the table ID is the primary key. and I might come across inserting same combination of MID,PID , but I shouldn't add them. Here ID is something which needs to be generated and can't be obtained or crawled. Is there any mechanism in SQL to check for uniqueness of the combination.
I an thinking of generating ID with auto increment, so it being primary key can't help here,another option I am thinking is, concatenate MID and PID and then set them as primary key. Else I could check if the data exists with a select command and then do the same. But all these kind of defeats the purpose, or to say the least not elegant. Are there any other methods?
Will creating a constraint serve it?
Yes, adding a (composite) uniqueness constraint is exactly what you want:
ALTER TABLE my_table ADD UNIQUE (MID, PID)
Basically we have the same problem as this question: ON DUPLICATE KEY update (with multiple where clauses)
But we can't have unique keys for the keys of reference because we need duplicates of both.
Is there a way to do this with one query?
We have a unique identifier, and also need to record date, and increment a value, but also be able to update/insert without making multiple queries.
Please excuse me if I'm understanding you incorrectly, but it seems to me that what you want can in fact be done with the UNIQUE contraint mentioned in the question you're referencing.
Are you aware that you can create a UNIQUE constraint on more than one column? That is, the combination of the 2 columns is unique, but the columns themselves don't have to be.
In your case, you would use ALTER TABLE table ADD CONSTRAINT uq_table_id_date UNIQUE (id, date).
It is my understanding that when I make a table without a primary key that MySQL creates a sort of underlying primary key that it uses internally.
I am working with a table that does not have a primary key, but it would be very useful for my application if I could somehow access this value, assuming it does in fact exist and is retrievable.
So, I am wanting to know if I am correct in believing that such a value exists somewhere and also if it is possible to get that value.
Edit: just to make it clear, it would be very useful for my application for this table to have an incrementing int attribute. Unfortunately, it was not implemented that way. So, I am sort of grasping at straws to find a solution. What I am trying to do is select every nth row in the table (n changes). So, as you can see if there was this key, this would be very simple.
If a table has no primary key then there's no way of specifying a specific row within it because there is no way to uniquely identify an item. Even if you use a query that specifies a specific value for every column that still wouldn't be certain to only return a single row as without a primary key there's nothing to prevent duplicate rows.
However, a primary key is simply a unique index. If a table has a unique index on one or more of its columns and those columns don't accept NULLs then this is the primary key for the table in all but name.
If you table has no unique columns then you've got nothing to go on. You'll have to either make one column or combination of columns (for a composite key) unique, or add a column that serves as the primary key for the table. Fortunately it's relatively easy to add columns to a MySQL table, just add a primary key autoincrement column to the existing table.
This is probably a common situation, but I couldn't find a specific answer on SO or Google.
I have a large table (>10 million rows) of friend relationships on a MySQL database that is very important and needs to be maintained such that there are no duplicate rows. The table stores the user's uids. The SQL for the table is:
CREATE TABLE possiblefriends(
id INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY(id),
user INT,
possiblefriend INT)
The way the table works is that each user has around 1000 or so "possible friends" that are discovered and need to be stored, but duplicate "possible friends" need to be avoided.
The problem is, due to the design of the program, over the course of a day, I need to add 1 million rows or more to the table that may or not be duplicate row entries. The simple answer would seem to be to check each row to see if it is a duplicate, and if not, then insert it into the table. But this technique will probably get very slow as the table size increases to 100 million rows, 1 billion rows or higher (which I expect it to soon).
What is the best (i.e. fastest) way to maintain this unique table?
I don't need to have a table with only unique values always on hand. I just need it once-a-day for batch jobs. In this case, should I create a separate table that just inserts all the possible rows (containing duplicate rows and all), and then at the end of the day, create a second table that calculates all the unique rows in the first table?
If not, what is the best way for this table long-term?
(If indexes are the best long-term solution, please tell me which indexes to use)
Add a unique index on (user, possiblefriend) then use one of:
INSERT ... ON DUPLICATE KEY UPDATE ...
INSERT IGNORE
REPLACE
to ensure that you don't get errors when you try to insert a duplicate row.
You might also want to consider if you can drop your auto-incrementing primary key and use (user, possiblefriend) as the primary key. This will decrease the size of your table and also the primary key will function as the index, saving you from having to create an extra index.
See also:
“INSERT IGNORE” vs “INSERT … ON DUPLICATE KEY UPDATE”
A unique index will let you be sure that the field is indeed unique, you can add a unique index like so:
CREATE TABLE possiblefriends(
id INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY(id),
user INT,
possiblefriend INT,
PRIMARY KEY (id),
UNIQUE INDEX DefUserID_UNIQUE (user ASC, possiblefriend ASC))
This will also speec up your table access significantly.
Your other issue with the mass insert is a little more tricky, you could use the in-built ON DUPLICATE KEY UPDATE function below:
INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE c=c+1;
UPDATE table SET c=c+1 WHERE a=1;