Подходящая многоязычная схема или перебор?


8

ОБНОВЛЕНИЕ 2 : Я фактически закончил тем, что использовал это, и это здорово после нескольких настроек. Вот мой пост о его фактическом дизайне и действии: http://tim.hithlonde.com/2013/lemon-schema-works/

Я создаю веб-приложение и хочу, чтобы оно поддерживало несколько языков. Эта структура состоит из двух компонентов:

  1. Соединение локали («английский», «немецкий» и т. Д.) С терминами и наличие розеттного камня, связывающего термины и термины на определенном языке.
  2. Группировка терминов по странице. Я не хочу говорить, ВЫБЕРИТЕ term1, term2 и т. Д. Через 30+ терминов, которые могут мне понадобиться на странице. Я хочу спросить на странице, с которой они связаны.

Вот моя предложенная структура таблицы (обратите внимание, что все идентификаторы имеют отношения / индексы для выполнения очень эффективных запросов):

Принципиальная схема

  * 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

Мне нужно только попросить два предмета; идентификатор языка, который мне нужен, и страница, которая мне нужна. Он будет обслуживать все термины на указанном языке, которые являются частью группы терминов для этой страницы.

Я думаю, что это действительно хорошая структура, но я хотел бы получить обратную связь.

ОБНОВЛЕНИЕ : Чтобы уточнить, мы просто говорим о локализации компонентов пользовательского интерфейса . (метки, навигация, полезный текст) Вся информация, которую вводит пользователь, будет храниться в Unicode, а не в этой схеме.

ОБНОВЛЕНИЕ 2 : Я фактически закончил тем, что использовал это, и это здорово. Вот мой пост о его фактическом дизайне и действии: http://tim.hithlonde.com/2013/lemon-schema-works/


1
Обычно (из того, что я видел) локализация осуществляется с помощью шаблонов на веб-стороне вещей. Какие вещи вы хотите локализовать со стороны базы данных?
Philᵀᴹ

Я хочу локализовать все метки, навигационное меню и любой полезный текст (предупреждения и т. Д.). Я считаю, что для извлечения этого из базы данных мне не нужна эта логика в моих шаблонах. В моих шаблонах я хочу, чтобы <?php echo $term['term_in_english'];?>я стремился к основательному подходу MVC.
Тим Хаберсак

Ответы:


6

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

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

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 с помощью языкового контроля или мета-фраз.

Итак, у нас была главная таблица фраз:

фразеид, английский, дополнительная информация

и локализованная таблица:

фразеид, локалид, перевод

В INNER JOINS вы также предполагали, что локализованные версии существуют - мы склонны их исключать до тех пор, пока они не будут переведены, так что ваш запрос в конечном итоге ничего не даст (даже по умолчанию)

Если перевода не существует, по умолчанию используется английский, а затем возвращается к предоставленному коду (в случае, если в базе данных не было идентификатора, и из кода также было ясно, какой идентификатор фразы «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.


Спасибо тебе за это! Я не думал о точках вставки. Я не верю, что в моем приложении они есть, но об этом стоит помнить. Также спасибо за комментарии к схеме. Некоторое время я занимался проектированием БД, но без хорошего набора сверстников для сравнения заметок, иногда я не уверен, что движусь в правильном направлении. :)
Тим Хаберсак

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. За исключением уровня контроллера, я буду запрашивать все термины, связанные с страницей, и язык, на котором я хочу это. Эта функция вызовет запрос, который я описал выше, и изменит магию, чтобы я вернул ассоциативный массив, где ключ будет мнемоникой, а значением будет термин. Количество терминов пользовательского интерфейса будет небольшим (<100), поэтому я не вижу проблем в управлении им в БД. Я, вероятно, создам простой интерфейс для ввода переведенных терминов и связывания страниц.
Тим Хаберсак

0

Просто создайте 3 таблицы

1.) Мастер языка (LangId, LangName)

2.) Мастер ресурсов (ResourceMasterId, TableId, ColumnId, ColumnName)

3.) Сведения о ресурсе (ResourceMasterId, LangId, Value)

составной ключ (ResourceMasterId, LangId) в подробностях ресурса

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.