如何在不丢失数据的情况下将MySQL的BIGINT转换为unsigned?
我需要将MySQL数据库表列从有符号的BIGINT转换为无符号的BIGINT。如果我这样做:如何在不丢失数据的情况下将MySQL的BIGINT转换为unsigned?,mysql,type-conversion,bigint,Mysql,Type Conversion,Bigint,我需要将MySQL数据库表列从有符号的BIGINT转换为无符号的BIGINT。如果我这样做: ALTER TABLE `$tblNm` MODIFY `flgs` BIGINT UNSIGNED; 设置了63位的任何值都将重置为0 我需要做什么才能转换所有值而不丢失?类似于 您还可以尝试添加带有无符号BIGINT的新列 然后使用cast更新新列中的casted值 然后放下flgs柱 使用flgs重命名新列 编辑 为了在事务中执行此操作,我们可以如下更新此操作 SET auto
ALTER TABLE `$tblNm` MODIFY `flgs` BIGINT UNSIGNED;
设置了63位的任何值都将重置为0
我需要做什么才能转换所有值而不丢失?类似于
您还可以尝试添加带有无符号BIGINT的新列
然后使用cast更新新列中的casted值
然后放下flgs柱
使用flgs重命名新列
编辑
为了在事务中执行此操作,我们可以如下更新此操作
SET autocommit=0;
START TRANSACTION;
ALTER TABLE `$tblNm`
ADD COLUMN new_column BIGINT UNSIGNED AFTER flgs;
UPDATE `$tblNm`
SET new_column=CAST(flgs AS UNSIGNED);
ALTER TABLE `$tblNm`
DROP COLUMN flgs;
ALTER TABLE `$tblNm`
CHANGE COLUMN new_column flgs BIGINT UNSIGNED;
COMMIT;
编辑-2
如果在启动事务之前需要锁定表,则上述脚本将更改为
SET autocommit=0;
LOCK TABLES `$tblNm` WRITE
ALTER TABLE `$tblNm`
ADD COLUMN new_column BIGINT UNSIGNED AFTER flgs;
UPDATE `$tblNm`
SET new_column=CAST(flgs AS UNSIGNED);
ALTER TABLE `$tblNm`
DROP COLUMN flgs;
ALTER TABLE `$tblNm`
CHANGE COLUMN new_column flgs BIGINT UNSIGNED;
COMMIT;
UNLOCK TABLES;
在这种情况下,您不需要显式地写入启动事务,正如我所理解的那样-您有一个位掩码存储为BIGINT signed,列包含负数,最左边的位设置为1。您希望将列类型转换为保留二进制值的BIGINT UNSIGNED 我建议将类型转换为BINARY8,然后再转换为biginunsigned。不幸的是,第二步没有成功。但是在我的测试中转换位64是可行的。因此,您可以尝试:
ALTER TABLE tbl MODIFY `flgs` BIT(64);
ALTER TABLE tbl MODIFY `flgs` BIGINT UNSIGNED;
测试用例:
create table tbl (flgs bigint);
insert into tbl (flgs) values (1), (-1);
ALTER TABLE tbl MODIFY `flgs` BIT(64);
ALTER TABLE tbl MODIFY `flgs` BIGINT UNSIGNED;
select * from tbl;
返回:
| flgs |
| -------------------- |
| 1 |
| 18446744073709551615 |
您的INSERT INTO语句有一个错误,它可能是一个更新,但除此之外,我喜欢这个想法。这就像是一个大的杀伤力,但似乎没有其他方法不丢失数据。演员必须是未签名的CASTflgs,而不是你在那里拥有的。然后必须有DROP列,后跟CHANGE列。因此,为什么不调整所有这些,我将把它标记为一个答案——除非其他人有更好的想法?我没有指定MySQL的版本,所以可能您的语法适用于较新的版本。我在5.7.25上,那里的CASTflgs必须是UNSIGNED,并且重命名ALTER TABLE tbl CHANGE new_column flgs BIGINT UNSIGNED。这可能需要一个事务或MySQL中的任何调用。设置自动提交=0;然后将其包装在BEGIN和COMMITID中,我们需要锁定表还是在BEGIN之后自动锁定表?此资料-从tbl LIMIT 018446744073709551615中选择*进行更新;嘿,有人不喜欢这个问题:是的,谢谢。这可能是一个更好的解决方案。此时,我已经使用我标记的方法转换了所有数据。因此,如果其他人遇到同样的问题,他们可能会尝试你的方法。
SET autocommit=0;
LOCK TABLES `$tblNm` WRITE
ALTER TABLE `$tblNm`
ADD COLUMN new_column BIGINT UNSIGNED AFTER flgs;
UPDATE `$tblNm`
SET new_column=CAST(flgs AS UNSIGNED);
ALTER TABLE `$tblNm`
DROP COLUMN flgs;
ALTER TABLE `$tblNm`
CHANGE COLUMN new_column flgs BIGINT UNSIGNED;
COMMIT;
UNLOCK TABLES;
ALTER TABLE tbl MODIFY `flgs` BIT(64);
ALTER TABLE tbl MODIFY `flgs` BIGINT UNSIGNED;
create table tbl (flgs bigint);
insert into tbl (flgs) values (1), (-1);
ALTER TABLE tbl MODIFY `flgs` BIT(64);
ALTER TABLE tbl MODIFY `flgs` BIGINT UNSIGNED;
select * from tbl;
| flgs |
| -------------------- |
| 1 |
| 18446744073709551615 |