[mysql] 데이터베이스에서 주석 및 좋아요 구현

저는 소프트웨어 개발자입니다. 코딩을 좋아하지만 데이터베이스가 싫습니다 … 현재 사용자가 엔티티를 좋아 하는 것으로 표시 (FB와 같이)하고 태그를 지정하고 주석을 달 수있는 웹 사이트를 만들고 있습니다 .

이 기능을 처리하기 위해 데이터베이스 테이블 디자인에 갇혀 있습니다. 한 가지 유형의 작업 (예 : 사진)에 대해서만이 작업을 수행 할 수 있으면 해결 방법은 간단합니다. 그러나 나는 이것을 5 가지 다른 것들에 대해 가능하게해야합니다 (현재는 서비스 전체가 커짐에 따라이 숫자가 커질 수 있다고 가정합니다).

비슷한 질문이 있지만 만족스러운 답변이 없으므로이 질문을 다시 묻습니다.

문제는 제대로하는 방법이며, 효율적으로 하고 탄성 이 다른에 대한 의견을 저장할 수 그래서, 데이터베이스를 설계 테이블 , 좋아하는 다른위한 테이블태그 그들을 위해. 대답으로 일부 디자인 패턴이 가장 좋습니다.)

자세한 설명 : 나는이 테이블 User 일부 사용자 데이터, 3 개 테이블 : Photo사진 , Articles기사 , Places장소 . 로깅 된 사용자가 다음을 수행 할 수있게하고 싶습니다.

  • 이 세 가지 표 중 하나에 의견

  • 그들 중 하나를 좋아하는 것으로 표시

  • 태그를 사용하여 태그를 지정하십시오

  • 또한 모든 요소에 대한 좋아요 수와 특정 태그가 사용 된 횟수를 세고 싶습니다.

1 접근법 :

A)를 들어 태그 , 나는 만듭니다 테이블을 Tag [TagId, tagName, tagCounter] , 그때가 만들 대다 관계 테이블을 위해 : Photo_has_tags, Place_has_tag, Article_has_tag.

b) 의견도 마찬가지입니다.

C) 나는 만듭니다 테이블을 LikedPhotos [idUser, idPhoto] , LikedArticles[idUser, idArticle], LikedPlace [idUser, idPlace]. 수 좋아하는가 에 의해 계산됩니다 쿼리 (I 나쁜 가정). 과…

나는 마지막 부분에 대해이 디자인이 마음에 들지 않습니다. 나에게 나쁜 냄새가납니다.)

2 접근법 :

나는 테이블이 만들어집니다 ElementType [idType, TypeName == some table name]의 이름 관리자 (나)에 의해 채워집니다 테이블 수 있습니다 좋아 , 주석 또는 태그를 . 그런 다음 테이블 을 만듭니다 .

a) LikedElement [idLike, idUser, idElementType, idLikedElement]각각에 대해 적절한 열이있는 주석 및 태그에 대해 동일합니다. 이제 사진을 좋아하게 만들려면 다음을 삽입하십시오.

typeId = SELECT id FROM ElementType WHERE TypeName == 'Photo'
INSERT (user id, typeId, photoId)

그리고 장소 :

typeId = SELECT id FROM ElementType WHERE TypeName == 'Place'
INSERT (user id, typeId, placeId)

등등 … 저는 두 번째 접근 방식이 더 낫다고 생각하지만,이 디자인에서도 뭔가 빠진 것 같은 느낌이 듭니다 …

마지막으로, 나는 그 요소가 몇 번이나 좋아되었는지 카운터를 저장할 가장 좋은 곳이 무엇인지 궁금합니다. 두 가지 방법 만 생각할 수 있습니다.

  1. 요소 ( Photo/Article/Place) 테이블
  2. count ()를 선택하십시오.

이 문제에 대한 나의 설명이 더 철저 해지기를 바랍니다.



답변

가장 확장 가능한 솔루션은 하나의 “기본”테이블 ( “좋아요”, 태그 및 주석에 연결됨)을 갖고 다른 모든 테이블을 “상속”하는 것입니다. 새로운 종류의 엔터티를 추가하려면 새로운 “상속 된”테이블을 추가하면됩니다. 그러면 자동으로 전체 유사 / 태그 / 코멘트 기계에 연결됩니다.

이에 대한 엔티티 관계 용어는 “카테고리”입니다 ( ERwin 메소드 안내서 , “서브 타입 관계”섹션 참조 ). 카테고리 기호는 다음과 같습니다.

범주

사용자가 여러 엔티티를 좋아할 수 있다고 가정하면 동일한 태그를 둘 이상의 엔티티에 사용할 수 있지만 주석은 엔티티마다 다르므로 모델은 다음과 같습니다.

응급실 다이어그램


BTW에는 “ER 카테고리”를 구현하는 대략 3 가지 방법이 있습니다.

  • 하나의 테이블에있는 모든 유형.
  • 별도의 테이블에있는 모든 콘크리트 유형.
  • 별도의 테이블에있는 모든 콘크리트 및 추상 유형.

매우 엄격한 성능 요구 사항이 없으면 세 번째 방법이 가장 좋습니다 (물리 테이블이 위 다이어그램의 엔터티와 1 : 1 일치 함).


답변

데이터베이스를 “증오”하기 때문에 왜 데이터베이스를 구현하려고합니까? 대신,이 물건을 사랑하고 호흡하는 사람의 도움을 요청하십시오.

그렇지 않으면 데이터베이스를 사랑하는 법을 배우십시오. 잘 설계된 데이터베이스는 프로그래밍을 단순화하고 사이트를 엔지니어링하며 지속적인 운영을 원활하게합니다. 숙련 된 d / b 디자이너조차 완벽하고 완벽한 예측력을 갖지 못할 것입니다. 사용 패턴이 나타나거나 요구 사항이 변경 될 때 일부 스키마 변경이 필요합니다.

이것이 단일 사용자 프로젝트 인 경우 저장 프로 시저 (add_user, update_user, add_comment, add_like, upload_photo, list_comments 등)를 사용하여 데이터베이스 인터페이스를 간단한 조작으로 프로그래밍하십시오. 스키마를 한 줄의 코드로 포함하지 마십시오. 이러한 방식으로 데이터베이스 스키마는 코드에 영향을주지 않고 변경 될 수 있습니다. 스토어드 프로 시저 만 스키마에 대해 알아야합니다.

스키마를 여러 번 리팩토링해야 할 수도 있습니다. 이것은 정상입니다. 처음부터 완벽하게 만드는 것에 대해 걱정하지 마십시오. 초기 디자인의 프로토 타입을 제작할 수있을 정도로 기능적으로 만드십시오. 호화로운 시간이 있다면 일부를 사용한 다음 스키마를 삭제하고 다시 수행하십시오. 그것은이다 항상 더 나은 두 번째 시간입니다.


답변

이것은 일반적인 아이디어입니다. 필드 이름 스타일링에 많은 관심을 기울이지 말고 관계 및 구조에 더 많은주의를 기울이십시오.

여기에 이미지 설명을 입력하십시오

이 의사 코드는 ID 5
SELECT * FROM actions
WHERE actions.id_Stuff = 5
AND actions.typeStuff = “photo” 인 사진의 모든 주석을 가져옵니다.
과 actions.typeAction = “코멘트”

이 의사 코드는 ID 5의 사진을 좋아하는 모든 좋아요 또는 사용자를
얻습니다 (카운트 수를 얻으려면 count ()를 사용할 수 있습니다)

SELECT * FROM actions
WHERE actions.id_Stuff = 5
AND actions.typeStuff="photo"
AND actions.typeAction = "like"  


답변

내가 이해하는 한도에서는. 여러 테이블이 필요합니다. 그들 사이에는 많은 관계가 있습니다.

  • 이름, 성, 생년월일과 같은 사용자 데이터를 ID 필드와 함께 저장하는 테이블입니다.
  • 데이터 유형을 저장하는 테이블입니다. 이러한 유형은 사진, 공유, 링크 일 수 있습니다. 각 유형에는 고유 한 테이블이 있어야합니다. 따라서 개별 테이블과이 테이블 간에는 관계가 있습니다.
  • 각기 다른 데이터 유형에는 테이블이 있습니다. 상태 업데이트, 사진, 링크 등이 있습니다.
  • 마지막 테이블은 ID, 사용자 ID, 데이터 유형 및 데이터 ID를 저장하는 다 대다 관계입니다.

답변

필요한 액세스 패턴을보십시오. 그것들 중 어느 것이 나의 하나의 디자인 선택 또는 다른 것을 특히 어렵거나 비효율적으로 만든 것 같습니까?

적은 수의 테이블이 필요한 테이블을 선호하지 않는 경우

이 경우 :

  1. 의견 추가 : 특정 많은 / 많은 테이블을 선택하거나 좋아하는 것으로 알려진 특정 식별자가있는 공통 테이블에 삽입하십시오. 두 번째 경우 클라이언트 코드가 약간 더 간단하다고 생각합니다.
  2. 항목에 대한 의견 찾기 : 여기에서 공통 테이블을 사용하는 것이 약간 더 쉬운 것 같습니다. 엔티티 유형별로 매개 변수가 지정된 단일 쿼리 만 있습니다.
  3. 한 가지 종류의 것에 대한 사람의 의견 찾기 : 두 경우 모두 간단한 쿼리
  4. 모든 것에 대한 사람의 모든 의견을 찾으십시오.

옵션 2 인 “차별 된”접근 방식은 경우에 따라 더 간단한 쿼리를 생성하고 다른 경우에는 훨씬 나쁘지 않은 것으로 생각합니다.


답변

하나의 테이블이 있고 각 행의 요소 유형을 저장하는 두 번째 방법을 사용하면 유연성이 훨씬 높아집니다. 기본적으로 더 적은 수의 테이블로 논리적으로 작업을 수행 할 수있는 경우 더 적은 수의 테이블로 작업하는 것이 좋습니다. 특정 사례에 대해 지금 내 마음에 떠오르는 한 가지 장점은 특정 사용자의 좋아하는 요소를 모두 삭제하려는 경우를 고려하십시오. 첫 번째 방법은 각 요소 유형에 대해 하나의 쿼리를 실행해야하지만 두 번째 방법으로는 수행 할 수 있습니다 하나의 쿼리로 또는 새 요소 유형을 추가 할 때 고려해야 할 첫 번째 방법으로 각 새 유형에 대한 새 테이블을 작성하지만 두 번째 방법으로는 아무것도하지 않아야합니다 …


답변

주석 등을 위해 엔티티 당 테이블 사용을 고려하십시오. 더 많은 테이블-더 나은 샤딩 및 스케일링. 내가 아는 모든 프레임 워크에 대해 많은 유사한 테이블을 제어하는 ​​것은 문제가되지 않습니다.

언젠가 그러한 구조에서 읽기를 최적화해야합니다. 기본 테이블 위에 축약 테이블을 쉽게 작성하고 쓰기 작업에서 약간의 손실을 입을 수 있습니다.

사전이있는 하나의 큰 테이블은 언젠가 제어 할 수 없게 될 수 있습니다.