게시물에 대한 좋아요 또는 투표


10

사용자가 글을 올리거나 블로그를 작성하는 작은 프로그램을 만들고 있습니다. 이러한 게시물에서 다른 사용자는 페이스 북에서와 같이 게시물을 좋아하거나 싫어하거나 스택 오버플로에서와 같이 게시물을 공감 또는 하향 투표 할 수 있습니다. 나는 일반적으로 사용되는 좋은 데이터베이스 구조를 알고 싶습니다. 프로그램은 그 구조와 효율적으로 작동합니다. 두 가지 옵션이 있습니다

먼저

게시하다:

id   head   message   datepost   likes   dislikes
1     ab    anchdg     DATE      1,2,3   7,55,44,3

위와 같이 idpostid입니다. 좋아요 열에 1,2,3는 게시물이나 블로그를 좋아하거나 투표 한 사용자의 ID가 있습니다. 7,55,44,3게시물이나 블로그를 싫어하거나 다운 보증 한 사용자의 ID입니다.

둘째

게시하다:

id    head  message   datepost
1     ab    anchdg     DATE

좋아요 :

id    postid    userid
1       1         1
2       2         2

싫어함 :

id    postid    userid
1       1         7
2       1         55

이런 식으로, 내가 좋아하는 것과 싫어하는 것이 포스트의 좋아하는 것을 얻기 위해 두 개의 분리 된 테이블을 만들어야한다. 이런 식으로, 테이블 은 Likes& & Dislikes크게 채워질 것입니다. 이로 인해 테이블이 무거워지고 처리 속도가 느려질 수 있습니다.

그래서이 작업을 수행하는 더 좋고 표준적인 방법이 무엇인지 알고 싶습니다.


4
사용자 가 게시물을 좋아 하고 싫어할 수 없다고 가정하고 있습니까? 그렇다면 좋아하는 것과 싫어하는 것에 대한 하나의 테이블이 있고 BIT 열 (좋아하는 경우 1, 싫어하는 경우 0)이 있습니다.
dwjv

1
또는 1과 -1 더 쉬운 합계
jkavalik

1
@dwjv 첫 번째 예에서 사용자 3은 실제로 게시물을 좋아 하고 싫어했습니다.
Dan Henderson

답변:


20

직면하는 문제는 데이터베이스의 "일반 형식", 특히 첫 번째 일반 형식으로 알려져 있습니다. https://en.wikipedia.org/wiki/First_normal_form .

연결된 사용자 ID (첫 번째 버전)가있는 데이터베이스는 첫 번째 정규 형식이 아닙니다.

정규화가 일반적인 이유와 방법에 대해서는 https://en.wikipedia.org/wiki/Database_normalization 을 참조 하십시오 .

첫 번째 예에서 "사용자 4는 더 이상 게시물을 좋아하지 않습니다"에 대한 쿼리가 복잡해집니다. 부작용과 코너 사례를 고려해야하는 문자열 조작을 수행해야합니다 (사용자는 유일한 "좋아하는"사용자, 사용자는 마지막으로 좋아하는 사용자, 사용자는 좋아하는 사용자 문자열의 중간에 있음). 나는 이것이 나쁘다는 것을 알 것이다. 하지마 정규화 된 디자인을 사용하십시오.

다시 : 데이터베이스가 무거워진다

4 백만 개의 좋아요가있는 게시물이있는 경우 데이터베이스 디자인 1에서 너비가 최소 4 백만자인 "likes"열이있는 행이 하나 있습니다 (세퍼레이터 문자로 쉼표가 필요하기 때문). 그런 다음 4 백만 자리 너비의 문자열에서 문자열 작업을 수행해야합니다. 이것은 매우 성능이 떨어지고 느립니다.

반면 데이터베이스는 수백만 행을 처리하도록 설계되었습니다. 우리는 수억 개의 행을 가진 데이터베이스를 가지고 있으며 count () 작업이 빠릅니다. 매우 빠릅니다. 따라서 성능 병목 현상이 아닙니다.

다음 문제는 가독성과 유지 관리 성입니다.

예를 들어,이 두 문장이 무엇을하는지 알려주십시오.

select count(*)
from posts
inner join likes on posts.postid = likes.postid
where postid = 7

select len(likes) - len(replace(likes, ',', ''))
from posts
where postid = 7

내가 언급했듯이, 테이블에 crores 또는 수십억 개의 좋아요가 있으면 테이블이 무겁지 않습니까? 테이블이 매우 빨리 채워 지므로 레코드가 많은 테이블을 검색하는 데 시간이 많이 걸리지 않습니까?
Harshit Shrivastava

6
@HarshitShrivastava mysql은 수십억 행의 간단한 테이블을 처리 할 수 ​​있지만 사용자 테이블에있는 수십억 개의 열을 문자열로 상상해보십시오.
jkavalik

3
@til_b가 직접 언급하지 않는 한 가지는 (일반적으로 일반 형식을 사용하여 암시 됨) 제대로 구현 된 두 번째 디자인은 기본 데이터베이스 엔진이 첫 번째 디자인 패턴으로는 수행 할 수없는 참조 무결성을 유지할 수 있다는 것입니다. 즉, 사용자 4가 삭제되면 데이터베이스는 사용자 4 레코드에 의존하는 레코드를 알고 있기 때문에 연결된 데이터를 정리합니다. 데이터베이스는 문자열에서 관계를 관리하는 방법을 직관적으로 알지 못하므로 첫 번째 디자인은 불가능합니다.
David Antaramian

9

두 번째 방법은 좋아요 / 싫어요를 쉽게 추가하거나 제거 할 수 있기 때문에 훨씬 좋습니다.

그러나 좋아하거나 싫어하는 테이블 하나를 사용하여 두 번째 솔루션을 수정해야합니다.
like / dislike 테이블의 열은 id, postid, userid 및 like 또는 dislike 값의 다른 열이어야합니다 (예 : dislike의 경우 1, like의 경우 -1).

post_id와 user_id를 복합 기본 키로 설정하면 정상적으로 작동합니다.

테이블 크기는 시간이 지남에 따라 커집니다. 그러나 두 개의 실제 열만 있습니다. 좋아요 / 싫어요의 id와 가치. postid와 userid는 오직 그것에 연결되어 있으며 사용자와 포스트 테이블에 저장됩니다.


3
당신은해야한다 user_id, post_id그리고 value테이블이다. 별도의 id열이 필요하지 않습니다 .
jkavalik

3
질문에 대한 @jkavalik의 의견에서 제안했듯이 1과 -1은 아마도 1과 2보다 좋아하고 싫어하는 값이 더 좋을 것입니다. "1"인 행 수에서 "2"인 행.
Dan Henderson

@ DanHenderson : 좋아하는 것-싫어하는 것이 합보다 훨씬 빠를 수 있습니다. (그러나 그것은 1과 -1에서도 작동합니다.)
cHao

사랑과 분노와 같은 2 가지 행동을 더한다면 어떻게 하시겠습니까? 나는 2 더 많은 행동으로 좋아하는 1과 싫어하는 -1을 의미
PirateApp

당신이 sum아무것도 하고 싶지 않다면 사랑 = 2와 분노 = 3을 설정할 수 있습니다.
Julian S
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.