Migrazione degli utenti e degli schemi di database Oracle® a Cloud SQL per PostgreSQL

Mantieni tutto organizzato con le raccolte Salva e classifica i contenuti in base alle tue preferenze.

Questo documento fa parte di una serie che fornisce informazioni chiave e istruzioni relative alla pianificazione e all'esecuzione di migrazioni di database Oracle® 11g/12c a Cloud SQL per PostgreSQL versione 12. Questo documento illustra le differenze di base tra Oracle® Database e Cloud SQL per PostgreSQL in relazione alla creazione di utenti, schemi, tabelle, indici e visualizzazioni.

Oltre alla parte introduttiva della configurazione, la serie include le seguenti parti:

Differenze di terminologia tra Oracle e Cloud SQL per PostgreSQL

Oracle e Cloud SQL per PostgreSQL hanno architetture e terminologia diverse per istanze, database, utenti e schemi. Per un riepilogo di queste differenze, consulta la parte relativa alla terminologia di questa serie.

Esportazione delle configurazioni Oracle

Uno dei primi passaggi per la pianificazione di una migrazione a Cloud SQL per PostgreSQL consiste nel rivedere le impostazioni dei parametri esistenti nel database Oracle di origine. Le impostazioni relative all'allocazione della memoria, al set di caratteri e ai parametri di archiviazione sono particolarmente utili perché possono determinare la configurazione e il dimensionamento iniziali dell'ambiente di destinazione Cloud SQL per PostgreSQL. Esistono diversi metodi per estrarre le impostazioni dei parametri Oracle. Di seguito sono riportati alcuni esempi:

  • I report sul repository di carichi di lavoro automatici contengono dati di allocazione delle risorse (CPU, RAM), configurazione dei parametri dell'istanza e numero massimo di sessioni attive.
  • DBA_HIST, V$OSSTAT e V$LICENSE per i dettagli di utilizzo della CPU.
  • V$PARAMETER per i parametri di configurazione del database.
  • Visualizzazione V$NLS_PARAMETERS per i parametri della lingua del database.
  • DBA_DATA_FILES per il calcolo delle dimensioni di archiviazione del database.
  • Oracle SPFILE per le configurazioni delle istanze di database.
  • Strumenti di pianificazione dei job (ad esempio, crontab) per identificare i backup di routine o i periodi di manutenzione da prendere in considerazione.

Importazione e configurazione di utenti in Cloud SQL per PostgreSQL

A livello generale, ogni schema Oracle deve essere creato come proprio schema in PostgreSQL. In un database Oracle, user è sinonimo di schema. Questo significa che lo schema viene creato durante la creazione di un utente. Esiste sempre una relazione 1:1 tra utenti e schemi. In PostgreSQL, gli utenti e gli schemi vengono creati separatamente. È possibile creare un utente senza creare uno schema corrispondente. Per mantenere lo stesso utente o struttura di schema Oracle in PostgreSQL, puoi creare uno schema per ogni utente.

La seguente tabella illustra gli esempi di conversione:

Tipo di azione Tipo di database Confronto comandi
Crea utente e schema Oracle CREATE USER username IDENTIFIED BY password;
PostgreSQL Utente e schema sono concetti distinti in PostgreSQL, pertanto sono necessarie due istruzioni CREATE separate

CREATE USER username WITH PASSWORD 'password';
CREATE SCHEMA schema_name;
Assegnare i ruoli di amministratore a un utente Oracle GRANT CONNECT TO username;
PostgreSQL GRANT pg_monitor TO username;
Concessione di privilegi Oracle GRANT SELECT, INSERT, UPDATE ON HR.EMPLOYEES TO username;
PostgreSQL GRANT SELECT, INSERT, UPDATE ON HR.EMPLOYEES TO username;
Revoca dei privilegi Oracle REVOKE UPDATE ON HR.EMPLOYEES FROM username;
PostgreSQL REVOKE UPDATE ON HR.EMPLOYEES FROM username;
Concedi DBA/super user Oracle GRANT DBA TO username;
PostgreSQL GRANT cloudsqlsuperuser TO username;
Rilascia utente Oracle DROP USER username CASCADE;
PostgreSQL Utente e schema sono concetti distinti in PostgreSQL, pertanto sono necessarie due istruzioni DROP separate

DROP USER username;
DROP SCHEMA schema_name CASCADE;
Metadati degli utenti Oracle DBA_USERS
PostgreSQL pg_catalog.pg_user
Metadati autorizzazioni Oracle DBA_SYS_PRIVS
DBA_ROLE_PRIVS
SESSION_PRIVS
PostgreSQL pg_catalog.pg_roles
Stringa di connessione dell'interfaccia a riga di comando Oracle sqlplus username/password@host/tns_alias
Sqlplus username/password@host:IP/sid
PostgreSQL Senza prompt della password:

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

Con il prompt della password:

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

Utenti dei database Oracle 12c:

Esistono due tipi di utenti in Oracle 12c, comuni e locali. Gli utenti comuni vengono creati nel CDB radice, inclusi i PDB. Sono identificati dal prefisso C## nel nome utente. Gli utenti locali vengono creati solo in un PDB specifico. È possibile creare diversi utenti di database con nomi utente identici in più PDB. Durante la migrazione da Oracle 12c a PostgreSQL, modifica gli utenti e le autorizzazioni in base all'architettura di PostgreSQL. Ecco due esempi comuni per illustrare queste differenze:

# 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)

Gestione degli utenti tramite la console Google Cloud

Per visualizzare gli utenti attualmente configurati in Cloud SQL per PostgreSQL, vai alla pagina seguente nella console Google Cloud:

Google Cloud > Storage > SQL > Istanza > Utenti

Screenshot della pagina Utenti.

Importazione di definizioni di tabelle e visualizzazioni

Oracle e PostgreSQL sono diversi in termini di sensibilità alle maiuscole. I nomi Oracle non fanno distinzione tra maiuscole e minuscole. I nomi PostgreSQL non sono sensibili alle maiuscole, tranne quando sono racchiusi tra virgolette doppie. Molti strumenti di esportazione di schema e SQL per Oracle, come DBMS_METADATA.GET_DDL, aggiungono automaticamente virgolette doppie ai nomi degli oggetti. Queste virgolette possono causare diversi tipi di problemi dopo la migrazione. Ti consigliamo di rimuovere tutte le virgolette che circondano i nomi degli oggetti dalle istruzioni DDL (Data Definition Language) prima di creare gli oggetti in PostgreSQL.

Crea sintassi della tabella

Durante la conversione delle tabelle da Oracle a tipi di dati PostgreSQL, il primo passaggio consiste nell'estrazione delle istruzioni di tabella Oracle per creare il database di origine. La seguente query di esempio estrae il DDL per la tabella delle località dallo schema 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

L'output completo include elementi di archiviazione, indici e informazioni sulla tabella, che sono stati omessi perché questi elementi aggiuntivi non sono supportati dall'istruzione CREATE TABLEPostgreSQL.

Dopo che il DDL è stato estratto, rimuovi le virgolette che circondano i nomi ed esegui la conversione della tabella in base ai tipi di dati Oracle-to-PostgreSQL tabella di conversione. Controlla ogni tipo di dati della colonna per verificare se è possibile convertirlo così com'è o, se non è supportato, scegli un tipo di dati diverso in base alla tabella delle conversioni. Ad esempio, di seguito è riportato il DDL convertito per la tabella delle località.

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)
)

Crea tabella come selezione (CTAS)

L'istruzione CREATE TABLE AS SELECT (CTAS) viene utilizzata per creare una nuova tabella basata su una tabella esistente. Tieni presente che solo i nomi e i tipi di dati delle colonne vengono copiati, al contrario di vincoli e indici. PostgreSQL supporta lo standard ANSI SQL per la funzionalità CTAS ed è compatibile con l'istruzione CTAS di Oracle.

Colonne invisibili Oracle 12c

PostgreSQL non supporta le colonne invisibili. Per risolvere il problema, crea una vista che contenga solo le colonne visibili.

Vincoli della tabella

Oracle offre sei tipi di vincoli della tabella che possono essere definiti durante la creazione della tabella o dopo la sua creazione utilizzando il comando ALTER TABLE. I tipi di vincoli Oracle sono PRIMARY KEY, FOREIGN KEY, UNIQUE, CHECK, NOT NULL e REF. Inoltre, Oracle consente all'utente di controllare lo stato di un vincolo tramite le seguenti opzioni:

  • INITIALLY IMMEDIATE: controlla il vincolo alla fine di ogni istruzione SQL successiva (lo stato predefinito).
  • DEFERRABLE/NOT DEFERRABLE: consente l'utilizzo della clausola SET CONSTRAINT nelle transazioni successive fino all'invio di un'istruzione COMMIT
  • INITIALLY DEFERRED: controlla il vincolo alla fine delle transazioni successive.
  • VALIDATE/NO VALIDATE: controlla (o deliberatamente non verifica) la presenza di errori in righe nuove o modificate. Questi parametri dipendono dal vincolo: ENABLED o DISABLED.
  • ENABLED/DISABLED: specifica se il vincolo deve essere applicato dopo la creazione (ENABLED per impostazione predefinita)

PostgreSQL supporta anche sei tipi di vincoli della tabella: PRIMARY KEY, FOREIGN KEY, UNIQUE, CHECK, NOT NULL e EXCLUDE. Tuttavia, esistono alcune differenze significative tra i tipi di vincolo Oracle e PostgreSQL, tra cui:

  • PostgreSQL non supporta il vincolo REF di Oracle.
  • PostgreSQL non crea automaticamente un indice sulle colonne di riferimento per un vincolo di chiave esterna. Se è necessario un indice, è necessaria un'istruzione CREATE INDEX separata nelle colonne di riferimento.
  • PostgreSQL non supporta la clausola ON DELETE SET NULL di Oracle. Questa clausola indica a Oracle di impostare i valori dipendenti nelle tabelle figlio su NULL quando il record nella tabella padre viene eliminato.
  • I vincoli su VIEWS non sono supportati, ad eccezione di CHECK OPTION.
  • PostgreSQL non supporta la disabilitazione dei vincoli. PostgreSQL supporta l'opzione NOT VALID quando viene aggiunta una nuova chiave esterna o un vincolo di controllo utilizzando un'istruzione ALTER TABLE. Questa opzione indica a PostgreSQL di saltare i controlli di integrità di riferimento sui record esistenti nella tabella secondaria.

La seguente tabella riassume le principali differenze tra i tipi di vincoli di Oracle e PostgreSQL:

Tipo di vincolo Oracle Supporto di Cloud SQL per PostgreSQL Equivalente Cloud SQL per PostgreSQL
PRIMARY KEY PRIMARY KEY
FOREIGN KEY Utilizza la stessa sintassi SQL ANSI di Oracle.

Utilizza la clausola ON DELETE per gestire i casi di eliminazione dei record padre FOREIGN KEY. PostgreSQL fornisce tre opzioni per gestire i casi in cui i dati vengono eliminati dalla tabella padre e a cui viene fatto riferimento a una tabella secondaria da un vincolo FOREIGN KEY:

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

PostgreSQL non supporta la clausola ON DELETE SET NULL di Oracle.

Utilizza la clausola ON UPDATE per gestire i casi di aggiornamento dei record padre di FOREIGN KEY.
PostgreSQL offre tre opzioni per gestire FOREIGN KEYgli eventi di aggiornamento del vincolo:

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

PostgreSQL non crea automaticamente un indice sulle colonne di riferimento per un vincolo di chiave esterna.
UNIQUE Crea un indice UNIQUE per impostazione predefinita.
CHECK CHECK
NOT NULL NOT NULL
REF No Non supportati.
DEFERRABLE/NOT DEFERRABLE DEFERRABLE/NOT DEFERRABLE
INITIALLY IMMEDIATE INITIALLY IMMEDIATE
INITIALLY DEFERRED INITIALLY DEFERRED
VALIDATE/NO VALIDATE No Non supportati.
ENABLE/DISABLE No Questa opzione è abilitata per impostazione predefinita. Utilizza l'opzione NOT VALID quando alla tabella viene aggiunta una nuova chiave esterna o un vincolo di controllo utilizzando un'istruzione ALTER TABLE per saltare i controlli di integrità referenziali sui record esistenti.
Vincolo di VIEW No Non supportata tranne VIEW WITH CHECK OPTION.
Metadati vincoli Oracle DBA_CONSTRAINTS
PostgreSQL INFORMATION_SCHEMA.TABLE_CONSTRAINTS

Colonne virtuali e generate

Le colonne virtuali di Oracle si basano sui risultati di calcolo di altre colonne. Vengono visualizzate come colonne normali, ma i valori vengono ricavati da un calcolo all'istante dal motore del database Oracle e non memorizzati nel database. Le colonne virtuali possono essere utilizzate con vincoli, indici, partizionamento delle tabelle e chiavi esterne, ma non possono essere manipolate tramite operazioni con il metodo di manipolazione dei dati (DML).

Le colonne generate di PostgreSQL sono paragonabili a quelle delle colonne virtuali di Oracle. Tuttavia, a differenza di Oracle, le colonne generate in PostgreSQL vengono archiviate e devi specificare un tipo di dati per ogni colonna generata, ovvero sarà occupata dallo spazio di archiviazione come se fossero colonne normali.

Esempio di colonna virtuale in 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

Esempio equivalente in 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)

Indici di tabella

Oracle e PostgreSQL forniscono una varietà di algoritmi di indicizzazione e tipi di indici utilizzabili per diverse applicazioni. Di seguito è riportato un elenco degli algoritmi di indicizzazione disponibili in PostgreSQL:

Algoritmo di indice Descrizione
Albero B
  • Tipo di indice predefinito per PostgreSQL, utilizzato per velocizzare le query sull'uguaglianza e sull'intervallo
  • Supporta tutti i tipi di dati primitivi e può essere utilizzato per recuperare valori NULL
  • I valori indice sono ordinati per ordine crescente per impostazione predefinita, ma possono essere configurati anche in un ordine decrescente
Hash
  • Utilizzato per velocizzare le ricerche sull'uguaglianza
  • Più efficiente dell'indice B-tre, ma limitato alla gestione delle ricerche sull'uguaglianza
GIN
  • Indici di albero invertiti
  • Più efficiente dell'indice B-tre per gestire le colonne che contengono più valori dei componenti, come la matrice e il testo
GiST
  • Non un singolo tipo di indice, ma un'infrastruttura per definire gli indici che potrebbero supportare più operatori di confronto rispetto a un normale indice B-albero
  • Utile per i dati geometrici quando è necessaria l'ottimizzazione delle ricerche "vicino a"
SP-GiST
  • Analogamente a GiST, SP-GiST è un'infrastruttura per le strategie di indicizzazione definite dall'utente
  • Consente una vasta gamma di diverse strutture di dati non bilanciate, come i quartili
  • Non disponibile in Cloud SQL per PostgreSQL
S poi
  • Blocco indexe di intervallo
  • Archivia i riepiloghi degli intervalli di blocchi fisici di una tabella
  • Per le colonne con un ordinamento lineare
  • Utile per la ricerca di intervalli su tabelle di grandi dimensioni

La tabella riportata di seguito confronta i tipi di indice tra Oracle e PostgreSQL:

Indice Oracle Descrizione Supportato da PostgreSQL Equivalente PostgreSQL
Indice bitmap Archivia una bitmap per ogni chiave di indice, più adatta per il recupero rapido dei dati per i carichi di lavoro OLAP No N/D
Indice albero B Tipo di indice più comune, adatto a una varietà di carichi di lavoro e può essere configurato nell'ordinamento ASC|DESC. Indice B-albero
Indice composto Vengono create su due o più colonne per migliorare le prestazioni di recupero dei dati. L'ordinamento delle colonne all'interno dell'indice determina il percorso di accesso. Indici di più colonne
Quando si crea un indice di più colonne, è possibile specificare fino a 32 colonne.
Indice basato sulle funzioni Archivia l'output di una funzione applicata ai valori di una colonna della tabella. Indici su espressioni
Indice univoco Un indice dell'albero B che applica un vincolo UNIQUE ai valori indicizzati in base alla colonna. Indice univoco
Indice dominio dell'applicazione Ideale per l'indicizzazione di dati non relazionali, come dati audio/video, dati LOB e altri tipi non testuali. No N/D
Indice invisibile Funzionalità Oracle che consente di gestire, gestire e testare gli indici senza influenzare il processo decisionale. No Per una soluzione alternativa, puoi creare un indice aggiuntivo su una replica di lettura a scopo di test senza influire sull'attività in corso.
Tabella organizzata dall'indice Un tipo di indice che controlla la modalità di archiviazione dei dati a livello di tabella e di indice. No PostgreSQL non supporta le tabelle organizzate in base all'indice. L'istruzione CLUSTER indica a PostgreSQL di organizzare l'archiviazione delle tabelle in base a un indice specificato. Ha uno scopo simile alla tabella organizzata da indice Oracle. Tuttavia, il clustering è un'operazione una tantum e PostgreSQL non mantiene la struttura della tabella negli aggiornamenti successivi. È necessario un clustering periodico manuale.
Indice locale e globale Utilizzato per indicizzare le tabelle partizionate in un database Oracle. Ogni indice è definito come LOCAL o GLOBAL. No Le partizioni di lavoro PostgreSQL hanno le stesse funzionalità degli indici locali Oracle (ovvero l'indice è definito a livello di partizione, il livello globale non è supportato).
Indici parziali per le tabelle partizionate (Oracle 12c) Crea un indice su un sottoinsieme delle partizioni di una tabella. Supporta LOCAL e GLOBAL. Il partizionamento in PostgreSQL funziona collegando le tabelle secondarie a una tabella padre. È possibile creare gli indici solo su un sottoinsieme di tabelle secondarie.
CREATE/DROP INDEX Comando utilizzato per la creazione e l'eliminazione dell'indice. PostgreSQL supporta il comando CREATE INDEX. Supporta anche ALTER TABLE tableName ADD INDEX indexName columnName
ALTER INDEX ... REBUILD Viene ricreato l'indice, che può causare un blocco esclusivo nella tabella indicizzata. Richiede una sintassi diversa PostgreSQL supporta le ricostruzioni dell'indice utilizzando l'istruzione REINDEX. La tabella è bloccata per le operazioni di scrittura durante questa operazione e sono consentite solo le letture.
ALTER INDEX ... REBUILD ONLINE Ricrea un indice senza creare un blocco esclusivo nella tabella. Richiede una sintassi diversa PostgreSQL supporta le ricostruzioni di indice simultanee utilizzando l'istruzione REINDEX TABLE CONCURRENTLY. In questa modalità, PostgreSQL tenta di ricostruire gli indici utilizzando il blocco minimo con il compromesso di richiedere più tempo e risorse per completare la ricostruzione.
Compressione degli indici Una funzionalità per ridurre le dimensioni fisiche dell'indice. No N/D
Allocazione
indice a uno spazio tabella
Crea uno spazio di tabella dell'indice che può essere archiviato su un disco separato dai dati della tabella per ridurre i colli di bottiglia di I/O del disco. No Anche se PostgreSQL consente di creare un indice in uno spazio tabella definito dall'utente, non è possibile creare spazi tabella in Cloud SQL per PostgreSQL e l'indice deve essere creato in uno spazio tabella predefinito.
Metadati degli indici (tabelle/visualizzazioni) Oracle DBA_INDEXES
DBA_PART_INDEXES
DBA_IND_COLUMNS
PostgreSQL pg_catalog.pg_index
pg_catalog.pg_attribute
pg_catalog.pg_class

Considerazioni sulla conversione dell'indice

Nella maggior parte dei casi, gli indici Oracle possono essere semplicemente convertiti in indici di albero B PostgreSQL, perché questo tipo di indice è il tipo di indice più utilizzato. Come in un database Oracle, viene creato automaticamente un indice sui campi PRIMARY KEY di una tabella. Analogamente, viene creato automaticamente un indice UNIQUE in campi con vincolo UNIQUE. Inoltre, gli indici secondari vengono creati utilizzando l'istruzione CREATE INDEX standard.

L'esempio seguente illustra come una tabella Oracle con più campi indicizzati può essere convertita in 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=>

Partizionamento tabella

Oracle e PostgreSQL offrono funzionalità di partizionamento per suddividere le tabelle di grandi dimensioni. A tal fine, segmenti fisicamente una tabella in parti più piccole, in cui ogni parte contiene un sottoinsieme orizzontale delle righe. La tabella partizionata è denominata tabella padre e le righe sono archiviate fisicamente nelle partizioni. Non tutti i tipi di partizione di Oracle sono supportati in PostgreSQL, ma PostgreSQL supporta quelli più comuni.

Le seguenti sezioni descrivono i tipi di partizione supportati da PostgreSQL, illustrando ciascuno di essi con un esempio su come creare le partizioni che corrispondono a quel tipo.

Partizionamento RANGE

Questo tipo di partizione assegna righe alle partizioni in base ai valori delle colonne che rientrano in un determinato intervallo. Ogni partizione contiene righe per le quali il valore dell'espressione di partizionamento si trova all'interno di un determinato intervallo. È importante notare che gli intervalli non si sovrappongono tra le partizioni.

Esempio

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);

Partizionamento LIST

Analogamente al partizionamento RANGE, il partizionamento LIST assegna righe alle partizioni in base ai valori delle colonne che rientrano in un insieme predefinito di valori. Le coppie chiave-valore che compaiono in ogni partizione sono esplicitamente elencate per le partizioni LIST.

Esempio

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);

Partizionamento HASH

Il partizionamento HASH è ideale quando l'obiettivo è ottenere una distribuzione uniforme dei dati tra tutte le partizioni. Un valore colonna (o un'espressione basata su un valore colonna da sottoporre ad hashing) e il valore riga vengono assegnati alla partizione corrispondente a tale valore hash. I valori hash devono essere assegnati in modo univoco alle partizioni e tutti i valori inseriti devono essere mappati esattamente a una partizione.

Esempio

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);

Partizionamento a più livelli

Il partizionamento a più livelli è un metodo per creare una gerarchia di partizioni per una singola tabella. Ogni partizione è ulteriormente suddivisa in una serie di partizioni diverse. Il numero di partizioni secondarie può variare da una partizione all'altra.

Esempio

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);

Collegare o scollegare le partizioni

In PostgreSQL, le partizioni possono essere aggiunte o rimosse dalla tabella padre. Una partizione scollegata può essere ricollegata in un secondo momento alla stessa tabella. Inoltre, quando si ricollega la partizione è possibile specificare nuove condizioni di partizionamento, il che consente di regolare i limiti di partizione.

Esempio

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;

La tabella seguente descrive dove i tipi di partizione Oracle e Cloud SQL per PostgreSQL sono equivalenti e dove è consigliata una conversione:

Tipo di partizione Oracle Supportato da PostgreSQL Implementazione PostgreSQL
RANGE partizioni PARTITION BY RANGE
LIST partizioni PARTITION BY LIST
HASH partizioni PARTITION BY HASH
SUB-PARTITIONING Partizionamento a più livelli
Partizioni a intervalli No Funzionalità non supportata
Consulente partizionamento No Funzionalità non supportata
Partizione delle preferenze No Funzionalità non supportata
Partizionamento virtuale basato su colonne No Come soluzione alternativa, valuta la possibilità di eseguire il partizionamento direttamente con l'espressione della colonna virtuale:

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)));

Partizionamento automatico degli elenchi No Funzionalità non supportata
Dividi
partizioni
No Per risolvere il problema, valuta la possibilità di scollegare o collegare le partizioni delle tabelle per regolare i limiti delle partizioni
Partizioni di Exchange DETACH / ATTACH PARTITION
Partizionamento multi-tipo (partizionamento composito) Partizionamento a più livelli
Metadati delle partizioni Oracle DBA_TAB_PARTITIONS
DBA_TAB_SUBPARTITIONS
PostgreSQL pg_catalog.pg_class
pg_catalog.pg_partitioned_table

L'esempio seguente mette a confronto la creazione di partizioni di tabelle su entrambe le piattaforme. Tieni presente che PostgreSQL non supporta il riferimento a uno spazio tabella nella clausola PARTITIONS del comando CREATE TABLE.

Implementazione 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
);

Implementazione 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);

Tabelle temporanee

In un database Oracle, le tabelle temporanee sono chiamate GLOBAL TEMPORARY TABLES, mentre in PostgreSQL sono note semplicemente come tabelle temporanee. La funzionalità di base di una tabella temporanea è identica su entrambe le piattaforme. Tuttavia, esistono alcune differenze significative:

  • Oracle archivia la struttura temporanea della tabella per un utilizzo ripetuto anche dopo il riavvio del database, mentre PostgreSQL archivia la tabella temporanea solo per la durata di una sessione.
  • diversi utenti con le autorizzazioni appropriate possono accedere a una tabella temporanea in un database Oracle. Al contrario, è possibile accedere a una tabella temporanea in PostgreSQL solo durante la sessione in cui è stata creata, a meno che non venga fatto riferimento alla tabella temporanea con nomi qualificati per lo schema.
  • In un database Oracle, esiste una distinzione tra GLOBAL e LOCALtabelle temporanee che specifica se i contenuti della tabella sono globali o specifici per la sessione. In PostgreSQL, le parole chiave GLOBAL e LOCAL sono supportate per motivi di compatibilità, ma non influiscono sulla visibilità dei dati.
  • Se la clausola ON COMMIT viene omessa durante la creazione di una tabella temporanea, il comportamento predefinito nel database Oracle è ON COMMIT DELETE ROWS, il che significa che Oracle tronca la tabella temporanea dopo ogni commit. Al contrario, in PostgreSQL il comportamento predefinito prevede il mantenimento delle righe nella tabella temporanea dopo ogni commit.

La seguente tabella evidenzia le differenze nelle tabelle temporanee tra Oracle e Cloud SQL per PostgreSQL.

Funzionalità temporanea della tabella Implementazione Oracle Implementazione PostgreSQL
Sintassi CREATE GLOBAL TEMPORARY TABLE CREATE TEMPORARY TABLE
Accessibilità Accessibile da più sessioni Sono accessibili solo dalla sessione del creator, a meno che non venga fatto riferimento con nomi qualificati come schema
Supporto degli indici
Assistenza per le chiavi esterne
Preserva DDL No
Azione predefinita: ON COMMIT I record sono stati eliminati I record vengono conservati
ON COMMIT PRESERVE ROWS
ON COMMIT DELETE ROWS
ON COMMIT DROP No
ALTER TABLE assistenza
Raccolta delle statistiche DBMS_STATS.GATHER_TABLE_STATS ANALYZE
Oracle 12c GLOBAL_TEMP_

TABLE_STATS
DBMS_STATS.SET_TABLE_PREFS ANALYZE

Colonne non utilizzate

La funzionalità di Oracle per contrassegnare colonne specifiche come UNUSED viene spesso utilizzata per rimuovere le colonne dalle tabelle senza rimuovere fisicamente i dati delle colonne. Questo per evitare i potenziali carichi elevati che si verificano durante l'eliminazione delle colonne da tabelle di grandi dimensioni.

In PostgreSQL, l'eliminazione di una colonna di grandi dimensioni non comporta la rimozione dei dati della colonna dallo spazio di archiviazione fisico e costituisce quindi un'operazione rapida anche su tabelle di grandi dimensioni. Non è necessario contrassegnare una colonna come UNUSED come in un database Oracle. Lo spazio occupato dalla colonna eliminata viene recuperato da nuove istruzioni DML o durante un'operazione VACUUM successiva.

Tabelle di sola lettura

Le tabelle di sola lettura sono una funzionalità Oracle che contrassegna le tabelle come di sola lettura utilizzando il comando ALTER TABLE. In Oracle 12c R2, questa funzionalità è disponibile anche per le tabelle con partizioni e partizioni. PostgreSQL non offre una funzionalità equivalente, ma esistono due possibili soluzioni:

  • Concedi a SELECT l'autorizzazione per le tabelle di utenti specifici. Tieni presente che ciò non impedisce al proprietario della tabella di eseguire operazioni DML sulle proprie tabelle.
  • Creare una replica di lettura Cloud SQL per PostgreSQL e indirizzare gli utenti alle tabelle di replica di sola lettura. Questa soluzione richiede l'aggiunta di un'istanza di replica di lettura a un'istanza Cloud SQL per PostgreSQL esistente.
  • Crea un trigger di database che solleva le eccezioni sulle istruzioni DML, ad esempio:

    -- 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=>
    

Set di caratteri

Oracle e PostgreSQL supportano un'ampia gamma di set di caratteri, regole di confronto e Unicode, incluso il supporto per linguaggi sia a byte singolo sia multi-byte. Inoltre, i database PostgreSQL che risiedono sulla stessa istanza possono essere configurati con set di caratteri distinti. Consulta l'elenco dei set di caratteri supportati in PostgreSQL.

Nel database Oracle, i set di caratteri sono specificati a livello di database (Oracle 12g R1 o versioni precedenti) o a livello di database collegabile (Oracle 12g R2 o successivo). In PostgreSQL, viene specificato un set di caratteri predefinito quando viene creata una nuova istanza Cloud SQL per PostgreSQL. Ogni database creato all'interno dell'istanza può essere creato con un set di caratteri diverso. L'ordinamento e la classificazione dei caratteri possono essere specificati per colonna della tabella.

Esempio

-- 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(> );

Visualizzazioni

PostgreSQL supporta viste sia semplici che complesse. Per le opzioni di creazione della visualizzazione, esistono alcune differenze tra Oracle e PostgreSQL. La tabella seguente evidenzia queste differenze.

Funzionalità Oracle View Descrizione Supporto di Cloud SQL per PostgreSQL Considerazioni sulle conversioni
FORCE Creare una vista senza verificare se le tabelle/visualizzazioni di origine esistono. No Nessuna opzione equivalente disponibile.
CREATE OR REPLACE Creare una vista inesistente o sovrascrivere una vista esistente. PostgreSQL supporta il comando CREATE OR REPLACE per le viste.
WITH CHECK OPTION Specifica il livello di applicazione forzata quando esegui operazioni DML rispetto alla vista. L'impostazione predefinita è CASCADED, determinando anche la valutazione delle viste di riferimento.

La parola chiave LOCAL determina solo la valutazione della visualizzazione corrente.
WITH READ-ONLY Consente solo operazioni di lettura sulla vista. Le operazioni DML non sono consentite. No Una soluzione alternativa consiste nel concedere a tutti gli utenti i privilegi SELECT sulla visualizzazione.
VISIBLE | INVISIBLE (Oracle 12c) Specifica se una colonna basata sulla visualizzazione è visibile o invisibile all'utente. No Crea VIEW solo con le colonne richieste.

L'esempio di conversione seguente mostra una conversione da Oracle a Cloud SQL PostgreSQL per le viste.

-- 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).

Visualizza gestione dell'accesso:

I proprietari di una vista devono disporre dei privilegi contenuti nelle tabelle di base per creare la vista. L'utente di una vista deve disporre delle opportune autorizzazioni SELECT sulla vista. Inoltre, hanno bisogno delle autorizzazioni INSERT, UPDATE e DELETE appropriate nella vista durante l'esecuzione di operazioni DML attraverso la vista. In entrambi i casi, gli utenti non hanno bisogno di autorizzazioni nelle tabelle sottostanti.

Passaggi successivi

  • Scopri di più sugli account utente PostgreSQL.
  • Esplora architetture di riferimento, diagrammi e best practice su Google Cloud. Dai un'occhiata al nostro Cloud Architecture Center.