5

更新:私は数年後に私がしたこの質問に出くわしました:今私はこれが非常に悪いアプローチであることを知っています。これは使用しないでください。i18nにはいつでも追加のテーブル(たとえばproductsproducts_lang)を使用でき、ロケールごとに個別のエントリがあります。インデックスに適している、検索に適しているなどです。


MySQL/PHPサイトにi18nを実装しようとしています。

「i18nは通常データベースの一部ではない」という回答を読んだことがありますが、これはやや偏狭なアプローチだと思います。名前の付いた製品、または私の例のように、データベースに格納されているメニュー構造とコンテンツはどうですか?

言語は拡張可能でなければならないことを考慮して、私のアプローチについてどう思いますか。そのため、「言語ソリューションごとに1つの列」を避けようとしています。

1つの解決策は、翻訳する文字列に参照(id)を使用し、翻訳可能なすべての列に、主キー、文字列ID、言語ID、および翻訳を含むテーブルを用意することです。

私が考えたもう1つの解決策は、JSONを使用することでした。したがって、私のデータベースのメニューエントリは次のようになります。

idmenu label
------ -------------------------------------------
5      {"en":"Homepage", "it":"pagina principale"}

このアプローチについてどう思いますか?

4

4 に答える 4

3

「1つの解決策は、翻訳する文字列に参照(id)を使用し、翻訳可能なすべての列に、主キー、文字列ID、言語ID、および翻訳を含むテーブルを用意することです。」

私は一度それを実装しました、私がしたことは、既存のデータベーススキーマを取り、翻訳可能なテキスト列を持つすべてのテーブルを探し、そのようなテーブルごとに、それらのテキスト列と、結び付ける追加の言語IDとIDのみを含む個別のテーブルを作成しました元のテーブルの「データ」行に移動します。だから私が持っていた場合:

create table product (
  id          int          not null primary key
, sku         varchar(12)  not null
, price       decimal(8,2) not null
, name        varchar(64)  not null
, description text          
)

私は作成します:

create table product_text (
  product_id  int          not null
, language_id int          not null
, name        varchar(64)  not null
, description text
, primary key (product_id, language_id)
, foreign key (product_id) references product(id)
, foreign key (language_id) references language(id)
)

そして、私はそのように質問したいと思います:

SELECT    product.id
,         COALESCE(product_text.name, product.name) name
,         COALESCE(product_text.description, product.description) description
FROM      product
LEFT JOIN product_text
ON        product.id = product_text.product_id 
AND       10         = product_text.language_id

(10はたまたまあなたが今興味を持っている言語IDです。)

ご覧のとおり、元のテーブルにはテキスト列が保持されています。現在の言語で翻訳が利用できない場合、これらはデフォルトとして機能します。

したがって、テキスト列ごとに個別のテーブルを作成する必要はありません。すべてのテキスト列に対して1つのテーブルを作成するだけです(元のテーブルごと)。

他の人が指摘しているように、JSONのアイデアには、クエリを実行することがかなり不可能であるという問題があります。つまり、特定の時間に必要な翻訳だけを抽出できないということです。

于 2012-07-24T11:32:27.880 に答える
1

これは拡張機能ではありません。リレーショナル データベースを使用する利点がすべて失われます。あなたのようserialize()に、デコードのパフォーマンスを大幅に向上させ、ファイルにデータを保存することもできます。このような構造で SQL を使用する特別な方法はありません。

すべての言語で列を使用しても問題ないと思います。CMS のプログラミングではさらに簡単です。リレーショナル データベースは、データを格納するためだけのものではありません。これは、データを合理的に処理し (たとえば、強力な組み込みメカニズムを使用して)、データの構造と整合性を制御するためのものです。

于 2012-07-24T11:25:24.383 に答える
0

最初の考え: これは明らかに sql WHERE label='Homepage' での正確な検索を妨げるでしょう 2 番目: ユーザーは検索中に不要な結果を見ることができます (たとえば、彼のクエリが他の言語の文字列で見つかった場合)

于 2012-07-24T11:20:29.477 に答える
0

データベースに単一の主要言語を保持し、追加のサブシステムを使用して翻訳を維持することをお勧めします。これは、Drupal などの Web アプリケーションの標準的なアプローチです。ほとんどの場合、ソフトウェア/アプリケーションのドメインでは、主要な言語文字列ごとに 1 つの翻訳が存在するため、コンテキストやあいまいさについて心配する必要はありません。(実際、最高のユーザー エクスペリエンスを得るには、独自の機能に対して独自のラベルを付けるように努める必要があります)。

独自のテーブルを回転させたい場合は、次のようにすることができます。

create table translations (
  id          int          not null primary key
, source      varchar(255) not null // the text in the primary language
, lang        varchar(5)   not null // the language of the translation
, translation varchar(255) not null // the text of the translation
) 

en_US、en_UKなどが必要になる可能性が高いため、おそらく言語には2文字以上が必要です。

于 2012-07-25T08:23:51.407 に答える