在 Firebird 2.1 中将表从一个数据库复制到另一个数据库
Copying tables from one database to another, in Firebird 2.1
我需要在 Firebird 2.1 中将表从一个数据库复制到另一个数据库,但在某种程度上这非常快,您可以 运行 在控制台上执行此操作。
我用了FBcopy,但是老大说太慢了。这必须在多个事务中完成,因为表非常大。我有什么想法可以做到这一点?
一种可能的解决方案是使用源 table(或至少:您要传输的数据)的布局创建 external tables,一个在源数据库中,另一个在目标数据库中数据库。
在源数据库中,您 select 您想要从源 table 传输的内容并将其插入(空的)外部 table。完成后,您可以将文件复制到其他数据库。如果它们在同一台服务器上,则可以直接使用相同的文件(我没有使用外部 tables 足以指出下面指出的风险之外的风险)。
在目标数据库上,您可以从外部 table select 插入最终目标 table.
创建和使用外部 table 时,请牢记以下几点:
外部 tables 文件是固定宽度的 binary 数据格式,我的文档 link 展示了如何制作它看起来像一个固定宽度的文本格式,但实际上不是。
字符数据的正确解释取决于字符集(正确的字符转换和数据长度),例如 UTF8 列是其声明长度的 4 倍。创建外部 tables 时,显式声明字符集以避免出现问题 - 例如 - 数据库之间的默认字符集不同。
使用单字节字符集与使用 4 字节字符集的区别会导致严重损坏,因为 WIN1252 数据库中的 CHAR(100)
将 written/read 为 100 字节,但在UTF8 数据库,它将 written/read 为 400 字节。所以一定要明确使用字符集,例如CHAR(100) CHARACTER SET WIN1252
.
鉴于其未压缩的特性,如果您的数据允许,最好使用单字节字符集而不是 - 例如 - UTF8。
外部 table 不支持 blob 或数组。
您不能删除或更新外部 table 中的行。要清除它,您需要删除底层外部文件(Firebird 会在必要时自动创建一个新文件)。
无法定义主键或外键约束,也无法在外部 tables
上定义索引
为了能够使用外部 tables,您需要配置 Firebird 以允许它访问这些文件。在服务器的 firebird.conf
中,将 ExternalFileAccess
设置从默认的 None
更改为 ExternalFileAccess = Restrict <path>
,其中路径是文件夹或分号分隔的文件夹列表,其中 Firebird有访问权限。阅读配置文件中有关此选项的文档!
一个(非常)小的例子。假设两个数据库都在同一台服务器上,并且您的数据库有一个 CUSTOMER
table 要传输:
create table customer (
id integer constraint pk_customer primary key,
customer varchar(25) character set win1252 not null
)
然后创建等效的外部 table:
create table ext_customer external file 'D:\data\DB\exttables\ext_customer.dat' (
id integer not null,
customer varchar(25) character set win1252 not null
)
在源数据库和目标数据库中创建这个table。
然后在源数据库中把客户数据放在外部table:
insert into ext_customer (id, customer) select id, customer from customer;
确保提交。
在目标数据库中,您就可以使用数据了。例如,如果 customer
table 当前为空,您可以简单地执行我们在源代码中所做的相反操作:
insert into customer (id, customer) select id, customer from ext_customer;
如果您需要更多控制,请考虑查看 MERGE
。
这是一个老问题但是;
您可以尝试禁用目标 table 上的索引。
复制数据,然后启用索引。
您还可以检查目标 table 上的触发器并禁用不需要的触发器。是否有从其他 table 中选择或插入其他 table 的触发器?
您还可以在目标数据库上禁用 "forced writes"。我假设您有一台带有冗余电源和 raid 磁盘系统(或云)的服务器
复制后,您可以重新打开 "forced writes"。
https://www.firebirdsql.org/pdfmanual/html/gfix-sync.html
我需要在 Firebird 2.1 中将表从一个数据库复制到另一个数据库,但在某种程度上这非常快,您可以 运行 在控制台上执行此操作。
我用了FBcopy,但是老大说太慢了。这必须在多个事务中完成,因为表非常大。我有什么想法可以做到这一点?
一种可能的解决方案是使用源 table(或至少:您要传输的数据)的布局创建 external tables,一个在源数据库中,另一个在目标数据库中数据库。
在源数据库中,您 select 您想要从源 table 传输的内容并将其插入(空的)外部 table。完成后,您可以将文件复制到其他数据库。如果它们在同一台服务器上,则可以直接使用相同的文件(我没有使用外部 tables 足以指出下面指出的风险之外的风险)。
在目标数据库上,您可以从外部 table select 插入最终目标 table.
创建和使用外部 table 时,请牢记以下几点:
外部 tables 文件是固定宽度的 binary 数据格式,我的文档 link 展示了如何制作它看起来像一个固定宽度的文本格式,但实际上不是。
字符数据的正确解释取决于字符集(正确的字符转换和数据长度),例如 UTF8 列是其声明长度的 4 倍。创建外部 tables 时,显式声明字符集以避免出现问题 - 例如 - 数据库之间的默认字符集不同。
使用单字节字符集与使用 4 字节字符集的区别会导致严重损坏,因为 WIN1252 数据库中的
CHAR(100)
将 written/read 为 100 字节,但在UTF8 数据库,它将 written/read 为 400 字节。所以一定要明确使用字符集,例如CHAR(100) CHARACTER SET WIN1252
.鉴于其未压缩的特性,如果您的数据允许,最好使用单字节字符集而不是 - 例如 - UTF8。
外部 table 不支持 blob 或数组。
您不能删除或更新外部 table 中的行。要清除它,您需要删除底层外部文件(Firebird 会在必要时自动创建一个新文件)。
无法定义主键或外键约束,也无法在外部 tables
上定义索引
为了能够使用外部 tables,您需要配置 Firebird 以允许它访问这些文件。在服务器的 firebird.conf
中,将 ExternalFileAccess
设置从默认的 None
更改为 ExternalFileAccess = Restrict <path>
,其中路径是文件夹或分号分隔的文件夹列表,其中 Firebird有访问权限。阅读配置文件中有关此选项的文档!
一个(非常)小的例子。假设两个数据库都在同一台服务器上,并且您的数据库有一个 CUSTOMER
table 要传输:
create table customer (
id integer constraint pk_customer primary key,
customer varchar(25) character set win1252 not null
)
然后创建等效的外部 table:
create table ext_customer external file 'D:\data\DB\exttables\ext_customer.dat' (
id integer not null,
customer varchar(25) character set win1252 not null
)
在源数据库和目标数据库中创建这个table。
然后在源数据库中把客户数据放在外部table:
insert into ext_customer (id, customer) select id, customer from customer;
确保提交。
在目标数据库中,您就可以使用数据了。例如,如果 customer
table 当前为空,您可以简单地执行我们在源代码中所做的相反操作:
insert into customer (id, customer) select id, customer from ext_customer;
如果您需要更多控制,请考虑查看 MERGE
。
这是一个老问题但是;
您可以尝试禁用目标 table 上的索引。 复制数据,然后启用索引。
您还可以检查目标 table 上的触发器并禁用不需要的触发器。是否有从其他 table 中选择或插入其他 table 的触发器?
您还可以在目标数据库上禁用 "forced writes"。我假设您有一台带有冗余电源和 raid 磁盘系统(或云)的服务器 复制后,您可以重新打开 "forced writes"。 https://www.firebirdsql.org/pdfmanual/html/gfix-sync.html