토이프로젝트: 공감 기능 만들기(2)

coolchaem·2022년 4월 5일
1

toyproject

목록 보기
13/21

DB table 수정

지난 포스팅 글에서 구성한 table은 POST_LIKES 이다.

기존 table에서 foreign key를 생성했을 때 상위 테이블의 참조하는 행이 지워지거나 수정될 때를 고려하지 않고 default(no action)로 만들었다.
그래서 foreign key가 뭔지 action이 뭔지 조사하고 alter문으로 수정하는 과정을 거쳤다.

Foreign Key Constraint

  • Foreign Key 정의 (in wiki)

    • 관계형 데이터베이스에서 외래 키(외부 키, Foreign Key)는 한 테이블의 필드(attribute) 중 다른 테이블의 행(row)을 식별할 수 있는 키
    • 쉽게 말하면 제약 조건을 설정한 필드이고, 한 테이블을 다른 테이블과 연결해주는 역할이라고 한다
    • 참조되는 테이블의 필드는 반드시 UNIQUE나 PRIMARY KEY 제약 조건이 설정되어 있어야 함
      • uuid로 id column을 만드는 이유를 알게되었다!
  • 생성 방법

    • CREATE 문 혹은 ALTER 문
CREATE TABLE 테이블이름
(
    필드이름 필드타입,
    ...,
    [CONSTRAINT 제약조건이름]
    FOREIGN KEY (필드이름)
    REFERENCES 테이블이름 (필드이름)
)

Action

참조되는 테이블 값이 변경되면 참조하고 있는 하위 테이블의 데이터를 어떻게 처리할 것인가? 이것에 대한 처리를 제약 조건 생성 시 미리 설정할 수 있다. delete/update 둘 다 같은 동작 종류가 있다.

  • no action
    • 상위 테이블 변경되어도 하위 테이블은 변경되지 않음
    • 종류에 따라 상위 테이블 변경이 롤백되거나 에러가 생기는 것으로 보임
  • cascade
    • 상위 테이블 데이터가 삭제되거나 수정되면, 하위 테이블에서도 동일하게 이루어짐
  • set null
    • 상위 테이블 데이터가 삭제되거나 수정되면, 하위 테이블의 값은 NULL로 변경한다고 함

ALTER SQL

ALTER 문은 column 필드로 제거/추가/수정할 때 사용한다. 이 때 foreign key constraint도 설정 가능하다.

ALTER TABLE 테이블이름
ADD [CONSTRAINT 제약조건이름]
FOREIGN KEY (필드이름)
REFERENCES 테이블이름 (필드이름)

실제 적용한 룰은 다음과 같다. postgre sql이라 mysql과 다를 수 있다.

ALTER TABLE IF EXISTS public."POST_LIKES"
	DROP CONSTRAINT fk_post_id,
    ADD CONSTRAINT fk_post_id FOREIGN KEY (fk_post_id)
    REFERENCES public."BLOG_POSTS" (id) MATCH SIMPLE
    ON UPDATE CASCADE
    ON DELETE CASCADE
    NOT VALID;

공감 기능 구현

User like api 수정

  • 의논사항: reading list 자원은 user에게 속하니 순서를 바꿀것인가?
/readingList/:userName/liked/
-> /:userName/readingList/liked/

API 호출 방식 수정

  • 이전 문제점: Post API 응답 받은 후 요청하는 문제
  • 생각한 방법: Post API 응답 시 like 정보가 있는 table과 join할 생각이었음
    • post, user, like table 3개 join
  • 실제 구현 방법: 병렬적 API 요청
    • join vs multi request: 일반적으로 join이 우세하나, table 양이 늘면 성능 측정을 직접 해보는 것이 좋다고 한다.
    • join을 3개나 하기보단 단독적으로 업데이트 되면 어떨까해서 병렬적으로 구현해보았다.

  useEffect(() => {
    axios({
      baseURL: API_HOST,
      url: `/@${userId}/${urlSlug}`,
    })
      .then(response => {
        setPost(response.data);
      })
      .catch(error => {
        console.error(error);
      });
  }, [userId, urlSlug]);

  useEffect(() => {
    axios({
      baseURL: API_HOST,
      url: `/${userId}/liked/${post.id}`,
    }).then(reponse => {
      setLiked(reponse.data.length !== 0);
    });
  }, [post.id, userId]);

  const handleLikeToggle = () => {
    setLiked(!liked);
  };

  return (
    <div>
      <PostHeader title={post.title} date={post.released_at} userName={userId || ''} />
      <PostBody>
        <PostLikeShareButton likeCount={post.likes} liked={liked} onLikeToggle={handleLikeToggle} />
        <PostBodyBox>{post.body && <ViewBody body={post.body} />}</PostBodyBox>
      </PostBody>
    </div>
  );

https://ko.wikipedia.org/wiki/%EC%99%B8%EB%9E%98_%ED%82%A4
http://www.tcpschool.com/mysql/mysql_constraint_foreignKey
https://stackoverflow.com/questions/1067016/join-queries-vs-multiple-queries

TODO

  • post DB table schema 수정
    • url null로 설정가능한 옵션 제거
    • 데이터 값 수정
  • like 스타일 수정
    • 테마 스타일 적용
  • 읽은 목록 page 구현(liked 탭만 기능 추가)
  • 로그인 기능 v2 인증 추가
  • share button 추가
profile
Front-end developer

0개의 댓글