2008-10-10 2 views
9

я ищу мнение, если следующая проблема может быть, есть лучше/другое/общее решение:базы данных локализации


У меня есть база данных для продуктов, который содержит имена продуктов на английском языке (языке по умолчанию этого приложения), и мне нужны переводы имен, если они доступны.

В настоящее время у меня есть эта установка:

таблица продукт

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

Выглядит хорошо для меня. Единственное, что я могу изменить, это то, как вы обрабатываете языки: это, вероятно, должна быть отдельная таблица. Таким образом, у вас будет:

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

Не следует ли, чтобы база данных могла оптимизировать поле символа (2) как интегральное, поскольку коды языка ISO 639-1 более читабельны по сравнению с целыми числами, если есть проблемы. – Fionn 2008-10-10 00:33:17

+0

Я думал точно так же. На первый взгляд, использование дополнительного слоя имеет ряд преимуществ: можно перечислять все доступные/настроенные языки (полезные в графическом интерфейсе), вы можете удалить весь язык (с ограничениями DB) и предотвратить «опечатки». Хотя последнее не имеет значения при использовании 2 кодов символов;) – kazu 2014-04-13 14:57:49

0

Выглядит прилично для меня.

Очевидно, что вы должны поместить локализованное имя в столбец Unicode, который вы можете выбрать, чтобы поместить английское значение по умолчанию в поле ASCII (при условии, что база данных поддерживает это). Лучше всего просто сделать Unicode и «забыть» об этом.

+0

Редактировал вопрос - данные всегда находятся в Юникоде (UTF-8). – Fionn 2008-10-10 00:39:22

1

Выглядит хорошо - похоже на мою предпочитаемую технику локализации - как насчет широких символов (японский)? Мы всегда использовали nvarchar, чтобы справиться с этим.

Фактически мы обнаружили, что в нашей международной операции по закупкам не было согласованности между международными границами на продуктах, поскольку поставщики в каждой стране были разными, поэтому мы интернационализировали/локализовали наш интерфейс, но базы данных были полностью различны.

+0

Изменили вопрос - данные всегда находятся в Юникоде (UTF-8). – Fionn 2008-10-10 00:39:57

1

Единственная вариация, которую я могу предложить, заключается в том, что вы также можете указать возможность страны/диалекта; например, вместо английского (en), используйте английский США (en-US). Таким образом, вы можете полностью учитывать варианты (например, британское правописание, французский канадский, вероятно, имеет отличия от французов, на которых говорят во Франции и т. Д.).

0

Единственный усложняющий фактор, который другие не упоминали, это наборы кода - сможете ли вы обрабатывать иврит, арабский, русский, китайский, японский? Если все Unicode, вам нужно только беспокоиться о GB18030 (китайский), который является (IIUC) надмножеством Unicode.

0

При работе с подобными вещами я использую для создания таблицы продуктов, не содержащей имени, и таблицы product_translation, содержащей только имена (и многое другое, очевидно).

Тогда я в конечном итоге с такой запрос:

 
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 
     ) 

Что вы думаете?

 Смежные вопросы

  • Нет связанных вопросов^_^