Memigrasikan pengguna dan skema Oracle® Database ke Cloud SQL untuk PostgreSQL

Dokumen ini adalah bagian dari rangkaian yang memberikan informasi dan panduan penting terkait perencanaan dan pelaksanaan migrasi database Oracle® 11g/12c ke Cloud SQL untuk PostgreSQL versi 12. Dokumen ini membahas perbedaan mendasar antara Oracle® Database dan Cloud SQL untuk PostgreSQL dalam kaitannya dengan pembuatan pengguna, skema, tabel, indeks, dan tampilan.

Selain bagian penyiapan pendahuluan, rangkaian ini mencakup bagian berikut:

Perbedaan terminologi antara Oracle dan Cloud SQL untuk PostgreSQL

Oracle dan Cloud SQL untuk PostgreSQL memiliki arsitektur dan terminologi yang berbeda untuk instance, database, pengguna, dan skema. Untuk mengetahui ringkasan perbedaan ini, lihat bagian terminologi dari rangkaian ini.

Mengekspor konfigurasi Oracle

Salah satu langkah pertama saat merencanakan migrasi ke Cloud SQL untuk PostgreSQL adalah meninjau setelan parameter yang ada di database Oracle sumber. Setelan seputar alokasi memori, himpunan karakter, dan parameter penyimpanan sangat berguna karena dapat menginformasikan konfigurasi awal dan ukuran lingkungan target Cloud SQL untuk PostgreSQL. Ada beberapa metode untuk mengekstrak setelan parameter Oracle. Berikut beberapa metode yang umum:

  • Laporan Automatic Workload Repository (AWR) menyimpan data alokasi resource (CPU, RAM), konfigurasi parameter instance, dan sesi aktif maksimum.
  • DBA_HIST, V$OSSTAT, dan V$LICENSE untuk detail penggunaan CPU.
  • Tampilan V$PARAMETER untuk parameter konfigurasi database.
  • Tampilan V$NLS_PARAMETERS untuk parameter bahasa database.
  • Tampilan DBA_DATA_FILES untuk menghitung ukuran penyimpanan database.
  • SPFILE Oracle untuk konfigurasi instance database.
  • Alat scheduler tugas (misalnya, crontab) untuk mengidentifikasi pencadangan rutin atau masa pemeliharaan yang harus dipertimbangkan.

Mengimpor dan mengonfigurasi pengguna di Cloud SQL untuk PostgreSQL

Pada tingkat tinggi, setiap skema Oracle harus dibuat sebagai skemanya sendiri di PostgreSQL. Dalam database Oracle, pengguna identik dengan skema. Artinya, skema akan dibuat saat Anda membuat pengguna. Selalu ada hubungan 1:1 antara pengguna dan skema. Di PostgreSQL, pengguna dan skema dibuat secara terpisah. Pengguna dapat dibuat tanpa membuat skema yang sesuai. Untuk mempertahankan struktur pengguna atau skema Oracle yang sama di PostgreSQL, Anda dapat membuat skema untuk setiap pengguna.

Tabel berikut menggambarkan contoh konversi:

Jenis tindakan Jenis database Perbandingan perintah
Membuat pengguna dan skema Oracle CREATE USER username IDENTIFIED BY password;
PostgreSQL Pengguna dan skema adalah konsep yang berbeda di PostgreSQL, oleh karena itu memerlukan dua pernyataan CREATE yang terpisah

CREATE USER username WITH PASSWORD 'password';
CREATE SCHEMA schema_name;
Menetapkan peran Oracle GRANT CONNECT TO username;
PostgreSQL GRANT pg_monitor TO username;
Memberikan hak istimewa Oracle GRANT SELECT, INSERT, UPDATE ON HR.EMPLOYEES TO username;
PostgreSQL GRANT SELECT, INSERT, UPDATE ON HR.EMPLOYEES TO username;
Mencabut hak istimewa Oracle REVOKE UPDATE ON HR.EMPLOYEES FROM username;
PostgreSQL REVOKE UPDATE ON HR.EMPLOYEES FROM username;
Memberikan DBA/superuser Oracle GRANT DBA TO username;
PostgreSQL GRANT cloudsqlsuperuser TO username;
Melepaskan pengguna Oracle DROP USER username CASCADE;
PostgreSQL Pengguna dan skema adalah konsep yang berbeda di PostgreSQL, oleh karena itu memerlukan dua pernyataan DROP yang terpisah

DROP USER username;
DROP SCHEMA schema_name CASCADE;
Metadata pengguna Oracle DBA_USERS
PostgreSQL pg_catalog.pg_user
Metadata izin Oracle DBA_SYS_PRIVS
DBA_ROLE_PRIVS
SESSION_PRIVS
PostgreSQL pg_catalog.pg_roles
String koneksi CLI Oracle sqlplus username/password@host/tns_alias
Sqlplus username/password@host:IP/sid
PostgreSQL Tanpa prompt sandi:

PGPASSWORD=password psql -h hostname -U username -d database_name

Dengan prompt sandi:

psql -h hostname -U username -W -d database_name

Pengguna database Oracle 12c:

Ada dua jenis pengguna di Oracle 12c, pengguna umum dan pengguna lokal. Pengguna umum dibuat di CDB root yang meliputi PDB. Mereka diidentifikasi dengan awalan C## dalam nama penggunanya. Pengguna lokal hanya dibuat dalam PDB tertentu. Pengguna database yang berbeda dengan nama pengguna yang identik dapat dibuat di beberapa PDB. Saat bermigrasi dari Oracle 12c ke PostgreSQL, ubah pengguna dan izin agar sesuai dengan arsitektur PostgreSQL. Berikut dua contoh umum untuk menggambarkan perbedaan ini:

# Oracle local user
SQL> ALTER SESSION SET CONTAINER=pdb;
SQL> CREATE USER username IDENTIFIED BY password QUOTA 50M ON USERS;

# PostgreSQL user for a single database and schema
postgres=> CREATE USER username WITH PASSWORD 'password';
postgres=> GRANT CONNECT TO DATABASE database_name TO username;
postgres=> GRANT USAGE ON SCHEMA schema_name TO username;
postgres=> -- Optionally, grant object privileges in the schema
postgres=> GRANT ALL ON ALL TABLES IN SCHEMA schema_name TO username;
postgres=> GRANT ALL ON ALL SEQUENCES IN SCHEMA schema_name TO username;
postgres=> GRANT ALL ON ALL FUNCTIONS IN SCHEMA schema_name TO username;
postgres=> GRANT ALL ON ALL PROCEDURES IN SCHEMA schema_name TO username;
postgres=> GRANT ALL ON ALL ROUTINES IN SCHEMA schema_name TO username;

# Oracle common user
SQL> CREATE USER c##username IDENTIFIED BY password CONTAINER=ALL;

# PostgreSQL user with permissions for all database (use the local user script above and repeat it for each database and schema)

Mengelola pengguna melalui konsol Google Cloud

Guna melihat pengguna Cloud SQL untuk PostgreSQL yang dikonfigurasi saat ini, buka halaman berikut di konsol Google Cloud:

Google Cloud > Penyimpanan > SQL > Instance > Pengguna

Screenshot halaman "Pengguna".

Mengimpor definisi tabel dan tampilan

Oracle dan PostgreSQL berbeda dalam hal kepekaan huruf besar/kecil. Nama Oracle tidak peka huruf besar/kecil. Nama PostgreSQL tidak peka huruf besar/kecil kecuali jika diapit oleh tanda kutip ganda. Banyak alat ekspor skema dan alat penghasil SQL untuk Oracle seperti DBMS_METADATA.GET_DDL yang otomatis menambahkan tanda kutip ganda ke nama objek. Tanda kutip ini dapat menyebabkan berbagai macam masalah setelah migrasi. Sebaiknya hapus semua tanda kutip yang mengelilingi nama objek dari pernyataan bahasa definisi data (DDL) sebelum Anda membuat objek di PostgreSQL.

Membuat sintaksis tabel

Saat mengonversi tabel dari Oracle ke jenis data PostgreSQL, langkah pertama yang harus dilakukan adalah mengekstrak pernyataan pembuatan tabel Oracle dari database sumber. Contoh kueri berikut mengekstrak DDL untuk tabel lokasi dari skema HR:

SQL> SELECT DBMS_METADATA.GET_DDL('TABLE', 'LOCATIONS') FROM DUAL;

CREATE TABLE "HR"."LOCATIONS"
   (  "LOCATION_ID" NUMBER(4,0),
  "STREET_ADDRESS" VARCHAR2(40),
  "POSTAL_CODE" VARCHAR2(12),
  "CITY" VARCHAR2(30) CONSTRAINT "LOC_CITY_NN" NOT NULL ENABLE,
  "STATE_PROVINCE" VARCHAR2(25),
  "COUNTRY_ID" CHAR(2),
  CONSTRAINT "LOC_ID_PK" PRIMARY KEY ("LOCATION_ID")
...
      CONSTRAINT "LOC_C_ID_FK" FOREIGN KEY ("COUNTRY_ID")
          REFERENCES "HR"."COUNTRIES" ("COUNTRY_ID") ENABLE

Output lengkap mencakup elemen penyimpanan, indeks, dan informasi tablespace, yang dihilangkan karena elemen tambahan ini tidak didukung oleh pernyataan CREATE TABLE PostgreSQL.

Setelah DDL diekstrak, hapus tanda kutip yang mengelilingi nama dan lakukan konversi tabel sesuai dengan tabel konversi jenis data Oracle-to-PostgreSQL. Periksa setiap jenis data kolom untuk melihat apakah data tersebut dapat dikonversi sebagaimana adanya, atau jika tidak didukung, pilih jenis data yang berbeda sesuai dengan tabel konversi. Misalnya, berikut ini adalah DDL yang dikonversi untuk tabel lokasi.

CREATE TABLE HR.LOCATIONS (
  LOCATION_ID NUMERIC(4,0),
  STREET_ADDRESS VARCHAR(40),
  POSTAL_CODE VARCHAR(12),
  CITY VARCHAR(30) CONSTRAINT LOC_CITY_NN NOT NULL,
  STATE_PROVINCE VARCHAR(25),
  COUNTRY_ID CHAR(2),
  CONSTRAINT LOC_ID_PK PRIMARY KEY (LOCATION_ID),
  CONSTRAINT LOC_C_ID_FK FOREIGN KEY (COUNTRY_ID)
REFERENCES HR.COUNTRIES (COUNTRY_ID)
)

Create Table As Select (CTAS)

Pernyataan CREATE TABLE AS SELECT (CTAS) digunakan untuk membuat tabel baru berdasarkan tabel yang ada. Perhatikan bahwa hanya nama kolom dan jenis data kolom yang disalin, sedangkan batasan dan indeks tidak. PostgreSQL mendukung standar ANSI SQL untuk fungsi CTAS, dan kompatibel dengan pernyataan Oracle CTAS.

Kolom tak terlihat Oracle 12c

PostgreSQL tidak mendukung kolom tak terlihat. Sebagai solusinya, buat tampilan yang hanya menampung kolom yang terlihat.

Batasan tabel

Oracle menyediakan enam jenis batasan tabel yang dapat ditentukan pada pembuatan tabel atau setelah pembuatan tabel menggunakan perintah ALTER TABLE. Jenis batasan Oracle adalah PRIMARY KEY, FOREIGN KEY, UNIQUE, CHECK, NOT NULL, dan REF. Selain itu, Oracle memungkinkan pengguna mengontrol status batasan melalui opsi berikut:

  • INITIALLY IMMEDIATE: Memeriksa batasan di akhir setiap pernyataan SQL berikutnya (status default).
  • DEFERRABLE/NOT DEFERRABLE: Mengaktifkan penggunaan klausa SET CONSTRAINT dalam transaksi berikutnya hingga pernyataan COMMIT dikirimkan
  • INITIALLY DEFERRED: Memeriksa batasan di akhir setiap transaksi berikutnya.
  • VALIDATE/NO VALIDATE: Memeriksa (atau dengan sengaja tidak memeriksa) error pada baris baru atau baris yang diubah. Parameter ini bergantung pada apakah batasannya adalah ENABLED atau DISABLED.
  • ENABLED/DISABLED: Menentukan apakah batasan harus diterapkan setelah pembuatan (ENABLED secara default)

PostgreSQL juga mendukung enam jenis batasan tabel: PRIMARY KEY, FOREIGN KEY, UNIQUE, CHECK, NOT NULL, dan EXCLUDE. Namun, ada beberapa perbedaan penting antara jenis batasan Oracle dan PostgreSQL, termasuk:

  • PostgreSQL tidak mendukung batasan REF Oracle.
  • PostgreSQL tidak secara otomatis membuat indeks pada kolom referensi untuk batasan kunci asing. Pernyataan CREATE INDEX terpisah pada kolom referensi diperlukan jika indeks diperlukan.
  • PostgreSQL tidak mendukung klausul ON DELETE SET NULL Oracle. Klausa ini memerintahkan Oracle untuk menetapkan nilai dependen apa pun dalam tabel turunan ke NULL saat data dalam tabel induk dihapus.
  • Batasan pada VIEWS tidak didukung, kecuali untuk CHECK OPTION.
  • PostgreSQL tidak mendukung penonaktifan batasan. PostgreSQL mendukung opsi NOT VALID saat kunci asing baru atau batasan pemeriksaan ditambahkan menggunakan pernyataan ALTER TABLE. Opsi ini memberi tahu PostgreSQL untuk melewati pemeriksaan integritas referensial pada data yang ada di tabel turunan.

Tabel berikut merangkum perbedaan utama antara jenis batasan Oracle dan PostgreSQL:

Jenis batasan Oracle Dukungan Cloud SQL untuk PostgreSQL Setara dengan Cloud SQL untuk PostgreSQL
PRIMARY KEY Ya PRIMARY KEY
FOREIGN KEY Ya Menggunakan sintaksis ANSI SQL yang sama dengan Oracle.

Menggunakan klausa ON DELETE untuk menangani kasus penghapusan data induk FOREIGN KEY. PostgreSQL menyediakan tiga opsi untuk menangani kasus ketika data dihapus dari tabel induk dan tabel turunan dirujuk oleh batasan FOREIGN KEY:

  • ON DELETE CASCADE
  • ON DELETE RESTRICT
  • ON DELETE NO ACTION

PostgreSQL tidak mendukung klausa ON DELETE SET NULL Oracle.

Menggunakan klausa ON UPDATE untuk menangani kasus pembaruan data induk FOREIGN KEY.
PostgreSQL menyediakan tiga opsi untuk menangani peristiwa pembaruan batasan FOREIGN KEY:

  • ON UPDATE CASCADE
  • ON UPDATE RESTRICT
  • ON UPDATE NO ACTION

PostgreSQL tidak secara otomatis membuat indeks di kolom referensi untuk batasan kunci asing.
UNIQUE Ya Membuat indeks UNIQUE secara default.
CHECK Ya CHECK
NOT NULL Ya NOT NULL
REF Tidak Tidak didukung.
DEFERRABLE/NOT DEFERRABLE Ya DEFERRABLE/NOT DEFERRABLE
INITIALLY IMMEDIATE Ya INITIALLY IMMEDIATE
INITIALLY DEFERRED Ya INITIALLY DEFERRED
VALIDATE/NO VALIDATE Tidak Tidak didukung.
ENABLE/DISABLE Tidak Diaktifkan secara default. Gunakan opsi NOT VALID saat kunci asing baru atau batasan pemeriksaan ditambahkan ke tabel menggunakan pernyataan ALTER TABLE untuk melewati pemeriksaan integritas referensial pada data yang sudah ada.
Batasan pada VIEW Tidak Tidak didukung kecuali VIEW WITH CHECK OPTION.
Metadata batasan Oracle DBA_CONSTRAINTS
PostgreSQL INFORMATION_SCHEMA.TABLE_CONSTRAINTS

Kolom yang dihasilkan dan virtual

Kolom virtual Oracle didasarkan pada hasil penghitungan kolom lain. Kolom ini muncul sebagai kolom reguler, tetapi nilainya diperoleh dari penghitungan langsung oleh mesin database Oracle dan tidak disimpan dalam database. Kolom virtual dapat digunakan dengan batasan, indeks, partisi tabel, dan kunci asing, tetapi tidak dapat dimanipulasi melalui operasi bahasa pengolahan data (DML).

Dalam hal fungsi, kolom yang dihasilkan PostgreSQL sebanding dengan kolom virtual Oracle. Namun, tidak seperti Oracle, kolom yang dihasilkan di PostgreSQL disimpan dan Anda harus menentukan jenis data untuk setiap kolom yang dihasilkan. Artinya, kolom tersebut menempati penyimpanan seolah-olah kolom tersebut adalah kolom normal.

Contoh kolom virtual di Oracle:

SQL> CREATE TABLE PRODUCTS (
        PRODUCT_ID     INT PRIMARY KEY,
        PRODUCT_TYPE   VARCHAR2(100) NOT NULL,
        PRODUCT_PRICE  NUMBER(6,2) NOT NULL,
        PRICE_WITH_TAX AS (ROUND(PRODUCT_PRICE * 1.01, 2))
);

SQL> INSERT INTO PRODUCTS(PRODUCT_ID, PRODUCT_TYPE, PRODUCT_PRICE)
     VALUES(1, 'A', 99.99);

SQL> SELECT * FROM PRODUCTS;
PRODUCT_ID PRODUCT_TYPE         PRODUCT_PRICE PRICE_WITH_TAX
---------- -------------------- ------------- --------------
         1 A                            99.99         100.99

Contoh yang setara di PostgreSQL:

postgres=> CREATE TABLE PRODUCTS (
postgres(>         PRODUCT_ID     INT PRIMARY KEY,
postgres(>         PRODUCT_TYPE   VARCHAR(100) NOT NULL,
postgres(>         PRODUCT_PRICE  NUMERIC(6,2) NOT NULL,
postgres(>         PRICE_WITH_TAX NUMERIC GENERATED ALWAYS AS (ROUND(PRODUCT_PRICE * 1.01, 2)) STORED
postgres(> );

postgres=> INSERT INTO PRODUCTS(PRODUCT_ID, PRODUCT_TYPE, PRODUCT_PRICE) VALUES(1, 'A', 99.99);

postgres=> SELECT * FROM PRODUCTS;
 product_id | product_type | product_price | price_with_tax
------------+--------------+---------------+----------------
          1 | A            |         99.99 |         100.99
(1 row)

Indeks tabel

Oracle dan PostgreSQL menyediakan berbagai algoritma pengindeksan dan jenis indeks yang dapat digunakan untuk berbagai aplikasi. Berikut adalah daftar algoritma pengindeksan yang tersedia di PostgreSQL:

Algoritma indeks Deskripsi
B-tree
  • Jenis indeks default untuk PostgreSQL, yang digunakan untuk mempercepat kueri kesetaraan dan rentang
  • Mendukung semua jenis data sederhana dan dapat digunakan untuk mengambil nilai NULL
  • Nilai indeks diurutkan dalam urutan menaik secara default, tetapi juga dapat dikonfigurasi dalam urutan menurun
Hash
  • Digunakan untuk mempercepat penelusuran kesetaraan
  • Lebih efisien daripada indeks B-tree, tetapi terbatas pada penanganan penelusuran kesetaraan saja
GIN
  • Indeks hierarki terbalik
  • Lebih efisien daripada indeks B-tree ketika menangani kolom yang berisi beberapa nilai komponen, seperti array dan teks
GiST
  • Bukan jenis indeks tunggal, melainkan infrastruktur untuk menentukan indeks yang dapat mendukung lebih banyak operator perbandingan daripada yang dapat didukung oleh indeks B-tree normal
  • Berguna untuk data geometris saat mengoptimalkan penelusuran "tetangga terdekat" diperlukan
SP-GiST
  • Mirip dengan GiST, SP-GiST adalah infrastruktur untuk strategi pengindeksan yang ditentukan pengguna
  • Memungkinkan berbagai struktur data tidak seimbang seperti quadtree
  • Tidak tersedia di Cloud SQL untuk PostgreSQL
BRIN
  • INdex Rentang Blok
  • Menyimpan ringkasan rentang blok fisik dari tabel
  • Untuk kolom dengan tata urutan linear
  • Berguna untuk pencarian rentang pada tabel berukuran besar

Tabel berikut membandingkan jenis indeks antara Oracle dan PostgreSQL:

Indeks Oracle Deskripsi Didukung oleh PostgreSQL Setara dengan PostgreSQL
Indeks bitmap Menyimpan bitmap untuk setiap kunci indeks, yang paling cocok untuk menyediakan pengambilan data yang cepat untuk workload OLAP Tidak T/A
Indeks B-tree Jenis indeks paling umum, sangat cocok untuk berbagai workload dan dapat dikonfigurasi dalam pengurutan ASC|DESC. Ya Indeks B-tree
Indeks komposit Membuat dua kolom atau lebih untuk meningkatkan performa pengambilan data. Urutan kolom di dalam indeks menentukan jalur akses. Ya Indeks beberapa kolom
Hingga 32 kolom dapat ditentukan saat membuat indeks beberapa kolom.
Indeks berbasis fungsi Menyimpan output dari fungsi yang diterapkan pada nilai kolom tabel. Ya Indeks pada ekspresi
Indeks unik Indeks B-tree yang menerapkan batasan UNIQUE pada nilai yang diindeks per kolom. Ya Indeks unik
Indeks domain aplikasi Cocok untuk mengindeks data non-relasional seperti data audio/video, data LOB, dan jenis non-tekstual lainnya. Tidak T/A
Indeks tidak terlihat Fitur Oracle yang memungkinkan Anda mengelola, memelihara, dan menguji indeks tanpa memengaruhi pengambilan keputusan pengoptimal. Tidak Sebagai solusi alternatif, Anda dapat membuat indeks tambahan pada replika baca untuk tujuan pengujian tanpa memengaruhi aktivitas yang sedang berlangsung.
Tabel yang diatur indeks Jenis indeks yang mengontrol cara data disimpan di tingkat tabel dan indeks. Tidak PostgreSQL tidak mendukung tabel yang diatur indeks. Pernyataan CLUSTER menginstruksikan PostgreSQL untuk mengatur penyimpanan tabel sesuai dengan indeks yang ditentukan. Tabel ini memiliki tujuan yang sama dengan tabel yang diatur indeks dari Oracle. Namun, pengelompokan adalah operasi yang bersifat satu kali, dan PostgreSQL tidak mempertahankan struktur tabel pada update berikutnya. Diperlukan pengelompokan manual dan berkala.
Indeks lokal dan global Digunakan untuk mengindeks tabel yang dipartisi dalam database Oracle. Setiap indeks ditentukan sebagai LOCAL atau GLOBAL. Tidak Indeks kerja partisi PostgreSQL memiliki fungsi yang sama dengan indeks lokal Oracle (yaitu, indeks ditetapkan pada level partisi, level global tidak didukung).
Indeks parsial untuk tabel berpartisi (Oracle 12c) Membuat indeks pada subset partisi tabel. Mendukung LOCAL dan GLOBAL. Ya Partisi di PostgreSQL berfungsi dengan melampirkan tabel turunan ke dalam tabel induk. Anda hanya dapat membuat indeks pada subset tabel turunan.
CREATE/DROP INDEX Perintah yang digunakan untuk membuat dan melepas indeks. Ya PostgreSQL mendukung perintah CREATE INDEX. PostgreSQL juga mendukung ALTER TABLE tableName ADD INDEX indexName columnName
ALTER INDEX ... REBUILD Membuat ulang indeks, yang dapat menyebabkan kunci eksklusif pada tabel yang diindeks. Memerlukan sintaksis yang berbeda PostgreSQL mendukung pembuatan ulang indeks menggunakan pernyataan REINDEX. Tabel dikunci untuk operasi tulis selama operasi ini dan hanya operasi baca yang diizinkan.
ALTER INDEX ... REBUILD ONLINE Membuat ulang indeks tanpa membuat kunci eksklusif pada tabel. Memerlukan sintaksis yang berbeda PostgreSQL mendukung pembuatan ulang indeks serentak menggunakan pernyataan REINDEX TABLE CONCURRENTLY. Dalam mode ini, PostgreSQL mencoba membuat ulang indeks menggunakan penguncian minimum yang berpotensi memerlukan lebih banyak waktu dan resource untuk menyelesaikan pembuatan ulang.
Kompresi indeks Fitur untuk mengurangi ukuran fisik indeks. Tidak T/A
Mengalokasikan
indeks ke tablespace
Membuat tablespace indeks yang dapat disimpan di disk terpisah dari data tabel untuk mengurangi bottleneck I/O disk. Tidak Meskipun PostgreSQL memungkinkan indeks dibuat dalam tablespace yang ditentukan pengguna, Anda tidak dapat membuat tablespace di Cloud SQL untuk PostgreSQL, dan indeks harus dibuat di tablespace default.
Mengindeks metadata (tabel/tampilan) Oracle DBA_INDEXES
DBA_PART_INDEXES
DBA_IND_COLUMNS
PostgreSQL pg_catalog.pg_index
pg_catalog.pg_attribute
pg_catalog.pg_class

Pertimbangan konversi indeks

Pada umumnya, indeks Oracle dapat dengan mudah dikonversi ke indeks B-tree PostgreSQL, karena jenis indeks ini adalah jenis indeks yang paling umum digunakan. Seperti dalam database Oracle, indeks otomatis dibuat di kolom PRIMARY KEY pada tabel. Demikian pula, indeks UNIQUE akan otomatis dibuat pada kolom yang memiliki batasan UNIQUE. Selain itu, indeks sekunder dibuat menggunakan pernyataan CREATE INDEX standar.

Contoh berikut mengilustrasikan cara mengonversi tabel Oracle dengan beberapa kolom terindeks ke PostgreSQL:

SQL> CREATE TABLE ORA_IDX_TO_PG (
        col1 INT PRIMARY KEY,
        col2 VARCHAR2(60),
        col3 DATE,
        col4 CLOB,
        col5 VARCHAR2(20)
      );

-- Single-field index
SQL> CREATE INDEX idx_col2 ON ora_idx_to_pg(col2);

-- Composite index
SQL> CREATE INDEX idx_cols3_2 ON ora_idx_to_pg(col3 DESC, col2);

-- Unique index
SQL> CREATE UNIQUE INDEX idx_col3_uni ON ora_idx_to_pg(col3);

-- Function-based index
SQL> CREATE INDEX idx_func_col3 ON
        ora_idx_to_pg(EXTRACT(MONTH FROM col3));

-- CLOB index
SQL> CREATE INDEX idx_col4 ON
       ora_idx_to_pg(col4) INDEXTYPE IS CTXSYS.CONTEXT;

-- Invisible index
SQL> CREATE INDEX idx_col5_inv ON
        ora_idx_to_pg(col5) INVISIBLE;

-- Drop index
SQL> DROP INDEX idx_col5_inv;

postgres=> CREATE TABLE ORA_IDX_TO_PG (
postgres(> col1 INT PRIMARY KEY,
postgres(> col2 VARCHAR(60),
postgres(> col3 DATE,
postgres(> col4 TEXT,
postgres(> col5 VARCHAR(20)
postgres(> );

-- Single index (supported)
postgres=> CREATE INDEX idx_col2 ON ora_idx_to_pg(col2);

-- Composite index (supported)
postgres=> CREATE INDEX idx_cols3_2 ON ora_idx_to_pg(col3 DESC, col2);

-- Unique index (supported)
postgres=> CREATE UNIQUE INDEX idx_col3_uni ON ora_idx_to_pg(COL3);

-- Function-based index (supported)
postgres=> CREATE INDEX idx_func_col3 ON
postgres->         ora_idx_to_pg(EXTRACT(MONTH FROM col3));

-- CLOB (Supported, but requires different syntax. See Full Text Search for details)
postgres=> CREATE INDEX idx_col4 ON ora_idx_to_pg
postgres->         USING GIN (to_tsvector('english', col4));

-- Invisible index (not supported)
-- Optional - create the index as a B-tree index
postgres=> CREATE INDEX idx_col5 ON ora_idx_to_pg(col5);

-- Drop index
postgres=> DROP INDEX idx_col2;

SQL> SELECT ui.table_name,
            ui.index_name,
            ui.index_type,
            ic.column_name
     FROM user_indexes ui JOIN user_ind_columns ic
     ON ui.index_name = ic.index_name
     WHERE ui.table_name = 'ORA_IDX_TO_PG'
     ORDER BY 4;

postgres=> select distinct
postgres->     t.relname as table_name,
postgres->     i.relname as index_name,
postgres-> pg_get_indexdef(ix.indexrelid) index_definition
postgres-> from
postgres->     pg_class t,
postgres->     pg_class i,
postgres->     pg_index ix
postgres-> where
postgres->     t.oid = ix.indrelid
postgres->     and i.oid = ix.indexrelid
postgres->     and t.relname = 'ora_idx_to_pg'
postgres-> order by
postgres->     t.relname,
postgres->     i.relname;

-- OR Use psql \d command:
postgres=> \d ora_idx_to_pg
                  Table "public.ora_idx_to_pg"
 Column |         Type          | Collation | Nullable | Default
--------+-----------------------+-----------+----------+---------
 col1   | integer               |           | not null |
 col2   | character varying(60) |           |          |
 col3   | date                  |           |          |
 col4   | text                  |           |          |
 col5   | character varying(20) |           |          |
Indexes:
    "ora_idx_to_pg_pkey" PRIMARY KEY, btree (col1)
    "idx_col2" btree (col2)
    "idx_col4" gin (to_tsvector('english'::regconfig, col4))
    "idx_col5" btree (col5)
    "idx_cols3_2" btree (col3 DESC, col2)
    "idx_func_col3" btree (date_part('month'::text, col3))

postgres=>

Partisi tabel

Oracle dan PostgreSQL menawarkan kemampuan melakukan partisi untuk memisahkan tabel besar. Hal ini dilakukan dengan mengelompokkan tabel secara fisik menjadi bagian-bagian yang lebih kecil, di mana setiap bagian berisi subset baris horizontal. Tabel berpartisi disebut sebagai tabel induk dan barisnya disimpan secara fisik di partisinya. Meskipun tidak semua jenis partisi Oracle didukung di PostgreSQL, PostgreSQL mendukung jenis yang paling umum.

Bagian berikut menjelaskan jenis partisi yang didukung PostgreSQL, yang menggambarkan masing-masing jenis dengan contoh cara membuat partisi yang sesuai dengan jenis tersebut.

Partisi RANGE

Jenis partisi ini menetapkan baris ke partisi berdasarkan nilai kolom yang berada dalam rentang tertentu. Setiap partisi berisi baris dengan nilai ekspresi partisi berada dalam rentang tertentu. Penting untuk diperhatikan bahwa rentang tidak tumpang tindih pada partisi.

Contoh

CREATE TABLE employees (
 empid     INT,
 fname     VARCHAR(30),
 lname     VARCHAR(30),
 hired     DATE,
 separated DATE,
 job_code  INT,
 store_id  INT)
 PARTITION BY RANGE (store_id);

CREATE TABLE employees_p0 PARTITION OF employees
 FOR VALUES FROM (MINVALUE) TO (6);
CREATE TABLE employees_p1 PARTITION OF employees
 FOR VALUES FROM (6) TO (11);
CREATE TABLE employees_p2 PARTITION OF employees
 FOR VALUES FROM (11) TO (16);
CREATE TABLE employees_p3 PARTITION OF employees
 FOR VALUES FROM (16) TO (21);

Partisi LIST

Serupa dengan partisi RANGE, partisi LIST menetapkan baris ke partisi berdasarkan nilai kolom yang berada dalam kumpulan nilai bawaan. Nilai kunci yang muncul di setiap partisi tercantum secara eksplisit untuk partisi LIST.

Contoh

CREATE TABLE employees (
 empid     INT,
 fname     VARCHAR(30),
 lname     VARCHAR(30),
 hired     DATE,
 separated DATE,
 job_code  INT,
 store_id  INT)
 PARTITION BY LIST (store_id);

CREATE TABLE employees_pNorth PARTITION OF employees
 FOR VALUES IN (3,5,6);
CREATE TABLE employees_pEast PARTITION OF employees
 FOR VALUES IN (1,2,10);
CREATE TABLE employees_pWest PARTITION OF employees
 FOR VALUES IN (4,12,13);
CREATE TABLE employees_pCnrl PARTITION OF employees
 FOR VALUES IN (7,8,15);

Partisi HASH

Partisi HASH paling cocok digunakan jika tujuannya adalah mencapai distribusi data yang merata di antara semua partisi. Nilai kolom (atau ekspresi berdasarkan nilai kolom yang akan di-hash) dan nilai baris ditetapkan ke partisi yang sesuai dengan nilai hash tersebut. Nilai hash harus ditetapkan secara unik ke partisi, dan semua nilai yang dimasukkan harus dipetakan ke satu partisi saja.

Contoh

CREATE TABLE employees (
 empid     INT,
 fname     VARCHAR(30),
 lname     VARCHAR(30),
 hired     DATE,
 separated DATE,
 job_code  INT,
 store_id  INT)
 PARTITION BY HASH (date_part('year', hired));

CREATE TABLE employees_p0 PARTITION OF employees
 FOR VALUES WITH (MODULUS 4, REMAINDER 0);
CREATE TABLE employees_p1 PARTITION OF employees
 FOR VALUES WITH (MODULUS 4, REMAINDER 1);
CREATE TABLE employees_p2 PARTITION OF employees
 FOR VALUES WITH (MODULUS 4, REMAINDER 2);
CREATE TABLE employees_p3 PARTITION OF employees
 FOR VALUES WITH (MODULUS 4, REMAINDER 3);

Partisi multi-level

Partisi multi-level adalah metode pembuatan hierarki partisi untuk satu tabel. Setiap partisi dibagi lagi menjadi sejumlah partisi yang berbeda. Jumlah sub-partisi dapat bervariasi antara satu partisi dengan partisi lainnya.

Contoh

CREATE TABLE sales (
 Saleid    INT,
 sale_date DATE,
 cust_code VARCHAR(15),
 income    DECIMAL(8,2))
PARTITION BY RANGE(date_part('year', sale_date));

CREATE TABLE sales_2019 PARTITION OF sales
 FOR VALUES FROM (2019) TO (2020)
 PARTITION BY RANGE(date_part('month', sale_date));

CREATE TABLE sales_2019_q1 PARTITION OF sales_2019
 FOR VALUES FROM (1) TO (4);
CREATE TABLE sales_2019_q2 PARTITION OF sales_2019
 FOR VALUES FROM (4) TO (7);
CREATE TABLE sales_2019_q3 PARTITION OF sales_2019
 FOR VALUES FROM (7) TO (10);
CREATE TABLE sales_2019_q4 PARTITION OF sales_2019
 FOR VALUES FROM (10) TO (13);

CREATE TABLE sales_2020 PARTITION OF sales
 FOR VALUES FROM (2020) TO (2021)
 PARTITION BY RANGE(date_part('month', sale_date));

CREATE TABLE sales_2020_q1 PARTITION OF sales_2020
 FOR VALUES FROM (1) TO (4);
CREATE TABLE sales_2020_q2 PARTITION OF sales_2020
 FOR VALUES FROM (4) TO (7);
CREATE TABLE sales_2020_h2 PARTITION OF sales_2020
 FOR VALUES FROM (7) TO (13);

Memasang atau melepaskan partisi

Di PostgreSQL, partisi dapat ditambahkan atau dihapus dari tabel induk. Partisi yang dilepas nantinya dapat dipasang kembali ke tabel yang sama. Selain itu, kondisi partisi baru dapat ditentukan saat memasang kembali partisi tersebut, sehingga batas partisi dapat disesuaikan.

Contoh

CREATE TABLE employees (
 empid     INT,
 fname     VARCHAR(30),
 lname     VARCHAR(30),
 hired     DATE,
 separated DATE,
 job_code  INT,
 store_id  INT)
 PARTITION BY RANGE (date_part('year', hired));

CREATE TABLE employees_p0 PARTITION OF employees
 FOR VALUES FROM (2010) TO (2015);
CREATE TABLE employees_p1 PARTITION OF employees
 FOR VALUES FROM (2015) TO (2020);

-- changing partition boundaries
BEGIN TRANSACTION;
ALTER TABLE employees DETACH PARTITION employees_p1;
ALTER TABLE employees ATTACH PARTITION employees_p1 FOR VALUES FROM (2015) TO (2022);
COMMIT TRANSACTION;

Tabel berikut menjelaskan persamaan jenis partisi Oracle dan Cloud SQL untuk PostgreSQL serta rekomendasi konversi:

Jenis partisi Oracle Didukung oleh PostgreSQL Implementasi PostgreSQL
Partisi RANGE Ya PARTITION BY RANGE
Partisi LIST Ya PARTITION BY LIST
Partisi HASH Ya PARTITION BY HASH
SUB-PARTITIONING Ya Partisi multi-level
Partisi interval Tidak Tidak didukung
Penasihat partisi Tidak Tidak didukung
Partisi preferensi Tidak Tidak didukung
Partisi berbasis kolom virtual Tidak Sebagai solusinya, pertimbangkan untuk membuat partisi dengan ekspresi kolom virtual secara langsung:

CREATE TABLE users (
id INT,
username VARCHAR(20),
first_letter VARCHAR(1)
GENERATED ALWAYS AS
(
UPPER(SUBSTR(TRIM(username), 1, 1))
) STORED
)
PARTITION BY LIST (UPPER(SUBSTR(TRIM(username), 1, 1)));

Pembuatan partisi daftar otomatis Tidak Tidak didukung
Pisahkan
partisi
Tidak Sebagai solusi, pertimbangkan untuk melepaskan atau memasang partisi tabel guna menyesuaikan batas partisi
Partisi pertukaran Ya DETACH / ATTACH PARTITION
Partisi multijenis (partisi gabungan) Ya Partisi multi-level
Metadata partisi Oracle DBA_TAB_PARTITIONS
DBA_TAB_SUBPARTITIONS
PostgreSQL pg_catalog.pg_class
pg_catalog.pg_partitioned_table

Contoh berikut adalah perbandingan per aspek dari pembuatan partisi tabel di kedua platform. Perhatikan bahwa PostgreSQL tidak mendukung referensi tablespace dalam klausa PARTITIONS dari perintah CREATE TABLE.

Implementasi Oracle

CREATE TABLE employees (
empid NUMBER,
fname VARCHAR2(30),
lname VARCHAR2(30),
hired DATE,
separated DATE,
job_code NUMBER,
store_id NUMBER)
PARTITION BY LIST (store_id) (
PARTITION employees_pNorth VALUES (3,5,6) TABLESPACE users,
PARTITION employees_pEast VALUES (1,2,10) TABLESPACE users,
PARTITION employees_pWest VALUES (4,12,13) TABLESPACE users,
PARTITION employees_pCnrl VALUES (7,8,15) TABLESPACE users
);

Implementasi PostgreSQL

CREATE TABLE employees (
empid INT,
fname VARCHAR(30),
lname VARCHAR(30),
hired DATE,
separated DATE,
job_code INT,
store_id INT)
PARTITION BY LIST (store_id);

CREATE TABLE employees_pNorth PARTITION OF employees
FOR VALUES IN (3,5,6);
CREATE TABLE employees_pEast PARTITION OF employees
FOR VALUES IN (1,2,10);
CREATE TABLE employees_pWest PARTITION OF employees
FOR VALUES IN (4,12,13);
CREATE TABLE employees_pCnrl PARTITION OF employees
FOR VALUES IN (7,8,15);

Tabel sementara

Tabel sementara dalam database Oracle disebut GLOBAL TEMPORARY TABLES, sedangkan tabel sementara di PostgreSQL hanya dikenal sebagai tabel sementara. Fungsi dasar tabel sementara identik di kedua platform. Namun, ada beberapa perbedaan penting:

  • Oracle menyimpan struktur tabel sementara untuk penggunaan berulang bahkan setelah database dimulai ulang, sedangkan PostgreSQL menyimpan tabel sementara hanya selama durasi sesi.
  • Tabel sementara dalam database Oracle dapat diakses oleh berbagai pengguna dengan izin yang sesuai. Sebaliknya, tabel sementara di PostgreSQL hanya dapat diakses selama sesi pembuatannya kecuali jika tabel sementara direferensikan dengan nama yang memenuhi syarat skema.
  • Dalam database Oracle, ada perbedaan jelas antara tabel sementara GLOBAL dan LOCAL yang menentukan apakah konten tabel bersifat global atau khusus sesi. Dalam PostgreSQL, kata kunci GLOBAL dan LOCAL didukung karena alasan kompatibilitas, tetapi tidak berpengaruh pada visibilitas data.
  • Jika klausa ON COMMIT dihilangkan saat membuat tabel sementara, perilaku default di Oracle Database adalah ON COMMIT DELETE ROWS. Artinya, Oracle akan memotong tabel sementara setelah setiap commit. Sebaliknya, di PostgreSQL, perilaku default-nya adalah mempertahankan baris dalam tabel sementara setelah setiap commit.

Tabel berikut menunjukkan perbedaan tabel sementara antara Oracle dan Cloud SQL untuk PostgreSQL.

Fitur tabel sementara Implementasi Oracle Implementasi PostgreSQL
Sintaks CREATE GLOBAL TEMPORARY TABLE CREATE TEMPORARY TABLE
Aksesibilitas Dapat diakses dari beberapa sesi Dapat diakses dari sesi kreator saja, kecuali jika dirujuk dengan nama yang memenuhi syarat skema
Dukungan indeks Ya Ya
Dukungan kunci asing Ya Ya
Mempertahankan DDL Ya Tidak
Tindakan default ON COMMIT Data dihapus Data dipertahankan
ON COMMIT PRESERVE ROWS Ya Ya
ON COMMIT DELETE ROWS Ya Ya
ON COMMIT DROP Tidak Ya
Dukungan ALTER TABLE Ya Ya
Mengumpulkan statistik DBMS_STATS.GATHER_TABLE_STATS ANALYZE
Oracle 12c GLOBAL_TEMP_

TABLE_STATS
DBMS_STATS.SET_TABLE_PREFS ANALYZE

Kolom yang tidak digunakan

Fitur Oracle untuk menandai kolom tertentu sebagai UNUSED sering digunakan untuk menghapus kolom dari tabel tanpa menghapus data kolom secara fisik. Hal ini untuk mencegah potensi pemuatan tinggi yang terjadi saat melepaskan kolom dari tabel besar.

Di PostgreSQL, data kolom tidak akan terhapus dari penyimpanan fisik apabila kolom besar dihapus. Oleh karena itu, ini merupakan operasi yang cepat bahkan pada tabel besar. Tidak perlu menandai kolom sebagai UNUSED seperti pada database Oracle. Ruang yang ditempati oleh kolom yang dilepas akan diklaim kembali dengan pernyataan DML baru atau selama operasi VACUUM selanjutnya.

Tabel hanya baca

Tabel hanya-baca adalah fitur Oracle yang menandai tabel sebagai hanya-baca menggunakan perintah ALTER TABLE. Di Oracle 12c R2, fitur ini juga tersedia untuk tabel dengan partisi dan subpartisi. PostgreSQL tidak menawarkan fitur yang setara, tetapi ada dua kemungkinan solusi:

  • Berikan izin SELECT di tabel untuk pengguna tertentu. Perlu perhatikan bahwa hal ini tidak menghalangi pemilik tabel untuk melakukan operasi DML di tabelnya.
  • Buat replika baca Cloud SQL untuk PostgreSQL dan arahkan pengguna ke tabel replika yang merupakan tabel hanya baca. Solusi ini memerlukan penambahan instance replika baca ke instance Cloud SQL untuk PostgreSQL yang ada.
  • Buat pemicu database yang memunculkan pengecualian pada pernyataan DML—misalnya:

    -- Define trigger function
    CREATE OR REPLACE FUNCTION raise_readonly_exception() RETURNS TRIGGER AS $$
    BEGIN
      RAISE EXCEPTION 'Table is readonly!';
      RETURN NULL;
    END;
    $$ LANGUAGE 'plpgsql';
    
    -- Fire trigger when DML statements is executed on read only table
    CREATE TRIGGER myTable_readonly_trigger
    BEFORE INSERT OR UPDATE OR DELETE OR TRUNCATE ON myTable FOR EACH STATEMENT
    EXECUTE PROCEDURE raise_readonly_exception();
    
    -- Testing the trigger
    postgres=> INSERT INTO myTable (id) VALUES (1);
    ERROR:  Table is readonly!
    CONTEXT:  PL/pgSQL function raise_readonly_exception() line 3 at RAISE
    postgres=>
    

Himpunan karakter

Oracle dan PostgreSQL mendukung berbagai himpunan karakter, kolasi, dan unicode, termasuk dukungan untuk bahasa byte tunggal dan multi-byte. Selain itu, database PostgreSQL yang berada pada instance yang sama dapat dikonfigurasi dengan himpunan karakter yang berbeda. Lihat daftar himpunan karakter yang didukung di PostgreSQL.

Dalam Oracle Database, himpunan karakter ditentukan pada level database (Oracle 12g R1 atau yang lebih lama) atau level database yang dapat dicocokkan (Oracle 12g R2 atau yang lebih baru). Di PostgreSQL, himpunan karakter default ditentukan saat instance Cloud SQL untuk PostgreSQL baru dibuat. Setiap database yang dibuat dalam instance tersebut dapat dibuat dengan himpunan karakter yang berbeda. Tata urutan dan klasifikasi karakter dapat ditentukan per kolom tabel.

Contoh

-- Create a database using UTF-8 character set and ja_JP.UTF collation
postgres=> CREATE DATABASE jpdb WITH ENCODING 'UTF8' LC_COLLATE='ja_JP.UTF8' LC_CTYPE='ja_JP.UTF8' TEMPLATE=template0;

-- Query the character set and collation settings of all databases
postgres=> SELECT datname AS DATABASE_NAME, datcollate AS LC_COLLATE, datctype AS LC_CTYPE from pg_database;
 database_name | lc_collate |  lc_ctype
---------------+------------+------------
 cloudsqladmin | en_US.UTF8 | en_US.UTF8
 template0     | en_US.UTF8 | en_US.UTF8
 template1     | en_US.UTF8 | en_US.UTF8
 postgres      | en_US.UTF8 | en_US.UTF8
 jpdb          | ja_JP.UTF8 | ja_JP.UTF8
(5 rows)

-- Alternatively, use psql \l command to query the database settings
postgres=> \l
                                                List of databases
     Name      |       Owner       | Encoding |  Collate   |   Ctype    |            Access privileges
---------------+-------------------+----------+------------+------------+-----------------------------------------
 cloudsqladmin | cloudsqladmin     | UTF8     | en_US.UTF8 | en_US.UTF8 |
 postgres      | cloudsqlsuperuser | UTF8     | en_US.UTF8 | en_US.UTF8 | =Tc/cloudsqlsuperuser                  +
               |                   |          |            |            | cloudsqlsuperuser=CTc/cloudsqlsuperuser+
               |                   |          |            |            | testuser=CTc/cloudsqlsuperuser
 template0     | cloudsqladmin     | UTF8     | en_US.UTF8 | en_US.UTF8 | =c/cloudsqladmin                       +
               |                   |          |            |            | cloudsqladmin=CTc/cloudsqladmin
 template1     | cloudsqlsuperuser | UTF8     | en_US.UTF8 | en_US.UTF8 | =c/cloudsqlsuperuser                   +
               |                   |          |            |            | cloudsqlsuperuser=CTc/cloudsqlsuperuser
-- Specifying column level collation
postgres=> CREATE TABLE test1 (
postgres(>     a text COLLATE "de_DE",
postgres(>     b text COLLATE "es_ES"
postgres(> );

Tabel Virtual

PostgreSQL mendukung tampilan sederhana dan kompleks. Untuk opsi pembuatan tampilan, ada beberapa perbedaan antara Oracle dan PostgreSQL. Tabel berikut menyoroti perbedaan tersebut.

Fitur tampilan Oracle Deskripsi Dukungan Cloud SQL untuk PostgreSQL Pertimbangan konversi
FORCE Buat tampilan tanpa memverifikasi keberadaan tabel/tampilan sumber. Tidak Tidak tersedia opsi yang setara.
CREATE OR REPLACE Membuat tampilan yang tidak ada atau menimpa tampilan yang ada. Ya PostgreSQL mendukung perintah CREATE OR REPLACE untuk tampilan.
WITH CHECK OPTION Menentukan tingkat penerapan saat menjalankan operasi DML terhadap tampilan. Ya Defaultnya adalah CASCADED, yang menyebabkan tampilan yang direferensikan juga dievaluasi.

Kata kunci LOCAL menyebabkan hanya tampilan saat ini yang dievaluasi.
WITH READ-ONLY Hanya mengizinkan operasi baca pada tampilan. Operasi DML dilarang. Tidak Solusinya adalah memberikan hak istimewa SELECT pada tampilan kepada semua pengguna.
VISIBLE | INVISIBLE (Oracle 12c) Tentukan apakah kolom yang berbasis tampilan dapat dilihat atau tidak terlihat oleh pengguna. Tidak Buat VIEW dengan kolom yang diperlukan saja.

Contoh konversi berikut menunjukkan cara melakukan konversi dari Oracle ke Cloud SQL PostgreSQL untuk tampilan.

-- Create view to retrieve employees from department 100 using the WITH CHECK -- OPTION option
SQL> CREATE OR REPLACE FORCE VIEW vw_emp_dept100
AS
SELECT EMPLOYEE_ID,
       FIRST_NAME,
       LAST_NAME,
       SALARY,
       DEPARTMENT_ID
FROM EMPLOYEES
WHERE DEPARTMENT_ID=100
WITH CHECK OPTION;

-- Perform an UPDATE operation on the VIEW
SQL> UPDATE vw_emp_dept100
     SET salary=salary+1000;

postgres=> CREATE OR REPLACE VIEW vw_emp_dept100
postgres-> AS
postgres-> SELECT EMPLOYEE_ID,
postgres->        FIRST_NAME,
postgres->        LAST_NAME,
postgres->        SALARY,
postgres->        DEPARTMENT_ID
postgres-> FROM EMPLOYEES
postgres-> WHERE DEPARTMENT_ID=100
postgres-> WITH CHECK OPTION;

-- Perform an UPDATE operation on the VIEW
postgres=> UPDATE vw_emp_dept100
postgres-> SET salary=salary+1000;

-- Update one employee department id to 60
postgres=> UPDATE vw_emp_dept100
postgres-> SET DEPARTMENT_ID=60
postgres-> WHERE EMPLOYEE_ID=110;

ERROR:  new row violates check option for view "vw_emp_dept100"
DETAIL:  Failing row contains (110, John, Chen, JCHEN, 515.124.4269, 1997-09-28, FI_ACCOUNT, 9200.00, null, 108, 60).

Lihat pengelolaan akses:

Pemilik tampilan harus memiliki hak istimewa di tabel dasar untuk membuat tampilan. Pengguna tampilan memerlukan izin SELECT yang sesuai pada tampilan. Mereka juga memerlukan izin INSERT, UPDATE, DELETE yang sesuai pada tampilan saat melakukan operasi DML melalui tampilan. Dalam kedua kasus tersebut, pengguna tidak memerlukan izin pada tabel yang mendasarinya.

Langkah selanjutnya