View a markdown version of this page

Émulez des baies PL/SQL associatives Oracle dans Amazon Aurora PostgreSQL et Amazon RDS for PostgreSQL - Recommandations AWS

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.

Émulez des baies PL/SQL associatives Oracle dans Amazon Aurora PostgreSQL et Amazon RDS for PostgreSQL

Rajkumar Raghuwanshi, Bhanu Ganesh Gudivada et Sachin Khanna, Amazon Web Services

Résumé

Ce modèle décrit comment émuler des tableaux PL/SQL associatifs Oracle avec des positions d'index vides dans les environnements Amazon Aurora PostgreSQL et Amazon RDS for PostgreSQL. Il décrit également certaines des différences entre les tableaux PL/SQL associatifs Oracle et les tableaux PostgreSQL en ce qui concerne la façon dont chacun gère les positions d'index vides lors des migrations.

Nous proposons une alternative PostgreSQL à l'aws_oracle_extutilisation de fonctions pour gérer les positions d'index vides lors de la migration d'une base de données Oracle. Ce modèle utilise une colonne supplémentaire pour stocker les positions des index et il permet à Oracle de gérer les tableaux épars tout en incorporant les fonctionnalités natives de PostgreSQL.

Oracle

Dans Oracle, les collections peuvent être initialisées comme vides et remplies à l'aide de la méthode de EXTEND collecte, qui ajoute NULL des éléments au tableau. Lorsque vous travaillez avec des tableaux PL/SQL associatifs indexés parPLS_INTEGER, la EXTEND méthode ajoute des éléments de manière séquentielle, mais NULL les éléments peuvent également être initialisés à des positions d'index non séquentielles. Toute position d'index qui n'est pas explicitement initialisée reste vide.

Cette flexibilité permet des structures matricielles clairsemées dans lesquelles les éléments peuvent être remplis à des positions arbitraires. Lors de l'itération dans des collections à l'aide d'un FOR LOOP with FIRST LAST et d'une limite, seuls les éléments initialisés (qu'ils aient NULL ou non une valeur définie) sont traités, tandis que les positions vides sont ignorées.

PostgreSQL (Amazon Aurora et Amazon RDS)

PostgreSQL gère les valeurs vides différemment des valeurs. NULL Il stocke les valeurs vides sous forme d'entités distinctes qui utilisent un octet de stockage. Lorsqu'un tableau contient des valeurs vides, PostgreSQL attribue des positions d'index séquentielles comme des valeurs non vides. Mais l'indexation séquentielle nécessite un traitement supplémentaire car le système doit itérer sur toutes les positions indexées, y compris les positions vides. Cela rend la création de tableaux traditionnelle inefficace pour les ensembles de données épars.

AWS Schema Conversion Tool

Le AWS Schema Conversion Tool (AWS SCT) gère généralement les Oracle-to-PostgreSQL migrations à l'aide de aws_oracle_ext fonctions. Dans ce modèle, nous proposons une approche alternative qui utilise les fonctionnalités natives de PostgreSQL, qui combine les types de tableaux PostgreSQL avec une colonne supplémentaire pour stocker les positions d'index. Le système peut ensuite itérer dans les tableaux en utilisant uniquement la colonne d'index.

Conditions préalables et limitations

Conditions préalables

  • Un actif Compte AWS

  • Autorisations d'administrateur dans Gestion des identités et des accès AWS (IAM)

  • Une instance compatible avec Amazon RDS ou Aurora PostgreSQL

  • Compétences d'architecte ou de développeur de bases de données avec Oracle et PostgreSQL

Limites

Versions du produit

Ce modèle a été testé avec les versions suivantes :

  • Amazon Aurora PostgreSQL 13.3

  • Amazon RDS pour PostgreSQL 13.3

  • AWS SCT 1,0674

  • Oracle 19c EE

Architecture

Pile technologique source

  • On-premises Base de données Oracle

Pile technologique cible

  • Amazon Aurora PostgreSQL

  • Amazon RDS pour PostgreSQL

Architecture cible

Le diagramme décrit les éléments suivants :

  • Une instance de base de données Amazon RDS for Oracle source

  • Une instance Amazon EC2 permettant de convertir AWS SCT les fonctions Oracle en un équivalent PostgreSQL

  • Une base de données cible compatible avec Amazon Aurora PostgreSQL

Outils

Services AWS

Autres outils

  • Oracle SQL Developer est un environnement de développement intégré qui simplifie le développement et la gestion des bases de données Oracle dans les déploiements traditionnels et basés sur le cloud.

  • pgAdmin 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. Dans ce modèle, pgAdmin se connecte à l'instance de base de données RDS pour PostgreSQL et interroge les données. Vous pouvez également utiliser le client de ligne de commande psql.

Bonnes pratiques

  • Testez les limites des ensembles de données et les scénarios périphériques.

  • Envisagez d'implémenter la gestion des erreurs pour les conditions d'index hors limites.

  • Optimisez les requêtes pour éviter de scanner des ensembles de données fragmentés.

Épopées

Sous-tâcheDescriptionCompétences requises

Créez un PL/SQL bloc source dans Oracle.

Créez un PL/SQL bloc source dans Oracle qui utilise le tableau associatif suivant :

DECLARE TYPE country_codes IS TABLE OF VARCHAR2(100) INDEX BY pls_integer; cc country_codes; cc_idx NUMBER := NULL; BEGIN cc(7) := 'India'; cc(3) := 'UK'; cc(5) := 'USA'; cc(0) := 'China'; cc(-2) := 'Invalid'; dbms_output.put_line('cc_length:' || cc.COUNT); IF (cc.COUNT > 0) THEN cc_idx := cc.FIRST; FOR i IN 1..cc.COUNT LOOP dbms_output.put_line('cc_idx:' || cc_idx || ' country:' || cc(cc_idx)); cc_idx := cc.next(cc_idx); END LOOP; END IF; END;
DBA

Exécutez le PL/SQL bloc.

Exécutez le PL/SQL bloc source dans Oracle. S'il existe des écarts entre les valeurs d'index d'un tableau associatif, aucune donnée n'est stockée dans ces espaces. Cela permet à la boucle Oracle d'itérer uniquement sur les positions de l'index.

DBA

Vérifiez la sortie.

Cinq éléments ont été insérés dans le tableau (cc) à des intervalles non consécutifs. Le nombre de tableaux est indiqué dans le résultat suivant :

cc_length:5 cc_idx:-2 country:Invalid cc_idx:0 country:China cc_idx:3 country:UK cc_idx:5 country:USA cc_idx:7 country:India
DBA
Sous-tâcheDescriptionCompétences requises

Créez un PL/pgSQL bloc cible dans PostgreSQL.

Créez un PL/pgSQL bloc cible dans PostgreSQL qui utilise le tableau associatif suivant :

DO $$ DECLARE cc character varying(100)[]; cc_idx integer := NULL; BEGIN cc[7] := 'India'; cc[3] := 'UK'; cc[5] := 'USA'; cc[0] := 'China'; cc[-2] := 'Invalid'; RAISE NOTICE 'cc_length: %', ARRAY_LENGTH(cc, 1); IF (ARRAY_LENGTH(cc, 1) > 0) THEN FOR i IN ARRAY_LOWER(cc, 1)..ARRAY_UPPER(cc, 1) LOOP RAISE NOTICE 'cc_idx:% country:%', i, cc[i]; END LOOP; END IF; END; $$;
DBA

Exécutez le PL/pgSQL bloc.

Exécutez le PL/pgSQL bloc cible dans PostgreSQL. S'il existe des écarts entre les valeurs d'index d'un tableau associatif, aucune donnée n'est stockée dans ces espaces. Cela permet à la boucle PostgreSQL d'itérer uniquement sur les positions d'index.

DBA

Vérifiez la sortie.

La longueur du tableau est supérieure à 5 car elle NULL est stockée dans les espaces entre les positions d'index. Comme indiqué dans le résultat suivant, la boucle effectue 10 itérations pour récupérer 5 valeurs dans le tableau.

cc_length:10 cc_idx:-2 country:Invalid cc_idx:-1 country:<NULL> cc_idx:0 country:China cc_idx:1 country:<NULL> cc_idx:2 country:<NULL> cc_idx:3 country:UK cc_idx:4 country:<NULL> cc_idx:5 country:USA cc_idx:6 country:<NULL> cc_idx:7 country:India
DBA
Sous-tâcheDescriptionCompétences requises

Créez un PL/pgSQL bloc cible avec un tableau et un type défini par l'utilisateur.

Pour optimiser les performances et correspondre aux fonctionnalités d'Oracle, nous pouvons créer un type défini par l'utilisateur qui stocke à la fois les positions de l'indice et les données correspondantes. Cette approche réduit les itérations inutiles en maintenant des associations directes entre les indices et les valeurs.

DO $$ DECLARE cc country_codes[]; cc_append country_codes := NULL; i record; BEGIN cc_append.idx = 7; cc_append.val = 'India'; cc := array_append(cc, cc_append); cc_append.idx = 3; cc_append.val = 'UK'; cc := array_append(cc, cc_append); cc_append.idx = 5; cc_append.val = 'USA'; cc := array_append(cc, cc_append); cc_append.idx = 0; cc_append.val = 'China'; cc := array_append(cc, cc_append); cc_append.idx = - 2; cc_append.val = 'Invalid'; cc := array_append(cc, cc_append); RAISE NOTICE 'cc_length: %', ARRAY_LENGTH(cc, 1); IF (ARRAY_LENGTH(cc, 1) > 0) THEN FOR i IN ( SELECT * FROM unnest(cc) ORDER BY idx) LOOP RAISE NOTICE 'cc_idx:% country:%', i.idx, i.val; END LOOP; END IF; END; $$;
DBA

Exécutez le PL/pgSQL bloc.

Exécutez le PL/pgSQL bloc cible. S'il existe des écarts entre les valeurs d'index d'un tableau associatif, aucune donnée n'est stockée dans ces espaces. Cela permet à la boucle PostgreSQL d'itérer uniquement sur les positions d'index.

DBA

Vérifiez la sortie.

Comme indiqué dans le résultat suivant, le type défini par l'utilisateur ne stocke que les éléments de données renseignés, ce qui signifie que la longueur du tableau correspond au nombre de valeurs. Par conséquent, LOOP les itérations sont optimisées pour traiter uniquement les données existantes, éliminant ainsi le besoin de suivre les positions vides.

cc_length:5 cc_idx:-2 country:Invalid cc_idx:0 country:China cc_idx:3 country:UK cc_idx:5 country:USA cc_idx:7 country:India
DBA

Résolution des problèmes

ProblèmeSolution

Erreur d'indexation hors limites

  • Problème : ERROR: array subscript out of bounds lors de l'accès aux éléments du tableau

  • Cause : tentative d'accès à une position d'index qui n'existe pas dans le tableau de types défini par l'utilisateur

Vous pouvez valider l'existence de l'index avant d'y accéder en utilisant un filtre de WHERE clauses sur la idx colonne lorsque vous dénichez le tableau, ou vous pouvez implémenter des contrôles de limites dans votre PL/pgSQL code.

Gestion des valeurs NULL

  • Problème : des valeurs NULL inattendues apparaissent dans les résultats de la requête lors de l'itération dans le tableau

  • Cause : les éléments du tableau ne sont pas correctement initialisés avec les deux val champs idx et avant d'être ajoutés

Assurez-vous que les deux champs du type défini par l'utilisateur sont renseignés avant de les utiliserarray_append(). Ajoutez des contrôles NULL explicites comme suit : IF cc_append.val IS NOT NULL THEN cc := array_append(cc, cc_append); END IF;

Ressources connexes

AWS documentation

Autres documentations

Informations supplémentaires

Considérations sur les performances

  • Cette approche réduit le temps d'itération de 50 % ou plus pour les tableaux épars par rapport aux tableaux PostgreSQL natifs avec des espaces réservés NULL.

  • L'efficacité du stockage s'améliore car seules les données réelles sont stockées, et non les positions d'index vides.

Remarques de compatibilité

  • Ce modèle conserve la sémantique des tableaux clairsemés d'Oracle tout en utilisant les capacités de tableau natives de PostgreSQL.

  • La solution est compatible avec toutes les versions de PostgreSQL qui prennent en charge les types composites définis par l'utilisateur.