適切な多言語スキーマ、またはやりすぎですか?


8

UPDATE 2:私は実際にこれを使用してしまいましたが、2、3の調整後は素晴らしいです。実際のデザインと実際の動作に関する私の投稿は次のとおりです。http//tim.hithlonde.com/2013/lemon-schema-works/

私はWebアプリを作成していますが、複数の言語をサポートしたいと考えています。この構造には2つのコンポーネントがあります。

  1. ロケール( 'english'、 'Deutch'など)と用語を関連付け、ロゼッタストーンの接続用語と特定の言語の用語を使用します。
  2. ページごとに用語をグループ化します。私は言いたくない、私がページで必要とするかもしれない30以上の用語を通して、term1、term2などを選択します。彼らが接続しているページで尋ねたいのですが。

これが私の提案するテーブル構造です(すべてのIDには非常に効率的なクエリを作成するために、ID間に関係/インデックスがあることに注意してください)。

スキーマ図

  * locale
      * id
      * value //English, Deutch, etc//
  * terms
    * id
    * value //In English//
  * page 
    * id
    * value //Think add entry, menu//
  * page_group //group all terms to a page, for easy pulling//
    * id
    * page.id
    * term.id
  * rosetta
    * id
    * locale.id
    * term.id
    * value //french word for amount, description, etc//

これにより、次のようなクエリが可能になります。

SELECT localization.value,
        terms.value
FROM localization
INNER JOIN terms ON terms.id=localization.termid
INNER JOIN page_group ON page_group.termid=localization.termid
INNER JOIN page ON page.id=page_group.pageid
INNER JOIN locale ON locale.id=localization.localeid
WHERE page.value='add_entry' AND locale.id=custlangid
ORDER BY terms.id

2つのアイテムを要求するだけで済みます。必要な言語IDと必要なページ。指定した言語で、そのページの用語グループの一部であるすべての用語を提供します。

これは本当に良い構造だと思いますが、フィードバックが欲しいです。

更新:明確にするために、UIコンポーネントのローカライズについて話しているだけです。(ラベル、ナビゲーション、役立つテキスト)ユーザーが入力するすべての情報は、このスキーマではなくUnicodeで保存されます。

アップデート2:私は実際にこれを使用してしまいました、そしてそれは素晴らしいです。実際のデザインと実際の動作に関する私の投稿は次のとおりです。http//tim.hithlonde.com/2013/lemon-schema-works/


1
通常(私が見たものから)、ローカリゼーションはWeb側のテンプレートを介して行われます。データベース側からローカライズしたいものは何ですか?
フィロ

すべてのラベル、ナビゲーションメニュー、および役立つテキスト(警告など)をローカライズしたいのですが、これをdbから取得する理由は、テンプレートにそのロジックを含めたくないためです。私のテンプレートで<?php echo $term['term_in_english'];?>は、しっかりとしたMVCアプローチを目指して努力したいと思います。
Tim Habersack 2012

回答:


6

これは多くのことを行っており、(管理)ユーザーは翻訳をライブで修正することが許可されていました。(まだキャッシュレイヤーが必要な場合がありますが、リソースファイルではなく実際のデータベースでこれを実行することに完全に夢中です-これにより、翻訳する必要のあるものをクエリして見つけるなどの膨大な能力が得られます)。あなたのスキーマはおそらく大丈夫だと思うので、役立つことを期待して学んだことをいくつか伝えます。

除外したのは、挿入ポイントのあるフレーズです。以下の例では、順序が逆で言語はまだ英語ですが、これは非常に簡単に2つの異なる言語になる可能性があります。これは通常、物事を異なる順序で並べている2つの言語だけであると仮定します。

Hello, <username> you have <x> points!

You've got <x> points to spend, <username>!

以前の.NETでは、挿入を行うルーチンがあったため、フレーズは次のようになります。

Hello, {0:username} you have {1:points} points!

You've got {1:points} points to spend, {0:username}!

これは明らかにあなたのコードで単に<%= String.Format(phrase, username, points); %>または同様に使用されます

これは翻訳者を少し助けました。ただし、.NET String.FOrmatは、残念ながらフォーマット文字列内のコメントをサポートしていません。

あなたが言うように、あなたはあなたのphpでロケール認識やメタフレーズでそれを処理したくないでしょう。

つまり、マスターフレーズテーブルでした。

フレーズID、英語、補足情報

とローカライズされたテーブル:

フレーズID、ロケールID、翻訳

また、INNER JOINSではローカライズされたバージョンが存在すると想定していました。翻訳されるまで除外する傾向があったため、最初のクエリでは何も返されなくなりました(デフォルトではありません)。

翻訳が存在しなかった場合、デフォルトは英語になり、次にコード提供にフォールバックしました(データベースにIDがなかった場合、およびコードからどのフレーズ識別子「TXT_LNG_WRNNG_INV_LOW」が実際に取得しようとしているかも明らかでした) )-したがって、このクエリに相当するものは、私たちが使用したものです:

SELECT COALESCE(localized.translation, phrase.english, @fallback)
FROM DUAL
LEFT JOIN phrase
    ON phrase.phraseid = @phraseid
LEFT JOIN localized
    ON localized.phraseid = phrase.phraseid
    AND localized.localeid = @localeid

明らかに、あなたはあなたのページシステムを使用して一度にすべてのものを得るかもしれません。

それらはページ間で(ページフラグメントやコントロールだけでなく)多く再利用されたため、ページにリンクしない傾向がありましたが、それは確かに問題ありません。

Windowsネイティブアプリの場合、リフレクションとコントロールファイルから変換タグへのマッピングファイルを使用したため、翻訳を再コンパイルする必要がありませんでした(.NET以前のアプリでは、タグやその他の特別なタグを使用してコントロールにタグを付ける必要がありましたプロパティ)。これはおそらくPHPまたはASP.NET MVCでは少し問題になりますが、本格的なサーバー側ページモデルがあるASP.NETでは可能です。

テストでは、明らかにクエリを実行して、欠落している翻訳を非常に簡単に見つけることができます。タグ付けが必要な場所を見つけるには、豚のラテン語またはクリンゴン語を使用して句の辞書全体を翻訳するか、スペース以外のすべての文字を?-英語が目立ち、裸の平文がHTMLに忍び込んだことを通知します。


これありがとう!挿入ポイントについては考えていませんでした。私のアプリには実際にあるとは思いませんが、覚えておくと良いでしょう。また、スキーマに関するコメントをありがとう。私はしばらくの間DB設計を行ってきましたが、ノートを比較するための適切なピアのセットがなければ、正しい方向に進んでいるかどうかが時々わかりません。:)
Tim Habersack 2012

0

通常、翻訳は外部の専門会社によって行われます。そのため、データベース内で翻訳されたコンテンツを管理するのは面倒です。それらは、プラットフォームが提供するある種の言語機能を介して、「バンドル」またはプロパティファイルで管理した方がよいでしょう。これを実現するには、データベースに文字列のニーモニックを配置するだけです。次に、目的の言語に基づいて、バンドルを検索します。例えば。

Data:
Employee_Status = empl_status.active

language Bundles:
Employee.us:  
  empl_status.active=Active

Employee.es
  empl_status.active=<spanish translation goes here>

To get the localized content:
    String status = getLocalizedContent("Employee","empl_status.active", "us");
    String status = getLocalizedContent("Employee","empl_status.active", "es");
    String status = getLocalizedContent("Employee","empl_status.active");

私たちは同じことについて話しているので、私は混乱しています。私はあなたと同等のものを構築しますgetLocalizedContent。コントローラーレベルを除いて、ページに関連付けられているすべての用語と必要な言語を要求します。この関数は、上で説明したクエリを呼び出し、いくつかの魔法をかけて、連想配列を取得します。ニーモニックになり、値が用語になります。UI用語の数は少ない(<100)ので、DBでの管理に問題があるとは思えません。翻訳された用語を入力したり、ページをバンドルしたりするためのシンプルなインターフェースを構築するでしょう。
Tim Habersack 2012

0

3つのテーブルを作成するだけ

1.)言語マスター(LangId、LangName)

2.)リソースマスター(ResourceMasterId、TableId、ColumnId、ColumnName)

3.)リソースの詳細(ResourceMasterId、LangId、Value)

リソース詳細の複合キー(ResourceMasterId、LangId)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.