Unique VS INSERT IGNORE - mysql

As you know, unique columns only accept non-repetitive values. Now, I saw a keyword named IGNORE (It is used after INSERT statement).
Well, I read about INSERT IGNORE in the documentation and I figured out its job is exactly what unique does! So, when should I use IGNORE instead of unique column? When it is useful?

These two constructs are complimentary. A unique constraint makes sure a column cannot get repetitive values. The ignore keyword in an insert statement allows the insert statement to ignore any errors (such as unique constraint violations) when inserting new rows to a table.
Without the constraint, your insert statement would just create repetitive values in the table. Without the ignore keyword, attempting to insert such values would error out instead of just silently doing nothing.

Related

What is the difference between “INSERT IGNORE” and “INSERT … ON DUPLICATE KEY UPDATE” in MySQL? [duplicate]

This question already has answers here:
"INSERT IGNORE" vs "INSERT ... ON DUPLICATE KEY UPDATE"
(12 answers)
Closed last month.
What is the difference between INSERT IGNORE and INSERT…ON DUPLICATE KEY UPDATE. I would also like to know which one is preferred over the other. Can someone please help?
If you use INSERT IGNORE, then the row won't actually be inserted if it results in a duplicate key. But the statement won't generate an error. It generates a warning instead. These cases include:
•Inserting a duplicate key in columns with PRIMARY KEY or UNIQUE constraints.
•Inserting a NULL into a column with a NOT NULL constraint.
•Inserting a row to a partitioned table, but the values you insert don't map to a partition.
If you use REPLACE, MySQL actually does a DELETE followed by an INSERT internally, which has some unexpected side effects:
•A new auto-increment ID is allocated.
•Dependent rows with foreign keys may be deleted (if you use cascading foreign keys) or else prevent the REPLACE.
•Triggers that fire on DELETE are executed unnecessarily.
•Side effects are propagated to replication slaves too.
Both REPLACE and INSERT...ON DUPLICATE KEY UPDATE are non-standard, proprietary inventions specific to MySQL. ANSI SQL 2003 defines a MERGE statement that can solve the same need (and more), but MySQL does not support the MERGE statement.
If you try to avoid duplication violation, then the difference is: INSERT IGNORE does not allow to specify an action (to alter something in a row) if unique constraint violation occures whereas for INSERT...ON DUPLICATE KEY UPDATE some action specifying is compulsory. Of course, you can specify fake update in INSERT...ON DUPLICATE KEY UPDATE (for example, SET id=id, where id is primary/unique key) - in this case there is no difference.
INSERT IGNORE also may ignore some another ignorable errors, rather than INSERT...ON DUPLICATE KEY UPDATE.

How to get the PK of a ignored row in an INSERT IGNORE statement

I have an INSERT statement with an IGNORE option, because I have a unique field in the insert statement, that is not the primary key. I am using the getGeneratedKeys() command on a PreparedStatement object to get the keys of newly generated rows. Is it possible to configure JDBC in a way so that it returns the id of the ignored row in the case of a query where the IGNORE triggers?
The answer mysql - after insert ignore get primary key seems to indicate that a multi-step workaround is required to retrieve the details of the ignored rows.
With the optional alternative of using REPLACE INTO if you can afford the additional overhead of replacing the rows rather than ignoring them.

Enforcing unique columns

If a column is made unique in a database table structure, is there any need to do a check to see if a new value to be inserted already exists in the table via script? Or would it be fine just to insert values letting the DBMS filter non-new values?
When you will try to insert a duplicate value in a unique column, your insert query will fail. So it might be a good idea to make sure you are checking to see if your insert queries went well or not. Althought regardless of the situation you should always check if your insert query went through or not :)
You should always validate your data before inserting it on the database. That being said, what will happen if you try to insert a non-unique value on a unique defined column is an SQLexception.
In order to validate this before insertion, you could for example do a
select 1
from mytable_with_unique_column
where my_unique_column = myNewValue
If the query returns anything, then simply do not try to insert as that will throw an SQLException.
Verification of unique constraint is definitely an overkill.
When you put unique constraint on your column, an implicit index is created for this column. Thus, DBMS can (and will) verify your data much faster. Unfortunately, when you try to insert duplicate value into your column, you will get constraint violation exception you have to deal with (but you have to deal with such error while using script verification either).
Good luck.
You can combine the insert statement and validation select into one statement:
insert into mytable_with_unique_column (...) values (...)
where not exists
(
select 1
from mytable_with_unique_column
where my_unique_column = myNewValue
)
This will only insert a new row if there isn't already a row with the given unique value.

Is it possible to declare to mysql queries?

I'm trying to create a code for a single button where it will perform either of two actions where it will add to the database if the user currently don't have the record while it will update the user's record if the user has records already. I've done it like this:
if() {
mysql_query("INSERT INTO table...");
}
else {
mysql_query("UPDATE table SET...");
}
Is it possible?
Yes, what you've written will work. If you have a way to know if there already exists a row or not without making an additional query just for this bit of code, then do exactly as you wrote.
If, however, you planned to first SELECT from the table to see if a row exists, then conditionally INSERT or UPDATE, you will perform more queries than necessary.
It would be better to either:
Have a PRIMARY KEY or other constraint on the table prevent duplicate INSERTs. Then issue an INSERT ... ON DUPLICATE KEY UPDATE query. This will attempt to INSERT the row, and if it is a duplicate, automatically perform the specified UPDATE to that row instead.
Issue the UPDATE query and check mysql_affected_rows to see if it updated an existing row. If not, then issue the INSERT query to create the new row.
Which one is more appropriate depends on your application.
you can use INSERT ... ON DUPLICATE KEY UPDATE Syntax like:
INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE c=c+1;
http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
If you have properly set unique keys, you should use REPLACE so you could remove the if.
REPLACE INTO table VALUE (...);
Pay attention that this is a MySQL extension, thus not portable to other DBs.
Yes, you could try the insert then if it fails try the update.
But you could use the MYSQL sql "REPLACE" keyword, which will insert a new record if it doesn't exist or delete the existing record and insert your new one if it does.
You could also use the INSERT ... ON DUPLICATE KEY UPDATE syntax
(explained here - Link to MYSQL ref which seems to be the closest fit to your requirement.
yes it is possible
first write a query for check that record is already exist or not.
Yes it is possible , it will work

INSERT IGNORE Inserting 0 rows

When I am attempting to run "INSERT IGNORE ..." in MYSQL to add only one variable to a table of several options, after the first insert, it refuses to work. It says "Inserted rows: 0" and doesn't insert my new value into the database. I believe this is because there is already an entry with a "nothing" value and MYSQL doesn't allow the empty field to be duplicated. This seems to be odd behavior (as long as the two inserts are not exactly the same), so I am wondering if there is some way to avoid this.
The two INSERT do not have to be exactly the same, they just have to be the same for the primary key columns.
INSERT IGNORE will ignore an insert if there is already a row with the same primary key.
If you did INSERT instead of INSERT IGNORE, you would be getting an error (duplicate primary key).
If you want to instead update the existing row, you can use REPLACE.
Either way, there can be only one row for each primary key.