

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# Migrer la fonctionnalité Oracle ROWID vers PostgreSQL sur AWS
<a name="migrate-oracle-rowid-functionality-to-postgresql-on-aws"></a>

*Rakesh Raghav et Ramesh Pathuri, Amazon Web Services*

## Résumé
<a name="migrate-oracle-rowid-functionality-to-postgresql-on-aws-summary"></a>

Ce modèle décrit les options de migration de la fonctionnalité de `ROWID` pseudocolonne d'Oracle Database vers une base de données PostgreSQL dans Amazon Relational Database Service (Amazon RDS) pour PostgreSQL, Amazon Aurora PostgreSQL Compatible Edition ou Amazon Elastic Compute Cloud (Amazon). EC2

Dans une base de données Oracle, la `ROWID` pseudocolonne est l'adresse physique d'une ligne d'une table. Cette pseudocolonne est utilisée pour identifier une ligne de manière unique même si la clé primaire n'est pas présente sur une table. PostgreSQL possède une pseudocolonne similaire `ctid` appelée, mais elle ne peut pas être utilisée en tant que. `ROWID` Comme expliqué dans la documentation de [PostgreSQL](https://www.postgresql.org/docs/current/ddl-system-columns.html)`ctid`, cela peut changer en cas de mise à jour ou après chaque processus. `VACUUM`

Vous pouvez créer la fonctionnalité de `ROWID` pseudocolonne de trois manières dans PostgreSQL :
+ Utilisez une colonne de clé primaire plutôt `ROWID` que pour identifier une ligne dans un tableau.
+ Utilisez une primary/unique clé logique (qui peut être une clé composite) dans la table. 
+ Ajoutez une colonne avec des valeurs générées automatiquement et faites-en une primary/unique clé à imiter`ROWID`.

Ce modèle vous guide à travers les trois implémentations et décrit les avantages et les inconvénients de chaque option.

## Conditions préalables et limitations
<a name="migrate-oracle-rowid-functionality-to-postgresql-on-aws-prereqs"></a>

**Conditions préalables**
+ Un compte AWS actif
+ Expertise en Language/PostgreSQL codage procédural (PL/pgSQL)
+ Base de données Oracle source
+ Un cluster compatible avec Amazon RDS for PostgreSQL ou Aurora PostgreSQL, ou une instance pour héberger la base de données PostgreSQL EC2 

**Limites**
+ Ce modèle fournit des solutions de contournement pour cette fonctionnalité. `ROWID` PostgreSQL ne fournit pas d'équivalent `ROWID` à Oracle Database.

**Versions du produit**
+ PostgreSQL 11.9 ou version ultérieure

## Architecture
<a name="migrate-oracle-rowid-functionality-to-postgresql-on-aws-architecture"></a>

**Pile technologique source**
+ Oracle Database

**Pile technologique cible**
+ Compatible avec Aurora PostgreSQL, Amazon RDS for PostgreSQL ou instance avec une base de données PostgreSQL EC2 

![Conversion d'une base de données Oracle en PostgreSQL sur AWS](http://docs.aws.amazon.com/fr_fr/prescriptive-guidance/latest/patterns/images/pattern-img/9a2ce994-4f68-4975-aab2-796cc20a3c82/images/6e7c2ef6-f440-476a-9003-f1f166718e15.png)


**Options de mise en œuvre**

Il existe trois options pour contourner le manque de `ROWID` support dans PostgreSQL, selon que votre table possède une clé primaire ou un index unique, une clé primaire logique ou un attribut d'identité. Votre choix dépend du calendrier de votre projet, de votre phase de migration en cours et des dépendances vis-à-vis du code de l'application et de la base de données.


| 
| 
| Option | Description | Avantages | Inconvénients | 
| --- |--- |--- |--- |
| **Clé primaire ou index unique** | Si votre table Oracle possède une clé primaire, vous pouvez utiliser les attributs de cette clé pour identifier une ligne de manière unique.  | Aucune dépendance à l'égard des fonctionnalités de base de données propriétaires.Impact minimal sur les performances, car les champs de clé primaire sont indexés. | Nécessite des modifications du code de l'application et de la base de données qui repose sur le passage `ROWID` aux champs de clé primaire.  | 
| ** primary/unique Clé logique** | Si votre table Oracle possède une clé primaire logique, vous pouvez utiliser les attributs de cette clé pour identifier une ligne de manière unique. Une clé primaire logique est constituée d'un attribut ou d'un ensemble d'attributs qui peuvent identifier une ligne de manière unique, mais qui n'est pas imposée à la base de données par le biais d'une contrainte. | Aucune dépendance à l'égard des fonctionnalités de base de données propriétaires. | Nécessite des modifications du code de l'application et de la base de données qui repose sur le passage `ROWID` aux champs de clé primaire.Impact significatif sur les performances si les attributs de la clé primaire logique ne sont pas indexés. Toutefois, vous pouvez ajouter un index unique pour éviter les problèmes de performances. | 
| **Attribut d'identité** | si votre table Oracle ne possède pas de clé primaire, vous pouvez créer un champ supplémentaire en tant que`GENERATED ALWAYS AS IDENTITY`. Cet attribut génère une valeur unique chaque fois que des données sont insérées dans la table. Il peut donc être utilisé pour identifier de manière unique une ligne pour les opérations DML (Data Manipulation Language). | Aucune dépendance à l'égard des fonctionnalités de base de données propriétaires.La base de données PostgreSQL renseigne l'attribut et conserve son caractère unique. | Nécessite des modifications du code de l'application et de la base de données sur `ROWID` lequel repose le passage à l'attribut d'identité.Impact significatif sur les performances si le champ supplémentaire n'est pas indexé. Vous pouvez toutefois ajouter un index pour éviter les problèmes de performances. | 

## Outils
<a name="migrate-oracle-rowid-functionality-to-postgresql-on-aws-tools"></a>
+ [Amazon Relational Database Service (Amazon RDS) pour PostgreSQL](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_PostgreSQL.html) vous aide à configurer, exploiter et dimensionner une base de données relationnelle PostgreSQL dans le cloud AWS.
+ [Amazon Aurora PostgreSQL Compatible Edition](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/Aurora.AuroraPostgreSQL.html) est un moteur de base de données relationnelle entièrement géré et compatible ACID qui vous aide à configurer, exploiter et dimensionner les déploiements PostgreSQL.
+ [L'interface de ligne de commande AWS (AWS CLI)](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) est un outil open source qui vous permet d'interagir avec les services AWS par le biais de commandes dans votre shell de ligne de commande. Dans ce modèle, vous pouvez utiliser l'interface de ligne de commande AWS pour exécuter des commandes SQL via **pgAdmin.**
+ [pgAdmin](https://www.pgadmin.org/) est un outil de gestion open source pour PostgreSQL. Il fournit une interface graphique qui vous permet de créer, de gérer et d'utiliser des objets de base de données.
+ [AWS Schema Conversion Tool (AWS SCT)](https://docs.aws.amazon.com/SchemaConversionTool/latest/userguide/CHAP_Welcome.html) prend en charge les migrations de bases de données hétérogènes en convertissant automatiquement le schéma de base de données source et la majorité du code personnalisé dans un format compatible avec la base de données cible.

## Épopées
<a name="migrate-oracle-rowid-functionality-to-postgresql-on-aws-epics"></a>

### Identifier les tables sources
<a name="identify-the-source-tables"></a>


| Sous-tâche | Description | Compétences requises | 
| --- | --- | --- | 
| Identifiez les tables Oracle qui utilisent `ROWID` cet attribut. | Utilisez l'outil AWS Schema Conversion Tool (AWS SCT) pour identifier les tables Oracle dotées de `ROWID` fonctionnalités. Pour plus d'informations, consultez la [documentation AWS SCT.](https://docs.aws.amazon.com/SchemaConversionTool/latest/userguide/CHAP_Source.Oracle.ToPostgreSQL.html#CHAP_Source.Oracle.ToPostgreSQL.ConvertRowID)<br />—ou—<br />Dans Oracle, utilisez la `DBA_TAB_COLUMNS` vue pour identifier les tables dotées d'un `ROWID` attribut. Ces champs peuvent être utilisés pour stocker des caractères alphanumériques de 10 octets. Déterminez l'utilisation et convertissez-les en `VARCHAR` champ, le cas échéant. | DBA ou développeur | 
| Identifiez le code qui fait référence à ces tables. | Utilisez AWS SCT pour générer un rapport d'évaluation de la migration afin d'identifier les procédures concernées par`ROWID`. Pour plus d'informations, consultez la [documentation AWS SCT.](https://docs.aws.amazon.com/SchemaConversionTool/latest/userguide/CHAP_AssessmentReport.html)<br />—ou—<br />Dans la base de données Oracle source, utilisez le champ de texte du `dba_source` tableau pour identifier les objets qui utilisent des `ROWID` fonctionnalités. | DBA ou développeur | 

### Déterminer l'utilisation des clés primaires
<a name="determine-primary-key-usage"></a>


| Sous-tâche | Description | Compétences requises | 
| --- | --- | --- | 
| Identifiez les tables dépourvues de clés primaires. | Dans la base de données Oracle source, utilisez `DBA_CONSTRAINTS` pour identifier les tables dépourvues de clés primaires. Ces informations vous aideront à déterminer la stratégie pour chaque table. Par exemple :<pre>select dt.*<br />from dba_tables dt<br />where not exists (select 1<br />                  from all_constraints ct<br />                  where ct.owner = Dt.owner<br />                    and ct.table_name = Dt.table_name<br />                    and ct.constraint_type = 'P'<br />                  )<br />and dt.owner = '{schema}'</pre> | DBA ou développeur | 

### Identifier et appliquer la solution
<a name="identify-and-apply-the-solution"></a>


| Sous-tâche | Description | Compétences requises | 
| --- | --- | --- | 
| Appliquez les modifications aux tables dotées d'une clé primaire définie ou logique.  | Apportez les modifications au code de l'application et de la base de données indiquées dans la section [Informations supplémentaires](#migrate-oracle-rowid-functionality-to-postgresql-on-aws-additional) pour utiliser une clé primaire unique ou une clé primaire logique afin d'identifier une ligne de votre table. | DBA ou développeur | 
| Ajoutez un champ supplémentaire aux tables qui ne possèdent pas de clé primaire définie ou logique. | Ajoutez un attribut de type`GENERATED ALWAYS AS IDENTITY`. Apportez les modifications au code de l'application et de la base de données indiquées dans la section [Informations supplémentaires](#migrate-oracle-rowid-functionality-to-postgresql-on-aws-additional). | DBA ou développeur | 
| Ajoutez un index si nécessaire. | Ajoutez un index au champ supplémentaire ou à la clé primaire logique pour améliorer les performances SQL. | DBA ou développeur | 

## Ressources connexes
<a name="migrate-oracle-rowid-functionality-to-postgresql-on-aws-resources"></a>
+ [CTID de PostgreSQL (documentation de PostgreSQL](https://www.postgresql.org/docs/current/ddl-system-columns.html))
+ [Colonnes générées](https://www.postgresql.org/docs/current/ddl-generated-columns.html) (documentation PostgreSQL)
+ [Pseudocolonne ROWID (documentation Oracle](https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/ROWID-Pseudocolumn.html#GUID-F6E0FBD2-983C-495D-9856-5E113A17FAF1))

## Informations supplémentaires
<a name="migrate-oracle-rowid-functionality-to-postgresql-on-aws-additional"></a>

Les sections suivantes fournissent des exemples de code Oracle et PostgreSQL pour illustrer les trois approches.

**Scénario 1 : utilisation d'une clé primaire unique**

Dans les exemples suivants, vous créez la table `testrowid_s1` avec `emp_id` comme clé primaire.

*Code Oracle :*

```
create table testrowid_s1 (emp_id integer, name varchar2(10), CONSTRAINT testrowid_pk PRIMARY KEY (emp_id));
INSERT INTO testrowid_s1(emp_id,name) values (1,'empname1');
INSERT INTO testrowid_s1(emp_id,name) values (2,'empname2');
INSERT INTO testrowid_s1(emp_id,name) values (3,'empname3');
INSERT INTO testrowid_s1(emp_id,name) values (4,'empname4');
commit;

SELECT rowid,emp_id,name FROM testrowid_s1;
ROWID                  EMP_ID NAME
------------------ ---------- ----------
AAAF3pAAAAAAAMOAAA          1 empname1
AAAF3pAAAAAAAMOAAB          2 empname2
AAAF3pAAAAAAAMOAAC          3 empname3
AAAF3pAAAAAAAMOAAD          4 empname4

UPDATE testrowid_s1 SET name = 'Ramesh' WHERE rowid = 'AAAF3pAAAAAAAMOAAB' ;
commit;

SELECT rowid,emp_id,name FROM testrowid_s1;
ROWID                  EMP_ID NAME
------------------ ---------- ----------
AAAF3pAAAAAAAMOAAA          1 empname1
AAAF3pAAAAAAAMOAAB          2 Ramesh
AAAF3pAAAAAAAMOAAC          3 empname3
AAAF3pAAAAAAAMOAAD          4 empname4
```

*Code PostgreSQL :*

```
CREATE TABLE public.testrowid_s1
(
    emp_id integer,
    name character varying,
    primary key (emp_id)
);

insert into public.testrowid_s1 (emp_id,name) values 
(1,'empname1'),(2,'empname2'),(3,'empname3'),(4,'empname4');

select emp_id,name from testrowid_s1;
 emp_id |   name   
--------+----------
      1 | empname1
      2 | empname2
      3 | empname3
      4 | empname4

update testrowid_s1 set name = 'Ramesh' where emp_id = 2 ;

select emp_id,name from testrowid_s1;
 emp_id |   name   
--------+----------
      1 | empname1
      3 | empname3
      4 | empname4
      2 | Ramesh
```

**Scénario 2 : utilisation d'une clé primaire logique**

Dans les exemples suivants, vous créez la table `testrowid_s2` avec `emp_id` comme clé primaire logique.

*Code Oracle :*

```
create table testrowid_s2 (emp_id integer, name varchar2(10) );
INSERT INTO testrowid_s2(emp_id,name) values (1,'empname1');
INSERT INTO testrowid_s2(emp_id,name) values (2,'empname2');
INSERT INTO testrowid_s2(emp_id,name) values (3,'empname3');
INSERT INTO testrowid_s2(emp_id,name) values (4,'empname4');
commit;

SELECT rowid,emp_id,name FROM testrowid_s2;
ROWID                  EMP_ID NAME
------------------ ---------- ----------
AAAF3rAAAAAAAMeAAA          1 empname1
AAAF3rAAAAAAAMeAAB          2 empname2
AAAF3rAAAAAAAMeAAC          3 empname3
AAAF3rAAAAAAAMeAAD          4 empname4

UPDATE testrowid_s2 SET name = 'Ramesh' WHERE rowid = 'AAAF3rAAAAAAAMeAAB' ;
commit;

SELECT rowid,emp_id,name FROM testrowid_s2;
ROWID                  EMP_ID NAME
------------------ ---------- ----------
AAAF3rAAAAAAAMeAAA          1 empname1
AAAF3rAAAAAAAMeAAB          2 Ramesh
AAAF3rAAAAAAAMeAAC          3 empname3
AAAF3rAAAAAAAMeAAD          4 empname4
```

*Code PostgreSQL :*

```
CREATE TABLE public.testrowid_s2
(
    emp_id integer,
    name character varying
);

insert into public.testrowid_s2 (emp_id,name) values 
(1,'empname1'),(2,'empname2'),(3,'empname3'),(4,'empname4');

select emp_id,name from testrowid_s2;
 emp_id |   name   
--------+----------
      1 | empname1
      2 | empname2
      3 | empname3
      4 | empname4

update testrowid_s2 set name = 'Ramesh' where emp_id = 2 ;

select emp_id,name from testrowid_s2;
 emp_id |   name   
--------+----------
      1 | empname1
      3 | empname3
      4 | empname4
      2 | Ramesh
```

**Scénario 3 : utilisation d'un attribut d'identité**

Dans les exemples suivants, vous créez la table `testrowid_s3` sans clé primaire et en utilisant un attribut d'identité.

*Code Oracle :*

```
create table testrowid_s3 (name varchar2(10));
INSERT INTO testrowid_s3(name) values ('empname1');
INSERT INTO testrowid_s3(name) values ('empname2');
INSERT INTO testrowid_s3(name) values ('empname3');
INSERT INTO testrowid_s3(name) values ('empname4');
commit;

SELECT rowid,name FROM testrowid_s3;
ROWID              NAME
------------------ ----------
AAAF3sAAAAAAAMmAAA empname1
AAAF3sAAAAAAAMmAAB empname2
AAAF3sAAAAAAAMmAAC empname3
AAAF3sAAAAAAAMmAAD empname4

UPDATE testrowid_s3 SET name = 'Ramesh' WHERE rowid = 'AAAF3sAAAAAAAMmAAB' ;
commit;

SELECT rowid,name FROM testrowid_s3;
ROWID              NAME
------------------ ----------
AAAF3sAAAAAAAMmAAA empname1
AAAF3sAAAAAAAMmAAB Ramesh
AAAF3sAAAAAAAMmAAC empname3
AAAF3sAAAAAAAMmAAD empname4
```

*Code PostgreSQL :*

```
CREATE TABLE public.testrowid_s3
(
    rowid_seq bigint generated always as identity,
    name character varying
);

insert into public.testrowid_s3 (name) values 
('empname1'),('empname2'),('empname3'),('empname4');

select rowid_seq,name from testrowid_s3;
 rowid_seq |   name   
-----------+----------
         1 | empname1
         2 | empname2
         3 | empname3
         4 | empname4

update testrowid_s3 set name = 'Ramesh' where rowid_seq = 2 ;

select rowid_seq,name from testrowid_s3;
 rowid_seq |   name   
-----------+----------
         1 | empname1
         3 | empname3
         4 | empname4
         2 | Ramesh
```