質問

の開発をしている多言語ソフトウェアです。どのアプリケーションコード、localizabilityいます。使用できる言語特有の資源としてのすべての種類のツールは動作します。

もう最高のアプローチを定めるための多言語データベースのスキーマ?ということかして多くのテーブル(100以上)が、各テーブルで複数の列のできる局在のnvarchar列きlocalizable).例えば、テーブルが製品情報:

CREATE TABLE T_PRODUCT (
  NAME        NVARCHAR(50),
  DESCRIPTION NTEXT,
  PRICE       NUMBER(18, 2)
)

私はを考えることができるというつのアプローチを支援多言語テキストの名前および説明の列:

  1. 別々のカラムのための言語

    時を追加しました新しい言語のシステム創造を行っていくことが必要に追加カラムの翻訳テキスト、このように:

    CREATE TABLE T_PRODUCT (
      NAME_EN        NVARCHAR(50),
      NAME_DE        NVARCHAR(50),
      NAME_SP        NVARCHAR(50),
      DESCRIPTION_EN NTEXT,
      DESCRIPTION_DE NTEXT,
      DESCRIPTION_SP NTEXT,
      PRICE          NUMBER(18,2)
    )
    
  2. 翻訳テーブルの列の各言語

    代わりに保存の翻訳テキストは、外部キーの翻訳テーブルが格納されています。の翻訳テーブルの列の各言語です。

    CREATE TABLE T_PRODUCT (
      NAME_FK        int,
      DESCRIPTION_FK int,
      PRICE          NUMBER(18, 2)
    )
    
    CREATE TABLE T_TRANSLATION (
      TRANSLATION_ID,
      TEXT_EN NTEXT,
      TEXT_DE NTEXT,
      TEXT_SP NTEXT
    )
    
  3. 翻訳テーブルの行の各言語

    代わりに保存の翻訳テキストは、外部キーの翻訳テーブルが格納されています。の翻訳テーブルのみを含むキーとは別のテーブルが含まれて行毎に翻訳する言語です。

    CREATE TABLE T_PRODUCT (
      NAME_FK        int,
      DESCRIPTION_FK int,
      PRICE          NUMBER(18, 2)
    )
    
    CREATE TABLE T_TRANSLATION (
      TRANSLATION_ID
    )
    
    CREATE TABLE T_TRANSLATION_ENTRY (
      TRANSLATION_FK,
      LANGUAGE_FK,
      TRANSLATED_TEXT NTEXT
    )
    
    CREATE TABLE T_TRANSLATION_LANGUAGE (
      LANGUAGE_ID,
      LANGUAGE_CODE CHAR(2)
    )
    

賛否両論ある各ソリューションと思うの経験これらのアプローチを何といいますは、どのようない設計の多言語データベースのスキーマ.

役に立ちましたか?

解決

各翻訳可能なテーブルに関連する変換テーブルを持っていることについてどう思いますか?

  

CREATE TABLE T_PRODUCT(pr_id int、PRICE NUMBER(18、2))

     

CREATE TABLE T_PRODUCT_tr(pr_id INT FK、言語コードvarchar、pr_nameテキスト、pr_descrテキスト)

このように複数の翻訳可能な列がある場合、それを取得するには単一の結合のみが必要になります+ translationidを自動生成しないため、関連する翻訳とともにアイテムをインポートする方が簡単な場合があります。

これのマイナス面は、複雑な言語のフォールバックメカニズムがある場合、各変換テーブルにそれを実装する必要がある場合があることです-ストアドプロシージャに依存している場合。アプリからこれを行う場合、これはおそらく問題になりません。

ご意見をお聞かせください-私はまた、次のアプリケーションのためにこれについて決定しようとしています。 これまで、3番目のタイプを使用しました。

他のヒント

これは興味深い問題は、しましょうnecromance.

まずは問題の方法1:
問題点:まdenormalizing保存します。
アプリケーションを除くPostGreSQLとhstoreできないパスパラメータの言語と言う:

SELECT ['DESCRIPTION_' + @in_language]  FROM T_Products

でいます:

SELECT 
    Product_UID 
    ,
    CASE @in_language 
        WHEN 'DE' THEN DESCRIPTION_DE 
        WHEN 'SP' THEN DESCRIPTION_SP 
        ELSE DESCRIPTION_EN 
    END AS Text 
FROM T_Products 

おに変更すべてのクエリを追加した場合、新しい言語です。この自然への"動的SQL"でのあいだに変更すべてのクエリ.

通常はこの結果ようなことに使用できません。視点やテーブル値関数のように、本当にあれば、問題は実際に必要なフィルター、ifrs上の負債の認識要件を満)

CREATE PROCEDURE [dbo].[sp_RPT_DATA_BadExample]
     @in_mandant varchar(3) 
    ,@in_language varchar(2) 
    ,@in_building varchar(36) 
    ,@in_wing varchar(36) 
    ,@in_reportingdate varchar(50) 
AS
BEGIN
    DECLARE @sql varchar(MAX), @reportingdate datetime

    -- Abrunden des Eingabedatums auf 00:00:00 Uhr
    SET @reportingdate = CONVERT( datetime, @in_reportingdate) 
    SET @reportingdate = CAST(FLOOR(CAST(@reportingdate AS float)) AS datetime)
    SET @in_reportingdate = CONVERT(varchar(50), @reportingdate) 

    SET NOCOUNT ON;


    SET @sql='SELECT 
         Building_Nr AS RPT_Building_Number 
        ,Building_Name AS RPT_Building_Name 
        ,FloorType_Lang_' + @in_language + ' AS RPT_FloorType 
        ,Wing_No AS RPT_Wing_Number 
        ,Wing_Name AS RPT_Wing_Name 
        ,Room_No AS RPT_Room_Number 
        ,Room_Name AS RPT_Room_Name 
    FROM V_Whatever 
    WHERE SO_MDT_ID = ''' + @in_mandant + ''' 

    AND 
    ( 
        ''' + @in_reportingdate + ''' BETWEEN CAST(FLOOR(CAST(Room_DateFrom AS float)) AS datetime) AND Room_DateTo 
        OR Room_DateFrom IS NULL 
        OR Room_DateTo IS NULL 
    ) 
    '

    IF @in_building    <> '00000000-0000-0000-0000-000000000000' SET @sql=@sql + 'AND (Building_UID  = ''' + @in_building + ''') '
    IF @in_wing    <> '00000000-0000-0000-0000-000000000000' SET @sql=@sql + 'AND (Wing_UID  = ''' + @in_wing + ''') '

    EXECUTE (@sql) 

END


GO

問題はこれは
a)日付フォーマットは非常に言語別、問題がない場合は入力ISO形式の庭園様々なプログラマは通常ない場合に報告し、ユーザーだとして地獄んだ場合でも、明示的に指導います。

b) 最も大きく, す ゆったりどのような構文チェック.の場合 <insert name of your "favourite" person here> 変化のスキーマがは突然の要件翼の変化、新しいテーブルが作成され、古いもので、参考に分野に名称変更などのような警告が表示されます。報告書も作品 ルがありますを選ぶことなく、ウイングパラメータ (==>こと.は空です)。が突然、実際のユーザーが実際に選択ウイング==> ブーム. この方法は完全にbreakesどのような試験をします。


方法2:
このように:"素晴らしい"ア(warning-戦闘)しましょうを組み合わせのデメリット方法3(ゆっくりとした速度を落とさなければならな多くの作品にも恐ろしいデメリットの方法1.
いずみさの、このメソッドは、このままですべての翻訳テーブル、そのため保守シンプルです。しかし、同じことを達成できる方法の1動的SQLを格納手続き(仮)テーブルを含む、翻訳の対象者の名称テーブル(もとお名前のすべてのテキストの分野が生じることがあります


方法3:
テーブルのすべての翻訳文:欠点:い店舗n外部キーのテーブルn分野です。そこでやらなければいけないということn接合のためのn。の翻訳テーブルは、グローバルで多くの応募、参加が遅くなってしまったこと。-また、ございますのT_TRANSLATIONテーブルn倍nます。これは非常にオーバーヘッド。今、何をしていまれなければならなカスタム翻訳をお客様の?いもう一2x n接合を追加する。ご参加えて10テーブル、2x2xn=4n追加、混乱!また、このデザインの使用が可能と同じ訳2を参照。場合に変更したい項目名を一つのテーブル、それから変更したいエントリの別のテーブルとして毎に時間がかかる?

プラス削除できませんの再インフォメーションのテーブルなので、その外部キー中の商品のテーブル...きのコースを省略する設定のFKsし <insert name of your "favourite" person here> できるテーブルを削除し、再度挿入全ての項目 newid() 【指定のidを挿入し、 アイデンティティ-ポリティックの挿入オフ"が、ようやま)がデータ処理(nullの参照を除く)った。


法4(非上場):保管すべての言語で、XML、データベースです。e.g

-- CREATE TABLE MyTable(myfilename nvarchar(100) NULL, filemeta xml NULL )


;WITH CTE AS 
(
      -- INSERT INTO MyTable(myfilename, filemeta) 
      SELECT 
             'test.mp3' AS myfilename 
            --,CONVERT(XML, N'<?xml version="1.0" encoding="utf-16" standalone="yes"?><body>Hello</body>', 2) 
            --,CONVERT(XML, N'<?xml version="1.0" encoding="utf-16" standalone="yes"?><body><de>Hello</de></body>', 2) 
            ,CONVERT(XML
            , N'<?xml version="1.0" encoding="utf-16" standalone="yes"?>
<lang>
      <de>Deutsch</de>
      <fr>Français</fr>
      <it>Ital&amp;iano</it>
      <en>English</en>
</lang>
            ' 
            , 2 
            ) AS filemeta 
) 

SELECT 
       myfilename
      ,filemeta
      --,filemeta.value('body', 'nvarchar') 
      --, filemeta.value('.', 'nvarchar(MAX)') 

      ,filemeta.value('(/lang//de/node())[1]', 'nvarchar(MAX)') AS DE
      ,filemeta.value('(/lang//fr/node())[1]', 'nvarchar(MAX)') AS FR
      ,filemeta.value('(/lang//it/node())[1]', 'nvarchar(MAX)') AS IT
      ,filemeta.value('(/lang//en/node())[1]', 'nvarchar(MAX)') AS EN
FROM CTE 

それを得ることができ価値XPath-クエアプリケーション、または文字列変数

filemeta.value('(/lang//' + @in_language + '/node())[1]', 'nvarchar(MAX)') AS bla

および更新することができますの価値のようになります:

UPDATE YOUR_TABLE
SET YOUR_XML_FIELD_NAME.modify('replace value of (/lang/de/text())[1] with "&quot;I am a ''value &quot;"')
WHERE id = 1 

が交換可能です /lang/de/...'.../' + @in_language + '/...'

いようにPostGre hstoreとによりオーバーヘッドの構文解析のXMLの代わりにエントリからの連想配列PG hstore)となりあまりにも遅いのxmlエンコーディングの従業員も把握しきれて苦しいことです。


法5(推奨するSunWuKung、選択すべき):一つの翻訳表"製品"。その一列毎語、"テキスト"の分野であり、つのみ(左)参加Nます。その後に簡単に追加できまデフォルトの場での"製品"テーブルで簡単に除して再インフォメーションの翻訳テーブルを作成できる第二のテーブルのカスタム-翻訳(需要)を削除することもでき、再挿入、まだすべての外国の鍵となります。

にしましょう例を参照この作品:

最初に作成したものをテーブル:

CREATE TABLE dbo.T_Languages
(
     Lang_ID int NOT NULL
    ,Lang_NativeName national character varying(200) NULL
    ,Lang_EnglishName national character varying(200) NULL
    ,Lang_ISO_TwoLetterName character varying(10) NULL
    ,CONSTRAINT PK_T_Languages PRIMARY KEY ( Lang_ID )
);

GO




CREATE TABLE dbo.T_Products
(
     PROD_Id int NOT NULL
    ,PROD_InternalName national character varying(255) NULL
    ,CONSTRAINT PK_T_Products PRIMARY KEY ( PROD_Id )
); 

GO



CREATE TABLE dbo.T_Products_i18n
(
     PROD_i18n_PROD_Id int NOT NULL
    ,PROD_i18n_Lang_Id int NOT NULL
    ,PROD_i18n_Text national character varying(200) NULL
    ,CONSTRAINT PK_T_Products_i18n PRIMARY KEY (PROD_i18n_PROD_Id, PROD_i18n_Lang_Id)
);

GO

-- ALTER TABLE dbo.T_Products_i18n  WITH NOCHECK ADD  CONSTRAINT FK_T_Products_i18n_T_Products FOREIGN KEY(PROD_i18n_PROD_Id)
ALTER TABLE dbo.T_Products_i18n  
    ADD CONSTRAINT FK_T_Products_i18n_T_Products 
    FOREIGN KEY(PROD_i18n_PROD_Id)
    REFERENCES dbo.T_Products (PROD_Id)
ON DELETE CASCADE 
GO

ALTER TABLE dbo.T_Products_i18n CHECK CONSTRAINT FK_T_Products_i18n_T_Products
GO

ALTER TABLE dbo.T_Products_i18n 
    ADD  CONSTRAINT FK_T_Products_i18n_T_Languages 
    FOREIGN KEY( PROD_i18n_Lang_Id )
    REFERENCES dbo.T_Languages( Lang_ID )
ON DELETE CASCADE 
GO

ALTER TABLE dbo.T_Products_i18n CHECK CONSTRAINT FK_T_Products_i18n_T_Products
GO



CREATE TABLE dbo.T_Products_i18n_Cust
(
     PROD_i18n_Cust_PROD_Id int NOT NULL
    ,PROD_i18n_Cust_Lang_Id int NOT NULL
    ,PROD_i18n_Cust_Text national character varying(200) NULL
    ,CONSTRAINT PK_T_Products_i18n_Cust PRIMARY KEY ( PROD_i18n_Cust_PROD_Id, PROD_i18n_Cust_Lang_Id )
);

GO

ALTER TABLE dbo.T_Products_i18n_Cust  
    ADD CONSTRAINT FK_T_Products_i18n_Cust_T_Languages 
    FOREIGN KEY(PROD_i18n_Cust_Lang_Id)
    REFERENCES dbo.T_Languages (Lang_ID)

ALTER TABLE dbo.T_Products_i18n_Cust CHECK CONSTRAINT FK_T_Products_i18n_Cust_T_Languages

GO



ALTER TABLE dbo.T_Products_i18n_Cust  
    ADD CONSTRAINT FK_T_Products_i18n_Cust_T_Products 
    FOREIGN KEY(PROD_i18n_Cust_PROD_Id)
REFERENCES dbo.T_Products (PROD_Id)
GO

ALTER TABLE dbo.T_Products_i18n_Cust CHECK CONSTRAINT FK_T_Products_i18n_Cust_T_Products
GO

その後のデータ

DELETE FROM T_Languages;
INSERT INTO T_Languages (Lang_ID, Lang_NativeName, Lang_EnglishName, Lang_ISO_TwoLetterName) VALUES (1, N'English', N'English', N'EN');
INSERT INTO T_Languages (Lang_ID, Lang_NativeName, Lang_EnglishName, Lang_ISO_TwoLetterName) VALUES (2, N'Deutsch', N'German', N'DE');
INSERT INTO T_Languages (Lang_ID, Lang_NativeName, Lang_EnglishName, Lang_ISO_TwoLetterName) VALUES (3, N'Français', N'French', N'FR');
INSERT INTO T_Languages (Lang_ID, Lang_NativeName, Lang_EnglishName, Lang_ISO_TwoLetterName) VALUES (4, N'Italiano', N'Italian', N'IT');
INSERT INTO T_Languages (Lang_ID, Lang_NativeName, Lang_EnglishName, Lang_ISO_TwoLetterName) VALUES (5, N'Russki', N'Russian', N'RU');
INSERT INTO T_Languages (Lang_ID, Lang_NativeName, Lang_EnglishName, Lang_ISO_TwoLetterName) VALUES (6, N'Zhungwen', N'Chinese', N'ZH');

DELETE FROM T_Products;
INSERT INTO T_Products (PROD_Id, PROD_InternalName) VALUES (1, N'Orange Juice');
INSERT INTO T_Products (PROD_Id, PROD_InternalName) VALUES (2, N'Apple Juice');
INSERT INTO T_Products (PROD_Id, PROD_InternalName) VALUES (3, N'Banana Juice');
INSERT INTO T_Products (PROD_Id, PROD_InternalName) VALUES (4, N'Tomato Juice');
INSERT INTO T_Products (PROD_Id, PROD_InternalName) VALUES (5, N'Generic Fruit Juice');

DELETE FROM T_Products_i18n;
INSERT INTO T_Products_i18n (PROD_i18n_PROD_Id, PROD_i18n_Lang_Id, PROD_i18n_Text) VALUES (1, 1, N'Orange Juice');
INSERT INTO T_Products_i18n (PROD_i18n_PROD_Id, PROD_i18n_Lang_Id, PROD_i18n_Text) VALUES (1, 2, N'Orangensaft');
INSERT INTO T_Products_i18n (PROD_i18n_PROD_Id, PROD_i18n_Lang_Id, PROD_i18n_Text) VALUES (1, 3, N'Jus d''Orange');
INSERT INTO T_Products_i18n (PROD_i18n_PROD_Id, PROD_i18n_Lang_Id, PROD_i18n_Text) VALUES (1, 4, N'Succo d''arancia');
INSERT INTO T_Products_i18n (PROD_i18n_PROD_Id, PROD_i18n_Lang_Id, PROD_i18n_Text) VALUES (2, 1, N'Apple Juice');
INSERT INTO T_Products_i18n (PROD_i18n_PROD_Id, PROD_i18n_Lang_Id, PROD_i18n_Text) VALUES (2, 2, N'Apfelsaft');

DELETE FROM T_Products_i18n_Cust;
INSERT INTO T_Products_i18n_Cust (PROD_i18n_Cust_PROD_Id, PROD_i18n_Cust_Lang_Id, PROD_i18n_Cust_Text) VALUES (1, 2, N'Orangäsaft'); -- Swiss German, if you wonder

そしてクエリのデータ

DECLARE @__in_lang_id int
SET @__in_lang_id = (
    SELECT Lang_ID
    FROM T_Languages
    WHERE Lang_ISO_TwoLetterName = 'DE'
)

SELECT 
     PROD_Id 
    ,PROD_InternalName -- Default Fallback field (internal name/one language only setup), just in ResultSet for demo-purposes
    ,PROD_i18n_Text  -- Translation text, just in ResultSet for demo-purposes
    ,PROD_i18n_Cust_Text  -- Custom Translations (e.g. per customer) Just in ResultSet for demo-purposes
    ,COALESCE(PROD_i18n_Cust_Text, PROD_i18n_Text, PROD_InternalName) AS DisplayText -- What we actually want to show 
FROM T_Products 

LEFT JOIN T_Products_i18n 
    ON PROD_i18n_PROD_Id = T_Products.PROD_Id 
    AND PROD_i18n_Lang_Id = @__in_lang_id 

LEFT JOIN T_Products_i18n_Cust 
    ON PROD_i18n_Cust_PROD_Id = T_Products.PROD_Id
    AND PROD_i18n_Cust_Lang_Id = @__in_lang_id

いぐさ、その後も利用できますが、ISO-TwoLetterName('DE','JA'など) 主キーの言語を表しいルックアップ言語のidです。だんだん使用したいのですが、 IETF-言語タグ 代わりに、よりおいしくなりますが、いただきますので、デCH de-deする場合には同じでないortography-wise(double sの代わりにβろがとっても同じベースの言語です。たばかりのとても小さかった素晴らしいホテルできるまでをもたらすと考えらブックマークグループで格安料金プランを選んでネットGB/en-CA/ja-AUはfr-FR/fr-CAは類似の課題です。
引用:いらないでいるだけでなくソフトウェアです。
回答:ありが一??

とにかく、ご利用の場合は整数値のIDには、柔軟で変更方法です。
及びその整数であり面倒で破壊で、面倒なり、失敗したDbのデザイン。

参照 RFC5646, ISO639-2,

とだ"として" のみ 当社は申込み 一つ 文化"(ブックマークグループ普通)-こんなことが必要な整数、その一環として行われた時期及び場所はもちろんのこと IANA言語タグ, ができるのではないか。
つけなきゃいけないんだようこ:

de-DE-1901
de-DE-1996

de-CH-1901
de-CH-1996

(ある正書法改革1996年に...) み単語辞書の場合は間違;これがとても重要にな応用が法律や公共サービスース等)をサポートしています
より重要なことは、ある領域からキリル文字へのラテン文字、直面倒による表面的な迷惑の無名の正書法改革はなぜこれは重要な検討事項になるものによっている国に暮らしやすいところです。片道またはその他でのやりとりしているの整数であり、例---

編集:
を追加 ON DELETE CASCADE

REFERENCES dbo.T_Products( PROD_Id )

できるだけ会うことが DELETE FROM T_Products, 得ない外部キーの侵害となります。

と照合いいようになります:

A)お客様が、ご自身のダル
B)保存し、ご希望の照合名の言語テーブル

するためのcollations、自分のテーブル、例えば:

SELECT * FROM sys.fn_helpcollations() 
WHERE description LIKE '%insensitive%'
AND name LIKE '%german%' 

C)いの照合名をご用意auth.ユーザーです。言語情報

D)の書SQLのようになります:

SELECT 
    COALESCE(GRP_Name_i18n_cust, GRP_Name_i18n, GRP_Name) AS GroupName 
FROM T_Groups 

ORDER BY GroupName COLLATE {#COLLATION}

E)し、これを実行する事ができます。にダル:

cmd.CommandText = cmd.CommandText.Replace("{#COLLATION}", auth.user.language.collation)

しているこのフラッSQLクエリ

SELECT 
    COALESCE(GRP_Name_i18n_cust, GRP_Name_i18n, GRP_Name) AS GroupName 
FROM T_Groups 

ORDER BY GroupName COLLATE German_PhoneBook_CI_AI

3番目のオプションは、いくつかの理由により最適です:

  • 新しい言語のデータベーススキーマを変更する必要はありません(したがって、コードの変更を制限します)
  • 未実装の言語や特定のアイテムの翻訳のために多くのスペースを必要としません
  • 最高の柔軟性を提供
  • スパーステーブルにならない
  • nullキーについて心配する必要はなく、nullエントリの代わりに既存の翻訳を表示していることを確認する必要があります。
  • 他の翻訳可能なアイテム/ものなどを含むようにデータベースを変更または拡張する場合、同じテーブルとシステムを使用できます-これは他のデータとは非常に切り離されています。

-アダム

この例を見てください:

PRODUCTS (
    id   
    price
    created_at
)

LANGUAGES (
    id   
    title
)

TRANSLATIONS (
    id           (// id of translation, UNIQUE)
    language_id  (// id of desired language)
    table_name   (// any table, in this case PRODUCTS)
    item_id      (// id of item in PRODUCTS)
    field_name   (// fields to be translated)
    translation  (// translation text goes here)
)

説明する必要はないと思います。構造自体が説明しています。

私は通常、このアプローチを採用します(実際のsqlではありません)。これは最後のオプションに対応します。

table Product
productid INT PK, price DECIMAL, translationid INT FK

table Translation
translationid INT PK

table TranslationItem
translationitemid INT PK, translationid INT FK, text VARCHAR, languagecode CHAR(2)

view ProductView
select * from Product
inner join Translation
inner join TranslationItem
where languagecode='en'

翻訳可能なテキストをすべて1か所にまとめると、メンテナンスが非常に簡単になります。場合によっては、翻訳が翻訳局に外注されるため、1つの大きなエクスポートファイルを送信して、同じように簡単にインポートして戻すことができます。

技術的な詳細と解決策に進む前に、しばらく立ち止まって要件についていくつか質問してください。答えは技術的な解決策に大きな影響を与える可能性があります。このような質問の例は次のとおりです。
  -すべての言語が常に使用されますか?
  -誰が、いつ、異なる言語バージョンで列を埋めますか?
  -ユーザーがテキストの特定の言語を必要とし、システムに何もない場合はどうなりますか?
  -テキストのみをローカライズするか、他のアイテムもあります(たとえば、価格は$と<!>#8364に格納できます。これらは異なる可能性があるため)

ローカライズのヒントを探していたところ、このトピックを見つけました。 これがなぜ使用されるのか疑問に思っていました:

CREATE TABLE T_TRANSLATION (
   TRANSLATION_ID
)

だから、user39603のようなものが表示されます:

table Product
productid INT PK, price DECIMAL, translationid INT FK

table Translation
translationid INT PK

table TranslationItem
translationitemid INT PK, translationid INT FK, text VARCHAR, languagecode CHAR(2)

view ProductView
select * from Product
inner join Translation
inner join TranslationItem
where languagecode='en'

テーブルTranslationをそのままにして、これを取得することはできません:

    table Product
    productid INT PK, price DECIMAL

    table ProductItem
    productitemid INT PK, productid INT FK, text VARCHAR, languagecode CHAR(2)

    view ProductView
    select * from Product
    inner join ProductItem
    where languagecode='en'

ランダマイザーに同意します。テーブル<!> quot; translation <!> quot;が必要な理由がわかりません。

これで十分だと思います:

TA_product: ProductID, ProductPrice
TA_Language: LanguageID, Language
TA_Productname: ProductnameID, ProductID, LanguageID, ProductName

以下のアプローチは実行可能でしょうか?複数の列を翻訳する必要があるテーブルがあるとします。したがって、製品の場合は、両方の製品名<!> ampを持つことができます。翻訳が必要な製品の説明。次のことができますか

CREATE TABLE translation_entry (
      translation_id        int,
      language_id           int,
      table_name            nvarchar(200),
      table_column_name     nvarchar(200),
      table_row_id          bigint,
      translated_text       ntext
    )

    CREATE TABLE translation_language (
      id int,
      language_code CHAR(2)
    )   

<!> quot;どちらが最適か<!> quot;プロジェクトの状況に基づいています。最初のものは選択と保守が簡単で、エンティティを選択するときにテーブルを結合する必要がないため、パフォーマンスも最適です。対象が2つまたは3つの言語のみをサポートしており、それが増えないことを確認した場合は、使用できます。

2つ目は大げさですが、理解と保守が困難です。そして、パフォーマンスは最初のものよりも悪いです。

最後の1つは拡張性は優れていますが、パフォーマンスは劣ります。 T_TRANSLATION_ENTRYテーブルはますます大きくなり、一部のテーブルからエンティティのリストを取得する場合はひどいものになります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top