#php #database-design
#php #база данных-дизайн
Вопрос:
Использование PHP 5.x и MySQL 5.x
Итак, вчера я задал вопрос о наилучшем способе обработки динамических данных в многоязычии, этот вопрос заключается в том, что было бы хорошим решением для структуры базы данных, чтобы справиться с этим. У меня есть записи в базе данных для таких вещей, как stories. Мой план состоит в том, чтобы хранить разные версии истории для каждого языка, доступного в БД. Итак, если сайт поддерживает английский и испанский языки, то в инструменте администрирования они могут добавить английскую версию истории и испанскую версию истории.
Мои мысли по этому поводу заключались в том, чтобы иметь отдельные таблицы в БД, по одной для каждого языка. Итак, одна таблица истории для английской версии, одна для испанского и одна для любых других языков. Затем во внешнем интерфейсе я просто разрешаю посетителю выбрать, на каком языке просматривать сайт, и через переменные узнаю, к какой таблице запросить, чтобы получить эту версию истории. Но одна проблема заключается в том, что, если нет испанской версии, но они выбрали испанский? Это хорошее решение или есть лучший способ сделать это? Ищу предложения.
Ответ №1:
Наличие нескольких таблиц действительно не обязательно, если вы не планируете иметь миллионы историй… Обычно я использую две таблицы: одну для элемента, а другую для локализованного элемента
Например, история может быть такой
таблица «история»
id INTEGER (Primary Key)
creation_date DATE_TIME
author VAR_CHAR(32)
..other general columns..
таблица «story_localized»
story_id INTEGER (Foreign Key of story.id)
lang CHAR(2) -- (Indexed, unique -- story_id lang)
content TEXT
..other localized columns..
Выполнение запроса — это просто вопрос JOIN
объединения двух таблиц :
SELECT s.*, sl.*
FROM story s
JOIN story_localized sl ON s.id = sl.story_id
WHERE s.id = 1 -- the story you're looking for here
AND sl.lang = 'en' -- your language here
-- other conditions here
Такая конфигурация дает несколько преимуществ :
- все ваши данные находятся в одной таблице, нет необходимости синхронизировать операции CRUD
- вы можете добавлять новые языки в любую статью без необходимости создавать еще больше таблиц
- и т.д.
** РЕДАКТИРОВАТЬ **
Просто в качестве бонуса, вот «хитрость», позволяющая легко восстановить историю, независимо от языка, на котором она была написана
SELECT *
FROM (SELECT *
FROM story s
JOIN story_localized sl ON s.id = sl.story_id
WHERE s.id = {storyId}
AND sl.lang = {desiredLanguage} -- example : 'es'
UNION
SELECT *
FROM story s
JOIN story_localized sl ON s.id = sl.story_id
WHERE s.id = {storyId}
AND sl.lang = {defaultLanguage} -- example : 'en'
UNION
SELECT *
FROM story s
JOIN story_localized sl ON s.id = sl.story_id
WHERE s.id = {storyId}
LIMIT 1 -- ..get the first language found
) story_l
LIMIT 1 -- only get the first SELECTed row found
Попытается извлечь историю на {desiredLanguage}
, если история недоступна на этом языке, попробуйте найти ее в {defaultLanguage}
(ie. язык сайта по умолчанию), и если по-прежнему ничего не найдено, тогда не имеет значения, на каком языке извлекать статью, поэтому извлекайте первую найденную. Все в одном запросе, и все, что вам нужно, — это 3 аргумента: идентификатор истории, желаемый язык и запасной язык по умолчанию.
Кроме того, вы можете легко узнать, на каком языке доступна история, с помощью простого запроса :
SELECT sl.lang
FROM story_localized sl
WHERE sl.story_id = {storyId}
Ответ №2:
Лучший способ сделать это — сохранить историю как многозначный атрибут. Как показал вам @Yanick. И было бы интерфейсно лучше, если бы вы заполнили свой элемент выбора языка только теми языками, на которых доступна эта история.
Ответ №3:
Еще один хороший подход, когда это не длинный текст: названия недель, месяцы… в моем приложении я локализую музыкальные жанры и музыкальные инструменты. Используйте текстовое поле для хранения данных в формате json.
Итак, в моей таблице музыкальных «жанров» есть текстовое поле с именем «lang». На in у меня есть следующая структура json:
{"es_gl":"MARCHA ESPAÑOLA", "es_EN" : "SPANISH MARCH"}
Тогда с помощью PHP действительно легко получить наши данные из структуры json. Допустим, у меня есть genre в моей переменной $ genre.
$myJSON = json_decode($genre->lang);
echo $myJSON->es_gl // This echoes MARCHA ESPAÑOLA
echo $myJSON->es_es // This echoes SPANISH MARCH
Это хорошее решение, когда ваши данные о локализации невелики… нравится посты или блоги.