代码之家  ›  专栏  ›  技术社区  ›  Fionn

数据库本地化

  •  10
  • Fionn  · 技术社区  · 16 年前

    如果以下问题可能有更好/不同/共同的解决方案,我正在征求意见:


    我有一个产品数据库,其中包含产品的英文名称(此应用程序的默认语言),如果可用,我需要这些名称的翻译。

    目前我有这个设置:

    产品表

    CREATE TABLE products
    (
      id serial NOT NULL,
      "name" character varying(255) NOT NULL,
      CONSTRAINT products_pkey PRIMARY KEY (id)
    )
    

    以及产品本地化表

    CREATE TABLE products_l10n
    (
      product_id serial NOT NULL,
      "language" character(2) NOT NULL,
      "name" character varying(255) NOT NULL,
      CONSTRAINT products_l10n_pkey PRIMARY KEY (product_id, language),
      CONSTRAINT products_l10n_product_id_fkey FOREIGN KEY (product_id)
          REFERENCES products (id) MATCH SIMPLE
          ON UPDATE CASCADE ON DELETE CASCADE
    )
    

    我使用以下查询检索本地化产品列表(本例中为德语),并返回默认的英文名称:

    SELECT p.id, COALESCE(pl.name, p.name) 
    from products p LEFT 
    JOIN products_l10n pl ON p.id = pl.product_id AND language = 'de';
    

    SQL代码是Postgres方言。数据存储为UTF-8。

    6 回复  |  直到 14 年前
        1
  •  6
  •   Daniel Spiewak    16 年前

    我觉得不错。我可能会改变的一件事是您处理语言的方式:那可能是一个单独的表。因此,您可以:

    CREATE TABLE products_l10n
    (
      product_id serial NOT NULL,
      language_id int NOT NULL,
      "name" character varying(255) NOT NULL,
      CONSTRAINT products_l10n_pkey PRIMARY KEY (product_id, language),
      CONSTRAINT products_l10n_product_id_fkey FOREIGN KEY (product_id)
          REFERENCES products (id) MATCH SIMPLE
          ON UPDATE CASCADE ON DELETE CASCADE
      CONSTRAINT products_l10n_language_id_fkey FOREIGN KEY (language_id)
          REFERENCES languages (id) MATCH SIMPLE
          ON UPDATE CASCADE ON DELETE CASCADE
    )
    
    CREATE TABLE languages
    )
      id serial not null
      "language" character(2) NOT NULL
    )
    

    除此之外,我认为你已经找到了最好的解决办法。

        2
  •  1
  •   Cade Roux    16 年前

    看起来不错-和我喜欢的本地化技术相似-宽字符(日语)怎么样?我们总是用nvarchar来处理这个问题。

    然而,在我们的国际采购业务中,我们发现产品在国际边界上没有一致性,因为每个国家的供应商都不同,所以我们将界面国际化/本地化,但数据库完全不同。

        3
  •  1
  •   Chris Shaffer    16 年前

    我能提供的唯一的变化是,你可能还想包括国家/方言的可能性;例如,而不仅仅是英语(en),使用英语(en-us)。这样你就可以解释所有的变化(例如,英国拼法,法裔加拿大人可能与法国讲的法语有差异,等等)。

        4
  •  0
  •   Rob Williams    16 年前

    我觉得不错。

    显然,您应该将本地化名称放入Unicode列中,您可以选择将英文默认值放入一个ASCII字段(假设数据库支持该字段)。最好的做法是通篇使用Unicode并“忘记”它。

        5
  •  0
  •   Jonathan Leffler Toon Krijthe    16 年前

    其他人没有提到的唯一复杂的因素是代码集——你能处理希伯来语、阿拉伯语、俄语、汉语、日语吗?如果一切都是Unicode,那么您只需要担心GB18030(中文),它是(IIUC)Unicode的超集。

        6
  •  0
  •   Emmanuel    14 年前

    在处理这类事情时,我使用构建一个完全不包含名称的产品表,以及一个只包含名称的产品翻译表(更明显的是)。

    最后我提出了这样的问题:

    SELECT 
        i.id, 
        i.price, 
        it.label 
    FROM 
        items i 
        LEFT JOIN items_trans it 
            ON i.id=it.item_id AND it.lang_id=(
                SELECT lang_id
                FROM items_trans
                WHERE item_id=i.id
                ORDER BY
                    (lang_id=1) DESC,
                    (lang_id=0) DESC
                LIMIT 1
            )
    

    你怎么认为?