Zastanawiam się jak przechowywać oceny i lajki w bazie. Hipotetyczna sytuacja - mam post napisany przez kogoś i można go zarówno lajkować i oceniać. Jeśli chodzi o lajki to coś takiego jak tutaj na forum docenianie postów - można docenić raz. Więc powiedzmy, że dla każdego posta mam złączenie z tabelą lajków(oneToMany) tylko teraz tak - wyciąganie z bazy wszystkich lajków tylko po to żeby je policzyć to chyba słabe rozwiązanie tym bardziej jeżeli będzie ich więcej. Poza tym muszę sprawdzić czy użytkownik taki już dodał ocenę i ewentualnie tego zabronić. Jeśli chodzi o oceny to sprawa wygląda bardzo podobnie z tym, że na przykład można ocenić post ocenami od 1 do 5 a prezentować średnią no i teraz - chyba też bez sensu wyciągać wszystkie oceny żeby policzyć średnią i sprawdzić czy taki użytkownik już oceniał dany post... Jakie rozwiązania się praktykuje w takim przypadku?
ps. jeśli to ma jakieś znaczenie obecnie używam jpa+mysql.
Przy poście zapisana ilość lików i średnia ocena. Aktualizowana triggerem przy dodaniu kolejnego.
Marcin.Miga napisał(a):
Przy poście zapisana ilość lików i średnia ocena. Aktualizowana triggerem przy dodaniu kolejnego.
Nie bardzo rozumiem co masz na myśli z tego co mi się wydaje powinno być to w osobnej tabeli a aktualizowane po dodaniu like lub ocenie a nie przy dodaniu kolejnego posta. Więc jak by ten trigger miał działać skoro ma się tyczyć konkretnego posta?
Ewentualnie myślałem tak:
W tabeli likeów trzymać : id posta, ilość likeów dla tego posta(i to aktualizowane w triggerze ale musi to być z klauzulą where jakoś-nie znam się na triggerach) a żeby zapobiec wielokrotnemu likeowaniu przez jednego użytkownika w osobnej tabeli trzymać id posta, id likeującego i robić zapytanie i jeżeli jest takie id to zabronić... To chyba ma jakiś sens.
Zrób 2 tabele:
TAB_POSTS
- POS_ID
- POS_CNT_LIKE
- POS_AVG_RATE
TAB_ATTRIBUTE_POST
- ATP_ID
- ATP_POS_ID
- ATP_USER_ID
- ATP_RATE
- ATP_LIKE
Triger niżej jest w oracle ale nie powinno zbytnio się róznic od MySQL
CREATE OR REPLACE TRIGGER T_AIU_ATP
AFTER INSERT OR UPDATE ON TAB_ATTRIBUTE_POST
FOR EACH ROW
BEGIN
UPDATE TAB_POSTS
SET POS_AVG_RATE = (SELECT NVL(AVG(ATP_RATE),0)
FROM TAB_ATRIBUTE_POST
WHERE ATP_POS_ID = :NEW.atp_pos_id)
POS_CNT_LIKE = (SELECT COUNT(*)
FROM TAB_ATRIBUTE_POST
WHERE ATP_POS_ID = :NEW.atp_pos_id
AND ATP_LIKE = <TWÓJ ZNACZNIK CZY JEST ZALAJKOWANY>)
WHERE POS_ID = = :NEW.atp_pos_id
END;