Project를 기획 및 준비하며..
이번에 Django 로 백엔드를 구축하는 파트를 맡게 되었는데, 그중 일단 DB를 구축을 해야 할것 같아 일단 기획단계에서 팀원분들과 논의 결과 Chat, User, Search_Log, Rag_data 간단하게 이렇게 4가지의 테이블을 ERD 형식으로 따게 되었다.
일단 이 프로젝트를 기획할때, Chatting log를 따로 보관하여, 이 후 Moderation 이나 RAG 모델의 퀄리티와 규칙들을 넣을려고 따로 Search Log 데이터를 만들기로 했다. 내가 전반적인 Backend 작업을 해야해서 먼저 간단한 message system의 CRUD 를 잡고 이번에 기획한 ERD 를 베이스로 DB를 구축하게 되었다.
우선 ERD 를 베이스로 한 DB 구축 을 설명하기전 , 위의 ERD를 설명하자면,
1) USERS 테이블
- 사용자 정보 관리
- UUID 생성 과 관리
- 세션 만료 시간 관리
from django.db import models
from django.utils.timezone import now
import uuid
import random
class User(models.Model):
user_id = models.CharField(max_length=16, primary_key=True, editable=False)
uuid = models.UUIDField(unique=True, editable=False)
created_datetime = models.DateTimeField(auto_now_add=True)
expired_datetime = models.DateTimeField(null=True, blank=True)
def save(self, *args, **kwargs):
if not self.uuid:
self.uuid = uuid.uuid4()
if not self.user_id:
while True:
prefix = f"{random.randint(0, 9999):04d}"
suffix = f"{random.randint(0, 9999):04d}"
user_id = f"U{prefix}0001{suffix}"
if not User.objects.filter(user_id=user_id).exists():
self.user_id = user_id
break
super().save(*args, **kwargs)
def __str__(self):
return f"User {self.user_id}"
2) CHAT 테이블
- 사용자 질문과 AI 응답을 저장
- 질문과 응답을 RAG 데이터와 연계
class Chat(models.Model):
question_id = models.AutoField(primary_key=True)
user = models.ForeignKey(User, on_delete=models.CASCADE)
question_text = models.TextField()
question_created_datetime = models.DateTimeField(auto_now_add=True)
response_text = models.TextField(null=True, blank=True)
data = models.ForeignKey(RagData, on_delete=models.SET_NULL, null=True, blank=True)
def __str__(self):
return f"Question {self.question_id} by User {self.user.user_id}"
3) SEARCH_LOGS 테이블
- 검색 기록 저장
- 질문 및 연관된 RAG 데이터와 연계
class SearchLog(models.Model):
search_log_id = models.AutoField(primary_key=True)
question = models.ForeignKey(Chat, on_delete=models.CASCADE)
data = models.ForeignKey(RagData, on_delete=models.SET_NULL, null=True, blank=True)
searching_time = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"Search {self.search_log_id} for Question {self.question.question_id}"
4) RAG_DATA 테이블
- AI의 검색 결과 데이터를 저장
- 이미지 URL 포함 가능
class RagData(models.Model):
data_id = models.AutoField(primary_key=True)
data_text = models.TextField()
image_urls = models.JSONField(null=True, blank=True)
def __str__(self):
return f"Data {self.data_id}"
5) METADATA 테이블
- 다양한 타입의 메타데이터를 저장하여 유연한 데이터 관리 가능
- 벡터 검색을 위한 추가적인 정보 제공
- JSON, 정수, 실수, 문자열, 불리언 데이터 등을 저장할 수 있도록 설계됨
import json
from django.db import models
class MetaData(models.Model):
key = models.CharField(max_length=50, primary_key=True)
string_value = models.TextField(null=True, blank=True)
integer_value = models.IntegerField(null=True, blank=True)
float_value = models.FloatField(null=True, blank=True)
boolean_value = models.BooleanField(null=True, blank=True)
json_value = models.TextField(null=True, blank=True)
last_updated = models.DateTimeField(auto_now=True)
description = models.TextField(null=True, blank=True)
def set_json(self, value):
"""Store a Python object as JSON string"""
self.json_value = json.dumps(value)
def get_json(self):
"""Retrieve a Python object from JSON string"""
if self.json_value:
return json.loads(self.json_value)
return None
def get_value(self):
"""Get the value in the most appropriate type"""
if self.string_value is not None:
return self.string_value
elif self.integer_value is not None:
return self.integer_value
elif self.float_value is not None:
return self.float_value
elif self.boolean_value is not None:
return self.boolean_value
elif self.json_value is not None:
return self.get_json()
return None
def __str__(self):
return f"{self.key}: {self.get_value()}"
이런식으로 정리를 해보았다. 이러한 ERD 를 바탕으로 Django 의 ORM (Object- Relational Mapping) 모델을 작성해보았다.
그전에 ERD 를 기반으로 데이터 구조를 정의하는것이 중요하다.
ERD를 기반으로 데이터 구조를 정의하는 것이 중요한 이유
ERD는 데이터베이스의 논리적 구조를 시각적으로 표현하는 도구로, 데이터의 관계를 명확하게 정의하고 효율적인 데이터 관리를 가능하게 한다 이를 통해
- 데이터 정규화를 수행하여 중복을 최소화할 수 있으며,
- 데이터 간 관계를 시각적으로 이해하고 확장성을 고려한 설계를 할 수 있고,
- 유지보수 및 데이터 조회 성능을 향상할 수 있다.
Django ORM을 활용하여 테이블을 모델로 매핑하는 방법
Django의 ORM(Object-Relational Mapping)은 데이터베이스의 테이블을 Python 클래스로 매핑하여 보다 직관적인 데이터 조작을 가능하게 하다 또한 이 프로젝트에서 sqlite를 사용하여 보다 쉽게 접근할수 잇었다. ORM 을 통해 테이블을 매핑한다면,
- SQL 문을 직접 작성하지 않아도 복잡한 데이터베이스 쿼리를 쉽게 관리할 수 있으며,
- 데이터베이스 변경 사항을 마이그레이션(Migration) 시스템을 통해 쉽게 반영할 수 있고,
- Django의 다양한 내장 기능(예: Django Admin, Form API)과 연계하여 개발 속도를 높일 수 있다.
3.3 메타데이터를 활용하여 검색 성능을 최적화하는 전략 (Search Log 활용을 위해)(Feat. for vector DB)
메타데이터를 활용하면 AI 검색 성능을 최적화하고 데이터 조회 속도를 향상할 수 있습니다. 메타데이터를 굳이 사용하는 이유는,
- 벡터 검색 최적화: 메타데이터를 ChromaDB 또는 SQLite에 저장하여 AI가 빠르게 검색할 수 있도록 지원하며,
- 검색 필터링 및 색인(Indexing): 관련 데이터를 사전 정리하여 불필요한 데이터 스캔을 줄이고, 검색 시점에서 성능을 향상하고,
- AI 추천 및 유사도 검색: 저장된 메타데이터를 기반으로 사용자의 질의와 가장 유사한 데이터를 빠르게 제공할 수 있다.
처음엔 그냥 Meta data 를 활용할때, 시스템설정갑을 저장하는 용도 및 다양한 유형의 데이터를 손쉽게 저장및 검색하기 위해 보다 활용도를 높이기에 범용성을 위주로 구축하였지만, 나중에 RAG모델과 Vector store 을 보았을떄, 모델의 finetuning 및 최적화를 위해 그만의 Vector Meta data 를 따로 구축할필요를 느껴 따로 구축했다.
솔찍이 초반 ERD를 통해 먼저 고민후 구축하긴 하였지만, 구축하면서 프로젝트의 향후 관리나 범용성등을 고려할때 어떻게 하면 좋을지 정말 많이 고민하게 된것 같다. 그리고 이번 프로젝트를 통해 Meta data 를 보다 다양하게 활용해 프로젝트에 녹일수 있음을 배웠다. 또한 구축시 처음 ERD 작성이후에 여럿 추가가 생겨 그에 따른 ERD 작성의 필요함을 느꼈다.
'[Project를 위한 공부]' 카테고리의 다른 글
[Project 위한 공부] Session 을 구축할때 내가 삽질한 이유 및 해결 방안에 대한 고민 정리 (1) | 2025.02.28 |
---|---|
[Project 를 위한 공부] API 와 같은 중요한 정보 관리 방법들.. (0) | 2025.01.23 |
[Project 를 위한 공부] Middleware 정리 (0) | 2025.01.21 |
[Project를 위한 공부] RAG 정의 정리 (1) | 2025.01.20 |
[Project 를 위한 공부] Serializer 와 Deserializer (3) | 2025.01.16 |