Два разных подхода для работы c tags

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
an.viktory@gmail.com
Сообщения: 536
Зарегистрирован: 2016.09.05, 23:21

Два разных подхода для работы c tags

Сообщение an.viktory@gmail.com »

ЧТО НУЖНО:
ЕСТЬ модель Sale, для нее нужно хранить tags для SMART поиска и отображения информации. класс Tags имеет основные свойства id, name, color, type.

ПРЕДЫСТОРИЯ:
viewtopic.php?f=19&t=45265&hilit=tags
Мне было рекомендовано хранить tags в связанной таблице при помощи связи один-ко-многим. Я так и сделал.

МЕТОД ПЕРВЫЙ (КЛАССИЧЕСКИЙ):
1 . создаем Class RealTags хранит именно соответствие записи id основной таблице и id Tags;

Код: Выделить всё

 public function getTags()
    {
        return $this->hasMany(RealTags::className(), ['sale_id' => 'id']);
    }
    
ВНИМАНИЕ: НЕ ИСПОЛЬЗУЮ ее как промежуточную таблицу (т.к. записей Tags немного (порядка 100)) я его кеширую (ON CHANGE) и использую как CONSTANT массив [ 1 => ['name', 'color,'type'], 2=> и т.д.] в итоге вместо tag->name имею $tag['name'];

МИНУСЫ: т.к. одной Sale соответствует в среднем 5 tags, то если sale->id = 10.000.000; то realtags->id = 5*10000000.
в итоге записи будут выглядеть так:

Код: Выделить всё

    id            |        sale_id    |      tag_id
50.000.000     10.000.000              2
50.000.001     10.000.000              6
50.000.002     10.000.000              11
50.000.003     10.000.000              56
50.000.004     10.000.000              99
Сейчас, когда количество записей sale 30.000, tags 130.000 (даже если я буду удалять sale и связанные tags, AUTO_INCREMENT будет все равно выставлять большие индексы, которые хранятся в базе и имеют свой (увеличивающийся) вес).
2. Поиск по Tags

Код: Выделить всё

$query->andWhere([RealTags::tableName() . '.tag_id' => $tags_array]);
$query->groupBy("s.id");
$query->having(new Expression("count(*)=".count($tags_array)));
МЕТОД ВТОРОЙ:

1. Храним tags, как текстовое поле $sale->tags_id = ",2,6,11,56,99,";
для упаковки и распаковки использовать простые методы

Код: Выделить всё

class Tags extends Activerecord 
{ ...
 public static function convertToString(array $arr)
    {
        return ",".implode(",", $arr).",";
    }

    public static function convertToArray($string)
    {
      if ($string)  return explode(",", preg_replace("/^,|,$/", "", $string));
    }

}
запихнуть в beforeSave и afterFind (или магические getTags и setTags) и работать, как с массивом.

2. Поиск:

Код: Выделить всё

foreach ($tags_sale as $tag) {
  $query->andWhere(['like', 's.tags_id', "," . $tag . ","]);
 }
МИНУСЫ: пока не нашел(сравнивал в основном время запроса с join И без JOIN).
ПЛЮСЫ:
1.нет минусов первого метода, разница в размерах таблицы Sale c tags_id и без нее 0,2Mб. ( но модели RealTags нет и таблицы Mysql весом 8.5 Mб.)
2. возможно поиск будет гораздо быстрее с elasticsearch.
Ваши комментарии?
kawabanga
Сообщения: 806
Зарегистрирован: 2013.10.12, 23:35
Откуда: Новосибирск

Re: Два разных подхода для работы c tags

Сообщение kawabanga »

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

item
id | title | etc

tag
id | title | description | count | etc

item_tag, с праймари кей по двум полям одновременно.
item_id | tag_id

И дальше нет никаких заморочек, не думаю что с 1 млн записей будет проблема вытянуть поля по первичному ключу.
an.viktory@gmail.com
Сообщения: 536
Зарегистрирован: 2016.09.05, 23:21

Re: Два разных подхода для работы c tags

Сообщение an.viktory@gmail.com »

может есть еще комментарии?
Nex-Otaku
Сообщения: 831
Зарегистрирован: 2016.07.09, 21:07

Re: Два разных подхода для работы c tags

Сообщение Nex-Otaku »

Ты же всё обдумал, плюсы и минусы расписал. Выбери любое решение, подходящее для бизнес-задачи.
an.viktory@gmail.com
Сообщения: 536
Зарегистрирован: 2016.09.05, 23:21

Re: Два разных подхода для работы c tags

Сообщение an.viktory@gmail.com »

а вдруг в будущем будут проблемы о которых я пока не подозреваю и потом придется все переделывать.
Аватара пользователя
rugabarbo
Сообщения: 1063
Зарегистрирован: 2015.06.21, 16:21
Контактная информация:

Re: Два разных подхода для работы c tags

Сообщение rugabarbo »

an.viktory@gmail.com писал(а): 2018.01.05, 11:09 а вдруг в будущем будут проблемы о которых я пока не подозреваю и потом придется все переделывать.
Так и будет. Кайдзен в помощь.
an.viktory@gmail.com
Сообщения: 536
Зарегистрирован: 2016.09.05, 23:21

Re: Два разных подхода для работы c tags

Сообщение an.viktory@gmail.com »

rugabarbo писал(а): 2018.01.05, 14:19

Так и будет. Кайдзен в помощь.
Кайдзен — японская философия или практика??
an.viktory@gmail.com
Сообщения: 536
Зарегистрирован: 2016.09.05, 23:21

Re: Два разных подхода для работы c tags

Сообщение an.viktory@gmail.com »

тогда надо открывать новую ветку yii2 philosophy extension
Ответить