Dokumen ini adalah bagian dari sebuah seri yang menyajikan 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 Database Oracle® dan Cloud SQL untuk PostgreSQL dalam kaitannya dengan membuat pengguna, skema, tabel, indeks, dan tabel virtual.
Selain bagian penyiapan pendahuluan, seri ini mencakup bagian-bagian berikut:
- Memigrasikan pengguna Oracle ke Cloud SQL untuk PostgreSQL: Terminologi dan fungsionalitas
- Memigrasikan pengguna Oracle ke Cloud SQL untuk PostgreSQL: Jenis data, pengguna, dan tabel
- Memigrasikan pengguna Oracle ke Cloud SQL untuk PostgreSQL: Kueri, serta prosedur, fungsi, dan pemicu tersimpan
- Memigrasikan pengguna Oracle ke Cloud SQL untuk PostgreSQL: Keamanan, operasi, pemantauan, dan logging
- Memigrasikan pengguna dan skema Oracle Database ke Cloud SQL untuk PostgreSQL (dokumen ini)
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 melihat ringkasan perbedaan ini, lihat bagian terminologi dalam seri ini.
Mengekspor konfigurasi Oracle
Salah satu langkah pertama saat merencanakan migrasi ke Cloud SQL untuk PostgreSQL adalah meninjau setelan parameter yang sudah ada di database Oracle sumber. Setelan terkait alokasi memori, himpunan karakter, dan parameter penyimpanan sangat berguna karena dapat menentukan konfigurasi awal dan penyesuaian 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) berisi data alokasi resource (CPU, RAM), konfigurasi parameter instance, dan sesi aktif maksimum.
DBA_HIST,V$OSSTAT, danV$LICENSEuntuk detail penggunaan CPU.- Tabel virtual
V$PARAMETERuntuk parameter konfigurasi database. - Tabel virtual
V$NLS_PARAMETERSuntuk parameter bahasa database. - Tabel virtual
DBA_DATA_FILESuntuk menghitung ukuran penyimpanan database. SPFILEOracle 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
Secara umum, setiap skema Oracle harus dibuat sebagai skemanya sendiri di PostgreSQL. Di database Oracle, pengguna sama 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 menciptakan skema yang terkait. Untuk mempertahankan struktur skema atau pengguna Oracle yang sama di PostgreSQL, Anda dapat membuat skema untuk setiap pengguna.
Tabel berikut menampilkan contoh konversi:
| Jenis tindakan | Jenis database | Perbandingan perintah |
|---|---|---|
| Membuat pengguna dan skema | Oracle |
CREATE USER username IDENTIFIED BY password; |
PostgreSQL |
Pengguna dan skema merupakan dua konsep yang berbeda di PostgreSQL dan, karenanya, memerlukan dua pernyataan CREATE berbedaCREATE USER username WITH PASSWORD 'password'; |
|
| 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 akses DBA/superuser | Oracle |
GRANT DBA TO username; |
PostgreSQL |
GRANT cloudsqlsuperuser TO username; |
|
| Menghapus pengguna | Oracle |
DROP USER username CASCADE; |
PostgreSQL |
Pengguna dan skema merupakan dua konsep yang berbeda di PostgreSQL dan, karenanya, memerlukan dua pernyataan DROP berbedaDROP USER username; |
|
| Metadata pengguna | Oracle |
DBA_USERS |
PostgreSQL |
pg_catalog.pg_user |
|
| Metadata izin | Oracle |
DBA_SYS_PRIVS |
PostgreSQL |
pg_catalog.pg_roles |
|
| String koneksi CLI | Oracle |
sqlplus username/password@host/tns_alias |
PostgreSQL |
Tanpa prompt sandi:PGPASSWORD=password psql -h hostname -U username -d database_nameDengan prompt sandi: psql -h hostname -U username -W -d database_name |
Pengguna database Oracle 12c:
Ada dua jenis pengguna di Oracle 12c, pengguna global dan pengguna lokal. Pengguna global dibuat di CDB root yang mencakup PDB. Pengguna ini diidentifikasi berdasarkan awalan C## dalam nama pengguna mereka. Pengguna lokal dibuat hanya di PDB tertentu.
Pengguna database yang berbeda dengan nama pengguna yang sama 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 saat ini dikonfigurasi, buka halaman berikut di Konsol Google Cloud :
Google Cloud > Storage > SQL > Instance > Users
Mengimpor definisi tabel dan tabel virtual
Oracle dan PostgreSQL berbeda dalam hal kepekaan huruf besar/kecil. Nama di Oracle tidak peka huruf besar/kecil. Nama di PostgreSQL tidak peka huruf besar/kecil kecuali jika diapit oleh tanda kutip ganda. Ada banyak alat ekspor skema dan penghasil SQL untuk Oracle yang otomatis menambahkan tanda kutip ganda ke nama objek, misalnya DBMS_METADATA.GET_DDL. Tanda kutip ini dapat menimbulkan berbagai masalah setelah migrasi.
Sebaiknya hapus semua tanda kutip yang mengapit nama objek dari pernyataan bahasa definisi data (DDL) sebelum Anda membuat objek tersebut di PostgreSQL.
Sintaksis create table
Saat mengonversi tabel dari Oracle ke jenis data PostgreSQL, langkah pertama adalah mengekstrak pernyataan create table Oracle dari database sumbernya. Contoh kueri berikut mengekstrak DDL untuk tabel locations 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 lengkapnya mencakup elemen penyimpanan, indeks, dan informasi tablespace, yang dihilangkan karena elemen tambahan tersebut tidak didukung oleh pernyataan CREATE TABLE PostgreSQL.
Setelah DDL diekstrak, hapus tanda kutip yang mengapit nama dan lakukan konversi tabel sesuai dengan tabel konversi jenis data Oracle ke PostgreSQL. Periksa jenis data di setiap kolom untuk mengetahui apakah jenis data tersebut dapat dikonversi apa adanya. Jika tidak, pilih jenis data lain sesuai dengan tabel konversi. Misalnya, berikut adalah DDL yang dikonversi untuk tabel locations.
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 sudah ada. Perhatikan bahwa hanya nama kolom dan jenis data kolom yang disalin, sedangkan batasan dan indeks tidak. PostgreSQL mendukung standar ANSI SQL untuk fungsionalitas CTAS, dan kompatibel dengan pernyataan CTAS Oracle.
Kolom tak terlihat di Oracle 12c
PostgreSQL tidak mendukung kolom tak terlihat. Sebagai solusinya, buat tabel virtual yang hanya menampung kolom terlihat.
Batasan tabel
Oracle menyediakan enam jenis batasan tabel yang dapat ditetapkan pada atau setelah langkah pembuatan tabel menggunakan perintah ALTER TABLE. Jenis batasan Oracle adalah PRIMARY KEY, FOREIGN KEY, UNIQUE, CHECK, NOT
NULL, dan REF. Selain itu, Oracle mengizinkan pengguna mengontrol status batasan melalui opsi berikut:
INITIALLY IMMEDIATE: Memeriksa batasan di akhir setiap pernyataan SQL berikutnya (status default).DEFERRABLE/NOT DEFERRABLE: Mengaktifkan penggunaan klausaSET CONSTRAINTdalam transaksi berikutnya sebelum pernyataanCOMMITdikirim.INITIALLY DEFERRED: Memeriksa batasan di akhir transaksi berikutnya.VALIDATE/NO VALIDATE: Memeriksa (atau sengaja tidak memeriksa) error pada baris baru atau baris yang diubah. Parameter ini bergantung pada apakah batasannya adalahENABLEDatauDISABLED.ENABLED/DISABLED: Menentukan apakah batasan harus diterapkan setelah pembuatan (ENABLEDsecara 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 di Oracle dan PostgreSQL, termasuk:
- PostgreSQL tidak mendukung batasan
REFOracle. - PostgreSQL tidak otomatis membuat indeks di kolom referensi untuk batasan kunci asing. Jika indeks dibutuhkan, pernyataan
CREATE INDEXberbeda diperlukan di kolom referensi. - PostgreSQL tidak mendukung klausa
ON DELETE SET NULLOracle. Klausa ini meminta Oracle menetapkan semua nilai dependen dalam tabel turunan keNULLsaat kumpulan data dalam tabel induk dihapus. - Batasan terkait
VIEWStidak didukung, kecuali untukCHECK OPTION. - PostgreSQL tidak mendukung batasan penonaktifan. PostgreSQL mendukung opsi
NOT VALIDsaat batasan kunci asing atau pemeriksaan baru ditambahkan menggunakan pernyataanALTER TABLE. Opsi ini meminta PostgreSQL melewati pemeriksaan integritas referensial pada kumpulan data yang ada dalam tabel turunan.
Tabel berikut merangkum perbedaan utama antara jenis batasan di Oracle dan di PostgreSQL:
| Jenis batasan di Oracle | Dukungan di 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 penghapusan data dari tabel induk dan tabel turunan direferensikan oleh batasan FOREIGN KEY:
PostgreSQL tidak mendukung klausa ON DELETE SET NULL Oracle. Menggunakan klausa ON UPDATE untuk menangani kasus pembaruan kumpulan data induk FOREIGN
KEY.PostgreSQL menyediakan tiga opsi untuk menangani peristiwa pembaruan batasan FOREIGN KEY:
PostgreSQL tidak 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 batasan kunci asing atau pemeriksaan baru ditambahkan ke tabel menggunakan pernyataan ALTER
TABLE untuk melewati pemeriksaan integritas referensial di kumpulan data yang sudah ada. |
| Batasan terkait VIEW | Tidak | Tidak didukung kecuali VIEW WITH CHECK OPTION. |
| Metadata batasan | Oracle | DBA_CONSTRAINTS |
| PostgreSQL | INFORMATION_SCHEMA.TABLE_CONSTRAINTS |
Kolom virtual dan kolom buatan
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 di 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 fungsionalitas, kolom buatan di PostgreSQL sebanding dengan kolom virtual di Oracle. Namun, tidak seperti di Oracle, kolom buatan di PostgreSQL disimpan dan jenis data untuk setiap kolom yang dibuat harus ditentukan, yang berarti kolom tersebut menggunakan penyimpanan seperti halnya kolom biasa.
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 aneka aplikasi. Berikut daftar algoritma pengindeksan yang tersedia di PostgreSQL:
| Algoritma indeks | Deskripsi |
|---|---|
| B-tree |
|
| Hash |
|
| GIN |
|
| GiST |
|
| SP-GiST |
|
| BRIN |
|
Tabel berikut membandingkan jenis indeks antara Oracle dan PostgreSQL:
| Indeks di Oracle | Deskripsi | Didukung oleh PostgreSQL | Indeks setara di PostgreSQL |
|---|---|---|---|
| Indeks bitmap | Menyimpan bitmap untuk setiap kunci indeks, ideal untuk mendukung pengambilan data cepat untuk workload OLAP | Tidak | T/A |
| Indeks B-tree | Jenis indeks yang 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 multi-kolom Hingga 32 kolom dapat ditentukan saat membuat indeks multi-kolom. |
| Indeks berbasis fungsi | Menyimpan output dari fungsi yang diterapkan pada nilai kolom tabel. | Ya | Indeks terkait 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 tak 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 di 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. Di PostgreSQL, penyimpanan tabel sesuai dengan indeks tertentu diatur menggunakan pernyataan CLUSTER. Pernyataan ini memiliki fungsi yang mirip dengan tabel yang diatur indeks di Oracle. Namun, pengelompokan merupakan operasi satu kali, dan PostgreSQL tidak mempertahankan struktur tabel pada pembaruan berikutnya. Pengelompokan manual dan berkala diperlukan. |
| Indeks lokal dan global | Digunakan untuk mengindeks tabel berpartisi di database Oracle. Setiap indeks ditetapkan sebagai LOCAL atau GLOBAL. |
Tidak | Indeks kerja partisi di PostgreSQL memiliki fungsionalitas yang sama dengan indeks lokal di Oracle (yaitu indeks ditetapkan di tingkat partisi; tingkat global tidak didukung). |
| Indeks parsial untuk tabel berpartisi (Oracle 12c) | Membuat indeks di sebagian partisi tabel. Mendukung LOCAL dan GLOBAL. |
Ya | Di PostgreSQL, partisi dibuat dengan melampirkan tabel turunan ke dalam tabel induk. Indeks hanya dapat dibuat di sebagian tabel turunan. |
CREATE/DROP INDEX |
Perintah yang digunakan untuk membuat dan menghapus indeks. | Ya | PostgreSQL mendukung perintah CREATE INDEX. Selain itu, ALTER TABLE tableName ADD INDEX indexName
columnName juga didukung. |
ALTER INDEX ... REBUILD |
Membuat ulang indeks, yang dapat menyebabkan penguncian eksklusif pada tabel yang diindeks. | Perlu sintaksis berbeda | PostgreSQL mendukung pembuatan ulang indeks menggunakan pernyataan REINDEX. Tabel dikunci untuk operasi tulis selama operasi ini berlangsung dan hanya operasi baca yang diizinkan. |
ALTER INDEX ... REBUILD ONLINE |
Membuat ulang indeks tanpa menimbulkan penguncian eksklusif di tabel itu. | Perlu sintaksis berbeda | PostgreSQL mendukung pembuatan ulang indeks serentak menggunakan pernyataan REINDEX TABLE
CONCURRENTLY. Dalam mode ini, PostgreSQL mencoba membuat ulang indeks menggunakan penguncian minimum, meskipun konsekuensinya pembuatan ulang indeks memerlukan waktu dan resource lebih banyak. |
| 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 pembuatan indeks dalam tablespace yang ditetapkan pengguna, Anda tidak dapat membuat tablespace di Cloud SQL untuk PostgreSQL, dan indeks harus dibuat di tablespace default. |
| Mengindeks metadata (tabel/tabel virtual) | Oracle | DBA_INDEXES |
|
| PostgreSQL | pg_catalog.pg_index |
Pertimbangan konversi indeks
Pada umumnya, indeks Oracle dapat dengan mudah dikonversi menjadi indeks B-tree PostgreSQL, karena jenis indeks ini paling umum digunakan.
Seperti dalam database Oracle, indeks otomatis dibuat di kolom PRIMARY KEY pada tabel. Demikian pula, indeks UNIQUE otomatis dibuat di kolom yang memiliki batasan UNIQUE. Selain itu, indeks sekunder dibuat menggunakan pernyataan CREATE INDEX standar.
Contoh berikut menunjukkan cara mengonversi tabel Oracle yang berisi beberapa kolom terindeks ke dalam 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 sama-sama menawarkan kapabilitas pembuatan partisi untuk memecah tabel berukuran besar. Partisi dibuat dengan menyegmentasikan tabel secara fisik menjadi bagian-bagian lebih kecil. Setiap bagian berisi sekumpulan baris horizontal. Tabel yang dipartisi disebut sebagai tabel induk dan baris-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-jenis partisi yang didukung di PostgreSQL. Setiap jenis disertai contoh cara membuat partisi yang berkaitan dengan jenis tersebut.
Partisi RANGE
Jenis partisi ini menetapkan baris ke partisi berdasarkan nilai kolom yang berada dalam rentang tertentu. Setiap partisi berisi baris yang nilai ekspresi pemartisiannya berada dalam rentang tertentu. Perlu 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
Mirip dengan partisi RANGE, partisi LIST menetapkan baris ke partisi berdasarkan nilai kolom yang berada dalam kumpulan nilai yang telah ditetapkan. 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 sasarannya 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 disisipkan 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 berbeda. Jumlah sub-partisi dapat bervariasi antara satu partisi dan 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 melepas 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 pemartisian yang 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 elemen jenis partisi yang sama di Oracle dan Cloud SQL untuk PostgreSQL, dan elemen yang perlu dikonversi:
| Jenis partisi di Oracle | Didukung oleh PostgreSQL | Implementasi di 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 membuat partisi dengan ekspresi kolom virtual secara langsung:
|
| Partisi daftar otomatis | Tidak | Tidak didukung |
| Memecah partisi |
Tidak | Sebagai solusinya, pertimbangkan melepas atau memasang partisi tabel untuk menyesuaikan batas partisi |
| Menukar partisi | Ya | DETACH / ATTACH PARTITION |
| Partisi multi-jenis (partisi komposit) | Ya | Partisi multi-level |
| Metadata partisi | Oracle | DBA_TAB_PARTITIONS |
| PostgreSQL | pg_catalog.pg_class |
Contoh berikut menunjukkan perbandingan per aspek dari pembuatan partisi tabel di kedua platform. Perhatikan bahwa PostgreSQL tidak mendukung pereferensian tablespace dalam klausa PARTITIONS perintah CREATE TABLE.
Implementasi di 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 di 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
Di database Oracle, tabel sementara disebut GLOBAL TEMPORARY TABLES, sedangkan di PostgreSQL, tabel sementara cukup disebut tabel sementara. Fungsionalitas dasar tabel sementara di kedua platform sama persis. Namun, ada beberapa perbedaan penting:
- Oracle menyimpan struktur tabel sementara untuk penggunaan berulang bahkan setelah database dimulai ulang. Di sisi lain, PostgreSQL menyimpan tabel sementara hanya selama durasi sesi.
- Tabel sementara di database Oracle dapat diakses oleh berbagai pengguna dengan izin yang sesuai. Sebaliknya, tabel sementara di PostgreSQL hanya dapat diakses selama sesi yang dibuat untuknya, kecuali jika tabel sementara tersebut direferensikan dengan nama yang memenuhi syarat skema.
- Di database Oracle, terdapat perbedaan jelas antara tabel sementara
GLOBALdanLOCALyang menentukan apakah isi tabel bersifat global atau khusus sesi. Di PostgreSQL, kata kunciGLOBALdanLOCALdidukung karena alasan kompatibilitas, tetapi tidak berpengaruh pada visibilitas data. - Jika klausa
ON COMMITdihilangkan saat membuat tabel sementara, perilaku default di database Oracle adalahON COMMIT DELETE ROWS. Artinya, Oracle akan memotong tabel sementara setelah setiap commit. Sebaliknya, di PostgreSQL, perilaku defaultnya 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 di Oracle | Implementasi di PostgreSQL |
|---|---|---|
| Sintaksis | CREATE GLOBAL TEMPORARY TABLE |
CREATE TEMPORARY TABLE |
| Aksesibilitas | Dapat diakses dari banyak sesi | Dapat diakses dari sesi pembuat saja, kecuali jika direferensikan dengan nama yang memenuhi syarat skema |
| Dukungan indeks | Ya | Ya |
| Dukungan kunci asing | Ya | Ya |
| Mempertahankan DDL | Ya | Tidak |
Tindakan default ON COMMIT |
Kumpulan data dihapus | Kumpulan data dipertahankan |
ON COMMIT PRESERVE ROWS |
Ya | Ya |
ON COMMIT DELETE ROWS |
Ya | Ya |
ON COMMIT DROP |
Tidak | Ya |
Dukungan ALTER TABLE |
Ya | Ya |
| Statistik pengumpulan | DBMS_STATS.GATHER_TABLE_STATS |
ANALYZE |
Oracle 12c GLOBAL_TEMP_TABLE_STATS |
DBMS_STATS.SET_TABLE_PREFS |
ANALYZE |
Kolom yang tidak digunakan
Di Oracle, fitur penandaan kolom tertentu sebagai UNUSED sering digunakan untuk menghapus kolom dari tabel tanpa menghapus data kolom secara fisik. Tindakan ini dilakukan untuk mencegah potensi muatan tinggi yang terjadi saat menghapus kolom dari tabel besar.
Di PostgreSQL, data kolom tidak akan terhapus dari penyimpanan fisik jika kolom besar dihapus. Oleh karena itu, operasi penghapusan berjalan cepat meskipun tabel berukuran besar. Anda tidak perlu menandai kolom sebagai UNUSED seperti di database Oracle. Ruang yang semula ditempati kolom yang dihapus akan diklaim kembali dengan pernyataan DML baru atau selama operasi VACUUM berikutnya.
Tabel hanya baca
Tabel hanya-baca adalah fitur di Oracle yang menandai tabel sebagai hanya-baca menggunakan perintah ALTER TABLE. Di Oracle 12c R2, fitur ini juga tersedia untuk tabel yang memiliki partisi dan subpartisi. PostgreSQL tidak menawarkan fitur yang setara, tetapi ada dua kemungkinan alternatif:
- Memberikan izin
SELECTatas tabel untuk pengguna tertentu. Perlu diperhatikan bahwa izin ini tidak menghalangi pemilik tabel untuk melakukan operasi DML di tabel miliknya. - Membuat replika baca Cloud SQL untuk PostgreSQL dan mengarahkan pengguna ke tabel replika yang merupakan tabel hanya baca. Solusi ini memerlukan penambahan instance replika baca ke instance Cloud SQL untuk PostgreSQL yang ada.
Membuat 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 sama-sama mendukung berbagai himpunan karakter, kolasi, dan unicode, termasuk dukungan untuk bahasa byte tunggal dan multi-byte. Selain itu, database PostgreSQL yang berada di instance yang sama dapat dikonfigurasi dengan himpunan karakter berbeda. Lihat daftar himpunan karakter yang didukung di PostgreSQL.
Di database Oracle, himpunan karakter ditentukan di tingkat database (Oracle 12g R1 atau yang lebih lama) atau di tingkat database pluggable (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
Baik tabel virtual sederhana maupun kompleks didukung di PostgreSQL. Untuk opsi pembuatan tabel virtual, ada beberapa perbedaan antara Oracle dan PostgreSQL. Tabel berikut menunjukkan perbedaan tersebut.
| Fitur tabel virtual di Oracle | Deskripsi | Dukungan di Cloud SQL untuk PostgreSQL | Pertimbangan konversi |
|---|---|---|---|
FORCE |
Membuat tabel virtual tanpa memverifikasi keberadaan tabel/tabel virtual sumber. | Tidak | Tidak tersedia opsi yang setara. |
CREATE OR REPLACE |
Membuat tabel virtual yang belum ada atau menimpa tabel virtual yang sudah ada. | Ya | PostgreSQL mendukung perintah CREATE OR REPLACE untuk tabel virtual. |
WITH CHECK OPTION |
Menentukan tingkat penerapan saat menjalankan operasi DML terhadap tabel virtual. | Ya | Setelan defaultnya adalah CASCADED, yang menyebabkan tabel virtual yang direferensikan juga dievaluasi.Kata kunci LOCAL menyebabkan hanya tabel virtual saat ini yang dievaluasi. |
WITH READ-ONLY |
Hanya mengizinkan operasi baca di tabel virtual. Operasi DML dilarang. | Tidak | Solusinya adalah memberikan hak istimewa SELECT atas tabel virtual kepada semua pengguna. |
VISIBLE | INVISIBLE (Oracle 12c) |
Menentukan apakah kolom yang didasarkan pada tabel virtual terlihat atau tidak terlihat oleh pengguna. | Tidak | Membuat VIEW dengan kolom yang diperlukan saja. |
Contoh konversi berikut menunjukkan cara mengonversi tabel virtual dari Oracle ke Cloud SQL PostgreSQL.
-- 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).
Pengelolaan akses tabel virtual:
Pemilik tabel virtual harus memiliki hak istimewa atas tabel dasar untuk membuat tabel virtual. Pengguna tabel virtual memerlukan izin SELECT yang sesuai atas tabel virtual.
Izin INSERT, UPDATE, dan DELETE yang sesuai atas tabel virtual juga diperlukan saat operasi DML dijalankan terhadap tabel virtual. Dalam kasus mana pun, pengguna tidak memerlukan izin atas tabel dasar.
Langkah berikutnya
- Pelajari lebih lanjut akun pengguna PostgreSQL.
- Pelajari arsitektur referensi, diagram, dan praktik terbaik tentang Google Cloud. Lihat Cloud Architecture Center kami.