如何在不丢失数据的情况下将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 |
我需要将 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 |