將甲骨文功能遷移到 AWS 上的 PostgreSQL - AWS 方案指引

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

將甲骨文功能遷移到 AWS 上的 PostgreSQL

由拉凱什拉格夫 (AWS) 和拉麥絲帕瑟里 (AWS) 創建

環境:PoC 或試點

來源:甲骨文數據庫

目標:AWS 上的資料庫

R 類型:重新平台

工作量:甲骨文

技術:移轉;資料庫

AWS 服務:Amazon Aurora; Amazon RDS; AWS SCT; AWS CLI

Summary

此模式描述了將 Oracle 資料庫中的ROWID虛擬資料欄功能遷移到 Amazon 關聯式資料庫服務 (Amazon RDS) 中的 PostgreSQL 資料庫的選項,適用於 PostgreSQL、Amazon Aurora PostgreSQL 相容版本或亞馬遜 Elastic Compute Cloud (Amazon EC2)。

在 Oracle 資料庫中,ROWID虛擬資料欄是資料表中資料列的實體位址。此偽列用於唯一標識行,即使主鍵不存在於表中。PostgreSQL 有一個類似的偽列ctid,但它不能用作. ROWIDPostgreSQL 文檔中所述,如果更新或每個VACUUM進程之後,ctid可能會更改。

有三種方法可以在 PostgreSQL 中創建ROWID虛擬列功能:

  • 使用主索引鍵欄,而不是識別資料表中的資料列。ROWID

  • 在表中使用邏輯主/唯一鍵(可能是複合鍵)。 

  • 添加一個包含自動生成值的列,並使其成為模擬的主/唯一鍵。ROWID

此模式會引導您完成所有三種實作,並說明每個選項的優缺點。

先決條件和限制

先決條件

  • 有效的 AWS 帳戶

  • 程序語 PostgreSQL 編碼專業知識

  • 來源 Oracle 資料庫

  • Amazon RDS for PostgreSQL 或 Aurora 與 PostgreSQL 相容的叢集,或用於託管 PostgreSQL 資料庫的 EC2 執行個體

限制

  • 此模式提供了功能的解決方法。ROWIDPostgreSQL 不提供與甲骨文數據庫ROWID中的相同內容。

產品版本

  • PostgreSQL 11.9 或更高版本

架構

源, 技術, 堆棧

  • Oracle Database

目標技術堆疊

  • Aurora PostgreSQL 相容的亞馬遜 RDS,或具有 PostgreSQL 資料庫的 EC2 執行個體

在 AWS 上將甲骨 PostgreSQL 數據庫轉換為

實作選項

有三個選項可以解決 PostgreSQL 缺乏ROWID支援的問題,這取決於您的資料表是否具有主索引鍵或唯一索引、邏輯主索引鍵或身分識別屬性。您的選擇取決於您的專案時間表、目前的移轉階段,以及應用程式和資料庫程式碼的相依性。

選項

Description

優點

缺點

主鍵或唯一索引

如果你的 Oracle 表有一個主鍵,你可以使用這個鍵的屬性來唯一標識一行。 

  • 不依賴於專有的數據庫功能。

  • 對效能的影響最小,因為主索引鍵欄位已編製索引。

  • 需要變更應用程式和資料庫程式碼,這些程式碼必ROWID須依賴於切換至主索引鍵欄位

 

邏輯主/唯一鍵

如果您的 Oracle 表具有邏輯主鍵,則可以使用此鍵的屬性唯一標識行。邏輯主索引鍵是由可唯一識別資料列的屬性或一組屬性所組成,但不會透過條件約束在資料庫上強制執行。

  • 不依賴於專有的數據庫功能。

  • 需要變更應用程式和資料庫程式碼,這些程式碼必ROWID須依賴於切換至主索引鍵欄位

  • 如果邏輯主索引鍵的屬性未編製索引,則會對效能造成重大影響。不過,您可以新增唯一索引來防止效能問題。

識別屬性

如果您的 Oracle 表沒有主鍵,則可以將其他字段創建為GENERATED ALWAYS AS IDENTITY。每當資料插入資料表時,這個屬性就會產生唯一的值,因此它可用來唯一識別資料處理語言 (DML) 作業的資料列。

  • 不依賴於專有的數據庫功能。

  • PostgreSQL 資料庫會填入屬性並維護其唯一性。

  • 需要變更依賴於切換到識別屬性的應用程式和資料庫程式碼。ROWID

  • 如果其他欄位未編製索引,則會對效能產生重大影響。但是,您可以添加索引以防止性能問題。

工具

史诗

任務描述所需技能

識別使用ROWID屬性的 Oracle 表格。

使用 AWS 結 Schema Conversion Tool (AWS SCT) 來識別具有ROWID功能的 Oracle 表格。如需詳細資訊,請參閱 AWS SCT 文件

—或—

在 Oracle 中,使用檢DBA_TAB_COLUMNS視表來識別具有ROWID屬性的表格。這些欄位可用來儲存 10 位元組英數字元。確定用法並將其轉換為適當的VARCHAR字段。

DBA 或開發人員

識別參考這些資料表的程式碼。

使用 AWS SCT 產生遷移評估報告,以識別受影響的程序。ROWID如需詳細資訊,請參閱 AWS SCT 文件

—或—

在來源 Oracle 資料庫中,使用dba_source表格的文字欄位來識別使用ROWID功能的物件。

DBA 或開發人員
任務描述所需技能

識別沒有主鍵的表。

在來源 Oracle 資料庫中,用DBA_CONSTRAINTS來識別沒有主索引鍵的資料表。此資訊將協助您決定每個表格的策略。例如:

select dt.* from dba_tables dt where not exists (select 1 from all_constraints ct where ct.owner = Dt.owner and ct.table_name = Dt.table_name and ct.constraint_type = 'P' ) and dt.owner = '{schema}'
DBA 或開發人員
任務描述所需技能

對具有已定義或邏輯主索引鍵的資料表套用變更。

變更 [其他資訊] 區段中顯示的應用程式和資料庫程式碼,以使用唯一的主索引鍵或邏輯主索引鍵來識別資料表中的資料列。

DBA 或開發人員

向沒有已定義或邏輯主索引鍵的資料表新增其他欄位。

新增類型的屬性GENERATED ALWAYS AS IDENTITY。變更 [其他資訊] 區段中顯示的應用程式和料庫程式碼。

DBA 或開發人員

如有必要,請新增索引。

將索引添加到其他字段或邏輯主鍵以提高 SQL 性能。

DBA 或開發人員

相關資源

其他資訊

以下各節提供甲骨文和 PostgreSQL 的代碼示例來說明這三種方法。

案例 1:使用主唯一索引鍵

在下列範例中,您會建立以emp_id做為主索引鍵的資料表testrowid_s1

甲骨文代碼:

create table testrowid_s1 (emp_id integer, name varchar2(10), CONSTRAINT testrowid_pk PRIMARY KEY (emp_id)); INSERT INTO testrowid_s1(emp_id,name) values (1,'empname1'); INSERT INTO testrowid_s1(emp_id,name) values (2,'empname2'); INSERT INTO testrowid_s1(emp_id,name) values (3,'empname3'); INSERT INTO testrowid_s1(emp_id,name) values (4,'empname4'); commit; SELECT rowid,emp_id,name FROM testrowid_s1; ROWID EMP_ID NAME ------------------ ---------- ---------- AAAF3pAAAAAAAMOAAA 1 empname1 AAAF3pAAAAAAAMOAAB 2 empname2 AAAF3pAAAAAAAMOAAC 3 empname3 AAAF3pAAAAAAAMOAAD 4 empname4 UPDATE testrowid_s1 SET name = 'Ramesh' WHERE rowid = 'AAAF3pAAAAAAAMOAAB' ; commit; SELECT rowid,emp_id,name FROM testrowid_s1; ROWID EMP_ID NAME ------------------ ---------- ---------- AAAF3pAAAAAAAMOAAA 1 empname1 AAAF3pAAAAAAAMOAAB 2 Ramesh AAAF3pAAAAAAAMOAAC 3 empname3 AAAF3pAAAAAAAMOAAD 4 empname4

PostgreSQL:

CREATE TABLE public.testrowid_s1 ( emp_id integer, name character varying, primary key (emp_id) ); insert into public.testrowid_s1 (emp_id,name) values (1,'empname1'),(2,'empname2'),(3,'empname3'),(4,'empname4'); select emp_id,name from testrowid_s1; emp_id | name --------+---------- 1 | empname1 2 | empname2 3 | empname3 4 | empname4 update testrowid_s1 set name = 'Ramesh' where emp_id = 2 ; select emp_id,name from testrowid_s1; emp_id | name --------+---------- 1 | empname1 3 | empname3 4 | empname4 2 | Ramesh

案例 2:使用邏輯主鍵

在下列範例中,您建立的資料表testrowid_s2emp_id做為邏輯主索引鍵。

甲骨文代碼:

create table testrowid_s2 (emp_id integer, name varchar2(10) ); INSERT INTO testrowid_s2(emp_id,name) values (1,'empname1'); INSERT INTO testrowid_s2(emp_id,name) values (2,'empname2'); INSERT INTO testrowid_s2(emp_id,name) values (3,'empname3'); INSERT INTO testrowid_s2(emp_id,name) values (4,'empname4'); commit; SELECT rowid,emp_id,name FROM testrowid_s2; ROWID EMP_ID NAME ------------------ ---------- ---------- AAAF3rAAAAAAAMeAAA 1 empname1 AAAF3rAAAAAAAMeAAB 2 empname2 AAAF3rAAAAAAAMeAAC 3 empname3 AAAF3rAAAAAAAMeAAD 4 empname4 UPDATE testrowid_s2 SET name = 'Ramesh' WHERE rowid = 'AAAF3rAAAAAAAMeAAB' ; commit; SELECT rowid,emp_id,name FROM testrowid_s2; ROWID EMP_ID NAME ------------------ ---------- ---------- AAAF3rAAAAAAAMeAAA 1 empname1 AAAF3rAAAAAAAMeAAB 2 Ramesh AAAF3rAAAAAAAMeAAC 3 empname3 AAAF3rAAAAAAAMeAAD 4 empname4

PostgreSQL:

CREATE TABLE public.testrowid_s2 ( emp_id integer, name character varying ); insert into public.testrowid_s2 (emp_id,name) values (1,'empname1'),(2,'empname2'),(3,'empname3'),(4,'empname4'); select emp_id,name from testrowid_s2; emp_id | name --------+---------- 1 | empname1 2 | empname2 3 | empname3 4 | empname4 update testrowid_s2 set name = 'Ramesh' where emp_id = 2 ; select emp_id,name from testrowid_s2; emp_id | name --------+---------- 1 | empname1 3 | empname3 4 | empname4 2 | Ramesh

案例 3:使用身份識別屬性

在下列範例中,您可以使用識別屬性來建立沒有主索引鍵的資料表testrowid_s3

甲骨文代碼:

create table testrowid_s3 (name varchar2(10)); INSERT INTO testrowid_s3(name) values ('empname1'); INSERT INTO testrowid_s3(name) values ('empname2'); INSERT INTO testrowid_s3(name) values ('empname3'); INSERT INTO testrowid_s3(name) values ('empname4'); commit; SELECT rowid,name FROM testrowid_s3; ROWID NAME ------------------ ---------- AAAF3sAAAAAAAMmAAA empname1 AAAF3sAAAAAAAMmAAB empname2 AAAF3sAAAAAAAMmAAC empname3 AAAF3sAAAAAAAMmAAD empname4 UPDATE testrowid_s3 SET name = 'Ramesh' WHERE rowid = 'AAAF3sAAAAAAAMmAAB' ; commit; SELECT rowid,name FROM testrowid_s3; ROWID NAME ------------------ ---------- AAAF3sAAAAAAAMmAAA empname1 AAAF3sAAAAAAAMmAAB Ramesh AAAF3sAAAAAAAMmAAC empname3 AAAF3sAAAAAAAMmAAD empname4

PostgreSQL:

CREATE TABLE public.testrowid_s3 ( rowid_seq bigint generated always as identity, name character varying ); insert into public.testrowid_s3 (name) values ('empname1'),('empname2'),('empname3'),('empname4'); select rowid_seq,name from testrowid_s3; rowid_seq | name -----------+---------- 1 | empname1 2 | empname2 3 | empname3 4 | empname4 update testrowid_s3 set name = 'Ramesh' where rowid_seq = 2 ; select rowid_seq,name from testrowid_s3; rowid_seq | name -----------+---------- 1 | empname1 3 | empname3 4 | empname4 2 | Ramesh