Laravel по-русски

Русское сообщество разработки на PHP-фреймворке Laravel.

Ты не вошёл. Вход тут.

#1 24.12.2017 13:26:41

Структура БД для нескольких языков

Здравствуйте.
Этот вопрос уже здесь поднимался, но та структура которая предложена там, меня не устраивает.
Во многих CMS с идет мультиязычность используя несколько таблиц, к примеру: articles и articles_lang. Но я не хочу использовать такую структуру, что бы не было по два запроса на один ресурс. Может как то по другому можно?

В голову пришло только вот это.
Создаем таблицу языков. Когда посетитель заходит на сайт, то определяем его язык браузера, делаем запрос в базу с языками, и выбираем язык по коду. Если такого языка в базе нет, выбираем дефолтный язык. Затем ставим ид этого языка в сессию, а потом глобальным скоупом, выбираем записи where('lang_id', $lang->id)

Нормально ли так делать? И есть ли еще какие то варианты. Спасибо.

Не в сети

#2 24.12.2017 15:22:34

Re: Структура БД для нескольких языков

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

Как бы я делал (и делал big_smile ) ресурсы на разных языках. Во первых, даже если одна статья это дословный перевод другой, это всё равно разные ресурсы, у них должен быть разный URL. Хотя вероятно у них будут перекрёстные ссылки. Отсюда естественным образом вытекает то, что достаточно одной таблицы articles. А атрибут язык это одно из полей таблицы. Для перекрёстных ссылок типа "варианты статьи на других языках" можно завести таблицу связку, чтобы организовать отношение many-to-many.

Изменено artoodetoo (24.12.2017 15:23:48)


There are two hard things in computer science: cache invalidation, naming things, and off-by-one errors.

Не в сети

#3 11.01.2018 14:08:39

Re: Структура БД для нескольких языков

  1. Как бы я делал (и делал big_smile ) ресурсы на разных языках. Во первых, даже если одна статья это дословный перевод другой, это всё равно разные ресурсы, у них должен быть разный URL. Хотя вероятно у них будут перекрёстные ссылки. Отсюда естественным образом вытекает то, что достаточно одной таблицы articles. А атрибут язык это одно из полей таблицы. Для перекрёстных ссылок типа «варианты статьи на других языках» можно завести таблицу связку, чтобы организовать отношение many-to-many.

Спасибо. Все понятно!

Не в сети

#4 21.01.2018 23:00:39

Re: Структура БД для нескольких языков

И опять я вернулся к этому вопросу. Использование в каждой записи поле land_id оказалось неудобным, потому что при сохранении нового ресурса, создаются ресурсы с разными идентификаторами. К примеру создаем категории:

- id
- name
- lang_id
-----------
id: 14
name: Новая категория
lang_id: 1

id: 15
name: New category
lang_id: 2

По этому решил сменить структуру бд на такую

// categories (hasMany CategoryLang)
- id
- created_at
...
// category_lang
- id
- category_id
- lang_id
- name

При такой структуре будит по 2 запроса уже, а не один. По этому хотелось бы максимально это все оптимизировать (составные индексы, что то еще). Особеннл на странице товара, где идет 15 переводимых ресурсов. Получается 30 запросов к бд.
Посоветуйте пожалуйста как максимально оптимизировать запросы? Спасибо!

Не в сети

#5 22.01.2018 09:51:35

Re: Структура БД для нескольких языков

Покажи пожалуйста код.

Не в сети

#6 22.01.2018 18:07:40

Re: Структура БД для нескольких языков

  1. Покажи пожалуйста код

Извини, а какой именно код показать?

Не в сети

#7 22.01.2018 19:11:28

Re: Структура БД для нескольких языков

Который генерирует 30 запросов.

Не в сети

#8 22.01.2018 20:00:44

Re: Структура БД для нескольких языков

  1. Который генерирует 30 запросов.
PHP
// Controller
    /**
     * Show product page
     *
     * @param string $slug
     * @return \Illuminate\Contracts\View\Factory
     */
    
public function showProduct($slug)
    {
        
$product $this->product->show($slug);

        return 
view('frontend.pages.product.product', [
            
'product' => $product,
            
'attributes' => $this->attribute->getCombinations($product->variation_ids),
            
'features' => $this->feature->getProductFeatures($product->feature_ids),
        ]);
    }
PHP
    // Model Product
    /**
     * Show product
     *
     * @param string $slug
     * @return mixed
     */
    
public function show($slug)
    {
        return 
$this->with(
            
'images',
            
'carriers',
            
'variations.combinations.attribute',
            
'features',
            
'reviews',
            
'reviews.images',
            
'video',
            
'categories'
        
)->actual()->findBySlug($slug);
    }
    
// Model Attribute
    /**
     * Get product combinations
     * Size - S, Color - Black
     * Size - M, Color - Black
     * Etc..
     *
     * @param array $variationIds
     * @return \Illuminate\Database\Eloquent\Collection|\Illuminate\Support\Collection|static[]
     */
    
public function getCombinations(array $variationIds = [])
    {
        return 
$this->whereHas('values', function($q) use($variationIds){
            
$q->whereHas('combinations', function($q) use($variationIds) {
                
$q->whereIn('product_variation_id'$variationIds);
            });
        })->
with([
            
'values' => function($q) use($variationIds) {
                
$q->whereHas('combinations', function($q) use($variationIds) {
                    
$q->whereIn('product_variation_id'$variationIds);
                });
            },
        ])->
get();
    }
    
// Model Features
    /**
     * Get product features
     *
     * @param array $featureIds
     * @return \Illuminate\Database\Eloquent\Collection
     */
    
public function getProductFeatures(array $featureIds)
    {
        return 
$this->whereHas('values', function($q) use($featureIds){
            
$q->whereIn('id'$featureIds);
        })->
with(['values' => function($q) use($featureIds){
            
$q->whereIn('id'$featureIds);
        }])->
get();
    }

Этов се сейчас создает 13 — 15 запросов. Но если использовать структуру для n-ного кол-ства языков как я писал выше вида

products -> product_langs
categories -> cateory_langs
attributes -> attribute_langs
attribute_values -> attribute_value_langs
features -> feature_langs
feature_values -> feature_values_lang
....

То запросы в 2 раза вырастут везде. Вот и хочу узнать, как максимально можно оптимизировать нагрузку.

Не в сети

#9 22.01.2018 21:01:49

Re: Структура БД для нескольких языков

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

Не в сети

#10 23.01.2018 11:42:15

Re: Структура БД для нескольких языков

  1. Спасибо. Мне кажется, что для такого функционала это количество запросов вполне нормальное. Медленно работает?

Сейчас нормально работает, но боюсь что при нормальным кол-стве визиторов, все сломается к чертям…
А можешь сказать сколько метров оперативы использует ларавел в каком нибудь из твоих проектов, схожим по функционаллу с моим?

Не в сети

#11 23.01.2018 12:35:28

Re: Структура БД для нескольких языков

А можешь сказать сколько метров оперативы использует ларавел в каком нибудь из твоих проектов, схожим по функционаллу с моим?

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

Не в сети

#12 23.01.2018 20:00:00

Re: Структура БД для нескольких языков

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

Дебагбар же ты используешь? Он же показывает сколько мб оперативки на запрос было истрачено

Не в сети

#13 23.01.2018 20:09:24

Re: Структура БД для нескольких языков

Дебагбар же ты используешь? Он же показывает сколько мб оперативки на запрос было истрачено

Ну дак на продакшене совсем другие циферки. К тому же они тебе не помогут, объем данных очень ведь разный и от сложности структуры и количества запросов не особо зависят.

Не в сети

Подвал раздела