Вот я типа думаю, куда записывать лайки юзеров (конкретных).
Есть идея записывать все в таблицу likes, и потом через select * from likes where user = 'vaska' and post_id =12345.
Подскажите, туда ли я вообще иду?
tukreb, вполне) Но тут mysql)) Поэтому заводить базу под лайки PostgreSQL не думаю что интересно) А что-то из no-sql всегда есть в проекте например, redis
ну ерунда же
имеется в виду наверное какая-то in-memory датабаза, но проблема-то в том что лайки надо хранить
то есть записывать на диск.
и каким местом здесь no-sql, в любой форме - не ясно
tukreb, называется "слышал звон, да не знаю где он".
увидел знакомое слово nosql и решил выдать где-то услышанную фразу про постгрес, такой триггер, типа условного рефлекса, да?
Хотя казалось бы - где лайки а где джейсон.
FanatPHP, можно лайки хранить в сете редиса не записывая в базу. таким же образом можно хранить какие нибудь подписки на что либо и т.п. типы данных. благодаря скорости можно будет хоть каждые 0,1 секунды менять статус со вкл на выкл с реляционной бд на больших объемах будут проблемы. Так же как только мы ставим в один ряд RDB и count() то тоже все не ок придется денормализовывать поле.
Так что nosql имеет место быть). и редис умеет писать на диск.
Андрей Галкин, это всё хорошо звучит только в теориях. не сказать фантазиях
Вся проблема с такими вот досужими рассуждениями на тостере, что их приводят те, кто не пробовал применять свои советы на практике.
редис умеет писать на диск ровно в 1 (один) поток. и из стремительного домкрата вся твоя стильная модная молодежная ноусиквел диби превращается в кусок кирпича
я не встречал использование редиса для каких-либо других целей кроме кэширования, по крайней мере под большими нагрузками
Не говоря уже о том что RDB на то и RDB, что позволяет связывать данные между собой и получать из исходного массива данных новые структуры. и я могу например получить все статьи, которые пользователь лайкал. и как ты это получишь из своего сета, где у статьи просто перечислены все пользователи, кто её лайкал?
<?php
include 'vendor/autoload.php';
$client = new \Predis\Client();
$client->connect();
for ($articleId = 0; $articleId < 1000000; ++$articleId) {
for ($i = 0; $i < rand(0, 500); ++$i) {
$client->sadd('article' . $articleId, [rand(0, 100000)]);
}
}
<?php
include 'vendor/autoload.php';
$client = new \Predis\Client();
$client->connect();
Bench::start();
$lua = <<<LUA
local ans, has, cursor = {}, {}, "0";
repeat
local t = redis.call("SCAN", cursor, "MATCH", "*", "COUNT", 10000000000);
local list = t[2];
for i = 1, #list do
local s = list[i];
local u = redis.call("SISMEMBER", s, "50000");
if u == 1 then
if has[s] == nil then has[s] = 1; ans[#ans + 1] = s; end;
end;
end;
cursor = t[1];
until cursor == "0";
return ans; --or return ans;
LUA;
$result_set = $client->eval($lua, 0);
print_r(Bench::getStats());
var_export($result_set);
да для пербора миллиона статей придется потратить полторы секунды но ничего не мешает закешировать данный результат... думаю объяснять что это самое тупое решение в лоб, не нужно?
Андрей Галкин, нужно :)
вот чтобы не заниматься такой фигнёй, как перебор записей вручную на коленке, и был придуман язык SQL :)
ну то есть я уважаю приложенные усилия, всегда приятно говорить с человеком который по крайней мере отвечает за свои слова. но тут же за километр уши торчат "решения ради решения", "усрусь, но сделаю!", которое никто в здравом уме применять в продакшене не будет
FanatPHP, на самом деле мне было интересно как редис реагирует на быдлокод а не решение ради решения). суть в том что благодаря луа можно создавать кастомные структуры данных на базе встроенных и ничего не мешает завести 2 сета для пользователя и статьи соответственно. На установку мы пишем скрипт который ведет эти 2 сета благодаря этому мы можем полностью обеспечить все требования ACID а скрипт выше выполняется 1 раз как "миграция" которая просчитает все необходимое. На самом деле мне не нужно тебе доказывать что носкуль "удобнее" чем рдб. Достаточно прикинуть сколько по факту вывезет sql операций записи. MySQL на самом мощном железе в OLTP Read Write проводит 50000 транзакций в секунду. До этого порога такими вещами можно не заморачиваться... но после уже никуда не деться... при условии что на это железо есть деньги разумеется))) https://www.mysql.com/why-mysql/benchmarks/mysql/ тут есть инфа
Андрей Галкин, MySQL упирается, но там где толстый сохнет, худой сдохнет. Вспоминаем про один поток записи в редисе и горестно плачем.
Если мы хотим чтобы это была именно зафиксированная транзакция, а не просто информация пока есть ток в рубильнике, то с редис уж совсем не при делах.
Мне кажется что транзакции на редисе - это что-то совсем из области фантазий. Ну по крайней мере настолько, насколько я вижу эту ситуацию. Сам я руками это всё не щупал, но из того что смотрел по теме, Redis server saves all its data to HDD from time to time, thus providing some level of persistence выглядит довольно правдоподобно. И совершенно неприемлемо с точки зрения требований, которые мы предъявляем к mysql, когда говорим об OLTP
FanatPHP, https://redis.io/topics/persistence здесь есть подробная инфа по сохранению и "качеству" сохранения, если вдруг появится интерес. Можно настроить чтобы он каждую выполненную комманду писал в файл (что то вроде бинлога) по которому можно восстановится. Я просто сам как-то попал на проект (причем довольно крупный) на котором балансы пользователей хранились в редисе, балансы менялись в нанобаксах и очень часто,иногда несколько раз в секунду для тысяч пользователей. За пару лет было ноль проблем да и до меня вроде конфузов не было, поэтому отношусь менее скептически, и тебе рекомендую. Ну и как не крути а редис это не серебрянная пуля и уж тем более не замена RDB. Он может пригодится как раз в тех случаях когда данные могут изменЯтся чаще чем раз в секунду для большого количества записей одновременно и тратить I/O RDB для этого накладно.