IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SQL Oracle Discussion :

Objet-relationnel standard SQL3


Sujet :

SQL Oracle

  1. #21
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 952
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 952
    Par défaut
    Bonjour Fsmrel,

    Merci d'être venu enrichir le débat, cependant il me reste une dernière question.

    J'avais cru comprendre via Oishiiii dans le lien sus mentionné que même une colonne contenant une liste 'Paris, Lille , Marseille' était conforme à la 1NF, peut être ai je mal compris Oishiiii, peut être vous avait il mal compris.
    Citation Envoyé par Oishiiii Voir le message
    une valeur '13;90;78' pour une colonne listeClient ne viole pas la 1NF.
    Pour moi ça correspond à la relation R2 décrite par Date dans le lien de mnitu.

    Or vous mentionnez au sujet de la "relation" R2 :
    Citation Envoyé par fsmrel Voir le message
    Dans R2, on a plus d’une valeur à l’intersection d’une ligne et d’une colonne, ce qui traduit un viol de 1NF patent (et R2 n'est donc pas une relation)
    Dans votre conclusion vous mentionnez l'évolution de pensée de Date :
    Si par le passé Date a donné comme tout le monde une définition de la 1NF impliquant l'atomicité (cf. paragraphe 2.3) et donc l'illégalité des RVA, après avoir étudié la vraie nature des types (domaines), il a été amené à remplacer la contrainte de l'atomicité par celle, moins restrictive, de l'unicité de la valeur prise dans chaque tuple par chaque attribut.
    Qui se retrouve dans le lien de mnitu :
    The real point I’m getting at here is that the notion of atomicity has no absolute meaning; it just depends on what we want to do with the data.
    Donc finalement si je comprends mieux (j'espère) une liste 'Paris, Lille, Marseille' peut être conforme 1NF ou peut ne pas l'être, tout dépend de l'utilisation que l'on souhaite en faire (et du niveau d'atomicité qu'on lui accorde), est ce correcte ?
    Et donc dans la pratique la plus part des listes violent bien la 1NF.

    J'espère que vous pourrez m'éclairer sur ce dernier point.

  2. #22
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 814
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 814
    Billets dans le blog
    14
    Par défaut
    Citation Envoyé par skuatamad
    PS2 : cinephil, as tu déjà été confronté à l'ineptie du stockage d'un serialize php ?
    Argh, je déteste cette fonction, enfin surtout l'utilisation qu'en font les développeurs php !
    Non, et heureusement ; j'aurais hurlé !

    Ceci dit, j'utilise des CMS et j'ai remarqué des bizarreries du genre que j'ai préféré ne pas explorer davantage.

    Sur le fond du débat, je reste sur ma position : Pas de tableaux dans mes colonnes ! N'en déplaise à Date !
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  3. #23
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 952
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 952
    Par défaut
    Dans ce cas reste éloigné de cantao (anciennement typolight) !

    Apparemment le concepteur du CMS ne connaissait pas les tables associatives... la totalité des relations (1,n) sont serialisées dans une colonne (de type blob, probablement au cas où on ait 1000000 de blocs par page....)

    Sait on jamais 2012 sera peut être l'année du scroll

    Et si j'ai effectivement mieux compris la 1NF, finalement stocker un serialise n'est pas conforme à la 1NF car la chaîne généré ne peut être considérée comme atomique !

  4. #24
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    Citation Envoyé par fsmrel Voir le message
    ...
    Je suppose que vous faites allusion à la 1NF (première forme normale). Mettre en œuvre un modèle normalisé au sens Merise (règle de vérification) comme vous l’avez fait est préférable, mais du point de vue de la théorie relationnelle, on ne viole pas la 1NF quand on niche des tables dans des colonnes (cf. le paragraphe 2.6 traitant des RVA (relation-valued attributes).
    Merci de vos précision.
    Je me permet de retenir pour l'instant que nous sommes d'accord sur le fait que la solution proposée respecte 1NF et du ce point de vue soutenir le contraire est erroné. Personnellement, je considère que si on ne mélangeait pas tout: performance, implémentation physique par le SGBD, violation par divers SGBD de la pureté de la théorie, expériences négatives, etc. cette discussion pourrait être vraiment utile.


    Citation Envoyé par fsmrel Voir le message
    ...
    Tout baigne. Le seul problème est que la page (34 en l’occurrence) est à moitié cachée (décidemment...) Incidemment, il est bon de comparer les relations R2 et R3 de la page suivante (Figure 2-1). Dans R2, on a plus d’une valeur à l’intersection d’une ligne et d’une colonne, ce qui traduit un viol de 1NF patent (et R2 n'est donc pas une relation), tandis qu’avec R3 on a exactement une valeur à l’intersection : la 1NF est en l’occurrence respectée.
    Voilà le paragraphe qui vous manque et qui n'apporte pas, d'après moi, de grosses nouvelles:

    • Fixed point numbers, which might be regarded as being decomposable into integers and
    fractional parts
    • Date and times, which might be regarded as being decomposable into year/month/day
    and hour/minute/second components, respectively

    Now I'd like to move on to a potentialy more startling example. Refer to figure 2.1.
    Relation R1 in that figure is a reduced version of the shipments relation from our running
    example; it shows that certain suppliers supply certain parts, and it contains one tuple for
    each legimate SBO-PNO combinations. For the sake of the example, let's agree that
    suppliers numbers and part numbers are indeed "atomic"; then we can presumably agree
    that R1, at least is in 1NF.

    Maintenant, permettez mois de ne pas être d'accord avec vous quand vous dites:
    Citation Envoyé par fsmrel Voir le message
    ...
    En tout état de cause, ne serait-ce qu’au nom de la symétrie, il est clair que dans le contexte des bases de données en production, la modélisation pratiquée par CinePhil est à privilégier, et il faut fuir les Nested Tables d’Oracle puisque le principe fondamental de l’information est violé, sans parler des problèmes évoqués par Mohamed et Waldar.
    Voyez vous, on peut pas fuir quand Oracle s'écarte du cadre théorétique avec cette argument et embrasser les autres écarts que Oracle a fait avec le modèle théorétique et que nous trouvons plutôt bons.

    Donc fuir ou non c'est plutôt une question des traitements que vous allez appliquer aux données que des considérations de pureté ou expériences personnelles traumatisantes.


    @skuatamad
    R1 est 1NF
    R2 n'est pas 1NF
    R3 est 1NF

  5. #25
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 952
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 952
    Par défaut
    merci mnitu

  6. #26
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    Citation Envoyé par fsmrel Voir le message
    ...
    En tout état de cause, ne serait-ce qu’au nom de la symétrie, il est clair que dans le contexte des bases de données en production, la modélisation pratiquée par CinePhil est à privilégier, et il faut fuir les Nested Tables d’Oracle puisque le principe fondamental de l’information est violé, sans parler des problèmes évoqués par Mohamed et Waldar.
    Finalement je pense que vous est allé un peut vite en besogne.
    Je vous donc propose un test sur un exemple simplifié:
    les tables:
    A)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    create type acteur_nt as table of varchar2(100)
    /
    create table film_avec_acteur (
      id_film	integer primary key,
      titre	varchar2(100),
      sortie	date,
      list_acteur acteur_nt
    )
    nested table list_acteur store as list_act_nt
    /
    B)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
     
    create table acteur (
      id_acteur  int primary key,
      nom        varchar2(50)
    )
    /
     
    create table film (
      id_film	integer primary key,
      titre	varchar2(100),
      sortie	date
    )
    /
     
    create table film_acteur(
      id_film	references film,
      id_acteur	references acteur,
      constraint pk_film_acteur primary key(id_film, id_acteur)
    )
    /
    les données
    A)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    insert into film_avec_acteur values (100, 'Les templiers d''Oracle', date '2010-04-02', acteur_nt('mnitu','pomalaix'))
    /
    insert into film_avec_acteur values (200, 'Les templiers redivivus', date '2011-04-02', acteur_nt('pomalaix', 'mnitu'))
    /
    insert into film_avec_acteur values (300, 'Mais qui est mister Date', date '2011-04-02', acteur_nt('cinephil','mnitu', 'fsmrel'))
    /
    insert into film_avec_acteur values (400, 'Le mystère du mister Date', date '2011-04-02', acteur_nt('pomalaix','mnitu', 'fsmrel'))
    /
    insert into film_avec_acteur values (500, 'La première forme normale', date '2011-04-02', acteur_nt('cinephil', 'waldar', 'fsmrel'))
    /
    insert into film_avec_acteur values (600, 'Les objets mon amour', date '2011-04-02', acteur_nt('waldar', 'mohamed'))
    /
    B)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
     
    insert into film values (100, 'Les templiers d''Oracle', date '2010-04-02')
    /
    insert into film values (200, 'Les templiers redivivus', date '2011-04-02')
    /
    insert into film values (300, 'Mais qui est mister Date', date '2011-04-02')
    /
    insert into film values (400, 'Le mystère du mister Date', date '2011-04-02')
    /
    insert into film values (500, 'La première forme normale', date '2011-04-02')
    /
    insert into film values (600, 'Les objets mon amour', date '2011-04-02')
    /
     
    insert into acteur values (1, 'mnitu')
    /
    insert into acteur values (2, 'pomalaix')
    /
    insert into acteur values (3, 'cinephil')
    /
    insert into acteur values (4, 'fsmrel')
    /
    insert into acteur values (5, 'waldar')
    /
    insert into acteur values (6, 'mohamed')
    /
     
    insert into film_acteur values (100, 1)
    /
    insert into film_acteur values (100, 2)
    /
    insert into film_acteur values (200, 2)
    /
    insert into film_acteur values (200, 1)
    /
    insert into film_acteur values (300, 3)
    /
    insert into film_acteur values (300, 1)
    /
    insert into film_acteur values (300, 4)
    /
    insert into film_acteur values (400, 2)
    /
    insert into film_acteur values (400, 1)
    /
    insert into film_acteur values (400, 4)
    /
    insert into film_acteur values (500, 3)
    /
    insert into film_acteur values (500, 5)
    /
    insert into film_acteur values (500, 4)
    /
    insert into film_acteur values (600, 5)
    /
    insert into film_acteur values (600, 6)
    /
    Les requêtes à analyser issues des traitements fonctionnels sont les suivantes:
    a) trouver le titre du film ayant l'id 100
    b) afficher la liste des titres des films et l'ensemble des acteurs du millésime 2011
    c) trouver tous les films dans lesquels ont joué que les acteurs mnitu et pomalaix
    d) trouver tous les films dans lesquels ont joué que 3 acteurs
    e) trouver tous les films dans lesquels a joué fsmrel

    Et les requêtes que je vous propose sont
    A)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    select titre
    From film_avec_acteur
    where id_film = 100
    /
     
    select titre, list_acteur
    From film_avec_acteur
    Where extract(year from sortie) = 2011
    /
     
    select titre
    from film_avec_acteur
    where list_acteur = acteur_nt('mnitu','pomalaix')
    /
     
    select titre
    from film_avec_acteur
    where cardinality(list_acteur) = 3
    /
     
    Select titre
      From film_avec_acteur p, Table(p.list_acteur) t
    Where t.column_value = 'fsmrel'
    /
    B)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
     
    select titre
    From film
    where id_film = 100
    /
     
     
    select titre, cast(collect(a.nom) as acteur_nt) list_acteur
      From film f
           Join
           film_acteur fa
        On f.id_film = fa.id_film
           Join
           acteur a
        on a.id_acteur = fa.id_acteur
    Where extract(year from sortie) = 2011
    Group By titre
    /
     
    select titre
      From film f
    Where exists (Select Null
                   from film_acteur fa
                        Join
                        acteur a
                     on a.id_acteur = fa.id_acteur
                  Where fa.id_film = f.id_film
                    and a.nom = 'mnitu'
                 )
      and exists (Select Null
                   from film_acteur fa
                        Join
                        acteur a
                     on a.id_acteur = fa.id_acteur
                  Where fa.id_film = f.id_film
                    and a.nom = 'pomalaix'
                 )
      and not exists (Select Null
                   from film_acteur fa
                        Join
                        acteur a
                     on a.id_acteur = fa.id_acteur
                  Where fa.id_film = f.id_film
                    and a.nom not in ('pomalaix','mnitu')
                 )
    /
     
    select titre
      From film f
           Join
           film_acteur fa
        On f.id_film = fa.id_film
           Join
           acteur a
        on a.id_acteur = fa.id_acteur
    Group By titre
    Having count(*) = 3
    /
     
     
    select titre
      From film f
           Join
           film_acteur fa
        On f.id_film = fa.id_film
           Join
           acteur a
        on a.id_acteur = fa.id_acteur
    Where a.nom = 'fsmrel'
    /
    Maintenant expliquez mois
    a) en quoi le principe de l'information a été violé
    b) quels sont les graves problèmes des performances intrinsèques du modèle A par la prisme des requêtes que j'ai vous donnée.

  7. #27
    Expert éminent
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 180
    Billets dans le blog
    16
    Par défaut
    Bonsoir,


    Citation Envoyé par mnitu Voir le message
    en quoi le principe de l'information a été violé
    Selon ce principe, dans l’en-tête d’une relvar (variable relationnelle, informellement table) déclarée par l’utilisateur, il ne doit pas y avoir de colonnes cachées, c'est-à-dire non définies par lui.

    Or, dans la documentation d’Oracle on trouve l’expression « hidden column » :
    Every nested table storage table contains a column, referenceable by NESTED_TABLE_ID, that keys rows in the storage table to the associated row in the parent table. A parent table that is itself a nested table has two system-supplied ID columns: one, referenceable by NESTED_TABLE_ID, that keys its rows back to rows in its own parent table, and one hidden column referenced by the NESTED_TABLE_ID column in its nested table children.
    En l’occurrence le message de Mohamed.Houri fait réfléchir et on peut le remercier pour les points qu’il a relevés. En tout état de cause, je tiens pour ma part à conserver la maîtrise des attributs de mes propres relvars (colonnes des tables). Au billard, on dit « dominer », une bille ne doit pas être cachée.

    En passant, le non respect du principe de l’information n’est pas anodin et cela a fortement contribué au report aux calendes grecques des propositions de prise en compte des données temporelles dans la norme SQL (voir notamment l’ouvrage de Date, Date on Databases, Writings 2000-2006 au chapitre 28, page 481). Le 1er jet de l’article correspondant est disponible sous forme de PDF.


    Citation Envoyé par mnitu Voir le message
    quels sont les graves problèmes des performances intrinsèques du modèle A par la prisme des requêtes que j'ai vous donnée.
    Je n’ai pas parlé de graves problèmes de performance intrinsèques au modèle. J’ai seulement dit que les Nested Tables étaient à fuir parce qu’elles violent le principe de l’information, central dans le Modèle Relationnel de Données. En l’espèce je vais peut-être un peu trop vite en besogne à votre goût, mais ce principe énoncé par Codd n'est pas négociable. Pour les performances, j’ai pris en considération les retours de Mohamed.Houri et Waldar. Mais pour être objectif, je dirai qu’un prototypage des performances s’impose (à commencer par les campagnes d’EXPLAIN, non suffisantes mais nécessaires), en relation avec des volumétries permettant de se prononcer (cf. les dix millions de personnes dont j’ai fait mention dans mon précédent message). Je renouvelle ma demande auprès des DBA à propos de leurs avis et tuyaux. Je ne pense pas aller trop vite en besogne en l’occurrence.


    Quelques remarques en passant.

    Typage des relations

    Dans le cadre de la théorie relationnelle, une relation est une valeur de relvar (informellement valeur de table). Le type d’une relation est défini par son en-tête :
    RELATION {A1 T1, A2 T2, ..., Ai Ti, ..., An Tn}
    Où la paire <Ai, Ti> est un attribut, Ai est le nom de l’attribut, Ti son type.

    Reprenons votre exemple :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    CREATE type acteur_nt AS TABLE of varchar2(100)
    Je ne dispose pas d’Oracle et ne peux donc pas vérifier la modélisation qu’il autorise, mais il apparaît que acteur_nt est le nom d’une variable de type table {...}, type qui ne respecte pas la construction d’attribut <Ai, Ti> puisque, si Ti est fourni (varchar2(100) en l’occurrence), Ai est absent. J’en déduis qu’Oracle n'hésite pas à se départir du Modèle Relationnel de Données et de ses principes fondamentaux.

    Pour mémoire, dans le cadre du Modèle Relationnel de Données, on aurait une relvar film_avec_acteur telle que celle-ci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    VAR film_avec_acteur BASE RELATION  
      {
        id_film Integer,
        titre Char,
        sortie Date,
        list_acteur  RELATION {Nom  Char, ...}
      } KEY {id_film} ;
    Je subodore le rôle de la table list_act_nt, mais dans le cadre du Modèle Relationnel de Données voilà un greffon dont on n’a manifestement pas besoin eu égard au principe d’essentialité.

    Toujours dans le cadre du Modèle Relationnel de Données, on n’a pas non plus besoin de définir un type non scalaire tel que acteur_nt. En reprenant la référence que vous donnez (SQL and Relational Theory) et en poussant jusqu’aux pages 40-41 (Scalar vs. Nonscalar Types) : après leur lecture, on peut inférer que si la table list_act_nt et le type acteur_nt sont essentiels pour les nested tables, c’est qu’on est bien dans un contexte étranger au Modèle Relationnel de Données.


    Quelques questions à propos des nested tables

    Mes questions paraîtront basiques, mais je répète que je ne dispose pas d’Oracle pour répondre moi-même, aussi je vous remercie de m’éclairer.

    Supposons que pour un même film, on ne puisse pas trouver plus d’une fois le même nom d’acteur, comment garantir cette contrainte avec la table film_avec_acteur ?

    Comment procéder pour qu’une colonne telle que list_acteur fasse l’objet d’une clé candidate (voire clé primaire) ?

    A supposer qu’une table tierce ait besoin de faire référence au nom des acteurs, comment traite-t-on de l’intégrité référentielle ?

    Dans l’autre sens, si c’est la colonne list_acteur qui doit faire référence à une table Acteur, comment là encore résout-on la contrainte d’intégrité référentielle ?

    Certaines mises-à-jour qui dans un cadre cinephilien (c'est-à-dire classique) requièrent seulement l’instruction INSERT (ajout d’un acteur dans la table film_acteur) ne requièrent-elles pas l’utilisation soit de l’instruction INSERT (ajout dans la table film_avec_acteur d’un film et des acteurs) soit de l’instruction UPDATE (ajouter un acteur pour un film existant déjà) ?
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  8. #28
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    Citation Envoyé par fsmrel Voir le message
    ...
    Selon ce principe, dans l’en-tête d’une relvar (variable relationnelle, informellement table) déclarée par l’utilisateur, il ne doit pas y avoir de colonnes cachées, c'est-à-dire non définies par lui.

    Or, dans la documentation d’Oracle on trouve l’expression « hidden column » :
    Every nested table storage table contains a column, referenceable by NESTED_TABLE_ID, that keys rows in the storage table to the associated row in the parent table. A parent table that is itself a nested table has two system-supplied ID columns: one, referenceable by NESTED_TABLE_ID, that keys its rows back to rows in its own parent table, and one hidden column referenced by the NESTED_TABLE_ID column in its nested table children.
    ...

    Bonjour et merci de votre retour,

    Je continue à penser qu’on mélange les choses. Donc, si je bien compris votre argumentation vous considérez que l’apparition de la colonne SYS_NC0000400005$ dans la structure de la table film_avec_acteur violerait le première principe

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    SQL> Select table_name, column_name
      2    From all_tab_cols
      3   Where table_name = 'FILM_AVEC_ACTEUR'
      4  /
     
    TABLE_NAME                     COLUMN_NAME
    ------------------------------ ------------------------------
    FILM_AVEC_ACTEUR               LIST_ACTEUR
    FILM_AVEC_ACTEUR               ID_FILM
    FILM_AVEC_ACTEUR               TITRE
    FILM_AVEC_ACTEUR               SORTIE
    FILM_AVEC_ACTEUR               SYS_NC0000400005$
     
    SQL>
    Soit ! Alors que pensez-vous de l’exemple suivant ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    SQL> create table TEST_NULL
      2  (
      3    NB  NUMBER,
      4    FIC CHAR(69)
      5  )
      6  /
     
    Table created
    SQL> create index IITEST_NULL2 on TEST_NULL (NB, 5)
      2  /
     
    Index created
     
    SQL> 
    SQL> Select table_name, column_name
      2    From all_tab_cols
      3   Where table_name = 'TEST_NULL'
      4  /
     
    TABLE_NAME                     COLUMN_NAME
    ------------------------------ ------------------------------
    TEST_NULL                      NB
    TEST_NULL                      FIC
    TEST_NULL                      SYS_NC00003$ 
    SQL>
    C’est la même chose non ? Une colonne est apparue par magie, n’est ce pas ? Donc, il faut fuir maintenant aussi les indexes fonctionnels. Et de quoi encore ?

    Malheureusement, l’intervention du Mohamed comme celle du Waldar était hors sujet. Vous même vous avez répondu que le modèle en question était bien considère comme respectant la première forme normale. Et vous le savez mieux que moi que le modèle relationnelle n’a rien à dire ni sur l’implémention physique ni sur les performances.

    Si vous pensez que j'ai mal compris, je suis prêt à apprendre et à changer mon point de vue en face des arguments cohérents.

    Je regarderais aussi attentivement les autres détails de votre réponse.

  9. #29
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Mnitu, il manque dans votre cas pratique la proposition suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    CREATE VIEW v_film_avec_acteur (id_film, titre, sortie, list_acteur)
    AS
      SELECT fl.id_film, fl.titre, fl.sortie
           , cast(collect(ac.nom) as acteur_nt)
        FROM film fl
             LEFT OUTER JOIN film_acteur fa
             INNER JOIN acteur ac
               ON ac.id_acteur = fa.id_acteur
               ON fa.id_film   = fl.id_film
    GROUP BY fl.id_film, fl.titre, fl.sortie;
    C'était mon retour d'expérience, peut-être hors sujet en effet.
    Conserver un modèle relationnel pour le stockage et si le besoin existe utiliser le modèle objet en interrogation.

  10. #30
    Membre Expert

    Homme Profil pro
    Inscrit en
    Mars 2010
    Messages
    536
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 536
    Par défaut
    Je veux juste faire une précision. Je n'ai jamais parlé de violation du premier principe ni du second ni de la 1NF ni de quoique ce soit à ce sujet. Au vu de mon expérience avec ce genre de tables,à chaque fois que je les vois être proposées dans des forums, je me permets d'avertir sur les problèmes, de performance et d'autres, qu'elles peuvent générer, mais pas sur la violation d'un quelconque principe fondamental de la modélisation en Oracle. J'ai lu à ce sujet, deux livres un de Tom Kyte et un autre de jonathan Lewis. Tous les deux n'ont pas parlé de violation de la 1NF, mais ils ont tous les deux conseillé d'éviter l'utilisation de ce genre de tables pour les raisons que je vais essayer de citer ci-dessous:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
     
    mhouri> desc film_avec_acteur
     Name                                      Null?    Type
     ----------------------------------------- -------- -------------
     ID_FILM                                   NOT NULL NUMBER(38)
     TITRE                                              VARCHAR2(100)
     SORTIE                                             DATE
     LIST_ACTEUR                                        ACTEUR_NT
     
    mhouri> select id_film, list_acteur
      2  from film_avec_acteur;
     
       ID_FILM      LIST_ACTEUR                                                                                                                                     
    ------------------------------------------------------------
           100     ACTEUR_NT('mnitu', 'pomalaix')                                                                                                                                  
           200     ACTEUR_NT('pomalaix', 'mnitu')                                                                                                                                  
           300     ACTEUR_NT('cinephil', 'mnitu', 'fsmrel')                                        
           400     ACTEUR_NT('pomalaix', 'mnitu', 'fsmrel')                                                                                                                        
           500     ACTEUR_NT('cinephil', 'waldar', 'fsmrel')                                                                                                                       
           600     ACTEUR_NT('waldar', 'mohamed')                                                  
     
     
    6 rows selected.
     
    mhouri> desc list_act_nt
     Name                                      Null?    Type
     ----------------------------------------- -------- -------------
     COLUMN_VALUE                                       VARCHAR2(100)
     
    mhouri> select * from list_act_nt
      2  ;
    select * from list_act_nt
                  *
    ERROR at line 1:
    ORA-22812: cannot reference nested table column's storage table
    Je peux la décrire mais je ne peux pas sélectionner des données à partir de cette table.

    Mieux encore, je peux créer un index sur cette table alors que je ne peux pas faire de select sur cette table.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    mhouri> create index ind_nt_col_val on list_act_nt(column_value);
     
    Index created.
    Encore mieux que ça, je peux créer un index sur une colonne qui, pour le commun des mortels, n'existe pas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    mhouri> create index ind_nt_nest_id on list_act_nt(nested_table_id);
    Index created.
    Et là, entre en jeux le fameux hint magique /*+NESTED_TABLE_GET_REFS*/ qui permet l'accès à cette nested table

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    mhouri> select /*+NESTED_TABLE_GET_REFS*/
      2  nt.*
      3  from list_act_nt nt;
     
    COLUMN_VALUE                                                                    
    -----------------------
    mnitu                                                                           
    pomalaix                                                                        
    pomalaix                                                                        
    mnitu                                                                           
    cinephil                                                                        
    mnitu                                                                           
    fsmrel                                                                          
    pomalaix                                                                        
    mnitu                                                                           
    fsmrel                                                                          
    cinephil                                                                        
    waldar                                                                          
    fsmrel                                                                          
    waldar                                                                          
    mohamed                                                                         
     
    15 rows selected.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    mhouri> select /*+NESTED_TABLE_GET_REFS*/
      2  nested_table_id, nt.*
      3  from list_act_nt nt;
     
    NESTED_TABLE_ID                              COLUMN_VALUE                                                                                                                                 
    -------------------------------------------------------------------
    B9F13D9DDC601F8DE044000B5DE02FC8             mnitu                                                                                                                                                           
    B9F13D9DDC601F8DE044000B5DE02FC8             pomalaix                                                                                                                                                        
    B9F13D9DDC611F8DE044000B5DE02FC8             pomalaix                                                                        
    B9F13D9DDC611F8DE044000B5DE02FC8             mnitu                                                                                                                                                           
    B9F13D9DDC621F8DE044000B5DE02FC8             cinephil                                                                                                                                                        
    B9F13D9DDC621F8DE044000B5DE02FC8             mnitu                                                                           
    B9F13D9DDC621F8DE044000B5DE02FC8             fsmrel                                                                                                                                                          
    B9F13D9DDC631F8DE044000B5DE02FC8             pomalaix                                                                                                                                                        
    B9F13D9DDC631F8DE044000B5DE02FC8             mnitu                                                                           
    B9F13D9DDC631F8DE044000B5DE02FC8             fsmrel                                                                                                                                                         
    B9F13D9DDC641F8DE044000B5DE02FC8             cinephil                                                                                                                                                        
    B9F13D9DDC641F8DE044000B5DE02FC8             waldar                                                                          
    B9F13D9DDC641F8DE044000B5DE02FC8             fsmrel                                                                                                                                                         
    B9F13D9DDC651F8DE044000B5DE02FC8             waldar                                                                                                                                                          
    B9F13D9DDC651F8DE044000B5DE02FC8             mohamed
    Ces NESTED_TABLE_ID représentent une Foreign Key(FK) entre la table film_avec_acteur et sa nested table list_act_nt. Pour rappel, nous n'avons pas créé cette FK, nous ignorions même l'existence de la colonne NESTED_TABLE_ID, qui en plus de son invisibilité, elle n'est pas indexée provoquant sans aucun doute que la jointure entre la table mère et sa table fille se fasse sans indexe. Sans parler de la possibilité de deadlock que je ne suis pas arrivé à simuler pour l’instant.

    Heureusement qu'Oracle autorise ceux qui viennent à le savoir, d'indexer cette FK cachée.

    Revenons maintenant encore une fois à la table film_avec_acteur. Nous savons tous que la colonne FK doit pointer sur (a) soit une ''primary key'' (b) soit sur une ''unique key''. Observons alors quelles sont les contraintes qui existent sur la table mère dans ce cas:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    mhouri> select constraint_name, constraint_type, table_name
      2  from user_constraints
      3  where table_name = 'FILM_AVEC_ACTEUR';
     
    CONSTRAINT_NAME                C TABLE_NAME                                     
    ------------------------------ - ------------------------------                 
    SYS_C00185826                  P FILM_AVEC_ACTEUR                               
    SYS_C00185827                  U FILM_AVEC_ACTEUR
    Tiens, jusqu'à preuve du contraire, Marius n'a créé qu'une seule contrainte c'est la ''primary key'' sur ID_FILM.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    select index_name, index_type, table_name, uniqueness
    from user_indexes
    where table_name = 'FILM_AVEC_ACTEUR';
     
    INDEX_NAME     INDEX_TYPE                  TABLE_NAME                   UNIQUENES
    ------------------------------ --------------------------- ------------------------------ 
    SYS_C00185826   NORMAL                      FILM_AVEC_ACTEUR               UNIQUE
    SYS_C00185827   NORMAL                      FILM_AVEC_ACTEUR               UNIQUE
     
    select index_name, column_name, column_length
    from user_ind_columns
    where table_name = 'FILM_AVEC_ACTEUR';     
     
    INDEX_NAME        COLUMN_NAME   COLUMN_LENGTH                    
    ------------------------------ -------------------
    SYS_C00185826	ID_FILM	   22
    SYS_C00185827	LIST_ACTEUR	   16
    Il est donc clair, qu'Oracle a créé sans qu'il nous le signale, une ''unique key'' sur laquelle il fait pointer la colonne FK de sa nested table LIST_ACT_NT. Je pense même qu'il a crée une colonne supplémentaire cachée, SYS_NC000XXX$, d'un type RAW(16) et c'est bien sur cette colonne qui est appliquée la UNIQUE KEY SYS_C00185827

    Encore un point (peut-être à ne pas négliger). Le calcul des statistiques de la table mère est indépendant de celui de sa nested table bien qu'elles aient été créés au même moment avec le même script SQL.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    mhouri> select table_name, last_analyzed
      2  from user_tables
      3  where table_name in ('FILM_AVEC_ACTEUR','LIST_ACT_NT');
     
    TABLE_NAME                     LAST_ANALYZED                                                                            
    ------------------------------ -------------------                                                                      
    FILM_AVEC_ACTEUR               28/02/2012 10:25:04                                                                      
    LIST_ACT_NT                    27/02/2012 22:00:16
     
    mhouri> exec dbms_stats.gather_table_stats (user, 'FILM_AVEC_ACTEUR');
     
    PL/SQL procedure successfully completed.
     
    mhouri> select table_name, last_analyzed
      2  from user_tables
      3  where table_name in ('FILM_AVEC_ACTEUR','LIST_ACT_NT');
     
    TABLE_NAME                     LAST_ANALYZED                                                                            
    ------------------------------ -------------------                                                                      
    FILM_AVEC_ACTEUR               28/02/2012 10:26:23                                                                      
    LIST_ACT_NT                    27/02/2012 22:00:16
    Encore, un autre point à vérifier (je ne l'ai jamais vérifié), c'est que ce genre de table ne peut être utilisé en mode parallèle.

    Lors d'un EXPORT d'une table de ce type, les deux tables sont exportées séparément ce qui peut causer des problèmes (en me basant sur la 8i et encore dans les autres versions jusqu'à preuve du contraire)

    Il me semble qu'il y a encore un problème de lock lorsqu'on update la nested table que je ne suis pas arrivé à simuler. Je ne dirai rien donc à ce sujet.

    C’est pour toutes ces raisons, que chacun de nous doit tempérer un peu son enthousiasme quant à l’utilisation des tables objet ou des tables ayant des colonnes du type objet (nested table) pour persister ses données.

  11. #31
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    Waldar,
    Le nested table n’est pas un Objet mais un type de données. Je pense que j’ai le même exemple que vous dans les requêtes que j’ai fourni. Je n’ai jamais dit qu’il faut utiliser que du nested table et que c’est la seule solution possible !

    Mohamed,

    Qui a dit que vous devez interroger directement la nested table? Interrogez-vous la colonne de type date directement ?

    Connaissez-vous des autres situations similaires ou Oracle stocke des données ailleurs ? Pourriez-vous investiguer et nous faire un retour de vos découvertes sur les choses qui se passent derrière la scène dans ces casses?

    Remarque Oracle 8i c’est un peu vieux. Par ailleurs je connais de choses vraiment affreuses sur Oracle 5, 6 et 7.

  12. #32
    Expert éminent
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 180
    Billets dans le blog
    16
    Par défaut
    Bonsoir,


    Citation Envoyé par Mohamed.Houri Voir le message
    Je veux juste faire une précision. Je n'ai jamais parlé de violation du premier principe ni du second ni de la 1NF ni de quoique ce soit à ce sujet. Au vu de mon expérience avec ce genre de tables, à chaque fois que je les vois être proposées dans des forums, je me permets d'avertir sur les problèmes, de performance et d'autres, qu'elles peuvent générer, mais pas sur la violation d'un quelconque principe fondamental de la modélisation en Oracle. J'ai lu à ce sujet, deux livres un de Tom Kyte et un autre de jonathan Lewis. Tous les deux n'ont pas parlé de violation de la 1NF, mais ils ont tous les deux conseillé d'éviter l'utilisation de ce genre de tables
    Ne vous inquiétez pas. De mon côté j’ai bien compris le sens de votre intervention très pertinente et fort utile. J’ai pris part au débat simplement parce qu’il portait sur la 1NF, et de fil en aiguille...

    Le problème du viol de la 1NF relève de la normalisation et ne concerne pas un SGBD en particulier, mais la théorie relationnelle, matrice des systèmes qui s’en réclament. Pour conclure avec cet aspect des choses, il y a une trentaine d’années le Professeur Jeffrey D. Ullman a parfaitement résumé les choses en une phrase, en mettant en évidence un pléonasme bref mais imparable (Principles of Database Systems, second edition, page 235) :
    “relation” is for us synonymous with “first normal form relation”
    Ce avec quoi Chris Date est parfaitement d’accord (cf. à nouveau SQL and Relational Theory, page 18 cette fois-ci) :
    relations are always normalized (equivalently, they’re in first normal form)
    Tout en ajoutant (cf. The Relational Database Dictionary page 69) :
    It follows that a “table,” in a language like SQL, can be considered to be in 1NF if and only if it’s a direct and faithful representation of some relvar

    Incidemment, la table film_avec_acteur n’étant pas l’image exacte d’une relvar (elle ne respecte pas la construction d’attribut <Ai, Ti> dont j’ai fait mention dans mon message précédent), après tout au sens de la théorie relationnelle elle n’est pas normalisée...

    Quoi qu’il en soit, Mohamed, on compte sur vous, merci et keep up the good job!


    Citation Envoyé par mnitu Voir le message
    si je bien compris votre argumentation vous considérez que l’apparition de la colonne SYS_NC0000400005$ dans la structure de la table film_avec_acteur violerait le première principe
    Quand dans le contexte de la théorie relationnelle je déclare la relvar film_avec_acteur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    VAR film_avec_acteur BASE RELATION  
      {
        id_film Integer,
        titre Char,
        sortie Date,
        list_acteur  RELATION {Nom  Char, ...}
      } KEY {id_film} ;
    Cette relvar est du type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    RELATION  
      {
        id_film Integer,
        titre Char,
        sortie Date,
        list_acteur  RELATION {Nom  Char, ...}
      } KEY {id_film} ;
    Mais pour les raisons que j’ai fournies en long et en large, un SGBD conforme au Modèle Relationnel de Données ne prendra jamais l’initiative de remplacer ce type par le suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    RELATION[/COLOR]  
      {
        id_film Integer,
        titre Char,
        sortie Date,
        list_acteur  RELATION {Nom  Char, ...},
        SYS_NC0000400005$ ...
      } KEY {id_film} ;
    En enfreignant ainsi impunément le principe de l’information (The Information Principle), quitte à ce que je prenne une vessie pour une lanterne.


    Citation Envoyé par mnitu Voir le message
    Soit ! Alors que pensez-vous de l’exemple suivant ?
    ...
    C’est la même chose non ? Une colonne est apparue par magie, n’est ce pas ?
    Voui, indubitablement ! Une fois de plus le système met en oeuvre une structure de table différente de celle que vous avez déclarée.


    Citation Envoyé par mnitu Voir le message
    Donc, il faut fuir maintenant aussi les indexes fonctionnels. Et de quoi encore ?
    Personne ne vous empêchera de vous servir des facilités technologiques offertes par votre SGBD ! Tout ce que j’ai à faire observer est qu’un index a pour objet la performance. Mais comme tout le monde le sait, la performance est hors sujet dans le cadre du Modèle Relationnel de Données (et.je suppose qu’il en va de même avec la norme SQL), sauf quand les mathématiciens s’y intéressent sur un plan purement théorique ; par exemple Zaniolo (cf. On the Design of Relational Database Schemata, page 32) démontre que la performance de tel algorithme de décomposition a une limite supérieure de l’ordre de O(n⁴ log n), et je le crois sur parole !
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  13. #33
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    Bonsoir,

    Bref, j'aimerais a ce moment que vous vous décidez, soit

    ...
    Je suppose que vous faites allusion à la 1NF (première forme normale). Mettre en œuvre un modèle normalisé au sens Merise (règle de vérification) comme vous l’avez fait est préférable, mais du point de vue de la théorie relationnelle, on ne viole pas la 1NF quand on niche des tables dans des colonnes (cf. le paragraphe 2.6 traitant des RVA (relation-valued attributes).
    soit

    Citation Envoyé par fsmrel Voir le message
    ..
    Incidemment, la table film_avec_acteur n’étant pas l’image exacte d’une relvar (elle ne respecte pas la construction d’attribut <Ai, Ti> dont j’ai fait mention dans mon message précédent), après tout au sens de la théorie relationnelle elle n’est pas normalisée...
    Ensuite, je vois donc
    Citation Envoyé par fsmrel Voir le message
    ...

    Quand dans le contexte de la théorie relationnelle je déclare la relvar film_avec_acteur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    VAR film_avec_acteur BASE RELATION  
      {
        id_film Integer,
        titre Char,
        sortie Date,
        list_acteur  RELATION {Nom  Char, ...}
      } KEY {id_film} ;
    Cette relvar est du type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    RELATION  
      {
        id_film Integer,
        titre Char,
        sortie Date,
        list_acteur  RELATION {Nom  Char, ...}
      } KEY {id_film} ;
    Mais pour les raisons que j’ai fournies en long et en large, un SGBD conforme au Modèle Relationnel de Données ne prendra jamais l’initiative de remplacer ce type par le suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    RELATION[/COLOR]  
      {
        id_film Integer,
        titre Char,
        sortie Date,
        list_acteur  RELATION {Nom  Char, ...},
        SYS_NC0000400005$ ...
      } KEY {id_film} ;
    En enfreignant ainsi impunément le principe de l’information (The Information Principle), quitte à ce que je prenne une vessie pour une lanterne.
    ...
    j'exécute la requête suivante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    mni@DIANA> select rowid from acteur;
     
    ROWID
    ------------------
    AAASQSAAEAAAJg2AAG
    AAASQSAAEAAAJg2AAH
    AAASQSAAEAAAJg2AAI
    AAASQSAAEAAAJg2AAJ
    AAASQSAAEAAAJg2AAK
    AAASQSAAEAAAJg2AAL
     
    6 ligne(s) sÚlectionnÚe(s).
    et je me demande maintenant que est-ce que dois-je comprendre ?

    Décidément je n'ai jamais déclare une colonne rowid dans ma table acteur! Est-ce que cela ça va avec le principe ou pas

  14. #34
    Membre émérite Avatar de Oishiiii
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2009
    Messages
    508
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Août 2009
    Messages : 508
    Par défaut
    Bonsoir à tous,

    Je ne fais que passer rapidement pour répondre au message (#21) de skuatamad.

    Citation Envoyé par skuatamad Voir le message
    J'avais cru comprendre via Oishiiii dans le lien sus mentionné que même une colonne contenant une liste 'Paris, Lille , Marseille' était conforme à la 1NF, peut être ai je mal compris Oishiiii, peut être vous avait il mal compris.
    Vous avez bien cru et je crois que nous sommes tous d'accord

    fsmrel n'a peut-être pas bien fait attention (c'est possible vu l'heure du message ) lorsqu'il a écrit qu'R2 n'était pas 1NF car ce n'est pas tout a fait exact d'après moi.

    On parle bien de la page 35 de l'ouvrage SQL and Relational Theory de Chris Date.
    On est dans le paragraphe 2.3, Data Value Atomicity, le but est de parler de cette notion d'atomicité, pour au final aborder la notion de RVA.

    Il commence la démonstration comme ceci :

    For the sake of the example, let's agree that supplier numbers and part numbers are indeed "atomic"; then we can presumably agree that R1, at least, is in 1NF.


    Il continue :
    Now suppose we replace R1 by R2...
    Then most people would surely say that R2 is not in 1NF; in fact, it looks like an example of "repeating groups," and repeating groups are the one thing that almost everybody agrees 1NF is supposed to prohibit (because such groups are obviously not atomic—right?).
    En regardant la relation R2, la plupart de gens diront qu'elle n'est pas 1NF, car elle présente a première vue un "groupe répétitif", une valeur non "atomique".

    De là il décide qu'R2 n'est pas en 1NF pour continuer sa démonstration.
    Well, let's agree for the sake of the argument that R2 isn't in 1NF..
    plus loin:
    But suppose we now replace R2 by R3. Then I claim that R3 is in 1NF!
    .....
    Il décide qu'R3 est 1NF parce qu'il a mit des accolades qui représenterai un ensemble est donc une certaine forme d'atomicité.

    D'après ce que je comprend, la démonstration n'est qu'une caricature de la notion d'atomicité, qui au final on est d'accord, n'est pas très précise voir même obsolète.
    Ce qu'il veux nous dire c'est que R2 ou R3, c'est finalement la même chose.

    Il se sert de R3 pour ensuite introduire la notion de RVA,
    Si l'attribut PNO (R2) ou PNO_SET (R3) ne prenait pas pour valeur de simple ensembles ou chaînes de caractères mais plutôt des relations, ce serait plus intéressant; utilisation de l'algèbre, etc.

    Au final il nous présente R4, en 1NF, tout comme R1, mais avec RVA :


    Citation Envoyé par skuatamad Voir le message
    Donc finalement si je comprends mieux (j'espère) une liste 'Paris, Lille, Marseille' peut être conforme 1NF ou peut ne pas l'être, tout dépend de l'utilisation que l'on souhaite en faire (et du niveau d'atomicité qu'on lui accorde), est ce correcte ?
    Et donc dans la pratique la plus part des listes violent bien la 1NF.
    Pour moi c'est non, le respect de la première forme normale n'est pas conditionnel comme cela.
    Une table SQL est considérée comme 1NF si c'est une image fidèle de la relation qu'elle représente.
    Si le type de donnée définissant l'attribut PMO de R2 est une chaine de caractères, la valeur 'P1, P2' ne viole pas la 1NF
    PS: Si le type était char(2) peut-être, mais c'est ambigu dès le départ de toute façon, nous n'avons pas la définition précise de R2.

    Bonne nuit
    Images attachées Images attachées   

  15. #35
    Expert éminent
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 180
    Billets dans le blog
    16
    Par défaut
    Bonsoir,


    Citation Envoyé par mnitu Voir le message
    j'aimerais a ce moment que vous vous décidez
    En attendant que je découvre autre chose et fasse une troisième proposition , ma 2e proposition annule et remplace la 1re. En effet quand j’ai écrit :

    Je suppose que vous faites allusion à la 1NF (première forme normale). Mettre en œuvre un modèle normalisé au sens Merise (règle de vérification) comme vous l’avez fait est préférable, mais du point de vue de la théorie relationnelle, on ne viole pas la 1NF quand on niche des tables dans des colonnes (cf. le paragraphe 2.6 traitant des RVA (relation-valued attributes).
    Je n’avais pas alors complètement disséqué la structure de votre table film_avec_acteur. Ce n’est que par la suite que je me suis rendu compte que la structure d’attribut <Ai, Ti> n’était pas respectée, d’où l’expression « après tout » que j’ai pris le soin de faire figurer à l’occasion de ma deuxième proposition :

    Incidemment, la table film_avec_acteur n’étant pas l’image exacte d’une relvar (elle ne respecte pas la construction d’attribut <Ai, Ti> dont j’ai fait mention dans mon message précédent), après tout au sens de la théorie relationnelle elle n’est pas normalisée...
    Je suis désolé d'avoir pu perturber votre réflexion...


    Citation Envoyé par mnitu Voir le message
    et je me demande maintenant que est-ce que dois-je comprendre ?
    Décidément je n'ai jamais déclare une colonne rowid dans ma table acteur! Est-ce que cela ça va avec le principe ou pas
    Vous n’avez pas déclaré de colonne ROWID dans la structure de votre table Acteur, le principe de l’information est donc une fois de plus bafoué par votre SGBD. Comme ce n’est pas vous qui maîtrisez les valeurs (des pointeurs ?) de cette colonne, si vous l’utilisez c’est à vos risques et périls, et si c’est pour aller plus vite, attention aux virages...
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  16. #36
    Membre Expert Avatar de pacmann
    Homme Profil pro
    Consulté Oracle
    Inscrit en
    Juin 2004
    Messages
    1 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consulté Oracle
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Par défaut
    Salut,

    Mais il dit quoi exactement son principe de l'information, à Codd ?
    Il dit qu'il ne faut pas que les lignes aient une adresse physique ? Que le SGBD ne doit s'appuyer sur aucune donnée technique ?

    Les colonnes cachées n'ont pas a être utilisées pour faire des requêtes, c'est clair.... le problème est-il qu'elles peuvent être consultées si on le souhaite vraiment ?

    Parce que quand je regarde la définition de la table, il n'y a ni rowid, ni SYSXXX, ni autre colonne cachée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    SQL> CREATE INDEX iitemp ON film_avec_acteur(id_film, 1);
     
    Index crÚÚ.
     
    EcoulÚ : 00 :00 :00.00
    SQL> select column_name from dba_tab_columns where table_name = 'FILM_AVEC_ACTEUR';
     
    COLUMN_NAME
    ------------------------------
    ID_FILM
    TITRE
    SORTIE
    LIST_ACTEUR
    En gros, là on reproche simplement à Oracle d'être trop transparent, en offrant via ses pseudo colonnes et colonnes cachées la possibilité de comprendre son fonctionnement interne ?
    (Car oui, le dictionnaire, c'est xxx_tab_columns. Je requête en général sur dba_tab_cols, qui elle montre les colonnes cachées, mais juste parce que c'est plus court à écrire )

    Pour moi, ce qui, au pire des cas, n'est pas conforme au principe de l'information (à confirmer par la lecture de l'énoncé exact, et la connaissance du contexte dans lequel il a été écrit), ce n'est pas l'existence ces colonnes techniques, ni de la nested table ... mais juste l'implémentation du SELECT (l'accès à ces données purement techniques).

  17. #37
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    Citation Envoyé par fsmrel Voir le message
    ...
    Vous n’avez pas déclaré de colonne ROWID dans la structure de votre table Acteur, le principe de l’information est donc une fois de plus bafoué par votre SGBD. Comme ce n’est pas vous qui maîtrisez les valeurs (des pointeurs ?)...
    Bonsoir,

    Oui des pointers précisément! Je savait depuis le début que si on commence par la violation des principes du modèle relationnel on finirait par «Oracle ne respecte pas la théorie» je vous l'avait dit. Il me semble qu'une relation n'accepte pas des doublons, comme les tables d'Oracle et le langage SQL le permet, n'est pas ça?

    Je suis en accord avec vous depuis le début quand vous dites que le modèle relationnel n'a rien à dire ni sur les performances (Waldar) ni sur l'implémentation physique (Mohamed).
    Par contre, le sujet de la première forme normale tiens de la théorie mais, j'ai bien peur que votre relvar film_avec_acteur (pas ma table) peut encore faire peur à votre ami Cinephil.

    J'espère que suite à cette discussion plus de monde se passionnera au sujet de la théorie du modèle relationnel. Avez vous remarqué que Mohamed Keep-The-Good-Job-Doing ne peut rien nous dire en absence des révélations de ses dieux TOM KYTE et JONATHAN LEWIS (Mohamed je vous demande des excuses par anticipation ).

  18. #38
    Expert éminent
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 180
    Billets dans le blog
    16
    Par défaut
    Bonsoir Oishiiii,


    Ça faisait un moment qu’on n’avait pas eu le plaisir de vous voir !

    Citation Envoyé par Oishiiii Voir le message
    fsmrel n'a peut-être pas bien fait attention (c'est possible vu l'heure du message ) lorsqu'il a écrit qu'R2 n'était pas 1NF car ce n'est pas tout a fait exact d'après moi.

    Je n’ai pas été le premier à l'affirmer ! Pour changer un peu je vais me référer à un autre ouvrage de Chris Date, Date on Database: Writings 2000-2006 au chapitre 8 « What first normal really means », ouvrage dans lequel les choses sont très claires.

    Page 111, Date présente la relation T2 suivante (équivalente à la relation R3 dont vous faites mention) :


    Et je le cite : « I claim that table T2 is in 1NF! » (en gras dans le texte original, page 112). Mais bien sûr, ce qui l’intéresse ce sont les RVA plus que les ensembles généraux, puisque l’objet du Modèle Relationnel de Données ce sont les relations.

    Maintenant, on peut lire page 129 du même ouvrage (l'utilisation du gras dans cette citation est de mon fait) :
    By way of example, consider Figure 8-13 (a revised version of Figure 8-2 from earlier in this chapter). Assume column P# is defined on domain P# (i.e., the domain whose contained values are part numbers). Then it’s clearly not the case that every row-and-column intersection contains exactly one value from the pertinent domain, and we therefore have a violation of first normal on our hands.


    Cette structure est équivalente à celle de la relation R2 dont vous faites mention, et Date affirme qu’elle viole la 1NF. Si donc une douce somnolence m’a gagné tandis que j’écrivais, manifestement je n’ai pas été le seul dans cette situation...
    En tout état de cause, la structure de la figure 8-13 est bien délinquante puisqu’à l’intersection d’une ligne et d’une colonne on a plusieurs numéros de pièces.
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  19. #39
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 952
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 952
    Par défaut
    Merci Oishiiii d'être passé préciser que j'avais bien compris ce que tu disais il y a quelques mois.
    Et surtout merci fsmrel d'avoir apporté la correction nécessaire.
    Then it’s clearly not the case that every row-and-column intersection contains exactly one value from the pertinent domain, and we therefore have a violation of first normal on our hands
    Ca implique bien que toutes les colonnes soient créées en NOT NULL ?

  20. #40
    Membre émérite Avatar de Oishiiii
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2009
    Messages
    508
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Août 2009
    Messages : 508
    Par défaut
    Huummm

    J'ai bien compris ce que vous écrivez fsmrel.

    Si le domaine de P#_SET dans la Figure 8-13 est un ensemble de "Part Numbers" et qu'un Part Number est sensé être de la forme Px, d'accord, la table nous présente une liste de valeur et pas une seule valeur légale pour le domaine concerné.

    Mais pour revenir au premier message (#23) de skuatamad qui faisait référence à un de mes messages, reprenons.

    Définissions l'attribut P#_SET ou disons P#_LIST pour être clair, sur le domaine des chaines de caractères, disons varchar(100) pour être précis.

    Une valeur 'P1, P2, P3' ne viole pas la 1NF. Exact ? Il s'agit bien d'une seule valeur au regard du domaine concerné.

    Citation Envoyé par skuatamad Voir le message
    Ca implique bien que toutes les colonnes soient créées en NOT NULL ?
    Oui, tout à fait.
    Sujet à lire dans la même veine par ici.

Discussions similaires

  1. Mapping Objet/Relationnel : optimisez les performances ?
    Par voyageur dans le forum Optimisations
    Réponses: 10
    Dernier message: 12/06/2007, 15h51
  2. Outil de mapping objet/relationnel OR not ?
    Par Exsilius dans le forum Général Dotnet
    Réponses: 5
    Dernier message: 01/02/2007, 18h52
  3. Classe et objet + Modules standards
    Par Girzi dans le forum Modules
    Réponses: 2
    Dernier message: 03/11/2006, 21h23
  4. Mapping Objet / Relationnel
    Par LordBob dans le forum Accès aux données
    Réponses: 7
    Dernier message: 27/10/2006, 14h42
  5. [SQL] Abstraction BDD et mapping objet/relationnel
    Par Invité dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 26/07/2006, 13h35

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo