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 :

Gestion du multilangue dans une base de données


Sujet :

Schéma

  1. #1
    Expert éminent
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Points : 7 752
    Points
    7 752
    Par défaut Gestion du multilangue dans une base de données
    Bonjour,

    Je me penche sur un problème, bientôt, je serai amené à réaliser un schéma pour une base de données SQL. le Sgbd exact n'est pas encore déterminé pour l'instant. Tout ce que je peux dire c'est qu'il ne s'agira pas d'un poids lourd (pas SQL server, DB2 ou oracle donc).

    L'application demandée est une gestion de vente/expédition de produits assez banales sur le fond. J'ai déjà une certaine expérience sur la façon de modéliser cela. La difficulté pour moi est qu'il est demandé à l'application de supporter plusieurs langues simultanément.
    Les entreprises visées ont des bureaux en France et parfois à l'étranger, et chaque utilisateur de l'entreprise doit pouvoir travailler dans sa langue, voir les noms de produits du catalogue sans sa langue, les catégories dans sa langue etc... Dans l'absolu, chaque poste d'application peut sélectionner une langue différente.

    Traduire les menus de l'application n'est pas un problème, ce sont plutôt les entités de la bases de données qui font souci à cause des contraintes suivantes, pour se cantonner à la problématique des produits :

    - Les libellés et descriptions des PRODUITS doivent pouvoir être traduits dans plusieurs langue.
    - Idem pour toutes les entités liées aux PRODUITS, les noms de CATEGORIES de produits, les noms de MATIERES, les noms des CLASSIFICATIONS, bref...
    - L'application possède une langue par défaut, puis N langue(s) additionnelles, nous pensons avec un haut degré de certitude que ce seront 4 langues au maximum qui seront utilisées (donc peut être 2, peut être 3, peut-être une seule suivant les entreprises).
    - Lorsque les traductions n'ont pas été saisies, c'est le texte de la langue par défaut qui est utilisé.


    Je pense à l'approche suivante :

    Une table des langues et une table des libellés par entité :


    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
    Table LANGUES
    
    Code langue | Nom
    -------------- ------ 
    FR           | Français
    DE           | Deutsch
    EN           | English
    
    
    
    Table PRODUITS
    
    No produit  | prix    | ....
    -------------------------
    001           | 5.40
    002           | 7.80
    
    Table NOMS_PRODUIT
    
    No Produit | code langue | Nom
    -----------------------------------------
    001          | FR           | Casque audio
    001          | EN           | Headphone
    L'avantage de cette approche est qu'elle me semble plutôt juste et extensible.

    Au niveau des inconvénients, j'en vois plusieurs :

    1) Une liste affichant le produit, sa catégorie, sa marque impliquerait vite beaucoup de tables et de nombreuses jointures.

    2) Pire encore, si on prend mon exemple ci-dessus le produit 001 n'a pas de nom en allemand, donc je dois écrire le libellé français "casque audio", FR étant la langue par défaut. Cela nécessite du LEFT JOIN à outrance ou la récupération des libellés dans une 2e requête SELECT (aïe le N+1).

    3) Il est difficile de sortir un dataset du type

    "No_produit", "nom_FR", "nom_DE", "nom_EN", "prix"

    Très utile pour la fabrication de rapports d'impression, car celui-ci nécessite un gros SELECT puis ensuite le "pivotage" les lignes en colonnes en éliminant soigneusement les doublons.




    En gros, parmi les solutions possibles :
    J'envisage, pour chaque produit, de générer automatiquement les noms manquants en utilisant la langue de référence, ainsi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    No Produit | code langue | Nom
    -----------------------------------------
    001          | FR           | Casque audio
    001          | EN           | Headphone
    001          | DE           | Casque audio (créé automatiquement)
    Cela semble contraire aux bonnes pratiques, crée de la redondance, mais me permet d'utiliser des INNER JOIN dans mes selects plutôt que de traiter systématiquement la non-existence d'une langue. Bref c'est un sacrifice qui me semble intéressant de par la simplification qu'il apporte à mes requêtes d'extraction.

    Reste le point 3 qui me pose vraiment problème... J'en suis presque arriver à penser à mettre 4 colonnes "noms" directement dans le produit (sachant que nous ne géreront que 4 langues au maximum) et laisser l'application décider quelle langue afficher mais c'est déplacer le problème dans l'application en l'obligeant à toujours "choisir" quelle colonne prendre en compte. En revanche ça a l'avantage d'être pratique pour les listes et le reporting...

    Bref, si quelqu'un a une expérience à partager avec moi sur ce genre de problème, ou des suggestions, n'hésitez pas.

  2. #2
    Expert confirmé Avatar de Richard_35
    Homme Profil pro
    Inscrit en
    Juillet 2007
    Messages
    3 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 3 121
    Points : 4 596
    Points
    4 596
    Par défaut
    Bonjour _skip,

    Intéressante problématique.

    Citation Envoyé par _skip
    .../... J'en suis presque arriver à penser à mettre 4 colonnes "noms" directement dans le produit .../...
    ==> fortement déconseillé : le jour où tu ajoutes une langue, il faut ajouter un champ dans l'ensemble des entités concernées...

    La solution que tu évoques dans ton exemple me paraît plus judicieuse.

    Suggestion :

    LANGUES
    - Id_Langue (PK)
    - Libelle
    ...
    PARAMETRE
    - Id_Pour_La_Forme (PK)
    - Langue_par_defaut
    ==> 1 seul enregistrement, à renseigner lors de la livraison du soft.
    PRODUITS
    - Id_Produit (PK)
    - Libelle (vide : sert à faire la liaison par le nom du champ)
    ...
    TRADUCTIONS
    - Nom_Entite (nom de la table/formulaire/état)
    - Id_Element (clé de l'élément à traduire, 0 pour objet de développement)
    - Nom_Objet_A_Traduire (nom du champ, du libellé écran)
    - Id_Langue
    - Texte_traduit
    ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    PRODUITS       1   Libelle    1   Casque audio
    PRODUITS       1   Libelle    2   Headphone
    PRODUITS       1   Libelle    3   Allemand(Casque audio)
    Form_Produits  0   Nom_Prod   1   Nom du produit
    Form_Produits  0   Nom_Prod   2   Product name
    A noter que, dans les langages de développement, on arrive à trouver, dynamiquement, par exemple, le nom du formulaire de saisie sur lequel on se trouve et le nom des champs de saisie le composant.

    Tu vois l'idée, je pense.
    Dis-nous et à bientôt,
    Richard.
    ----------------------------------------------------------------------------------------------
    En cas de résolution, et afin de faciliter la tâche des bénévoles, merci de cliquer sur .
    et permettent aux forumeurs de cibler leur recherche dans une discussion : n'hésitez pas à voter !

  3. #3
    Expert éminent
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Points : 7 752
    Points
    7 752
    Par défaut
    Merci beaucoup Richard,

    Pour la partie applicative, j'ai été un peu imprécis, les langues supportées dans l'application sont fixées, donc je peux les gérer à l'aide de ressources. J'ai déjà une solution qui avale un fichier excel contenant les traductions (faites par des non développeurs) et génère des resources bundle ainsi que des classes d'accès.

    Mon souci c'est vraiment les données produites. Ce que tu suggères c'est donc un peu ce que je pensais faire à cette différence que tu regrouperais les chaînes traduites dans une seule table avec un indicateur de quelle type d'entité c'est, quel champ ainsi que quelle langue.

    Ca me donne un truc genre

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT prod.id_produit, 
    tlib.texte AS libelle, 
    tdec.texte AS description
    FROM PRODUITS AS prod
    INNER JOIN  TRADUCTIONS AS tlib ON (tlib.id_Element = prod.id_produit AND tlib.typeEntite = 'PRODUITS' AND tlib.id_langue = @id_langue AND nom_object = 'libelle')
    INNER JOIN  TRADUCTIONS AS tdesc on (tdesc .id_Element = prod.id_produit AND tdesc .typeEntite = 'PRODUITS' AND tdesc.id_langue = @id_langue AND nom_object = 'description' )


    Pas si trivial donc... L'une des solutions que j'explore et qui pourrait simplifier ceci est d'utiliser une VIEW comme modèle externe ou toutes ces jointures seraient déjà faites. Mon problème c'est que je ne sais pas à quel point ce sera digeste ou non en terme de performance avec toutes ces conditions.

    Et aussi, toutes les primary keys des différentes entités doivent être de même type et les contraintes de clés étrangères ne sont pas applicables.
    Je me tâte, entre polluer le modèle de 15 tables supplémentaires (1 par entité) ou alors regrouper le tout dans une seule comme tu le proposes...

  4. #4
    Expert confirmé Avatar de Richard_35
    Homme Profil pro
    Inscrit en
    Juillet 2007
    Messages
    3 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 3 121
    Points : 4 596
    Points
    4 596
    Par défaut
    Citation Envoyé par _skip
    Je me tâte, entre polluer le modèle de 15 tables supplémentaires (1 par entité) .../...
    ==> excuses-moi, je n'ai pas très bien compris.

    En tout cas, si l'idée est :
    PRODUITS
    - Id_Produit (PK)
    - Libelle_FR
    - Libelle_EN
    - Libelle_DE
    ...
    ==> alors, sincèrement, c'est une mauvaise idée :
    - si tu ajoutes une langue (on ne sait jamais), il faut, dans toutes les tables, ajouter autant de champs que de champs déjà traduits... pas simple ;
    - si tu ajoutes un champ dans une table (on ne sait jamais), il faut ajouter autant de champs que de langues disponibles... pas simple.

    Idem, si l'idée est de créer autant de tables que de champs à traduire :
    - si tu ajoutes une langue (on ne sait jamais), il faut, dans toutes les tables, ajouter une langue... pas simple ;
    - si tu ajoutes un champ dans une table (on ne sait jamais), il faut créer une table supplémentaire... pas simple.

    Dans ces 2 cas, je ne te parle même pas des impacts sur les développements existants...

    Mais, effectivement, l'accès à la table :
    TRADUCTIONS
    - Nom_Entite (PK) (nom de la table/formulaire/état)
    - Id_Element (PK) (clé de l'élément à traduire, 0 pour objet de développement)
    - Nom_Objet_A_Traduire (PK) (nom du champ, du libellé écran)
    - Id_Langue (PK)
    - Texte_traduit
    ...
    doit faire l'objet d'une attention particulière quant aux performances d'accès : il faut créer des index et des vues judicieux.

    Par exemple, tu peux scinder en deux les enregistrements concernant les champs de table et ceux concernant les éléments de développement via Id_Element<>0 ou =0, et coupler cela avec l'index qui va bien. Donc, ajouter un index IDX :
    TRADUCTIONS
    - Nom_Entite (IDX)
    - Id_Element ==> ignoré dans l'index
    - Nom_Objet_A_Traduire (IDX)
    - Id_Langue (IDX)
    - Texte_traduit
    ...
    et créer 2 vues : une ne prenant que Id_Element<>0, l'autre que Id_Element=0.

    Tester, ensuite, sur des tables de test.
    Dis-nous et à bientôt,
    Richard.
    ----------------------------------------------------------------------------------------------
    En cas de résolution, et afin de faciliter la tâche des bénévoles, merci de cliquer sur .
    et permettent aux forumeurs de cibler leur recherche dans une discussion : n'hésitez pas à voter !

  5. #5
    Expert éminent
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Points : 7 752
    Points
    7 752
    Par défaut
    Merci,

    Non l'idée de mettre 4 colonnes dans chaque table c'est abandonné. C'est un élément de réflexion que j'ai assez vite écarté car, même si le nombre maximum de langues est défini, il posera des soucis récurrents de logique applicative.

    Ma réflexion à présent c'est de dire une table ou plusieurs tables pour la traduction... Si je résume :

    1) Une table

    Avantages :
    - Ajout d'une langue plus aisé (bon on le fait pas tous les jours hein..)
    - Modèle moins "bloated"
    - Ajout de nouveaux champs plus aisés
    - modifications plus aisées

    Inconvénients :
    - Jointures plus complexes et (potentiellement?) moins performantes
    - Pas de contrainte de clef étrangère
    - Obligation de n'utiliser que des clefs primaires d'un même type pour les entités/tables contenant des textes traduits.

    2) Plusieurs tables

    Avantages :
    - Contraintes FK
    - Liberté dans le choix du type des clefs
    - Jointures straightforward

    Inconvénients
    - Plus de tables sont nécessaires (ça en fera une 15aine selon estimation)
    - Ajout d'une langue nécessite duplication dans 15 table (a nouveau c'est pas un truc qu'on fait tous les matins)
    - Ajouts de nouveaux champs plus délicats

    Je dois encore réfléchir...

  6. #6
    Expert confirmé Avatar de Richard_35
    Homme Profil pro
    Inscrit en
    Juillet 2007
    Messages
    3 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 3 121
    Points : 4 596
    Points
    4 596
    Par défaut
    Bonjour _skip,

    Bonne réflexion, donc.

    Mais, souviens-toi que, en maintenance, nous passons 70% de notre temps à intervenir sur des cas qui ont 5% de chance de se produire (ou approchant).

    D'autre part, tu as analysé que l'ajout d'une langue sera très rare : OK.

    Mais, dans la vie d'une application, il arrive très souvent d'avoir besoin d'ajouter un champ dans une table (un libellé, un flag,...), voire d'ajouter une table (relation passant de (1,1) à (1,n), nouvelle table de paramétrage, etc...). Surtout pour une nouvelle application.
    Dis-nous et à bientôt,
    Richard.
    ----------------------------------------------------------------------------------------------
    En cas de résolution, et afin de faciliter la tâche des bénévoles, merci de cliquer sur .
    et permettent aux forumeurs de cibler leur recherche dans une discussion : n'hésitez pas à voter !

Discussions similaires

  1. Réponses: 14
    Dernier message: 01/04/2015, 01h03
  2. [AC-2010] Gestion de liens hypertexts dans une Base de données Access
    Par ouzal dans le forum Access
    Réponses: 7
    Dernier message: 20/01/2012, 11h45
  3. [Recherche] script gestion de mails dans une base de données
    Par emilie13 dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 2
    Dernier message: 20/06/2007, 15h59
  4. [Conception] Gestion des accents dans une base de données
    Par MiJack dans le forum PHP & Base de données
    Réponses: 7
    Dernier message: 07/07/2005, 11h41
  5. [Strategie][Java][XML] Import dans une base de données
    Par nad dans le forum XML/XSL et SOAP
    Réponses: 2
    Dernier message: 23/09/2002, 11h12

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