[英]Copying tables from one database to another, in Firebird 2.1
我需要在 Firebird 2.1 中將表從一個數據庫復制到另一個數據庫,但以某種方式非常快,您可以在控制台上運行它。
我使用了 FBcopy,但從老板那里得到的答案是它太慢了。 這必須在多個事務中完成,因為表非常大。 任何想法我怎么能做到這一點?
一種可能的解決方案是使用源表(或至少:要傳輸的數據)的布局創建外部表,一個在源數據庫中,另一個在目標數據庫中。
在源數據庫中,您從源表中選擇要傳輸的內容並將其插入(空)外部表中。 完成后,您可以將文件復制到其他數據庫。 如果它們在同一台服務器上,則可以直接使用相同的文件(我沒有使用足夠的外部表來指出除下面指出的風險之外的風險)。
在目標數據庫上,您可以從外部表中進行選擇並插入到最終的目標表中。
創建和使用外部表時,請記住以下幾點:
外部表文件是固定寬度的二進制數據格式,我鏈接的文檔顯示了如何使它看起來像固定寬度的文本格式,但實際上並非如此。
字符數據的正確解釋取決於字符集(正確的字符轉換和數據長度),例如 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
。
這是一個老問題,但是;
您可以嘗試禁用目標表上的索引。 復制數據,然后啟用索引。
您還可以檢查目標表上的觸發器並禁用不必要的觸發器。 是否有任何觸發器從其他表中進行選擇或插入?
您還可以在目標數據庫上禁用“強制寫入”。 我假設您有一台帶有冗余電源的服務器和一個 RAID 磁盤系統(或雲) 復制后,您可以重新打開“強制寫入”。 https://www.firebirdsql.org/pdfmanual/html/gfix-sync.html
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.