11.6 扩展序列列的取值范围 2025-07-01
11.7 序列顶部数值的再使用
11.8 确保各行按照给定顺序重编号
思路
1、 创建表的空克隆
2、 使用insert into ......select 从源表自制行
3、删除源表, 并将克隆表重命名为源表表名
4、如果是巨大的MyISAM, 并含有多个索引,创建新表时不定义除了auto_increment列之外的索引,会使整个过程更高效
重新编号时解决主键冲突的示例
通过一个完整的可运行示例来演示如何安全地重新编号表中的主键,避免冲突。
示例场景
假设我们有一个用户表 users,其中主键 id 不是连续的(可能因为删除了某些行),现在需要重新编号使其连续。
1. 创建原始表并插入数据
sql
-- 创建原始表
CREATE TABLE users (
id INT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 插入一些数据(故意跳过某些ID)
INSERT INTO users (id, username, email) VALUES
(1, 'user1', '[email protected]'),
(3, 'user3', '[email protected]'),
(7, 'user7', '[email protected]'),
(10, 'user10', '[email protected]');
2. 方法一:创建新表并重新编号
sql
-- 创建新表结构(不包含主键约束)
CREATE TABLE users_new LIKE users;
ALTER TABLE users_new DROP PRIMARY KEY;
-- 插入数据并重新编号
INSERT INTO users_new (id, username, email, created_at)
SELECT
ROW_NUMBER() OVER (ORDER BY id) AS new_id,
username,
email,
created_at
FROM users;
-- 删除旧表并重命名新表
DROP TABLE users;
RENAME TABLE users_new TO users;
-- 重新添加主键
ALTER TABLE users ADD PRIMARY KEY (id);
-- 验证结果
SELECT * FROM users;
3. 方法二:更高效的MyISAM表处理
如果表很大且是MyISAM引擎:
sql
-- 创建只有基本结构的新表(无索引)
CREATE TABLE users_new (
id INT,
username VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL,
created_at TIMESTAMP
) ENGINE=MyISAM;
-- 插入数据并重新编号
INSERT INTO users_new (id, username, email, created_at)
SELECT
@row := @row + 1 AS new_id,
username,
email,
created_at
FROM users, (SELECT @row := 0) r
ORDER BY id;
-- 删除旧表并重命名新表
DROP TABLE users;
RENAME TABLE users_new TO users;
-- 添加主键和索引
ALTER TABLE users ADD PRIMARY KEY (id);
ALTER TABLE users ADD INDEX (email);
-- 验证结果
SELECT * FROM users;
注意事项
外键约束:如果表有外键引用,需要先删除约束,操作后再重新添加
事务:在大表上操作时,考虑使用事务确保数据安全
备份:操作前务必备份数据
权限:确保有足够的权限执行这些操作
完整示例(包含外键处理)
sql
-- 创建有外键关系的表
CREATE TABLE departments (
dept_id INT PRIMARY KEY,
dept_name VARCHAR(50)
);
CREATE TABLE employees (
emp_id INT PRIMARY KEY,
emp_name VARCHAR(50),
dept_id INT,
FOREIGN KEY (dept_id) REFERENCES departments(dept_id)
);
-- 插入数据
INSERT INTO departments VALUES (1, 'HR'), (2, 'IT');
INSERT INTO employees VALUES
(5, 'Alice', 1),
(8, 'Bob', 2),
(12, 'Charlie', 1);
-- 1. 删除外键约束
ALTER TABLE employees DROP FOREIGN KEY employees_ibfk_1;
-- 2. 创建新表并重新编号
CREATE TABLE employees_new LIKE employees;
ALTER TABLE employees_new DROP PRIMARY KEY;
INSERT INTO employees_new (emp_id, emp_name, dept_id)
SELECT
ROW_NUMBER() OVER (ORDER BY emp_id) AS new_id,
emp_name,
dept_id
FROM employees;
-- 3. 替换表
DROP TABLE employees;
RENAME TABLE employees_new TO employees;
-- 4. 重新添加约束
ALTER TABLE employees ADD PRIMARY KEY (emp_id);
ALTER TABLE employees ADD CONSTRAINT fk_dept
FOREIGN KEY (dept_id) REFERENCES departments(dept_id);
-- 验证结果
SELECT * FROM employees;
通过以上方法,可以安全地重新编号表中的主键,即使存在外键约束也能正确处理。
更优的重新编号主键方法
确实有比创建新表更高效的方案,特别是在生产环境中处理大表时。以下是几种更优的方法:
方法一:使用临时列交换(无需重建表)
sql
-- 1. 添加临时列存储新ID
ALTER TABLE users ADD COLUMN new_id INT;
-- 2. 更新临时列为新编号
SET @row_number = 0;
UPDATE users
SET new_id = (@row_number := @row_number + 1)
ORDER BY id;
-- 3. 删除原主键约束
ALTER TABLE users DROP PRIMARY KEY;
-- 4. 更新原ID列
UPDATE users SET id = new_id;
-- 5. 删除临时列并重建主键
ALTER TABLE users DROP COLUMN new_id;
ALTER TABLE users ADD PRIMARY KEY (id);
优点:
不需要创建新表
减少磁盘空间使用
保留所有原始表属性(触发器、权限等)
方法二:事务处理确保数据安全
sql
START TRANSACTION;
-- 禁用外键检查(如有外键约束)
SET FOREIGN_KEY_CHECKS = 0;
-- 使用临时变量重新编号
SET @new_id = 0;
UPDATE users
SET id = (@new_id := @new_id + 1)
ORDER BY id;
-- 重置自增值
ALTER TABLE users AUTO_INCREMENT = @new_id + 1;
-- 重新启用外键检查
SET FOREIGN_KEY_CHECKS = 1;
COMMIT;
方法三:针对InnoDB的优化方案
sql
-- 1. 创建临时序列表
CREATE TEMPORARY TABLE sequence (new_id INT AUTO_INCREMENT PRIMARY KEY);
-- 2. 生成连续序号
INSERT INTO sequence ()
SELECT NULL FROM users ORDER BY id;
-- 3. 联表更新(单次操作完成)
UPDATE users u
JOIN sequence s ON 1=1
SET u.id = s.new_id
ORDER BY u.id
LIMIT (SELECT COUNT(*) FROM users);
-- 4. 清理
DROP TEMPORARY TABLE sequence;
方法四:使用存储过程(适合复杂场景)
sql
DELIMITER //
CREATE PROCEDURE renumber_ids()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE old_id, new_id INT;
DECLARE cur CURSOR FOR SELECT id FROM users ORDER BY id;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
SET new_id = 0;
OPEN cur;
read_loop: LOOP
FETCH cur INTO old_id;
IF done THEN
LEAVE read_loop;
END IF;
SET new_id = new_id + 1;
-- 只有当ID不同时才更新
IF old_id != new_id THEN
-- 处理可能的冲突
UPDATE users SET id = -old_id WHERE id = old_id;
UPDATE users SET id = new_id WHERE id = -old_id;
END IF;
END LOOP;
CLOSE cur;
-- 重置自增值
SELECT MAX(id) INTO @max_id FROM users;
SET @sql = CONCAT('ALTER TABLE users AUTO_INCREMENT = ', @max_id + 1);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END //
DELIMITER ;
-- 执行存储过程
CALL renumber_ids();
最佳实践建议
评估必要性:主键是否真的需要连续?业务上是否有此需求?
外键处理:
sql
-- 查找所有外键约束
SELECT TABLE_NAME, COLUMN_NAME, CONSTRAINT_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE REFERENCED_TABLE_NAME = 'users';
-- 临时禁用外键检查
SET FOREIGN_KEY_CHECKS = 0;
-- 执行重编号操作...
SET FOREIGN_KEY_CHECKS = 1;
性能优化:
对大表操作时添加适当索引
分批处理(每次更新10000行)
在低峰期执行
原子性保障:
sql
START TRANSACTION;
-- 执行重编号操作
COMMIT;
-- 或出错时 ROLLBACK;
选择哪种方法取决于您的具体场景:
小表:方法一或方法二
大表:方法三或方法四
有复杂约束:存储过程方案
11.9 从某个特定值开始一个序列
mysql> create table tt01
-> (id int unsigned not null auto_increment, primary key (id));
Query OK, 0 rows affected (0.11 sec)
mysql> insert into tt01 (id) values(null);
Query OK, 1 row affected (0.01 sec)
mysql> insert into tt01 (id) values(null);
Query OK, 1 row affected (0.01 sec)
mysql> insert into tt01 (id) values(null);
Query OK, 1 row affected (0.01 sec)
mysql> select id from tt01 order by id;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
+----+
3 rows in set (0.00 sec)
-- 删除表前先检查是否存在
DROP TABLE IF EXISTS table_name;
AI写代码
在上面的代码中,IF EXISTS 关键字用于判断表是否存在,如果表存在则执行删除操作,否则不会报错。一些需要注意的事项:
1. 数据备份
在删除表之前,务必进行数据备份。无论是误操作还是其他意外原因导致数据丢失,备份可以帮助恢复数据,避免信息丢失造成的损失。
2. 确认操作对象
在执行删除表操作前,要确保明确操作的是正确的表。避免误删其他重要表,确认操作对象是正确的是非常重要的。
3. 删除表前查看依赖关系
在删除表之前,要先查看该表是否被其他表或程序所依赖。如果存在外键关联或其他依赖关系,需要先解除这些关系,否则可能导致其他功能异常。
4. 谨慎使用DELETE语句
在删除表中数据时,要谨慎使用DELETE语句,确保只删除需要的数据行。同时,如果只是删除表而不需要保留表结构,建议使用DROP TABLE命令,效率更高。
5. 使用事务
在删除表操作中,可以使用事务来确保操作的一致性和完整性。如果删除表是一个重要的操作,可以结合事务来处理,避免意外中断导致数据不一致。
6. 注意权限控制
在删除表时,要注意当前用户是否具有足够的权限。确保只有授权人员才能执行删除表的操作,避免未经授权的删除操作带来安全风险。
————————————————
原文链接:https://blog.csdn.net/q7w8e9r4/article/details/138009452
mysql> drop table tt02;
Query OK, 0 rows affected (0.04 sec)
mysql> create table tt02
-> (id int unsigned not null auto_increment, primary key (id))
-> auto_increment = 100;
Query OK, 0 rows affected (0.04 sec)
mysql> insert into tt02 (id) values(null);
Query OK, 1 row affected (0.01 sec)
mysql> insert into tt02 (id) values(null);
Query OK, 1 row affected (0.01 sec)
mysql> insert into tt02 (id) values(null);
Query OK, 1 row affected (0.01 sec)
mysql> select id from tt02 order by id;
+-----+
| id |
+-----+
| 100 |
| 101 |
| 102 |
+-----+
3 rows in set (0.00 sec)
mysql> create table tt02
-> (id int unsigned not null auto_increment, primary key (id))
-> auto_increment = 100;
Query OK, 0 rows affected (0.04 sec)
mysql> insert into tt02 (id) values(null);
Query OK, 1 row affected (0.01 sec)
mysql> insert into tt02 (id) values(null);
Query OK, 1 row affected (0.01 sec)
mysql> insert into tt02 (id) values(null);
Query OK, 1 row affected (0.01 sec)
mysql> select id from tt02 order by id;
+-----+
| id |
+-----+
| 100 |
| 101 |
| 102 |
+-----+
3 rows in set (0.00 sec)
mysql> create table tt03
-> (id int unsigned not null auto_increment, primary key (id))
-> alter table tt03 auto_increment = 100;
Query OK, 0 rows affected (0.04 sec)
mysql> insert into tt03 (id) values(null);
Query OK, 1 row affected (0.01 sec)
mysql> insert into tt03 (id) values(null);
Query OK, 1 row affected (0.01 sec)
mysql> insert into tt03 (id) values(null);
Query OK, 1 row affected (0.01 sec)
mysql> select id from tt03 order by id;
+-----+
| id |
+-----+
| 100 |
| 101 |
| 102 |
+-----+
3 rows in set (0.00 sec)
mysql> CREATE TABLE tt04 (
-> id INT UNSIGNED NOT NULL AUTO_INCREMENT,
-> PRIMARY KEY (id)
-> ) ENGINE = InnoDB;
Query OK, 0 rows affected (0.04 sec)
mysql> insert into tt04 (id) values(99);
Query OK, 1 row affected (0.01 sec)
mysql> insert into tt04 (id) values(null);
Query OK, 1 row affected (0.01 sec)
mysql> insert into tt04 (id) values(null);
Query OK, 1 row affected (0.01 sec)
mysql> insert into tt04 (id) values(null);
Query OK, 1 row affected (0.01 sec)
mysql> delete from tt04 where id = 99;
Query OK, 1 row affected (0.01 sec)
mysql> select * from tt04 order by id;
+-----+
| id |
+-----+
| 100 |
| 101 |
| 102 |
+-----+
3 rows in set (0.00 sec)
11.10 序列化一个未序列的表
CREATE TABLE tt05 (
name VARCHAR(50) NOT NULL,
age INT NOT NULL,
PRIMARY KEY (name) -- 假设name是唯一的,设为主键
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO tt05 (name, age) VALUES
('boris', 47),
('clarence', 62),
('abner', 53),
('alice', 71);
-- 1. 删除现有的主键约束(需要先删除依赖它的外键,如果有的话)
ALTER TABLE tt05 DROP PRIMARY KEY;
-- 2. 添加自增ID列并设为主键
ALTER TABLE tt05
ADD COLUMN id INT NOT NULL AUTO_INCREMENT FIRST, -- 添加到第一列
ADD PRIMARY KEY (id);
mysql> select * from tt05;
+----+----------+-----+
| id | name | age |
+----+----------+-----+
| 1 | abner | 53 |
| 2 | alice | 71 |
| 3 | boris | 47 |
| 4 | clarence | 62 |
+----+----------+-----+
4 rows in set (0.00 sec)
方法 2:保留原主键,只添加自增ID(但不设为主键)
sql
复制
下载
-- 仅添加自增ID列(作为普通列)
ALTER TABLE tt05
ADD COLUMN id INT NOT NULL AUTO_INCREMENT FIRST;
方法 3:创建新表并迁移数据
如果数据量不大,可以重建表:
sql
复制
下载
-- 1. 创建新表
CREATE TABLE tt05_new (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
age INT NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY (name) -- 保持name唯一
) ENGINE=InnoDB;
-- 2. 导入数据
INSERT INTO tt05_new (name, age)
SELECT name, age FROM tt05;
-- 3. 删除旧表,重命名新表
DROP TABLE tt05;
RENAME TABLE tt05_new TO tt05;
+----------+-----+----+
| name | age | id |
+----------+-----+----+
| abner | 53 | 1 |
| alice | 71 | 2 |
| boris | 47 | 3 |
| clarence | 62 | 4 |
+----------+-----+----+
方法 1:重建表结构(推荐)
直接创建符合要求的表结构(适用于数据量小或新表):
mysql> -- 1. 创建新表(id在第三列)
mysql> CREATE TABLE tt05_new (
-> name VARCHAR(50) NOT NULL,
-> age INT NOT NULL,
-> id INT NOT NULL AUTO_INCREMENT,
-> PRIMARY KEY (id),
-> UNIQUE KEY (name) -- 可选:确保name唯一
-> ) ENGINE=InnoDB;
Query OK, 0 rows affected (0.08 sec)
mysql>
mysql> -- 2. 导入原数据(不指定id,让MySQL自动生成)
mysql> INSERT INTO tt05_new (name, age)
-> SELECT name, age FROM tt05;
Query OK, 4 rows affected (0.01 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql>
mysql> -- 3. 替换旧表
mysql> DROP TABLE tt05;
Query OK, 0 rows affected (0.04 sec)
mysql> RENAME TABLE tt05_new TO tt05;
Query OK, 0 rows affected (0.04 sec)
mysql> select * from tt05;
+----------+-----+----+
| name | age | id |
+----------+-----+----+
| abner | 53 | 1 |
| alice | 71 | 2 |
| boris | 47 | 3 |
| clarence | 62 | 4 |
+----------+-----+----+
4 rows in set (0.00 sec)________________________________________
方法 2:通过 ALTER TABLE 调整(复杂)
如果必须保留原表,可通过临时列实现:
sql
复制
下载
-- 1. 移除id的自增属性(需先删除主键)
ALTER TABLE tt05 MODIFY id INT NOT NULL;
ALTER TABLE tt05 DROP PRIMARY KEY;
-- 2. 将id列重命名为临时列
ALTER TABLE tt05 CHANGE id temp_id INT;
-- 3. 在末尾添加新的自增id列
ALTER TABLE tt05 ADD COLUMN id INT NOT NULL AUTO_INCREMENT FIRST;
ALTER TABLE tt05 ADD PRIMARY KEY (id);
-- 4. 将数据从temp_id复制到新id列(如果需要保留原id值)
UPDATE tt05 SET id = temp_id;
-- 5. 删除临时列
ALTER TABLE tt05 DROP COLUMN temp_id;
-- 6. 将id列移动到第三位(MySQL不支持直接移动列,需重建表)
-- 此处需使用方法1的步骤
mysql> -- 1. 删除现有id列
mysql> ALTER TABLE tt05 DROP COLUMN id;
Query OK, 4 rows affected (0.13 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> -- 2. 添加新的自增id列
mysql> ALTER TABLE tt05
-> ADD COLUMN id INT NOT NULL AUTO_INCREMENT FIRST,
-> ADD PRIMARY KEY (id),
-> AUTO_INCREMENT = 100;
Query OK, 0 rows affected (0.12 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> select * from tt05;
+-----+----------+-----+
| id | name | age |
+-----+----------+-----+
| 100 | abner | 53 |
| 101 | alice | 71 |
| 102 | boris | 47 |
| 103 | clarence | 62 |
+-----+----------+-----+
4 rows in set (0.00 sec)
11.11 使用auto_increment栏来创建多重序列
需要将自增列id单独设为主键。原表定义中同时使用name和id作为复合主键,且id为自增列,这违反了 MySQL 的规则。以下是修正后的 SQL 语句:
sql
CREATE TABLE bug (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
name VARCHAR(30) NOT NULL,
date DATE NOT NULL,
origin VARCHAR(30) NOT NULL,
PRIMARY KEY (id), -- 仅使用id作为主键
UNIQUE KEY (name) -- 如果需要确保name唯一,可添加唯一索引
);
INSERT INTO bug (name, date, origin) VALUES
('mosquito', '2006-10-08', 'bathroom'),
('spider', '2006-10-08', 'basement'),
('fly', '2006-10-08', 'kitchen'),
('moth', '2006-10-09', 'bedroom'),
('centipede', '2006-10-09', 'garage'),
('millipede', '2006-10-09', 'back yard'),
('roach', '2006-10-09', 'kitchen'),
('bee', '2006-10-10', 'garden'),
('wasp', '2006-10-10', 'porch'),
('ladybug', '2006-10-10', 'front yard'),
('butterfly', '2006-10-11', 'garden'),
('grasshopper', '2006-10-11', 'back yard'),
('termite', '2006-10-11', 'basement'),
('flea', '2006-10-12', 'living room'),
('tick', '2006-10-12', 'front yard'),
('silverfish', '2006-10-12', 'bathroom'),
('earwig', '2006-10-13', 'garage'),
('gnat', '2006-10-13', 'kitchen'),
('firefly', '2006-10-13', 'back yard'),
('dragonfly', '2006-10-14', 'garden'),
('aphid', '2006-10-14', 'front yard'),
('caterpillar', '2006-10-14', 'garden'),
('weevil', '2006-10-15', 'pantry'),
('carpenter ant', '2006-10-15', 'basement'),
('black widow', '2006-10-15', 'garage'),
('brown recluse', '2006-10-16', 'basement'),
('cricket', '2006-10-16', 'living room'),
('housefly', '2006-10-16', 'kitchen'),
('fruit fly', '2006-10-17', 'kitchen'),
('woodlouse', '2006-10-17', 'back yard');
mysql> select * from bug order by name, id;
+----+---------------+------------+-------------+
| id | name | date | origin |
+----+---------------+------------+-------------+
| 21 | aphid | 2006-10-14 | front yard |
| 8 | bee | 2006-10-10 | garden |
| 25 | black widow | 2006-10-15 | garage |
| 26 | brown recluse | 2006-10-16 | basement |
| 11 | butterfly | 2006-10-11 | garden |
| 24 | carpenter ant | 2006-10-15 | basement |
| 22 | caterpillar | 2006-10-14 | garden |
| 5 | centipede | 2006-10-09 | garage |
| 27 | cricket | 2006-10-16 | living room |
| 20 | dragonfly | 2006-10-14 | garden |
| 17 | earwig | 2006-10-13 | garage |
| 19 | firefly | 2006-10-13 | back yard |
| 14 | flea | 2006-10-12 | living room |
| 3 | fly | 2006-10-08 | kitchen |
| 29 | fruit fly | 2006-10-17 | kitchen |
| 18 | gnat | 2006-10-13 | kitchen |
| 12 | grasshopper | 2006-10-11 | back yard |
| 28 | housefly | 2006-10-16 | kitchen |
| 10 | ladybug | 2006-10-10 | front yard |
| 6 | millipede | 2006-10-09 | back yard |
| 1 | mosquito | 2006-10-08 | bathroom |
| 4 | moth | 2006-10-09 | bedroom |
| 7 | roach | 2006-10-09 | kitchen |
| 16 | silverfish | 2006-10-12 | bathroom |
| 2 | spider | 2006-10-08 | basement |
| 13 | termite | 2006-10-11 | basement |
| 15 | tick | 2006-10-12 | front yard |
| 9 | wasp | 2006-10-10 | porch |
| 23 | weevil | 2006-10-15 | pantry |
| 30 | woodlouse | 2006-10-17 | back yard |
+----+---------------+------------+-------------+
30 rows in set (0.00 sec)
mysql> select * from housewares;
+------------+------------------+
| id | description |
+------------+------------------+
| DIN40672US | dining table |
| KIT00372UK | garbage disposal |
| KIT01729JP | microwave oven |
| BED00038SG | bedside lamp |
| BTH00485US | shower stall |
| BTH00415JP | lavatory |
+------------+------------------+
6 rows in set (0.00 sec)
关键修改点:
1. 将自增列serial单独设为主键(MySQL 要求自增列必须是主键)
2. 添加唯一索引UNIQUE (category, country, serial)来满足原复合主键的业务逻辑
3. 保留id列的唯一性约束
ALTER TABLE housewares
ADD category VARCHAR(3) NOT NULL FIRST,
ADD serial INT UNSIGNED NOT NULL AUTO_INCREMENT AFTER category,
ADD country VARCHAR(2) NOT NULL AFTER serial,
ADD PRIMARY KEY (serial), -- 将自增列单独设为主键
ADD UNIQUE KEY (category, country, serial), -- 添加唯一约束确保业务逻辑
ADD UNIQUE KEY (id); -- 保持原id唯一性
mysql> select * from housewares;
+----------+--------+---------+------------+------------------+
| category | serial | country | id | description |
+----------+--------+---------+------------+------------------+
| | 1 | | DIN40672US | dining table |
| | 2 | | KIT00372UK | garbage disposal |
| | 3 | | KIT01729JP | microwave oven |
| | 4 | | BED00038SG | bedside lamp |
| | 5 | | BTH00485US | shower stall |
| | 6 | | BTH00415JP | lavatory |
+----------+--------+---------+------------+------------------+
6 rows in set (0.00 sec)
mysql> update housewares set category = left(id, 3);
Query OK, 6 rows affected (0.01 sec)
Rows matched: 6 Changed: 6 Warnings: 0
mysql> update housewares set serial = mid(id, 4, 5);
Query OK, 6 rows affected (0.01 sec)
Rows matched: 6 Changed: 6 Warnings: 0
mysql> update housewares set country = right(id, 2);
Query OK, 6 rows affected (0.01 sec)
Rows matched: 6 Changed: 6 Warnings: 0
mysql> alter table housewares drop id;
Query OK, 0 rows affected (0.15 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> select * from housewares;
+----------+--------+---------+------------------+
| category | serial | country | description |
+----------+--------+---------+------------------+
| BED | 38 | SG | bedside lamp |
| KIT | 372 | UK | garbage disposal |
| BTH | 415 | JP | lavatory |
| BTH | 485 | US | shower stall |
| KIT | 1729 | JP | microwave oven |
| DIN | 40672 | US | dining table |
+----------+--------+---------+------------------+
6 rows in set (0.00 sec)
mysql> select category, serial, country,
-> concat(category, lpad(serial, 5, '0'), country) as id
-> from housewares order by category, country, serial;
+----------+--------+---------+------------+
| category | serial | country | id |
+----------+--------+---------+------------+
| BED | 38 | SG | BED00038SG |
| BTH | 415 | JP | BTH00415JP |
| BTH | 485 | US | BTH00485US |
| DIN | 40672 | US | DIN40672US |
| KIT | 1729 | JP | KIT01729JP |
| KIT | 372 | UK | KIT00372UK |
+----------+--------+---------+------------+
6 rows in set (0.00 sec)
mysql> alter table housewares
-> modify serial int(5) unsigned zerofill not null auto_increment;
Query OK, 0 rows affected, 2 warnings (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 2
mysql> select category, serial, country,
-> concat(category, serial, country) as id
-> from housewares order by category, country, serial;
+----------+--------+---------+------------+
| category | serial | country | id |
+----------+--------+---------+------------+
| BED | 00038 | SG | BED00038SG |
| BTH | 00415 | JP | BTH00415JP |
| BTH | 00485 | US | BTH00485US |
| DIN | 40672 | US | DIN40672US |
| KIT | 01729 | JP | KIT01729JP |
| KIT | 00372 | UK | KIT00372UK |
+----------+--------+---------+------------+
6 rows in set (0.00 sec)
mysql> CREATE FUNCTION houseware_id( category varchar(3),
-> serial int unsigned,
-> country varchar(2))
-> returns varchar(10) deterministic
-> return concat(category, lpad(serial, 5, '0'), country);
Query OK, 0 rows affected (0.01 sec)
mysql> select category, serial, country,
-> houseware_id(category, serial, country) as id
-> from housewares;
+----------+--------+---------+------------+
| category | serial | country | id |
+----------+--------+---------+------------+
| BED | 00038 | SG | BED00038SG |
| BTH | 00415 | JP | BTH00415JP |
| BTH | 00485 | US | BTH00485US |
| DIN | 40672 | US | DIN40672US |
| KIT | 01729 | JP | KIT01729JP |
| KIT | 00372 | UK | KIT00372UK |
+----------+--------+---------+------------+
6 rows in set (0.00 sec)