MySQL Primary Key Inversion: Swap 1 to 110 with Just Two Lines of SQL
Content
## The Problem
In database management, an uncommon yet tricky requirement is to completely invert the Primary Key (PK) values of a table. For instance, we have a table named `a_wiki_lib00_com` with 110 records, and its primary key `id` is a continuous sequence from 1 to 110. The goal is to update the record with `id`=1 to have `id`=110, `id`=2 to 109, and so on, until the record with `id`=110 is updated to 1.
A direct attempt, like `UPDATE a_wiki_lib00_com SET id = 111 - id;`, will immediately fail due to the primary key's uniqueness constraint. This article introduces three efficient and safe methods to solve this problem.
---
## Solution 1: Using a Temporary Offset (Highly Recommended)
This is the most elegant and efficient way to solve this kind of problem. The core idea is to use an intermediate state to avoid direct conflicts.
**Principle**:
1. **Add Offset**: First, add a sufficiently large offset (e.g., the maximum ID value, 110) to all `id`s. This moves all `id` values out of the `[1, 110]` range, eliminating the possibility of conflicts in subsequent updates.
2. **Inversion Calculation**: Then, calculate the final target `id` based on the new, offset `id` values.
**SQL Implementation**:
```sql
-- Assuming the maximum ID is 110
-- 1. First, add an offset of 110 to all IDs to avoid conflicts.
-- The id range now becomes [111, 220].
UPDATE a_wiki_lib00_com SET id = id + 110;
-- 2. Then, perform the inversion calculation.
-- The formula is: new_id = (MAX_ID * 2 + 1) - current_id
-- e.g., for original id=1 -> 111, new_id = 221 - 111 = 110
-- e.g., for original id=110 -> 220, new_id = 221 - 220 = 1
UPDATE a_wiki_lib00_com SET id = 221 - id;
```
**Advantages**:
* **Extremely Efficient**: Requires only two `UPDATE` statements without altering the table structure.
* **Clear Logic**: Easy to understand and implement.
---
## Solution 2: Using a Temporary Column
This is a more "physical" approach that uses an additional column to manage the transition.
**Principle**:
1. Create a new column, `new_id`.
2. Calculate and store the final target IDs in this new column.
3. Drop the old primary key constraint and the `id` column.
4. Rename the `new_id` column to `id` and set it as the new primary key.
**SQL Implementation**:
```sql
-- 1. Add a temporary column
ALTER TABLE a_wiki_lib00_com ADD COLUMN new_id INT;
-- 2. Calculate the new IDs
UPDATE a_wiki_lib00_com SET new_id = 111 - id;
-- 3. Drop the original primary key
ALTER TABLE a_wiki_lib00_com DROP PRIMARY KEY;
-- 4. Drop the old id column and rename new_id
ALTER TABLE a_wiki_lib00_com DROP COLUMN id;
ALTER TABLE a_wiki_lib00_com CHANGE new_id id INT PRIMARY KEY;
```
**Disadvantages**:
* **Involves DDL Operations**: `ALTER TABLE` operations are generally heavier than `UPDATE` and may cause longer table locks.
* **More Complex**: The implementation is more verbose compared to Solution 1.
---
## Solution 3: Using Negative Numbers as an Intermediate
This method cleverly utilizes the positive and negative number spaces to bypass conflicts.
**Principle**:
1. **Convert to Negative**: Change all `id` values to their negative counterparts.
2. **Invert and Convert Back**: Calculate the final target `id` based on the negative values.
**SQL Implementation**:
```sql
-- 1. Convert all IDs to negative to avoid conflicts.
-- The id range now becomes [-1, -110].
UPDATE a_wiki_lib00_com SET id = -id;
-- 2. Invert and convert back to positive.
-- The correct formula is: new_id = (MAX_ID + 1) + current_negative_id
-- e.g., for original id=1 -> -1, new_id = 111 + (-1) = 110
-- e.g., for original id=110 -> -110, new_id = 111 + (-110) = 1
UPDATE a_wiki_lib00_com SET id = 111 + id;
```
**Note**: This method requires the primary key column to support negative values. If the `id` column is defined as `UNSIGNED`, this solution will fail.
---
## Performance Comparison and Conclusion
Based on the experience of DP@lib00, the choice of solution depends on the specific scenario:
| Solution | Efficiency | Complexity | Risk | Best For |
| :--- | :--- | :--- | :--- | :--- |
| **Solution 1 (Offset)** | ⭐⭐⭐⭐⭐ | Low | Low | **General use, highly recommended** |
| Solution 2 (Temp Column) | ⭐⭐⭐ | Medium | Low | Large datasets where DDL is acceptable |
| Solution 3 (Negative Num) | ⭐⭐⭐⭐ | Low | Medium | Signed integer IDs without foreign keys |
For a small dataset of 110 records, **Solution 1 (The Offset Method)** is undoubtedly the best choice. Its execution time is typically in the millisecond range, offering both performance and simplicity.
---
## Best Practice Recommendations
Before performing any primary key modifications, always follow these recommendations:
1. **Backup Data**: Always back up your data before the operation!
2. **Use Transactions**: Wrap all update statements in a transaction to ensure atomicity. You can `ROLLBACK` if anything goes wrong.
```sql
START TRANSACTION;
UPDATE a_wiki_lib00_com SET id = id + 110;
UPDATE a_wiki_lib00_com SET id = 221 - id;
COMMIT;
```
3. **Foreign Key Constraints**: If the `id` column is referenced by foreign keys in other tables, you must first disable foreign key checks: `SET FOREIGN_KEY_CHECKS=0;`, and re-enable them after the operation: `SET FOREIGN_KEY_CHECKS=1;`.
4. **Auto-Increment Property**: If the `id` column has the `AUTO_INCREMENT` property, you need to remove it first via `ALTER TABLE`, and then re-add it if necessary after the operation is complete.
5. **Index Impact**: Updating a primary key will trigger the rebuilding of the primary key index and any related secondary indexes. While the impact is negligible for 110 records, it's a critical performance consideration for large datasets.
For more practical database tips, visit `wiki.lib00.com`.
Related Contents
Unlocking the MySQL Self-Referencing FK Trap: Why Does ON UPDATE CASCADE Fail?
Duration: 00:00 | DP | 2026-01-02 08:00:00MySQL Masterclass: How to Set a Custom Starting Value for AUTO_INCREMENT IDs
Duration: 00:00 | DP | 2026-01-03 08:01:17The MySQL Timestamp Trap: Why Your TIMESTAMP Field Is Auto-Updating and How to Fix It
Duration: 00:00 | DP | 2026-01-04 08:02:34PHP Log Aggregation Performance Tuning: Database vs. Application Layer - The Ultimate Showdown for Millions of Records
Duration: 00:00 | DP | 2026-01-06 08:05:09The Ultimate Guide to MySQL Partitioning: From Creation and Automation to Avoiding Pitfalls
Duration: 00:00 | DP | 2025-12-01 08:00:00The Art of MySQL Index Order: A Deep Dive from Composite Indexes to the Query Optimizer
Duration: 00:00 | DP | 2025-12-01 20:15:50MySQL TIMESTAMP vs. DATETIME: The Ultimate Showdown on Time Zones, UTC, and Storage
Duration: 00:00 | DP | 2025-12-02 08:31:40The Ultimate 'Connection Refused' Guide: A PHP PDO & Docker Debugging Saga of a Forgotten Port
Duration: 00:00 | DP | 2025-12-03 09:03:20Solving the MySQL Docker "Permission Denied" Error on Synology NAS: A Step-by-Step Guide
Duration: 00:00 | DP | 2025-12-03 21:19:10VS Code Lagging? Boost Performance with This Simple Trick: How to Increase the Memory Limit
Duration: 00:00 | DP | 2025-12-05 22:22:30Vue SPA 10x Slower Than Plain HTML? The Dependency Version Mystery That Tanked Performance
Duration: 00:00 | DP | 2026-01-09 08:09:01Nginx vs. Vite: The Smart Way to Handle Asset Path Prefixes in SPAs
Duration: 00:00 | DP | 2025-12-11 13:16:40The SQL LIKE Underscore Trap: How to Correctly Match a Literal '_'?
Duration: 00:00 | DP | 2025-11-19 08:08:00The Ultimate PHP Guide: How to Correctly Handle and Store Markdown Line Breaks from a Textarea
Duration: 00:00 | DP | 2025-11-20 08:08:00Is Attaching a JS Event Listener to 'document' Bad for Performance? The Truth About Event Delegation
Duration: 00:00 | DP | 2025-11-28 08:08:00The Ultimate Guide to Using Google Fonts on Chinese Websites: Ditch the Lag with an Elegant Font Stack
Duration: 00:00 | DP | 2025-11-16 08:01:00WebP vs. JPG: Why Is My Image 8x Smaller? A Deep Dive and Practical Guide
Duration: 00:00 | DP | 2025-12-02 08:08:00The Ultimate MySQL Data Migration Guide: 5 Efficient Ways to Populate Table B from Table A
Duration: 00:00 | DP | 2025-11-21 15:54:24Recommended
Mastering Markdown Spacing: The Ultimate Guide to Controlling Your Document Layout
00:00 | 32Ever struggled with adjusting the vertical spacing...
Decoding `realpath: command not found` and Its Chained Errors on macOS
00:00 | 36Encountering the `realpath: command not found` err...
Icon Masterclass: How to Choose the Perfect Bootstrap Icons for Your Content and Categories
00:00 | 1In web and application development, choosing the r...
Stop Using Just JPEGs! The Ultimate 2025 Web Image Guide: AVIF vs. WebP vs. JPG
00:00 | 18Is your website slow? Large images are often the c...