2

在我的数据库中,我有几个具有 INTEGER 类型的字段。我需要将其中一些更改为 BIGINT。

所以我的问题是,我可以只使用以下命令吗?

ALTER TABLE MyTable ALTER COLUMN MyIntegerColumn TYPE BIGINT;

包含的数据是否以正确的方式转换?转换后,此列是“真正的”BIGINT 列吗?

我知道如果此列有限制(触发器、ForeingKey、...),这是不可能的。但是,如果没有限制,是否可以这样做?

还是通过帮助列转换它更好:

MyIntegerColumn -> MyIntegerColumnBac -> MyBigIntColumn
4

1 回答 1

8

当你执行

ALTER TABLE MyTable ALTER COLUMN MyIntegerColumn TYPE BIGINT;

Firebird 不会将现有数据从 转换INTEGERBIGINT,而是为表创建一个新的格式版本。

插入新行或更新现有行时,该值将存储为 a BIGINT,但在读取 Firebird 时,会将“旧”行即时转换INTEGERBIGINT。作为用户,这对您来说是透明的。这是为了防止需要重写所有现有行,这可能是昂贵的(IO、旧版本行的垃圾收集等)。

所以,请使用ALTER TABLE .. ALTER COLUMN,不要使用MyIntegerColumn -> MyIntegerColumnBac -> MyBigIntColumn。此规则有一些例外情况,例如(可能)有损字符集转换最好以这种方式进行,以防止select新字符集中不存在字符时出现音译错误,或将 (var)char 列更改为更短(这不能用alter column) 来完成。

更具体一点:当在数据库中写入一行时,它包含该行的格式版本(也称为版本计数)。格式版本指向一行(数据类型等)Firebird 应该如何读取该行的描述。alter table 将创建一个新的格式版本,并且在写入新行或更新现有行时将应用该格式。读取旧行时,Firebird 将应用必要的转换以将该行呈现为新格式(例如添加具有默认值的新列,转换列的数据类型)。

这些格式版本也是限制更改表数量的一个原因:如果您在单个表上应用超过 255 个更改表,则必须在允许进一步更改之前备份和恢复数据库(格式版本为单字节)那张桌子。

于 2017-03-15T12:10:35.670 回答