How can I do 'insert if not exists' in MySQL?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
When working with MySQL, sometimes you need to insert a new record but only if it doesn't already exist in the database. This pattern is known as "insert if not exists". Different methodologies can be employed to ensure this behavior, including using SQL clauses like INSERT IGNORE, REPLACE INTO, or leveraging the unique constraints with INSERT ... ON DUPLICATE KEY UPDATE. This article will dive into each method, providing a technical explanation and examples to guide your implementation.
Using INSERT IGNORE
The INSERT IGNORE statement is one of the simplest ways to perform an "insert if not exists". This command tries to insert new data, but if an error occurs because a row would violate a unique index or primary key, the error is ignored, and the insert operation is skipped.
Example:
Suppose you have the following table:
You want to add a new employee but only if there isn't already an employee with the same email:
If there's already an employee with the email [email protected], the operation will be silently skipped.
Using REPLACE INTO
REPLACE INTO works similarly to INSERT, but if an old row in the table has the same value as a new row for a PRIMARY KEY or a UNIQUE index, the old row is deleted before the new row is inserted.
Example:
Using the same employees table, if you execute:
If the ID 1 already exists, that row will be replaced entirely by the new data, changing both the name and email.
Using INSERT ... ON DUPLICATE KEY UPDATE
This method provides more control when an insertion is attempted on a duplicate key. Instead of ignoring or replacing, it updates the existing row. Moreover, you avoid the overhead of deleting and then reinserting rows, which can be significant.
Example:
If the entry with ID 2 exists, it updates the name and email; otherwise, it inserts the new row.
Implementing with Transactions and Locks
If your table doesn’t have a unique constraint or if your application requires custom duplication checks, you might have to manually handle the logic in your application or use transactions and selective locking for concurrency control.
Example:
This approach manually locks the rows involved in the transaction, so it's safe from race conditions.
Summary Table
| Method | Use Case | Behavior |
INSERT IGNORE | Simple ignoring of duplicate entries | Ignores the error and does not insert |
REPLACE INTO | Replace the old rows with new data | Deletes old row, inserts new row |
INSERT ... ON DUPLICATE KEY UPDATE | Update existing rows upon constraint violation | Updates existing row with new data |
| Manual Transaction and Locks | Complex logic or no unique constraints | Full control, manual locking of rows |
Conclusion
Choosing the right approach depends largely on your specific requirements and the structure of your database. For straightforward use cases, INSERT IGNORE or INSERT ... ON DUPLICATE KEY UPDATE can often suffice. However, for more complex scenarios, you might find manually managing transactions provides the necessary control.
Whatever method you choose, ensure it aligns with both performance considerations and the integrity of your data, providing a seamless and error-free user experience.

