在Firebird 2.1中将表从一个数据库复制到另一个数据库

时间:2018-07-06 11:00:50

标签: sql database firebird firebird2.1

我需要在Firebird 2.1中将表从一个数据库复制到另一个数据库,但是以某种非常快速的方式,您可以在控制台上运行它。

我使用了FBcopy,但从老板那里得到了答案,它太慢了。这必须在多个事务中完成,因为表很大。有什么想法可以做到吗?

2 个答案:

答案 0 :(得分:2)

一种可能的解决方案是使用源表(或至少:要传输的数据)的布局创建external tables,一个在源数据库中,另一个在目标数据库中。

在源数据库中,从源表中选择要传输的内容,然后将其插入(空)外部表中。完成之后,您可以将文件复制到另一个数据库。如果它们在同一台服务器上,则可以直接使用同一文件(我没有使用足够多的外部表来指出超出以下指出的风险)。

然后在目标数据库上,您可以从外部表中选择并插入最终目标表中。

在创建和使用外部表时,请记住以下几点:

  • 外部表文件是固定宽度的 binary 数据格式,我链接的文档显示了如何使它看起来像固定宽度的文本格式,但实际上不是。

  • 对字符数据的正确解释取决于字符集(用于正确的字符转换和数据长度),例如,UTF8列是其声明长度的4倍。创建外部表时,显式声明字符集,以避免(例如)数据库之间的不同默认字符集出现问题。

    使用单字节字符集与4字节字符集之间的差异将导致极端损坏,因为WIN1252数据库中的CHAR(100)将被写入/读取为100字节,但是在UTF8数据库中,它将被写入/读取为400字节。因此,请确保明确使用字符集,例如CHAR(100) CHARACTER SET WIN1252

  • 鉴于其未压缩的性质,如果您的数据允许,最好使用单字节字符集而不是-例如-UTF8。

  • 外部表不支持Blob或数组。

  • 您不能删除或更新外部表中的行。要清除它,您需要删除基础外部文件(Firebird会在必要时自动创建一个新文件)。

  • 不可能定义主键或外键约束,也不能在外部表上建立索引

要能够使用外部表,您需要配置Firebird以使其能够访问那些文件。在服务器的firebird.conf中,将ExternalFileAccess设置从默认值None更改为ExternalFileAccess = Restrict <path>,其中path是文件夹或用分号分隔的文件夹列表,其中Firebird有访问权限。阅读配置文件中有关此选项的文档!

一个(非常)小的例子。假设两个数据库都在同一服务器上,并且您的数据库具有要传输的CUSTOMER表:

create table customer (
    id integer constraint pk_customer primary key,
    customer varchar(25) character set win1252 not null
)

然后创建等效的外部表:

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
)

在源数据库和目标数据库中都创建此表。

然后在源数据库中将客户数据放入外部表中

insert into ext_customer (id, customer) select id, customer from customer;

请务必提交。

然后可以在目标数据库中使用数据。例如,如果customer表当前为空,则可以简单地执行与源代码中相反的操作:

insert into customer (id, customer) select id, customer from ext_customer;

如果您需要更多控制权,请考虑查看MERGE

答案 1 :(得分:1)

这是一个古老的问题,但是;

您可以尝试禁用目标表上的索引。 复制数据,然后启用索引。

您还可以检查目标表上的触发器,并禁用不必要的触发器。是否有任何触发器可以从其他表中选择或插入其他表?

您还可以在目标数据库上禁用“强制写入”。我假设您有一台具有冗余电源的服务器和一个RAID磁盘系统(或云) 复制后,可以重新打开“强制写入”。 https://www.firebirdsql.org/pdfmanual/html/gfix-sync.html