如何在不丢失数据的情况下将MySQL的BIGINT转换为unsigned?

How to convert MySQL's BIGINT into unsigned without losing data?

我需要将 MySQL 数据库表列从(有符号)BIGINT 转换为无符号 BIGINT。如果我这样做:

ALTER TABLE `$tblNm` MODIFY `flgs` BIGINT UNSIGNED;

任何设置为 63 位的值都将重置为 0!

我需要做什么才能无损地转换所有值?

类似于

您也可以尝试使用 unsigned BIGINT 添加新列

         ALTER TABLE `$tblNm`
         ADD COLUMN new_column BIGINT UNSIGNED AFTER flgs;

然后使用 cast

更新新列中的强制转换值
        UPDATE `$tblNm` 
        SET new_column=CAST(flgs AS UNSIGNED);

然后删除列 flgs

       ALTER TABLE `$tblNm`
       DROP COLUMN flgs;

将新列重命名为 flgs

       ALTER TABLE `$tblNm`
       CHANGE COLUMN new_column flgs BIGINT UNSIGNED

编辑 为了在交易中执行此操作,我们可以按以下方式更新它。

         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;

EDIT-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;

在这种情况下,你不需要显式写START TRANSACTION

据我了解 - 您有一个存储为 BIGINT(带符号)的位掩码并且该列包含负数(最左边的位设置为 1)。您想将列类型转换为 BIGINT UNSIGNED 保留二进制值。

我建议将类型转换为 BINARY(8),然后再转换为 BIGINT UNSIGNED。不幸的是,第二步没有奏效。但是转换超过 BIT(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;

Returns:

| flgs                 |
| -------------------- |
| 1                    |
| 18446744073709551615 |

View on DB Fiddle