Skip to content

docs: DynamoDB 싱글 테이블 설계서 작성#4

Merged
farmer0010 merged 8 commits into
mainfrom
docs/dynamodb-design
Jun 17, 2026
Merged

docs: DynamoDB 싱글 테이블 설계서 작성#4
farmer0010 merged 8 commits into
mainfrom
docs/dynamodb-design

Conversation

@farmer0010

Copy link
Copy Markdown
Owner

다이나모 디비 싱글 테이블 설계서 작성입니다!

@losnuyh

losnuyh commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

use case가 뭐뭐인거야?
나열해봐

dynamodb gsi quota 몇인지 체크해봐
왜케 많이 만들어

지금 설계 완전 이상한거같은데?

@losnuyh

losnuyh commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

dynamodb 싱글 테이블 설계도는

필드 다 빼고

index들 세팅한거

  • use case

@farmer0010

Copy link
Copy Markdown
Owner Author

필드 명세 제거, Use Case 및 조회 패턴 추가, Base Table / GSI 구성만 남도록 정리해두면 싱글 테이블에 맞게 수정해보았습니다!
코드 관련 pr은 feat/read-memo-api에 따로 분리하여 올려두었고 추가로 GSI Quota도 확인해봤는데 기본 20개였습니다.
기존에는 조회 조건별로 GSI를 나눠놨는데 단일 GSI로 변경하였고 카테고리나 검색어 조건은 필터링으로 처리하도록 수정했습니다.

Comment thread docs/DYNAMODB_DESIGN.md Outdated

조회 패턴

* GSI1PK = USER#{user_id}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* GSI1PK = USER#{user_id}
* PK = USER#{user_id}

이거 그냥 PK랑 똑같은거아냐? 왜 따로 GSI1PK가 있는거여

Comment thread docs/DYNAMODB_DESIGN.md Outdated
조회 패턴

* GSI1PK = USER#{user_id}
* search_content FilterExpression

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FilterExpression <- 어떻게 동작하는지 찾아봐

@losnuyh

losnuyh commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

usecase d

user_id로 해당 유저가 작성한 memo들 조회 가능
user_id로 해당 유저가 작성한 memo중에 특정 카테고리 메모들 조회
memo id로 memo 단건 조회

dynamodb 에서 PK, SK 라고 하는게 index 키를 이야기하는 것과 필드명을 이야기하는 것을 구분해야함

만약에 default table 설정이 아래와 같다면...

key field value
PartitionKey PK ~~값
SortKey SK ~~값

GSI는 다음과 같이 구성 가능

name: GSI1

key field value
PartitionKey SK ~~값
SortKey PK ~~값

name: GSI2
??? 필요할까?


모든 id는 ulid로 만든다.

데이터 설계
PK: user#<user_id>
SK: category#<카테고리명>#memo#<memo_id>

user_id로 해당 유저가 작성한 memo들 조회 가능
-> PK=user#<user_id>

user_id로 해당 유저가 작성한 memo중에 특정 카테고리 메모들 조회
-> PK=user#<user_id>, begins_with(SK, "category#<블라블라>")

memo id로 memo 단건 조회 << 해결
-> GIS1, SK="memo#<memo_id>"

공부할 것

  • 다이나모디비가 어떻게 물리적인 데이터베이스를 유연하게 확장하는가?
    -> Q. SK를 SK: category#<카테고리명>로만 지정하면 발생하는 문제는???
  • CAP 이론
  • ULID, https://en.wikipedia.org/wiki/Snowflake_ID
  • dynamodb 조회시 제공하는 기능들 (ex, begins_with)

@farmer0010

farmer0010 commented Jun 5, 2026

Copy link
Copy Markdown
Owner Author

SK : category#<카테고리명> 로만 지정하면 생기는 문제점에 관하여 고민해보았는데 SK를 category#<카테고리명> 지정해버리면 같은 유저가 같은 카테고리에 다음 메모를 쓰는 순간에 기존 메모리는 덮어 씌여저버리는 문제가 발생하여 같은 카테고리 안에서도 키 값의 고유성을 보장하기 위해 SK 맨뒤에 memo.id와 같이 유일한 값을 결합해주어야만 데이터가 덮어 씌어지지 않기때문에 이러한 점이 보완되어야 한다고 생각합니다!

GSI1 사용 이유:
메모 수정 및 삭제는 memo_id만으로 수행되지만 기본 테이블은 PK = USER#{user_id} 구조이므로 사용자 정보를 모르면 단건 조회가 불가능한 상황이 생겨 이를 해결하기 위해 Base Table의 PK, SK를 재사용하는 Inverted Index를 구성하여 memo_id만으로 원본 데이터를 찾을 수 있도록 설계하였습니다!

GSI2 사용 이유:
초기에는 Sort Key에 카테고리를 포함하여 카테고리별 조회를 처리하려고 했었는데 이 경우에는 전체 메모 조회 시 정렬 기준이 카테고리가 되어 최신순 타임라인이 깨지는 문제가 발생하게 되서 전체 메모 최신순 조회와 카테고리별 최신순 조회를 모두 만족시키기 위해 Base Table은 전체 타임라인 조회에 집중하고, 카테고리 조회는 별도의 GSI로 분리하였습니다!

Comment thread docs/DYNAMODB_DESIGN.md Outdated
| Key | Value |
| ------ | ------------- |
| GSI1PK | Base Table SK |
| GSI1SK | Base Table PK |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이게 inverted index ??

@farmer0010 farmer0010 Jun 9, 2026

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분은 제가 용어를 잘못 사용했습니다! 인버티드 인덱스라고 적었는데 memo_id가 고유한 ULID 값이라 단건 조회용 룩업 인덱스에 더 가깝습니다. 현재 유즈케이스에서는 수정이나 삭제 및 단건 조회 시 user_id 없이 memo_id만 넘어오도록 구현되어 있어서 해당 메모의 원본 PK(USER#{user_id})를 찾기 위해 GSI1을 추가되어있으며 Base Table은 PK와 SK를 모두 알아야 단건 조회나 수정 및 삭제가 가능하기 때문에, memo_id만으로 접근해야 하는 현재 구조에서는 이를 한 번 찾아주는 역할이 필요하다고 생각했습니다!

Comment thread docs/DYNAMODB_DESIGN.md Outdated
Comment on lines +34 to +35
* GSI2PK = USER#{user_id}#CATEGORY#{category}
* ScanIndexForward = False

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

카테고리별 메모 조회가 목적인거면

pk: USER#{user_id}
sk: C#{category name}#M#{memo_id}

로 한 다음에

Suggested change
* GSI2PK = USER#{user_id}#CATEGORY#{category}
* ScanIndexForward = False
* PK=user#1234, begins_with(SK, "C#java")

로 찾아도 되는거 같은데?

너가 남긴 코멘트보면

유저의 전체메모 조회때
sort 기준이 최신 순서를 조회할 때 SK가 카테고리이름의 정렬 순서가 고정이여서 안된다고 말한거 같은데?

설계 잘못됨.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LSI 찾아봐.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵 확인해서 수정해서 올리겠습니다!

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LSI에 대해 다시 찾아보니 현재 카테고리 조회 패턴은 별도의 GSI 없이도 처리 가능하다는 알게 되었고 말씀해주신 것처럼 LSI를 활용하면 기존 GSI2가 담당하던 역할을 대체할 수 있어 이 부분은 LSI 기반으로 수정하겠습니다!

Comment thread docs/DYNAMODB_DESIGN.md Outdated
Comment on lines +63 to +64
| Partition Key | GSI1PK | Base Table SK |
| Sort Key | GSI1SK | Base Table PK |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| Partition Key | GSI1PK | Base Table SK |
| Sort Key | GSI1SK | Base Table PK |
| Partition Key | SK | Base Table SK |
| Sort Key | PK | Base Table PK |

GSI1PK, GSI1SK 이게 뭘 의미하는거야?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

기존 PK, SK 속성을 그대로 인덱스 키로 사용할 수 있는데 제가 GSI용 필드를 별도로 추가하면서 데이터를 중복 저장되는걸 확인해서 PK, SK를 그대로 활용하는 방향으로 설계서랑 레포지토리 코드 수정해두겠습니다!

Comment thread docs/DYNAMODB_DESIGN.md Outdated
* `GSI1PK = MEMO#{memo_id}`
* 조회된 원본 PK(`GSI1SK`)와 SK(`GSI1PK`)를 이용하여 수정 및 삭제

### 전체 메모 조회

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
### 전체 메모 조회
### 특정 유저의 전체 메모 조회

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵 수정완료했습니다!

Comment thread docs/DYNAMODB_DESIGN.md Outdated
* `PK = USER#{user_id}`
* `ScanIndexForward = False`

### 카테고리별 메모 조회

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
### 카테고리별 메모 조회
### 특정 유저의 카테고리별 메모 조회

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵 수정완료했습니다!

@farmer0010 farmer0010 merged commit ded6b59 into main Jun 17, 2026
@farmer0010 farmer0010 deleted the docs/dynamodb-design branch June 17, 2026 01:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants