views:

1943

answers:

7

What is the best way to create multilanguage database? To create localized table for every table is making design and querying complex, in other case to add column for each language is simple but not dynamic, please help me to understand what is the best choose for enterprise applications
Thanks a lot!

A: 

Use a collation that should be capable of handling the languages you expect.... like utf-8

for mysql this would be utf8_general_ci though it might depend on you particular dbms

Jonathan Fingland
I mean to store different languages for localizing hole application
ArsenMkrt
A: 

It may depend on what you're specifically trying to accomplish, but if your database is in unicode it shouldn't matter what languages you're putting into it.

Then you handle the localization in your controller and view layers...

Gabriel Hurley
So the controller and view layers will translate a Japanese product description into German? The unicode is useful for storing Japanese but it is not a solution or answer
gbn
Well... with any of a variety of translation services it *could*... but no, that's not ideal.I would use a 2-table solution similar to Martin's above so you've got a one-to-many relationship between the product and its translations.
Gabriel Hurley
+12  A: 

What we do, is to create two tables for each multilingual object.

E.g. the first table contains only language-neutral data (primary key, etc.) and the second table contains one record per language, containing the localized data plus the ISO code of the language.

In some cases we add a DefaultLanguage field, so that we can fall-back to that language if no localized data is available for a specified language.

Example:

Table "Product":
----------------
ID                 : int
<any other langauge-neutral fields>


Table "ProductTranslations"
---------------------------
ID                 : int      (foreign key referencing the Product)
Language           : varchar  (e.g. "en-US", "de-CH")
IsDefault          : bit
ProductDescription : nvarchar
<any other localized data>

With this approach, you can handle as many languages as needed (without having to add additional fields for each new language).

M4N
Yes, no need for multiple columns: key by language. Although here is would be useful to have ProductDescription as nvarchar, I suspect.
gbn
yes of course! fixed.
M4N
Please add more details in creating business objects in this case, creating separate businees object will be suitable for CMS, but creating one localized business object for other cases
ArsenMkrt
what if the only language-neutral field is the id? and how exactly do you insert the foreign key reference when inserting a row?
YuriKolovsky
+2  A: 

I find this type of approach works for me:

Product     ProductDetail        Country
=========   ==================   =========
ProductId   ProductDetailId      CountryId
- etc -     ProductId            CountryName
            CountryId            Language
            ProductName          - etc -
            ProductDescription
            - etc -

The ProductDetail table holds all the translations (for product name, description etc..) in the languages you want to support. Depending on your app's requirements, you may wish to break the Country table down to use regional languages too.

Nick
+2  A: 

I'm using next approach:

Product

ProductID OrderID,...

ProductInfo

ProductID Title Name LanguageID

Language

LanguageID Name Culture,....

omoto
+3  A: 

I recommend the answer posted by Martin.

But you seem to be concerned about your queries getting too complex:

To create localized table for every table is making design and querying complex...

So you might be thinking, that instead of writing simple queries like this:

SELECT price, name, description FROM Products WHERE price < 100

...you would need to start writing queries like that:

SELECT
  p.price, pt.name, pt.description
FROM
  Products p JOIN ProductTranslations pt
  ON (p.id = pt.id AND pt.lang = "en")
WHERE
  price < 100

Not a very pretty perspective.

But instead of doing it manually you should develop your own database access class, that pre-parses the SQL that contains your special localization markup and converts it to the actual SQL you will need to send to the database.

Using that system might look something like this:

db.setLocale("en");
db.query("SELECT p.price, _(p.name), _(p.description)
          FROM _(Products p) WHERE price < 100");

And I'm sure you can do even better that that.

The key is to have your tables and fields named in uniform way.

Rene Saarsoo
the other question is, to create one business object for product? or to create two... in first case it's easy to work with that item, in 2 nd easy to write CMS
ArsenMkrt
A: 

Martin's solution is very similar to mine, however how would you handle a default descriptions when the desired translation isn't found ?

Would that require an IFNULL() and another SELECT statement for each field ?

The default translation would be stored in the same table, where a flag like "isDefault" indicates wether that description is the default description in case none has been found for the current language.

doM