我有两张桌子:
CREATE TABLE table_a (
id SERIAL
);
CREATE TABLE table_b (
id SERIAL
);
我想将表交换掉,并将new table_a的auto_increment设置为table_b的MAX(id)+1。 E.g。
SELECT @A:=MAX(id) FROM table_a;
SET @qry = CONCAT('ALTER TABLE table_b AUTO_INCREMENT =', @A+1);
PREPARE stmt FROM @qry;
EXECUTE stmt;
RENAME TABLE table_a TO table_b_tmp, table_b TO table_a, table_b_tmp TO table_a;
不幸的是,我无法锁定表,也无法在事务中执行此操作,因为RENAME TABLE无法在锁定的表上运行,并且ALTER TABLE会隐式提交。
我能想到避免重叠id的唯一解决方案是设置auto_increment + 50,但由于这个过程经常发生,我宁愿在我的id中没有大量的漏洞。
有什么想法吗?
答案 0 :(得分:0)
只要服务器不在MS Windows版本上并且您坚持使用非事务性表,您就应该能够使用表锁并ALTER TABLE
table_name
RENAME TO
new_table_name
声明。
LOCK TABLES table_a WRITE, table_b WRITE;
SELECT @A:=MAX(id)+1 FROM table_a;
ALTER TABLE table_a RENAME TO table_a_tmp;
LOCK TABLES table_b WRITE, table_a_tmp WRITE;
PREPARE stmt FROM 'ALTER TABLE table_b RENAME TO table_a, AUTO_INCREMENT = ?';
EXECUTE stmt USING @A;
ALTER TABLE table_a_tmp RENAME TO table_b;
UNLOCK TABLES;
第二把锁让我担心。如果还有其他待处理会话,他们会在锁定之前获得表格吗?关于上述工作,我也很容易出错。我基于以下关于锁,事务和ALTER语句的页面。
我的另一个想法是你可以为插入创建一个MERGE表,将合并方法更新为FIRST或LAST而不是(连同?)交换表。那会有用吗?