Supabase를 이용한 데이터 저장 방식 및 최적화

liinyeye·2024년 11월 19일

[TIL]

목록 보기
9/10

1. Supabase를 활용한 데이터 삽입 로직 비교

방법 1: 데이터를 먼저 배열(todoToInsert)에 저장한 뒤 삽입

const todoToInsert = items.map((item) => ({
    todo_id: uuid4(),
    created_at: new Date().toISOString(),
    todo_title: item,
    todo_description: null,
    user_id: user.id,
    address: { lat: 0, lng: 0 },
    event_datetime: dayjs().set("hour", 0).set("minute", 0).toISOString(),
    is_done: false,
    is_chat: true,
    is_all_day_event: true
  }));

  const { data, error } = await supabase.from("todos").insert(todoToInsert).select();

  if (error) {
    console.error("Error saving chat todo items", error);
    throw error;
  }
  return data;
};

방법 2: 데이터 배열을 생성과 동시에 삽입

const { data, error } = await supabase.from("todos").insert(
    items.map((item) => ({
      //   session_id: sessionId,
      todo_id: uuid4(),
      created_at: new Date().toISOString(),
      todo_title: item,
      todo_description: null,
      user_id: user.id,
      address: { lat: 0, lng: 0 },
      event_datetime: dayjs().set("hour", 0).set("minute", 0).toISOString(),
      is_done: false,
      is_chat: true,
      is_all_day_event: true
    }))
  );
  if (error) {
    console.error("Error saving chat todo items", error);
    throw error;
  }
  return data;
  • 코드 구조
    • 방법 1 : todoToInsert 배열을 먼저 생성한 후 insert 작업을 수행
  • 가독성
    • 방법 1 : 데이터 준비와 삽입 작업이 분리되어 있어 더 가독성이 좋음
  • 재사용성
    • 방법 1 : todoToInsert 배열을 다른 용도로 재사용 가능
  • 디버깅
    • 방법 1 : todoToInsert 배열을 중간에 확인할 수 있어 디버깅이 더 쉬움

결론, 데이터를 먼저 배열에 저장한 뒤 삽입하는 방식이 가독성, 재사용성, 디버깅 편의성 면에서 더 유리함

2. Supabase .select() 사용 여부

.select() 사용 시

  • 삽입된 전체 데이터 반환
  • 삽입된 데이터를 즉시 확인 가능
  • 추가적인 데이터베이스 작업(select)이 수행되므로 약간의 성능 오버헤드 가능성
  • 삽입된 데이터가 응답으로 전송되므로 네트워크 트래픽 증가 가능성
  • 반환되는 데이터의 타입이 더 구체적으로 예측 가능
  • 삽입 후 즉시 삽입한 데이터로 추가 작업을 수행해야할 때 유용
    ex) 생성된 id를 사용하여 관련 레코드를 생성하거나 클라이언트에 전체 데이터를 즉시 표시해야하는 경우

결론

  • 현재 로직에서는 데이터가 저장 됐는지 안 됐는지의 성공 여부만 필요하기 때문에 .select()를 사용할 필요는 없음.
  • 다만, 저장된 데이터로 또 다른 추가작업을 해야한다면 이때는 .select() 필요
  if (saveTodo) {
    try {
      const result = await handleSaveChatTodo(supabase, sessionId);
      if (result.success) {
        todoItems = [];
        updatedTodoList = [];
        console.log("todoItems saveTodo => ", todoItems);
        return NextResponse.json({ message: result.message });
      } else {
        return NextResponse.json({ error: result.error }, { status: 400 });
      }
    } catch (error) {
      return NextResponse.json({ error: "An error occurred while saving todo list." }, { status: 500 });
    }
  }
  
  export const handleSaveChatTodo = async (supabase: SupabaseClient, sessionId: string) => {
  const { data: sessionData } = await supabase
    .from(CHAT_SESSIONS)
    .select("messages")
    .eq("session_id", sessionId)
    .single();

  if (sessionData && sessionData.messages) {
    const lastMessage = sessionData.messages[sessionData.messages.length - 1];
    if (lastMessage && lastMessage.content) {
      const todoItems = extractTodoItemsToSave(lastMessage.content);
      if (todoItems.length > 0) {
        await saveChatTodoItems(supabase, sessionId, todoItems);
        return {
          success: true,
          message:
            "투두리스트가 저장되었습니다. 새로운 투두리스트를 작성하고 싶다면 투두리스트 작성하기 버튼을, 아니라면 새로운 대화를 이어나가보세요!"
        };
      }
    }
  }
  return { success: false, error: "저장할 투두리스트 항목이 없습니다." };
};
profile
웹 프론트엔드 UXUI

0개의 댓글