Javascript-форум (https://javascript.ru/forum/)
-   Серверные языки и технологии (https://javascript.ru/forum/server/)
-   -   Реализация кэша БД (https://javascript.ru/forum/server/74381-realizaciya-kehsha-bd.html)

xShift 05.07.2018 21:26

Реализация кэша БД
 
Собсно, вопрос про кэш БД на PHP.

Есть ли у MySQL какая-то команда, которая выплевывает текущий хэш состояния или какой-то слепок MD5?

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

То есть мне по факту нужен MD5 конкретной таблицы ...

Есть ли у MySQL такая фича?

laimas 05.07.2018 22:01

Нет такого, есть триггеры, используйте.

xShift 06.07.2018 15:35

laimas, хреново, придется сделать ... Я лет 5 назад смотрел на instance SHEMA, который есть у БД MySQL и у меня родилась вот такая идея, но потом почему то все не довел до конца.

Какие-то есть идеи как это можно использовать или как бы это можно было реализовать?


Ура. Я сделал нормальный кэш :)


Цитата:

CHECKSUM TABLE tbl_name [, tbl_name] ... [QUICK | EXTENDED]
https://dev.mysql.com/doc/refman/5.7...sum-table.html

laimas 06.07.2018 15:59

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

Есть и другая проблема. Если бы у базы был один "ленивый" пользователь, еще ладно, но что делать, если в момент время вычисления хеш Th производится запрос на модификацию Tm (считаем, что программно мы определяем только модификацию, на которую и реагируем). Если прибегнуть к блокировке, то можно завершить вычисление хеш, но он будут некорректным, а значит и смысла в ней нет, придется сбрасывать и производить операцию заново по окончании запроса Tm. Но опять не все так просто, ибо запрос может быть обновление-выборка-вставка и т.п.

Вряд ли есть необходимость следить за всей базой (решение проблем с потерями данных возлагается на резервное копирование), но бывает необходимость слежения за изменением определенных данных в таблицах и для этого служат триггеры.

laimas 06.07.2018 16:09

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

xShift 06.07.2018 16:16

laimas, к словам придираетесь.

Мне надо было знать что кэш статика(тупо JSON) соответствует контенту в БД, а за триггер спасибо. Подцеплю на insert, delete и update триггер для добавления этой checksum в табличку хэш и перед выполнением select буду сравнивать хэш статики и хэш в таблице hash_tables. Это даст мне офигенный прирост скорости. Щас укладываюсь в 20 запросов на все что нужно. Будет 1 - станет отлично.

p.s.: жалко что хостинг в SCHEMA не пускает из-за того, что это корневая фича(каждая БД разделена на аккаунты без этих привилегий - там есть эта срань).

laimas 06.07.2018 17:04

Ну почему придираюсь. )

md5, это на криптостойком генераторе со всеми прелестями из-за этого, а для расчета контрольной суммы есть и более щадящие алгоритмы.

А в контексте кеширования сопутствующих вопросов куча, которые придется решать. Но коли база, это нечто простое, то хозяин барин. ;)

xShift 06.07.2018 19:54

laimas, будете ли вы, Сэр, напрягаться из-за одного запроса перед обработкой всех данных, который будет дефайнить массив в глобальную переменную с хэшами текущего состояния базы?

Чувствую предлагаете вы использовать низкоуровневые функции MySQL для построчной обработки всех ячеек и последующей конкатенации какого-то более простого cheksumm? Нет, медихлорианы мои подсказывают, что мсье бы и знал толк в извращениях, но не стал бы это делать.

~80% активности это просмотр, а значит select. Цифра не случайна и вытекает из того, что большинство запросов создается анонами, ботами.

Один запрос в инициализацию ядра и мы имеем статический кэш. Один чуть более нагруженный inset/update и delete и мы имеем обновление. Одна файловая операция записи на эти уточнения и все чики-пуки.

Насчет триггеров, кстати, какая то там построковая непонятная логика. Пока не проверил, но FOREACH ROWS меня смущает. Наверное даже от три тригера откажусь.

Собсно, сегодня обнаружил, что у меня get comments зациклился и получилось 57 запросов. Оптимизировал - стало 17. Разница выполнения смешная: 0,02 секунды против 0,2 сек.

Исходя из того, что у меня есть свой движок для БД на базе конкатенации запроса абстракций из структурного массива и есть хэлпер, который просто получает то, что нужно по GetData('any_shit') - я просто добавляю автоматику для получения и обновления кэша, добавляю туда же автоматику для сброса и получения статики и больше ни о чем не думаю.

Сосали все Doctryne и ORM потому, что тот же WP жрет 60 запросов без обвязки, а кэш у него говно. А эти DQL вообще нахер не нужны.

Когда Node.JS доживет до своей нормальной БД - я задумаюсь уходить с backend PHP. Нода щас хуже раз в 15, а PHP стает слегка асинхронным.

Вот такой беспонтовый опус про BigData-идиотов.

laimas 06.07.2018 20:38

Если ваше кеширование, это "не изменилось, значит не тревожим", ваше право, но это не есть гибкость приложения. Данные в базе даже неизменяемые во времени совсем еще не означают, что запрос на выборку всегда одинаков. Чего вы там пытаетесь хранить и зачем, вам виднее.

А если говорить об истинном кешировании SQL запросов, то кто вам мешает почитать, ведь об этом написано предостаточно, например, или, и т.д., в общем Гугл в помощь.

xShift 06.07.2018 23:13

laimas, тщательно протестировал.

Вот пример query для создания хэша:

выполняется при update, insert, delete и выставляет флаг для следующего

Цитата:

$SQL = 'CHECKSUM TABLE `'. self::$sql_hash_table .'`;';
выполняется, если предыдущее выставило флаг

Цитата:

$SQL = 'INSERT INTO `revolver__hash` (`field_id`, `field_'. explode('__', self::$sql_hash_table)[1] .'`) VALUES (\'1\', \''. self::$sql_actual_hash .'\')
ON DUPLICATE KEY UPDATE `field_id`=\'1\', `field_'. explode('__', self::$sql_hash_table)[1] .'`=\''. self::$sql_actual_hash .'\';';
дальше таблица пишется в файл полностью и к ней лепится метка self::$sql_actual_hash.

Запускается процесс и первым делом выставляется define('cache_hashe', [hashes] );

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

Каждая нужная таблица - отдельный файл.

Таким образом не нужны никакие метки протухания и планировщики.

Весь класс пока выложить не могу - еще нужна обкатка.

Мемкэш мне не нужен - это зависимости модуля и как правило 'залипание'.
Кэш есть и у самой БД внутри - это я знаю.
Кэш шаблонизатора - это тоже фигня фактически, хотя смерти в свое время был шикарен.
Cron - не гарантирует моментальное обновление и подразумевает геморройный batch.

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

p.s.: уложился в 1 запрос для создания checksumm и в 2 запроса при обновлении(checksumm+action), а также для сайтов со статическим содержимым типа библиотек без комментирования и пользователей всего 1 запрос на отрисовку.

laimas 06.07.2018 23:59

Разговор ни о чем. Можно привести массу примеров, когда кеш как файл, это бесполезная работа.

Чего и для чего вы это делаете мне трудно судить, но первое что надо сделать, это оптимизировать запросы, EXPLAIN в помощь. И только потом кеширование.

А один или два запроса, это еще не показатель успеха.

xShift 07.07.2018 10:42

laimas, окей. покажу свою базу. Мне это все не нужно уже.

Цитата:


...

$STRUCT_STATS = [
'field_id' => [
'type' => 'num', // int
'auto' => true, // auto increment
'length' => 255,
'value' => 0
],
'field_date' => [
'type' => 'text',
'length' => 100,
'fill' => true
],
'field_time' => [
'type' => 'text',
'length' => 100,
'fill' => true
],
'field_track' => [
'type' => 'text',
'length' => 100,
'fill' => true
],
'field_route' => [
'type' => 'text',
'length' => 255,
'fill' => true
],
'field_user_agent' => [
'type' => 'text',
'length' => 255,
'fill' => true
],
'field_ip' => [
'type' => 'text',
'length' => 255,
'fill' => true
],
'field_referer' => [
'type' => 'text',
'length' => 500,
'fill' => true
],
];

$STRUCT_HASH = [
'field_id' => [
'type' => 'num', // int
'auto' => true, // auto increment
'length' => 255,
'value' => 0
],
'field_statistics' => [
'type' => 'text',
'length' => 100,
'fill' => true
],
'field_comments' => [
'type' => 'text',
'length' => 100,
'fill' => true
],
'field_nodes' => [
'type' => 'text',
'length' => 100,
'fill' => true
],
'field_messages' => [
'type' => 'text',
'length' => 100,
'fill' => true
],
'field_roles' => [
'type' => 'text',
'length' => 100,
'fill' => true
],
'field_points' => [
'type' => 'text',
'length' => 100,
'fill' => true
],
'field_users' => [
'type' => 'text',
'length' => 100,
'fill' => true
],
'field_categories' => [
'type' => 'text',
'length' => 100,
'fill' => true
],
'field_files' => [
'type' => 'text',
'length' => 100,
'fill' => true
],
'field_twilio' => [
'type' => 'text',
'length' => 100,
'fill' => true
],
'field_settings' => [
'type' => 'text',
'length' => 100,
'fill' => true
]
];

// Compare structs
define('SCHEMA',
array(
'statistics' => $STRUCT_STATS,
'comments' => $STRUCT_COMMENTS,
'nodes' => $STRUCT_NODES,
'messages' => $STRUCT_MESSAGES,
'roles' => $STRUCT_ROLES,
'points' => $STRUCT_POINTS,
'users' => $STRUCT_USER,
'categories' => $STRUCT_CATEGORIES,
'files' => $STRUCT_FILES,
'twilio' => $STRUCT_TWILIO_SETTINGS,
'settings' => $STRUCT_SITE,
'hash' => $STRUCT_HASH
)
);

...
Вот тип структуры, который подхватывает движок. Запросы я не пишу вообще(они сами консервируются и сами выполняются, сами оптимизируются). Вместо JOIN UNION. Все в ядре.

Я добавил структуру - движок создал таблицу. Я описал поля и действие - движок выполнил запрос.

Вот например:

Цитата:

// twilio settings
$dbx::query('c', 'revolver__twilio', $STRUCT_TWILIO_SETTINGS);

$STRUCT_TWILIO_SETTINGS['field_id']['value'] = 0;
$STRUCT_TWILIO_SETTINGS['field_sid']['value'] = 'XXXXXXXXXXXX';
$STRUCT_TWILIO_SETTINGS['field_token']['value'] = 'XXXXXXXXXXXX';
$STRUCT_TWILIO_SETTINGS['field_number']['value'] = 'XXXXXXXXXXXX';
$STRUCT_TWILIO_SETTINGS['field_enabled']['value'] = 0;

$dbx::query('i', 'revolver__twilio', $STRUCT_TWILIO_SETTINGS);
И все это на файловом кэше.

Кэш файл бесполезным быть не может. Любая база это и так файл. У меня база отвалится, а сайт будет работать как ни в чем не бывало. Только операции записи не будут выполняться.

laimas 07.07.2018 12:51

И это все из-за чего весь сыр бор?

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

https://habr.com/post/322532/

xShift 08.07.2018 14:41

Я не могу читать этих е%аных лобосеков и прочее PHD. Это же интеллектуальные извращенцы. Пишут чуть ли не книги ни о чем. Ни кода ни примеров ни даже актуальных графиков. Трендами меряются и все.

У меня родилась идея кстати на фоне предыдцэущего mysql запроса реализовать вместо update insert на базе duplicate key. И назову я это inject запрос. Это сделает мою либу еще удобнее :)

laimas 08.07.2018 15:00

Я не понимаю вообще о чем речь среди жаргона, делайте что хотите. )

xShift 08.07.2018 16:19

Эх. Как мне жить? Нет мне места в этом мире ... :D лобосеки нэгодуэ.

xShift 12.07.2018 09:15

Если кому интересно, вот про ON DUPLICATE KEY UPDATE английском(русском писать не умею - идет один сленг, мат и ненависть к мудакам).

https://cyberx.pro/backend/mysql-dup...te-and-insert/

laimas 12.07.2018 12:27

Цитата:

Сообщение от xShift
русском писать не умею - идет один сленг, мат и ненависть к мудакам

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

xShift 12.07.2018 17:16

Вот я и стараюсь. Со славянами я развиваюсь на 30% при вей их адекватности. С англичанами и американцами на 90%. Мозги ни к черту в российской системе. Я живу в планетарной. У меня включился российский мост в англию и один тамошний разработчик - я начал создавать что то чего еще не делал и щебенькать на английском. У меня включились хабры - я стал лохом потому что они обосрали не только меня но еще и пол системы с которой я работал. Лучше на корявом английском с воспитанными, чем с такими ухмыляющимися лобосеками. Ведь вы понимаете о чем речь? Вы есть в разработчиках ? У нас конфедерация. Мы почти ни к кому не лезем и ни с кем особо не разговариваем, просто иногда скучно через транслитерацию общаться. Половина смысла теряется и начинаешь использовать фразы типа "не нормальным не можешь не считаться". Скажите так кому нибудь - от вас застрелиться. Поэтому все периодически высаживают негатив на родной язык. А так мосту привыкнешь просто перестанешь разговаривать, что не очень хорошо. Мозги в планетарке - ты уже не человек для остальных людей, все стает системным и систематическим, если оно полезно.


Часовой пояс GMT +3, время: 17:43.