web-dev-qa-db-fra.com

Modélisation de bases de données à des fins internationales et multilingues

J'ai besoin de créer un modèle de base de données à grande échelle pour une application Web qui sera multilingue.

Un doute que j'ai à chaque fois que je pense à la façon de le faire est de savoir comment résoudre plusieurs traductions pour un champ. Un exemple de cas.

Le tableau des niveaux de langue, que les administrateurs peuvent éditer depuis le backend, peut avoir plusieurs éléments comme: basique, avancé, courant, mattern ... Dans un avenir proche, ce sera probablement un type de plus. L'administrateur va au backend et ajoute un nouveau niveau, il le triera dans la bonne position .. mais comment je gère toutes les traductions pour les utilisateurs finaux?

Un autre problème avec l'internationalisation d'une base de données est que, probablement, pour les études d'utilisateurs, les États-Unis, le Royaume-Uni et le DE peuvent différer ... dans chaque pays, ils auront leur niveau (que ce sera probablement équivalent à un autre mais finalement différent). Et la facturation?

Comment modélisez-vous cela à grande échelle?

38
udexter

Voici la façon dont je conçois la base de données:

Data model

Visualisation par DB Designer Fork

La table i18n Contient uniquement un PK, de sorte que toute table n'a qu'à référencer ce PK pour internationaliser un champ. La table translation est alors en charge de lier cet ID générique à la bonne liste de traductions.

locale.id_locale Est une VARCHAR(5) pour gérer à la fois en et en_USsyntaxes ISO .

currency.id_currency Est une CHAR(3) pour gérer syntaxe ISO 4217 .

Vous pouvez trouver deux exemples: page et newsletter. Ces deux entités gérées par l'administrateur doivent internationaliser leurs champs, respectivement title/description Et subject/content.

Voici un exemple de requête:

select
  t_subject.tx_translation as subject,
  t_content.tx_translation as content

from newsletter n

-- join for subject
inner join translation t_subject
  on t_subject.id_i18n = n.i18n_subject

-- join for content
inner join translation t_content
  on t_content.id_i18n = n.i18n_content

inner join locale l

  -- condition for subject
  on l.id_locale = t_subject.id_locale

  -- condition for content
  and l.id_locale = t_content.id_locale

-- locale condition
where l.id_locale = 'en_GB'

  -- other conditions
  and n.id_newsletter = 1

Notez qu'il s'agit d'un modèle de données normalisé. Si vous avez un énorme ensemble de données, vous pourriez peut-être penser à le dénormaliser pour optimiser vos requêtes. Vous pouvez également jouer avec des index pour améliorer les performances des requêtes (dans certaines bases de données, les clés étrangères sont automatiquement indexées, par exemple MySQL/InnoDB ).

58
sp00m

Quelques questions précédentes de StackOverflow sur ce sujet:

Quelques ressources externes utiles:

La meilleure approche consiste souvent, pour chaque tableau existant, à créer un nouveau tableau dans lequel les éléments de texte sont déplacés; le PK de la nouvelle table est le PK de l'ancienne table avec la langue.

Dans ton cas:

  1. Le tableau des niveaux de langue, que les administrateurs peuvent éditer depuis le backend, peut avoir plusieurs éléments comme: basique, avancé, courant, mattern ... Dans un avenir proche, ce sera probablement un type de plus. L'administrateur va au backend et ajoute un nouveau niveau, il le triera dans la bonne position .. mais comment je gère toutes les traductions pour les utilisateurs finaux?

    Votre table existante ressemble probablement à ceci:

     + ---- + ------- + --------- + 
     | id | prix | tapez | 
     + ---- + ------- + --------- + 
     | 1 | 299 | de base | 
     | 2 | 299 | avance | 
     | 3 | 399 | courant | 
     | 4 | 0 | mattern | 
     + ---- + ------- + --------- + 
    

    Il devient alors deux tables:

     + ---- + ------- + + ---- + ------ + ------------- + 
     | id | prix | | id | lang | tapez | 
     + ---- + ------- + + ---- + ------ + ------------- + 
     | 1 | 299 | | 1 | en | de base | 
     | 2 | 299 | | 2 | en | avance | 
     | 3 | 399 | | 3 | en | courant | 
     | 4 | 0 | | 4 | en | mattern | 
     + ---- + ------- + | 1 | fr | élémentaire | 
     | 2 | fr | avance | 
     | 3 | fr | 
    :::: 
     + ---- + ------ + ------------- + 
    
  2. Un autre problème avec l'internationalisation d'une base de données est que, probablement, pour les études d'utilisateurs, les États-Unis, le Royaume-Uni et le DE peuvent différer ... dans chaque pays, ils auront leurs niveaux (que ce sera probablement équivalent à un autre mais finalement différent). Et la facturation?

    Toute localisation peut se faire par une approche similaire. Au lieu de simplement déplacer des champs de texte vers la nouvelle table, vous pouvez déplacer tous les champs localisables - seuls ceux qui sont communs à tous les paramètres régionaux resteront dans la table d'origine.

33
eggyal