게시글 리스트에서 '좋아요' 버튼을 눌렀는지 판별

조회수 5557회

간단한 게시판에 Facebook처럼 좋아요 버튼을 만들어 넣으려고 시도중입니다.

게시판 테이블과, 좋아요 테이블이 따로 있는 형태이며

Bbs.java

private int id;
private String title;
private String content;
private int likeCount;
private User writeUser;
// 넣어야 하는지
private Set<Likes> likes;
Likes.java

private int id;
private int userId;
private int boardId;

좋아요를 누를경우 해당 게시판 테이블의 좋아요 count 를 +1 해줘서 좋아요가 늘어나고

이미 좋아요 했을경우엔 좋아요 테이블에서 해당 사용자가 해당 게시글을 좋아요 한적이 있나 판단해 차단하는데

리스트를 쭉 불러올때 내가 좋아요 했던 글인지 아닌지 판단을 어떻게 해야할지 궁금합니다.

게시판 테이블에 Set의 형태로 좋아요 한 사람들의 목록을 넣어주게 되면 가능하나.

리스트 출력시에 SQL문이 너무 복잡해져 성능에 무리가 있지 않을까 걱정이 되면서도

내가 좋아요 한 글을 판별할때 저것말고 다른 방법이 있을까 궁금합니다.

  • (•́ ✖ •̀)
    알 수 없는 사용자

3 답변

  • 게시글 가져오기

    SELECT * FROM Bbs WHERE <Condition>
    

    위의 쿼리에서 "내가 좋아요 했던 글인지 아닌지 판단" 이 목적이라면,

    SELECT Bbs.*, CASE WHEN Likes.id IS NULL THEN false ELSE true END FROM Bbs LEFT JOIN Likes ON Bbs.id=Likes.boardId AND Likes.userId=<myId> WHERE <Condition>
    

    위와 같이 질의를 하면 될 것 같네요.

    전제조건은 LEFT JOIN 에 의해서 글(BBS)당 좋아요가 1개씩만 연결되어야만 합니다. 이를 위해 한 사용자는 한 글에 하나의 좋아요만 할 수 있게 해주어야 합니다. 따라서 Likes 테이블에서 userId와 boardId가 UNIQUE KEY여야 합니다. 그리고 LEFT JOIN에서 ON 문에 Likes.userId=<myId>를 써주어서 한 사람이 한 글(BBS)에 1개의 좋아요를 지정할 수 있도록 하면 됩니다.

    이렇게 하면, ON Bbs.id=Likes.boardId AND Likes.userId=<myId> 에 의해서 Bbs의 레코드는 1개의 Likes 레코드와 JOIN되거나 Likes 레코드가 없는 경우 Likes에 해당하는 모든 컬럼이 NULL로 JOIN되게 됩니다.

    그렇게 다면 CASE WHEN Likes.id IS NULL THEN false ELSE true END 구문으로, Likes한적이 있는 지 없는지 판별할 수 있습니다. 이 구문은 Likes.id가 있으면 true를 없으면 false로 하도록하는 if 구문이라고 생각하시면됩니다. DB에 따라서는 이에 해당 구문이 함수로 제공하기도 합니다. mysql은 ifnull, 오라클은 nvl, MS-SQL은 isnull 같은 함수를 사용해도 됩니다.

    • 결국 조인해서 나와야하는군요 성능이 많이떨어지지않는지 걱정됩니다 답변감사합니다 알 수 없는 사용자 2016.4.14 17:22
    • 성능을 조금 높이려면 SQL에서 CASE 를 쓰지 말고, Likes.id를 받고, 응용단에서 NULL 체크를 하시면 될것 같습니다. 그리고 JOIN에 참여하는 tuple을 가능하면 줄이는 쪽으로 SQL를 만들면 조금 더 성능이 좋아집니다. 한번에 리스트에서 보여주는 아이템수가 많지 않다면, 2회 질의(먼지 BBS목록을 구하고, 이 리스트에 해당하는 Likes만 구하는 것)하는 쪽으로 생각하셔도 될것 같습니다. 허대영(소프트웨어융합대학) 2016.4.15 17:41
  • 목록을 JSON으로 넣는다 가정하면

    { '누구아이디', '홍길동아이디', '개똥이아이디' } ...

    위와같이 계속 쌓이게 되면 관리가 복잡해집니다.

    없애버리고 아래와같이 하면 매우 편리해져요

    SELECT 0 FROM Likes WHERE userId = '내 id' AND boardId = '글 id'
    

    지금글 아이디가 5라고 가정하고 내가 좋아요를 했다면

    위의 쿼리대로면 좋아요 기록 테이블에서 내 유저아이디와 지금 글 아이디인 5를 가져오게 되는거죠.

    없다면 아무것도 안가져오겠고 있다면 뭐라도 가져올테니 그걸로 체크를 하시면 될것같습니다

    어차피 여부만 확인하면 되니 SELECT 0 으로 해주어 db부하도 줄일수 있습니다

    • (•́ ✖ •̀)
      알 수 없는 사용자
    • 제 질문이 정확하지않았나보네요 ㅠㅠ / 궁금한게 게시글 리스트를 불러올때 각각 글마다 좋아요 카운트다 표시됩니다 그중 제가 카운트한 게시글이 알 수 없는 사용자 2016.4.13 00:44
    • 어떤건지, 리스트에서 바로 확인을 하고싶어서 입니다, 알 수 없는 사용자 2016.4.13 00:45
  • 게시판 목록을 읽어올 때 boardId의 리스트에 해당하는 모든 Likes를 읽어오고 애플리케이션 내에서 이 목록에 있는지 체크해야할 것 같습니다. 게시판 테이블의 Set은 필요없을 것 같구요.

    SELECT * FROM Likes WHERE userId = 1 AND (boardId > 1 AND boardId < 20)
    

    만일 postgresql을 사용하신다면 Array type column을 사용할 수가 있는데 이 경우 게시판 테이블에 좋아요한 userId array column을 추가하면 목록을 읽어올 때 편리합니다.

    http://www.postgresql.org/docs/9.4/static/arrays.html

    • (•́ ✖ •̀)
      알 수 없는 사용자
    • 감사합니다 저도 이게성능이 젤빠를거같긴한데 한번 판단작업이 들어가야겠네요 알 수 없는 사용자 2016.4.14 17:23

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)