Fonctionnalités Objet-Relationnel d’Oracle, par Tom Kyte

Cet article est la traduction d’une réponse Tom Kyte à des questions sur les fonctionnalités Objet-Relationnel d’Oracle
(L’article original en anglais se trouve sur AskTom ici).

Tom Kyte donne son avis sur l’utilisation de ces fonctionnalités (Tables Relationnelles, vues Objet-Relationnel, Tables Objet-Relationnel)

Question:

Bonjour Tom,

J’ai quelques questions sur les fonctionnalités Objet-Relationnel d’Oracle.

J’ai la structure suivante:

CREATE TYPE adresse_typ AS OBJECT (ligne1 VARCHAR2(20), ville VARCHAR2(20), pays VARCHAR2(20));
 
CREATE TYPE telephone_typ AS OBJECT (prefixe VARCHAR2(10), num_tel VARCHAR2(10));
 
CREATE TYPE telephone_liste_typ AS TABLE OF telephone_typ;
 
CREATE TYPE personne_typ AS OBJECT  (nom VARCHAR2(20), prenom VARCHAR2(20), adresse adresse_typ, telephones telephone_liste_typ) NOT FINAL;
 
CREATE TYPE personne_commercial_typ UNDER personne_typ (personne_commercial_id NUMBER, salaire NUMBER, nombre_de_ventes NUMBER);
 
CREATE TYPE personne_client_typ UNDER personne_typ (personne_client_id NUMBER, total_achat NUMBER);
 
CREATE TABLE personne_obj OF personne_typ NESTED TABLE telephones STORE AS telephones_tab;

Mes questions sont les suivantes:
[…]

Réponse:

Je vous déconseille fortement de faire cela. Utilisez des tables relationnelles et créez des vues OR (Object-Relational) au dessus si vous le désirez, mais n’utilisez pas de tables imbriquées (nested tables), ni de tables de type objet. Il y a une surcharge énorme (overhead) pour pouvoir fournir cette syntaxe alléchante.

Une table imbriquée (nested table), par exemple, ajoute 16 octets supplémentaires à la fois sur la table parent et la table fille, avec une contrainte unique sur le parent pour cette colonne de type RAW, et vous force donc à créer un index sur la colonne RAW de la table fille (voir commentaire de Mohamed Houri ci-dessous). Et pourtant vous n’avez besoin de rien de tout ça.

Donc, faites un modèle relationnel approprié, et utilisez-le.

Je suis sûr 100% que vous voudrez un jour interroger la table des adresses, pour des requêtes du genre ‘trouver tous ceux qui vivent dans le pays XXX’. Si vous utilisez une nested table, vous n’avez plus de vraie table. Les modèles objet ont une portée excessivement réduite. Ils présentent un unique point de vue sur les données, et il y a toujours de nombreuses vues possibles sur les données.

Et pour faire une recherche genre ‘annuaire inversé’ à partir d’un numéro de téléphone ? Pas si facile avec un modèle Object-Relationnel, et pourtant banal avec un modèle relationnel approprié.

C’est donc un grande non-réponse à vos questions, mais il faut voir le côté positif: d’après moi, vous étiez en train de faire une grosse erreur.

Autre question:

J’ai l’impression que que le modèles Orienté Objet et le modèle Relationnel ne se mélangent pas très bien

Réponse:

Non, pas du tout. Au contraire.

Mais ce qui est très important, c’est que vous devez commencer par bâtir une bonne base relationnelle, et construire les vues orienté objet par dessus.

Je dis que les vues orientées objets sont de faibles portées (‘myopic’). Pourquoi ? Parce qu’elles ne sont focalisées que sur l’application et non pas sur les données.

La suite est sur une autre page de AskTom (ici) sur la comparaison entre le Relationnel et l’Orienté Objet.

Tout d’abord, sous Oracle, vous devez comparer le Relationnel avec l’Objet-Relationnel, et non pas avec l’Orienté Objet. Il y a des extensions objet au relationnel, mais ce n’est pas une base orientée objet.

Pour répondre à cette question, il faut regarder les données avec lesquelles vous travaillez. Disons que vous êtes en train de construire une application bancaire. Vous faites cette application pour le caissier qui s’occupe du client quand il rentre dans la banque. L’objet parfait pour cette application est ‘Client’, identifié par un nom ou un numéro de compte. Le client a tous les attributs d’un client de banque: un nom, une adresse, une liste de comptes avec tous les attributs des comptes, une liste des dernières opérations bancaires, etc. Un gros paquet de données qui représentent toutes les informations d’un client.
C’est parfait du point de vue du caissier. MAIS, à la fin de la journée, il y a quelqu’un qui a une vision complètement différente des données, et qui a besoin de compter le nombre d’opérations bancaires qu’il y a eu dans la journée, ou combien d’argent il y a dans la banque. Sa perspective sur les données est orientée sur les opérations et non sur les clients.
Dans ce cas, le modèle parfait est un modèle RELATIONNEL, avec éventuellement des vues spécifiques objet-relationnel. Vous avez besoin d’une table des comptes, qui est liée à une table des opérations et à une table des clients. Avec ça, celui qui veut compter les opérations est aussi satisfait que celui qui a une vue orienté client.

C’est cela la puissance du modèle relationnel: il est capable de donner des vues différentes sur les mêmes données. Pensez aux tables EMP et DEPT de scott/tiger. Il peut paraître censé de créer un type objet EMP, une nested table de type EMP, un objet DEPT avec un attribut nested table de EMP et enfin une table des types DEPT. Et maintenant, toutes les données de démo scott/tiger tiennent dans une table de 4 lignes.
Cela parait formidable. Mais le problème est que des gens vont poser les questions suivantes:

  • Combien ai-je d’employés ?
  • KING est là devant la porte, est-ce un employé ou pas ?
  • Quelle est somme des salaires des comptables sur l’année dernière ?

etc.

Avec une vision des données orientée sur DEPT, on ne peut répondre facilement à aucune de ces questions.

Juste de quoi y réfléchir. Je n’ai jamais utilisé les concepts objet-relationnel comme un mécanisme de STOCKAGE. Je les ai beaucoup utilisé dans mes programmes PL/SQL. Je tend à rester sur des vraies tables et à utiliser des objets fréquemment dans le code.

2 réflexions au sujet de « Fonctionnalités Objet-Relationnel d’Oracle, par Tom Kyte »

  1. Bonjour Franck,

    Il y a un petit problème dans cette traduction. Particulièrement dans la traduction de ce paragraphe

    « A nested table for example makes it so you have an extra 16 byte raw added to both parent and child, along with a unique constraint on parent on this raw column – and makes you index the raw in the child. You just do not need any of those. »

    qui a été traduit par ceci

    « Une table imbriquée (nested table), par exemple, ajoute 16 octets supplémentaires à la fois sur la table parent et la table fille, avec une contrainte unique sur le parent pour cette colonne de type RAW, ET UN INDEX sur la colonne RAW de la table fille. Et pourtant vous n’avez besoin de rien de tout ça ».

    En réalité, les nested tables ajoutent certes une colonne supplémentaire NESTED_TABLE_ID, non visible avec un desc ordinaire, qui sert de Foreign Key entre la table relationnelle et la nested table utilisée pour décrire une colonne de cette table relationnelle, mais le grand problème ici, c’est qu’Oracle justement NE CREE pas d’index pour couvrir cette FK entrainant par la même des problèmes de deadlocks.

    J’en parle en connaissance de cause vu que j’ai corrigé ce problème chez un client et que j’en ai parlé avec Tom Kyte de vive voix quand je l’ai rencontré à Paris en décembre 2008.

    La traduction doit être corrigée comme suit

    « Une table imbriquée (nested table), par exemple, ajoute 16 octets supplémentaires à la fois sur la table parent et la table fille, avec une contrainte unique sur le parent pour cette colonne de type RAW, ET VOUS FORCE DONC A CREER un index sur la colonne RAW de la table fille. Et pourtant vous n’avez besoin de rien de tout ça ».

Laisser un commentaire