2010-01-12 7 views
12

Possible en double:
Schema for a multilanguage databaseLa conception d'une base de données Localisée schéma

Je travaille sur une application web que je prévois de mettre à la disposition en plusieurs langues. Lorsque je conçois la base de données, je fais deux va-et-vient entre deux façons différentes de stocker des descriptions localisées et d'autres choses dans la base de données.

La première option est le table_name bien connu, l'option de type table_name_ml:

TABLE Category (
    ID int, 
    ParentID int, 
    Name varchar(50), 
    Description varchar(255) 
) 

TABLE Category_ML (
    ID int, 
    CategoryID int, 
    LocaleID int, 
    Name varchar(50), 
    Description varchar(255) 
) 

La deuxième option serait de ne pas stocker le texte dans les tableaux de base à tous, mais à la place un jeton qui pourrait être utilisé pour rechercher le texte localisé réelle ailleurs, comme ceci:

TABLE Category (
    ID int, 
    ParentID int, 
    NameToken varchar(50), 
    DescriptionToken varchar(50), 
) 

// Tables in a separate content management type system 
TABLE Content (
    ID int, 
    Token varchar(50) 
) 

TABLE Translation (
    ID int 
    ContentID int, 
    LocaleID int, 
    Value text 
) 

l'idée est que les tables de contenu et traduction détiendraient le texte localisé pour de nombreuses entités différentes dans la base de données. La couche de service renverrait les objets de base avec seulement les jetons et la couche de vue rechercherait les valeurs de texte réelles en utilisant les tables Content/Translation - qui seraient fortement mises en cache. Les tables de contenu/traduction seraient également utilisées pour stocker d'autres contenus de type CMS (texte statique sur les pages web, etc.)

J'aime la première option parce que c'est essayé et vrai, mais la deuxième option semble avoir tant d'autres avantages:

  1. Tout mon texte/contenu localisé est en un seul endroit (facilite la traduction).
  2. La couche de service n'a pas vraiment besoin de se soucier des paramètres régionaux.
  3. Simplifie les requêtes en n'ayant pas à faire partie d'un groupe de tables de type ML.

Depuis que je ne l'ai jamais vu un dessin comme ça avant, je suppose que je dois manquer quelque chose. De bonnes raisons de ne pas le concevoir de cette façon? Ou peut-être y a-t-il une meilleure option à laquelle je n'ai pas pensé?

+1

Pourquoi avez-vous une table de contenu? Ne pourriez-vous pas utiliser votre jeton pour rechercher directement la traduction dans la table de traduction? –

+0

Non que je pense à cela, si les jetons ne contient que des informations comme . . pourquoi la catégorie de table aurait besoin de jeton-propriétés de toute façon ?? –

+0

@paskster - La table de contenu est là pour éviter de dupliquer la colonne de jeton dans la table de traduction. Il y aurait beaucoup de traductions pour un jeton donné. Cela vous permet également d'avoir RI entre la table Category et la table Content si vous le souhaitez. –

Répondre

3

Je vais d'abord dire que je n'ai pas traité de localisation avant donc c'est vraiment juste mon opinion et non basée sur l'expérience.

J'aime votre 2ème option. Dans la mesure où la DB va .. ses données et un moyen d'accéder/manipuler les données. Dans ce cas, toutes les données sont là et vous le lirez pour la plupart et vous aurez un bon moyen d'y accéder. Vous pouvez répondre au même problème dans les deux scénarios. Je préférerais la 2ème option moi-même car elle réduit les tables folles partout. Vous gardez une table dans le but précis de la traduction. Vous pouvez le réutiliser (pas créer plus de tables juste pour les mises à niveau plus tard) et maintenir l'intégrité. Vous pouvez même réutiliser des noms si cela a du sens quelque part. Comme si vous aviez 'Mantequilla' en tant que catégorie et en tant que favori ailleurs. J'aime mettre les données connexes dans un tableau lorsque cela est possible et ne pas avoir de données liées à la «traduction» à plusieurs endroits.

Le seul endroit où cela peut échouer est si vous avez plus que juste Nom et Description pour quelque chose qui a besoin de traduction. Peut-être que vous avez un nom, une description, un code, un mot magique, un surnom idiot, etc. Bien que vous puissiez contourner cela en ajoutant plus de NameTokens dans cette table pertinente et en réutilisant Name, mais c'est un peu un hack.

Assurez-vous simplement que le modèle répond à vos besoins tout le monde et qu'il devrait fonctionner correctement. Vous pouvez toujours ajouter une table de traduction spéciale si nécessaire plus tard pour une table spécifique. Cela ne serait pas différent de créer beaucoup de tableau, même si une solution hybride pourrait prêter à confusion. Il est préférable de trouver un moyen et essayer de s'y tenir.

+0

Avoir plus que le nom et la description ne devrait pas être un problème . Le champ de jeton est juste un morceau de texte libre. Par exemple, le "NameToken" pour une catégorie avec un ID de 1 peut être "DB.Category.1.Name". Si j'avais un champ appelé "MagicWord" sur cette table, le jeton pour cela pourrait être "DB.Category.1.MagicWord". Donc, généralement, les jetons seraient nommés comme 'DB. . . '. J'espère que cela a du sens. –

+0

ok bien alors il semble que vous avez tous les cas je peux penser à planifié :) semble être un bon modèle pour moi. –

-1

Il y a une option supplémentaire et je pense que je parierai sur ceci!

  • Séparer la base de données totalement!

RAISONS (SIRP):

  • Pyhsically Seperated base de données localisée
  • échafaudage (Generated Couches de présentation)
  • facile Orm

CONS:

  • Vous devez résoudre le problème UniqueId (réplication)
  • Vous devez synchroniser le schéma et la non-localisation des données
+0

Vos "pros" sont des faits, pas des avantages. Les "cons" sont assez lourds contre les petits "pros". – SandRock

+0

Serhat n'a pas mentionné le Pro de mise à mort: pour une grande base de données, il est optimisé par rapport aux recherches d'informations de langues obligatoires - il est déjà séparé de la langue. Mais c'est bon pour les grands dbs seulement. – aiho

Questions connexes