当你执行
ALTER TABLE MyTable ALTER COLUMN MyIntegerColumn TYPE BIGINT;
Firebird 不会将现有数据从 转换INTEGER
为BIGINT
,而是为表创建一个新的格式版本。
插入新行或更新现有行时,该值将存储为 a BIGINT
,但在读取 Firebird 时,会将“旧”行即时转换INTEGER
为BIGINT
。作为用户,这对您来说是透明的。这是为了防止需要重写所有现有行,这可能是昂贵的(IO、旧版本行的垃圾收集等)。
所以,请使用ALTER TABLE .. ALTER COLUMN
,不要使用MyIntegerColumn -> MyIntegerColumnBac -> MyBigIntColumn
。此规则有一些例外情况,例如(可能)有损字符集转换最好以这种方式进行,以防止select
新字符集中不存在字符时出现音译错误,或将 (var)char 列更改为更短(这不能用alter column
) 来完成。
更具体一点:当在数据库中写入一行时,它包含该行的格式版本(也称为版本计数)。格式版本指向一行(数据类型等)Firebird 应该如何读取该行的描述。alter table 将创建一个新的格式版本,并且在写入新行或更新现有行时将应用该格式。读取旧行时,Firebird 将应用必要的转换以将该行呈现为新格式(例如添加具有默认值的新列,转换列的数据类型)。
这些格式版本也是限制更改表数量的一个原因:如果您在单个表上应用超过 255 个更改表,则必须在允许进一步更改之前备份和恢复数据库(格式版本为单字节)那张桌子。