les-anatoliy
@les-anatoliy

Как организовать структуру БД для мультиязычия CMS?

Доброго времени суток, тостерчане!
Вопрос собственно такой.
Как максимально удобно организовать структуру БД для написания мультиязычной CMS?
Цель такая: Нужно как то хранить переводы названий разделов, переводы новостей, страниц, и чтоб потом можно было организовать поиск по сайту а конкретно по переводам того или иного языка.
Я организовал вот так (структура таблицы с переводами новостей и разделов в данном случае):
----------------------------------------------------------------
| id | section_id | news_id | lang | title | description | ... |
----------------------------------------------------------------

Но при таком подходе когда нужно выбрать переводы на любом языке, то все супер если такая запись есть, а если нет, то нужно выбрать запись на языке который заведен по умолчанию. Все как бы супер, но если выбираю например Новости, которых 1000 то это +1000 запросов на получение переводов.
Плюсы в таком подходе несколько:
  1. не нужно лезть в БД и изменять структуру если добавляется новый язык
  2. Очень удобно реализовывать поиск
  3. Все переводы хранятся в одной таблице

Из минусов только то, что куча запросов, но может это у меня не хватает ума правильно организовать выборку.
Тогда может подскажете как правильно это разрулить?
Пример запроса ниже:
$news = News::get();
    foreach ($news as $nws) {
        $data[] = [
            'id' => $nws->id,
            'good' => $nws->good,
            'translates' => $nws->translations()->where('lang', App::getLocale())->get()->toArray()
        ];
    }

На хабре есть статья, но я подумал, может тут кто поделится еще своим опытом.
  • Вопрос задан
  • 379 просмотров
Пригласить эксперта
Ответы на вопрос 3
muhammad_97
@muhammad_97
PHP-разработчик
Для каждой сущности создаются две таблицы: основная и таблица с переводами. Еще должна быть таблица со списком языков (languages) Например у нас есть сущность Post (публикация), для нее будет следующая структура БД:

posts

id, slug, published_at

posts_texts

id, post_id, language_id, title, content
Ответ написан
Комментировать
xmoonlight
@xmoonlight
https://sitecoder.blogspot.com
Я делал прямоугольником: одна запись - это одна публикация/статья, а переводы - в колонках.
id | section_id | news_id | title[en-en] | title[ru-ru] | description[en-en] | description[ru-ru] |...
просто, что будет больше 4-5 языков у вас - это вряд ли, а на скорость на поиск(фильтрацию) по нужному языку и по нужным колонкам - это сильно влияет в лучшую сторону. Не забывайте указывать чётко те колонки, которые нужно отображать в результатах запроса (и LIMIT тоже иногда) и всё.
Ответ написан
megafax
@megafax
web-программист
У Вас по факту получается, что одна новость, это набор записей в БД. Если прибегать к 1-й нормальной форме, то получится что то вида
id | lang_id | title | text
Причем первичным ключом в этом случае выступает уже связка id + lang_id. При входящем запросе уже определяется язык, который нужен браузеру и просто ко всем значениям подставляется
WHERE `lang_id`='$lang_id'
Но тогда придется самостоятельно организовывать работу с AUTO_INCREMENT, поскольку уникальность уже идет на уровне id+lang_id
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы