Diskuze: Like systém pro nepřihlášené uživatele
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.
Člen
Zobrazeno 9 zpráv z 9.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.
V případě přidání sloupečku like ke komentářům asi s 2 situací nic
neuděláš, maximálně tak do session uložit co lajknul, ale po zavření
prohlížeče by moh zase...
Ještě mě napadá tam mít uloženej dlouhej string se všemi ID uživatelů,
co již hlasovali, ale to je asi pitomost
Pokud by jsi měl dvě tabulky, tak by to bylo jednoduché, prostě by si při
lajku zjistil, jestli v tabulce lajků není řádek, kde je příspěvek s
tímto ID a zároveň je u něho záznam s ID uživatele a vynadáš mu že
nemůže...
Funkci GROUP neznám, každopádně já bych to řešil pomocí COUNT (spočítal bych záznamy s ID příspěvku, kde je v like true, spočítal záznamy s like false, odečet a hotovo (za předpokladu že tabulka like by měla sloupce id příspěvku, id uživatele a like, kde by bylo T/F, podle toho, jestli dal like/dislike) teď sem v SQL dlouho nedělal, tak to možná bude špatně, ale mělo by to vypadat nějak takhle:
SELECT COUNT(*) FROM likes WHERE prispevekID=$pripevekId and like=True
) . Nevím, co je vhodnější, GROUP neznám, každopádně potřebuješ
počet, takže mi COUNT příde logické.
//teď ni dlošlo, že uživatel nemusí být přihlášen, takže když nebude
registrován, tak bych místo jeho ID použil aspoň jeho IP. Sice třeba ze
školy (která mívá jednu IP pro všechny zařízení) si lajkne jeden
člověk, ale je to asi jedinný způsob, jak zamezit tomu nekonečnému
lajkování
Udělej si ty dvě tabulky. Nemůžeš přeci všechno strkat do jedné.
Příspěvky jsou jasné. V druhé tabulce pro "lajky" si udělej sloupce pro
to id komentáře, id "lajku", +/-, datum a IP. IP kvůli jedinečnosti.
Pak z toho data a IP si to můžeš odvodit a podle toho kontrolovat. No a podle
id komentáře budeš počítat like a mínusy.
Snad jsem to napsal srozumitelně ...
//EDIT: Ach jo, zas byl někdo rychlejší.
Ahoj,
Pokud bys tyto informace nechtěl, pak bych se spíše rozhodl z hlediska výkonu. Myslím, že dělání UPDATE by mělo být o něco rychlejší, než provádění hromady INSERTů každou chvíli. Ale to by se spíš mělo týkat situací, kdy je velký počet liků každou chvíli (třeba jako má FB ).
Při situaci s INSERTy pak stačí akorát COUNT(*) AS pocetLiku WHERE comment_id = ...
V tomto případě nepůjde použít unikátní klíč, ale můžeš použít trigger BEFORE INSERT a zkontrolovat, zda v daném časovém období již like z dané IP nepřibyl.
Daný INSERT pak můžeš pomocí triggeru zastavit pomocí signálu:
https://dev.mysql.com/…/signal.html
Něco ve smyslu
CREATE TRIGGER nazev BEFORE INSERT ON tabulka_s_liky
BEGIN:
SET @actualTime = NOW();
-- mělo by vytáhnout záznam s posledním časem pro danou IP
SET @lastLikeTime = (
SELECT `time` FROM `like`
WHERE `ip` = NEW.ip
ORDER BY `time` DESC
LIMIT 1
);
IF DATE_ADD(@lastLikeTime, INTERVAL tvoje_casove_obdobi SECOND) > @actualTime THEN
SIGNAL SQLSTATE '045000'
SET MESSAGE_TEXT = 'V tomto komentáři jsi likoval nedávno';
END IF;
END;
Psal jsem to z hlavy, takže to syntakticky nemusí být správně. Návodů na triggery je na netu hromada
1.) Je lepší to dát do jedné tabulky se sloupečkem "like". Však ty potřebuješ jenom výsledné hodnocení příspěvku, ne?
2.) Založ si tabulku, kde budeš ukládat, který návštěvník lajkoval.
Tam bys ukládal buď IP adresu, nebo pokud by byl přihlášený, tak id
uživatele a samozřejmě id příspěvku.
//EDIT: Ups. někdo už odpovídal. No, snad příště.
Děkuju mnohokrát Jste fakt šikulové !!
Funkce GROUP se používám v SQL pro vytvoření právě té skupiny, ze které chci počítat COUNT()... V MySQL to asi není nutné.. to teď nevím z hlavy
Vytvoření té druhé tabulky s IP a časem bude asi nejlepší varianta Jinak, když už jsem vznesl dotaz... IP adresa je jediný identifikátor nepřihlášeného uživatele, který jde pro tyto účely použít, chápu to správně?
Ano, akorát někdo se může připojit ze školy, kde ty počítače mají stejnou IP. Tam v tom je problém, ale jinak v pohodě.
Pokud se nepletu, tak existuje v PHP i funkce gethostname(), která
ti vrátí název počítače, na kterém je uživatel připojen, ale pokud
budeš mít sérii BFU, kteří si nechali počítač jak je z výroby, tak by
se moh u všech jmenovat třeba HP (netuším jak si to výrobci
pojmenovávaj), nebo někteří tam zase mají franta-pc, a frantů
může bejt víc.
Možná, pokud se s tim chceš patlat, tak bych ještě při shodě IP zkusil
rozdíl názvu počítače (tím vyřadíš to že v celé škole si lajkne
jeden člověk)
Řešení je jednoduché, použít jak celkový počet, kde budeš při hlasování přidávat odebírat 1 a zvláštní tabulku, kde budeš uchovávat informace o hlasování (uživatel, ip, id příspěvku, atd) jak tu už někdo psal. Tedy při hlasování ověříš, zda ten člověk již nehlasoval (nepoužívat pouze ověření ip, vhodné je připojit i cookies, otisk prohlížeče a třeba i hostname), pokud nehlasoval, zapíšeš do tabulky a u příspěvku přidáš, odebereš hodnotu.
Důležitá věc co tu nezazněla - nepoužívat count, ani group, jednoduše proto, protože je to zbytečné, tím že budeš uchovávat aktuální stav (+12, -6 atd) se vyhneš vypočítávání při každém požadavku. Ano, existují indexy a ty funkce jsou rychlé, při pár tisících hodnot je to stále rychlé, nicméně pokud systém nabobtná a těch záznamů bude najednou milion a na jedné stránce zobrazíš 50 příspěvků, začneš pociťovat problémy s výkonem, při desítkách requestů za sekundu budeš mít opravdový problém.
Každý kdo tyto a podobné hodnoty vypočítává online, nechť si dá facku. Nehledě na to že když se bude uchovávat hodnotu v tabulce u příspěvku, ušetří se jeden sql dotaz.
Zobrazeno 9 zpráv z 9.