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

Schéma Discussion :

Internationalisation des données (i18n)


Sujet :

Schéma

  1. #1
    Membre régulier
    Homme Profil pro
    Webmaster
    Inscrit en
    Septembre 2016
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Webmaster
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2016
    Messages : 67
    Points : 90
    Points
    90
    Par défaut Internationalisation des données (i18n)
    Bonjour à tous,

    Je cherche à internationaliser ma base de données, c'est à dire traduire dans différentes langues les noms de produits, les noms de gammes, les descriptifs de produits, etc.

    Voici un MCD partiel ne portant que sur la traduction des intitulés des produits / gammes de produits / catégories de produits. La structure est inspirée d'une suggestion de fsmrel dans une autre discussion.

    Nom : nom_entites_1.png
Affichages : 238
Taille : 20,4 Ko

    Les règles de gestion sont les suivantes :
    - un produit (une gamme / une catégorie) peut porter plusieurs noms
    - un produit (une gamme/ une catégorie) ne porte qu'un seul nom dans une seule langue
    - le slug* est unique sur l'ensemble des noms (produits, gammes et catégories).

    * Un slug est une chaîne de caractères explicite et descriptive utilisée dans les URLs pour le référencement naturel. Par exemple : le produit appelé Tee-shirt rouge à manches longues (UTF-8) aura un slug nommé tee-shirt-rouge-a-manches-longues (ASCII).

    Pour tous les descriptifs, descriptifs courts, légendes de photo, etc, j'utilise la même structure entités/relations, hormis le fait qu'il n'y a plus la contrainte d'unicité du slug (il n'y a pas de slug pour un descriptif de produit ou une légende de photo, par exemple). Il y a donc autant de tables de textes que d'entités à traduire.
    C'est pratique et simple à gérer mais je me demande s'il n'est pas possible de "mutualiser" les traductions qui ont la même structure de tables. Par exemple, produits / gammes / catégories (avec slug) d'un côté, et descriptifs / descriptifs courts / légendes d'un autre côté.

    Je pensais à un MCD du type de celui-ci :

    Nom : nom_entites_2.png
Affichages : 235
Taille : 13,9 Ko

    Les règles restent les mêmes mais je place un identifiant unique pour les traductions (je ne pense pas que l'identification relative soit possible dans ce cas, bien que je puisse théoriquement utiliser le slug s'il y en a un) et j'introduis un champ décrivant le type d'élément traduit (produit, gamme ou catégorie).

    Est-ce que cette factorisation est judicieuse ?
    Est-ce que les cardinalités sont bonnes dans mon modèle ?

    Merci par avance,
    Vincent

  2. #2
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    7 966
    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 : 7 966
    Points : 30 778
    Points
    30 778
    Billets dans le blog
    16
    Par défaut
    Bonjour Vincent,

    Je prends mon café et je me penche sur votre souci de généralisation...
    (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.

  3. #3
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    7 966
    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 : 7 966
    Points : 30 778
    Points
    30 778
    Billets dans le blog
    16
    Par défaut
    Bonjour Vincent,

    On peut s’orienter vers la généralisation ou la spécialisation.
    Par exemple, définir une classe d'entités qui soit une surclasse, que je nomme ici ENTITE (en attendant que quelqu’un trouve un terme plus pertinent).

    Vous me direz si cette approche vous convient.

    Comme l’explique très bien Paprick dans son ouvrage :

    Soit on procède à une généralisation des classes PRODUIT, GAMME, CATEGORIE, c’est-à-dire que ces classes conservent les propriétés qui leur son propres et elles héritent en plus de l’identifiant de la surclasse ENTITE, à des fins de factorisation des propriétés communes (nom, slug) ;  



    Soit on procède à la spécialisation de la surclasse en sous-classes, PRODUIT, GAMME, CATEGORIE ce qui revient à ne conserver que l’identifiant de la surclasse et évacuer les identifiants spécifiques des sous-classes.



    Génération par Looping du code dans le cas de la généralisation :

    CREATE TABLE LANGUE(
       LangueId INT,
       LangueNom VARCHAR(24) NOT NULL,
       CONSTRAINT LANGUE_PK PRIMARY KEY(LangueId)
    );
    
    CREATE TABLE ENTITE(
       EntiteId INT,
       EntiteNom VARCHAR(50) NOT NULL,
       EntiteSlug VARCHAR(50) NOT NULL,
       LangueId INT NOT NULL,
       CONSTRAINT ENTITE_PK PRIMARY KEY(EntiteId),
       CONSTRAINT ENTITE_AK UNIQUE(EntiteSlug),
       CONSTRAINT ENTITE_LANGUE_FK FOREIGN KEY(LangueId) REFERENCES LANGUE(LangueId)
    );
    
    CREATE TABLE GAMME(
       GammeId INT,
       GammeCode VARCHAR(8) NOT NULL,
       EntiteId INT NOT NULL,
       CONSTRAINT GAMME_PK PRIMARY KEY(GammeId),
       CONSTRAINT GAMME_AK UNIQUE(EntiteId),
       CONSTRAINT GAMME_1_AK UNIQUE(GammeCode),
       CONSTRAINT GAMME_ENTITE_FK FOREIGN KEY(EntiteId) REFERENCES ENTITE(EntiteId)
    );
    
    CREATE TABLE CATEGORIE(
       CategorieId INT,
       CategorieCode VARCHAR(8) NOT NULL,
       EntiteId INT NOT NULL,
       CONSTRAINT CATEGORIE_PK PRIMARY KEY(CategorieId),
       CONSTRAINT CATEGORIE_AK UNIQUE(EntiteId),
       CONSTRAINT CATEGORIE_1_AK UNIQUE(CategorieCode),
       CONSTRAINT CATEGORIE_ENTITE_FK FOREIGN KEY(EntiteId) REFERENCES ENTITE(EntiteId)
    );
    
    CREATE TABLE PRODUIT(
       ProduitId INT,
       ProduitCode VARCHAR(8) NOT NULL,
       EntiteId INT NOT NULL,
       CONSTRAINT PRODUIT_PK PRIMARY KEY(ProduitId),
       CONSTRAINT PRODUIT_AK UNIQUE(EntiteId),
       CONSTRAINT PRODUIT_1_AK UNIQUE(ProduitCode),
       CONSTRAINT PRODUIT_ENTITE_FK FOREIGN KEY(EntiteId) REFERENCES ENTITE(EntiteId)
    );
    Génération par Looping du code dans le cas de la spécialisation :

    CREATE TABLE LANGUE(
       LangueId INT,
       LangueNom VARCHAR(24) NOT NULL,
       CONSTRAINT LANGUE_PK PRIMARY KEY(LangueId)
    );
    
    CREATE TABLE ENTITE(
       EntiteId INT,
       EntiteNom VARCHAR(50) NOT NULL,
       EntiteSlug VARCHAR(50) NOT NULL,
       LangueId INT NOT NULL,
       CONSTRAINT ENTITE_PK PRIMARY KEY(EntiteId),
       CONSTRAINT ENTITE_AK UNIQUE(EntiteSlug),
       CONSTRAINT ENTITE_LANGUE_FK FOREIGN KEY(LangueId) REFERENCES LANGUE(LangueId)
    );
    
    CREATE TABLE GAMME(
       EntiteId INT,
       GammeCode VARCHAR(8) NOT NULL,
       CONSTRAINT GAMME_PK PRIMARY KEY(EntiteId),
       CONSTRAINT GAMME_AK UNIQUE(GammeCode),
       CONSTRAINT GAMME_ENTITE_FK FOREIGN KEY(EntiteId) REFERENCES ENTITE(EntiteId)
    );
    
    CREATE TABLE CATEGORIE(
       EntiteId INT,
       CategorieCode VARCHAR(8) NOT NULL,
       CONSTRAINT CATEGORIE_PK PRIMARY KEY(EntiteId),
       CONSTRAINT CATEGORIE_AK UNIQUE(CategorieCode),
       CONSTRAINT CATEGORIE_ENTITE_FK FOREIGN KEY(EntiteId) REFERENCES ENTITE(EntiteId)
    );
    
    CREATE TABLE PRODUIT(
       EntiteId INT,
       ProduitCode VARCHAR(8) NOT NULL,
       CONSTRAINT PRODUIT_PK PRIMARY KEY(EntiteId),
       CONSTRAINT PRODUIT_AK UNIQUE(ProduitCode),
       CONSTRAINT PRODUIT_ENTITE_FK FOREIGN KEY(EntiteId) REFERENCES ENTITE(EntiteId)
    ); 
    (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.

  4. #4
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    7 966
    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 : 7 966
    Points : 30 778
    Points
    30 778
    Billets dans le blog
    16
    Par défaut
    Selon le MCD que vous avez proposé, chaque ligne de la table SQL Nom générée fait obligatoirement référence à un produit, à une gamme et à une catégorie, ce qui n’est certes pas le but recherché

    En passant, vous ne votez plus ?
    (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.

  5. #5
    Membre régulier
    Homme Profil pro
    Webmaster
    Inscrit en
    Septembre 2016
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Webmaster
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2016
    Messages : 67
    Points : 90
    Points
    90
    Par défaut
    Bonjour François,

    Je n'avais pas pensé à l'héritage.

    J'ai quand même une petite interrogation.
    Imaginons que je veuille donner 2 noms différents (en français et en anglais, par exemple) à un même produit. Pour chaque nom, je créé donc une entrée avec un EntiteId dans la surclasse ENTITE, avec un EntiteNom et un EntiteSlug. Dans le cas de la généralisation, je me retrouve avec 2 produits différents avec 2 EntiteId différents dans la table PRODUIT donc 2 ProduitId mais portant le même ProduitCode (c'est à dire le même produit). Je doublonne aussi les champs supplémentaires. Si on inverse la vue, dans cette même table PRODUIT, un ProduitId ne pourra référencer qu'un seul nom de produit (EntiteNom) dans la table ENTITE, alors que je souhaite qu'un produit puisse porter plusieurs noms (donc qu'il puisse se référer à plusieurs EntiteId).

    J'ai l'impression qu'il y a un problème.
    Dans mes règles de conception :
    - Un produit peut porter plusieurs noms
    - Un produit peut porter un seul nom par langue

    Ai-je bien saisi vos modèles ou pas ?

    Pour mon deuxième modèle, je vais vérifier

    Vincent

  6. #6
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    7 966
    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 : 7 966
    Points : 30 778
    Points
    30 778
    Billets dans le blog
    16
    Par défaut
    Salve Vincent,

    J’aurais dû tester...

    En fait, il faut en revenir à votre 1er MCD du post #1, mais en remplaçant par 0,N les cardinalités 1,1 portées par les pattes des associations Porter :



    Je teste…

    Code sql : 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
    CREATE TABLE LANGUE
    (
       LangueId INT
     , LangueNom VARCHAR(24) NOT NULL
     , CONSTRAINT LANGUE_PK PRIMARY KEY(LangueId) 
    );
     
    INSERT INTO LANGUE VALUES
        (1, 'français'), (2, 'anglais') ;
     
    CREATE TABLE PRODUIT
    (
       ProduitId INT
     , ProduitCode VARCHAR(8) NOT NULL
     , CONSTRAINT PRODUIT_PK PRIMARY KEY(ProduitId)
     , CONSTRAINT PRODUIT_1_AK UNIQUE(ProduitCode)
    ) ;
     
    INSERT INTO PRODUIT VALUES
        (1, 'P001'), (2, 'P002'), (3, 'P003') ;
     
    CREATE TABLE CATEGORIE
    (
       CategorieId INT
     , CategorieCode VARCHAR(8) NOT NULL
     , CONSTRAINT CATEGORIE_PK PRIMARY KEY(CategorieId)
     , CONSTRAINT CATEGORIE_AK UNIQUE(CategorieCode) 
    );
     
    INSERT INTO CATEGORIE VALUES
        (1, 'C001'), (2, 'C002'), (3, 'C003') ;
     
    CREATE TABLE NOM
    (
       NomId INT,
       Nom VARCHAR(50) NOT NULL,
       Slug VARCHAR(50) NOT NULL,
       LangueId INT NOT NULL,
       CONSTRAINT NOM_PK PRIMARY KEY(NomId),
       CONSTRAINT NOM_AK UNIQUE(Slug),
       CONSTRAINT NOM_LANGUE_FK FOREIGN KEY(LangueId) REFERENCES LANGUE(LangueId)
    );
     
    INSERT INTO NOM VALUES
        (1, 'écrou', 'ecrou', 1), (2, 'nut', 'nut', 2)
      , (3, 'lourd', 'lourd', 1), (4, 'heavy', 'heavy', 2)

    Code sql : 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
    CREATE TABLE NOM_PRODUIT
    (
       NomId INT
     , ProduitId INT
     , CONSTRAINT NOM_PRODUIT_PK PRIMARY KEY(NomId, ProduitId)
     , CONSTRAINT NOM_PRODUIT_PRODUIT_FK FOREIGN KEY(ProduitId) REFERENCES PRODUIT (ProduitId)
     , CONSTRAINT NOM_ENTITE_ENTITE_FK FOREIGN KEY(NomId) REFERENCES NOM (NomId)
    );
     
    INSERT INTO NOM_PRODUIT VALUES
        (1, 1),  (2, 1) ;
     
    SELECT ProduitCode, LangueNom, Nom, Slug 
    FROM   PRODUIT AS p 
      JOIN NOM_PRODUIT AS n ON n.ProduitId = p.ProduitId
      JOIN NOM AS e ON n.NomId = e.NomId
      JOIN LANGUE AS l ON e.LangueId = l.LangueId ;
    Au résultat
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ProduitCode	LangueNom	Nom	Slug
    P001		français	écrou	ecrou
    P001		anglais		nut	nut
    Code sql : 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
    CREATE TABLE NOM_CATEGORIE
    (
       NomId INT
     , CategorieId INT
     , CONSTRAINT NOM_CATEGORIE_PK PRIMARY KEY(NomId, CategorieId)
     , CONSTRAINT NOM_CATEGORIE_CATEGORIE_FK FOREIGN KEY(CategorieId) REFERENCES CATEGORIE (CategorieId)
     , CONSTRAINT NOM_CATEGORIE_ENTITE_FK FOREIGN KEY(NomId) REFERENCES NOM (NomId)
    );
     
    INSERT INTO NOM_CATEGORIE VALUES
        (3, 1),  (4, 1) ;
     
    SELECT 'categorie_langue' as categorie_langue, CategorieCode, LangueNom, Nom, Slug 
    FROM   CATEGORIE AS c 
      JOIN NOM_CATEGORIE AS n ON n.CategorieId = c.CategorieId
      JOIN NOM AS e ON n.NomId = e.NomId
      JOIN LANGUE AS l ON e.LangueId = l.LangueId ;

    Au résultat
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    CategorieCode	LangueNom	Nom	Slug
    C001		français	lourd	lourd
    C001		anglais		heavy	heavy
    Les cracks de SQL ont sans doute une solution plus élégante, mais est-ce qu'on se rapproche de votre but ?
    (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.

  7. #7
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    7 966
    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 : 7 966
    Points : 30 778
    Points
    30 778
    Billets dans le blog
    16
    Par défaut
    Bonsoir Vincent,

    Où en êtes-vous dans votre réflexion ?

    Le MCD tient la route ?
    (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. #8
    Membre régulier
    Homme Profil pro
    Webmaster
    Inscrit en
    Septembre 2016
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Webmaster
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2016
    Messages : 67
    Points : 90
    Points
    90
    Par défaut
    Bonsoir François,

    Il tient bien la route (mais je n'en doutais pas). Je l'ai intégré, ainsi que vos conseils sur la modélisation de l'arbre hiérarchique, dans un post sur la modélisation d'un catalogue de produits.

    Vincent

Discussions similaires

  1. [CR7]Actualisation des données depuis VB
    Par elifqaoui dans le forum SDK
    Réponses: 4
    Dernier message: 24/11/2003, 14h44
  2. cherche module ou langage pour récupérer des données audio..
    Par Ry_Yo dans le forum Langages de programmation
    Réponses: 5
    Dernier message: 12/05/2003, 18h44
  3. Réponses: 13
    Dernier message: 20/03/2003, 09h11
  4. Structure des données en retour d'un DBExtract ?
    Par mikouts dans le forum XMLRAD
    Réponses: 4
    Dernier message: 24/01/2003, 16h15
  5. Réponses: 2
    Dernier message: 18/12/2002, 11h30

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