Na navigaci | Klávesové zkratky

Renaming ENUM Values Without Data Loss: A Safe Guide

Renaming values in a MySQL ENUM column can be tricky. Many developers attempt a direct change, which often results in data loss or errors. We'll show you the correct and safe way to do it.

Imagine a typical scenario: You have an orders table in your database with a status column of type ENUM. It contains the values waiting_payment, processing, shipped, and cancelled. The requirement is to rename waiting_payment to unpaid and shipped to completed. How can this be done without risk?

What Doesn't Work

First, let's look at what does not work. Many developers try this straightforward approach:

-- THIS DOES NOT WORK!
ALTER TABLE orders
MODIFY COLUMN status ENUM(
    'unpaid',      -- previously 'waiting_payment'
    'processing',  -- unchanged
    'completed',   -- previously 'shipped'
    'cancelled'    -- unchanged
);

This approach is a recipe for disaster. MySQL will attempt to map existing values to the new ENUM, and since the original values are no longer in the definition, it will either replace them with an empty string or return the error Data truncated for column 'status' at row X. In a production database, this would mean losing important data.

Backup First!

Before making any structural changes to your database, it is absolutely crucial to create a data backup. Use MySQL-dump or another trusted tool.

The Correct Approach

The correct approach consists of three steps:

  1. First, extend the ENUM with new values.
  2. Update the data.
  3. Finally, remove the old values.

Let's go through it step by step:

1. The first step is to add the new values to the ENUM while keeping the original ones:

ALTER TABLE orders
MODIFY COLUMN status ENUM(
    'waiting_payment',  -- original value
    'processing',       -- unchanged
    'shipped',         -- original value
    'cancelled',       -- unchanged
    'unpaid',          -- new value (replaces waiting_payment)
    'completed'        -- new value (replaces shipped)
);

2. Now we can safely update the existing data:

UPDATE orders SET status = 'unpaid' WHERE status = 'waiting_payment';
UPDATE orders SET status = 'completed' WHERE status = 'shipped';

3. Finally, once all data has been converted to the new values, we can remove the old ones:

ALTER TABLE orders
MODIFY COLUMN status ENUM(
    'unpaid',
    'processing',
    'completed',
    'cancelled'
);

Why Does This Work?

This works because of how MySQL handles ENUM values. When performing an ALTER TABLE modification on an ENUM column, MySQL tries to map existing values based on their textual representation. If the original value does not exist in the new ENUM definition, MySQL will either throw an error (if STRICT_ALL_TABLES is enabled in sql_mode) or replace it with an empty string.

That's why it's crucial to have both old and new values present in the ENUM simultaneously during the transition phase. In our case, this ensures that every record in the database retains its exact textual equivalent. Only after executing the UPDATE queries—when we are sure that all data is using the new values—can we safely remove the old ones.

17 days ago in section PHP | blog written by David Grudl | back to top

You might be interested in

Leave a comment

Text of the comment
Contact

(kvůli gravataru)



*kurzíva* **tučné** "odkaz":http://example.com /--php phpkod(); \--

phpFashion © 2004, 2025 David Grudl | o blogu

Ukázky zdrojových kódů smíte používat s uvedením autora a URL tohoto webu bez dalších omezení.