DogKaeBi

[Next.js] Database 없는 설계 고려

데이터베이스가 없으면 어떻게 될까?하는 궁금증으로 여러 생각을 해 봤다. 결론은 차후 데이터베이스는 필요하지만 지금은 사용하지 않아도 필요한 기능이 작동한다.

[Next.js] Database 없는 설계 고려

서론

Database는 고민할수록 어려운 것 같다.

이상적인 구조는
24시간 켜져있는 컴퓨터가
서버와 DB를 담당하는 것 같다.

AWS 같은 클라우드 컴퓨팅을 사용하는 것이 정석이겠지만...
테스트로 만들어보는 사이트에 비용을 어디까지 투자할지 애매한 것 같다.



Without Database?

"데이터베이스"...
이 단어에 너무 얼매인 것 같은 느낌이 들었다.

현재 데이터

지금 저장이 필요한 데이터는

  1. 한자 데이터
  2. 단어 데이터
  3. 음절 데이터
  4. 일기 데이터

로그인, 인허인가, 개인정보에 대한 정보가 아니어서 보안성이 중요한 것 같지 않다.
임시로 변수를 사용해도 문제가 없을 것 같았다.


데이터 크기

한자, 단어, 음절은
아마 1만개를 등록하면 9.7mb 정도일 것 같다.

일반 소통하는데
사용하는 한자가 3000개이고,
광둥어 특성상
사용되는 한자를 더해도
3500자가 넘지 않을 것으로 예상한다.

단어는 무한대로 많아질 수 있지만...
내 시간이 무한대가 아니다...

일기 markdown은 1편당 10kb정도이다.
매일 한편이면 1년이면 3650kb, 3.56mb 정도이다.
md파일을 바로 저장하는 것이 아니면
온라인 storage에 저장하고
일기 정보 데이터를 따로 만들수 있다.
일기 정보를 변수로 만들면 1편 당 1kb정도다.


현재 데이터

이렇게 정리해서 보니
데이터 테이블(객체이겠지만)은
변수로 만들어도 될 것 같다는 느낌이 든다.

이외에 필요한 파일,
이미지, md 등만 따로 저장하면
사용에 큰 지장을 없을 것 같다.
(나중에 로그인이나 댓글 기능을 만들면 어차피 필요하지만...)


한자/단어/발음 데이터

크게 달라질 내용은 없다.
javascript의 객체 변수를 사용하거나,

export const charData = {
  一: {
    tc: "一",
    type: "숫자",
    mean: "숫자 1",
    jam: "jat1",
  },
};

혹은 json를 사용하면 된다.

{
  "一": {
    "type": "숫자",
    "mean": "숫자 1",
    "jam": "jat1"
  }
}

json을 사용한다면
json은 문자열을 인식되기 때문에
사용하는 곳에서 객체로 파싱을 해야한다.

대부분 fetch와 같이 사용해서
responese에 json()을 사용한다.

const req = "http://localhost:8080/char.json";
const testData = await fetch(req).then((res) => res.json());

블로그 데이터

블로그 데이터는 여러 방식을 생각해 볼 수 있는 것 같다.

  1. public에 md를 저장하는 방법
  2. google에 md를 저장하는 방법

public - fs 사용

public를 사용한다면..
markdown을 불려오는 것은 쉽지만
리스트를 만드는 방법은 생각해봐야 한다.

  1. 정보 데이터를 별도로 만드는 방법
  2. 파일을 front matter를 사용하는 방법

별도 파일을 만들지 않으면
front matter를 읽기 위해
전체 파일의 리스트를 만들어야 한다.
파일 읽기는 node.js의
fs, path를 사용할 수 있다.

읽은 내용의 front matter는
별도로 파싱해야 한다.
[gray-matter로 Markdown의 front matter 사용하기 참고]

import fs from "fs";
import path from "path";
import matter from "gray-matter";

const directoryPath = path.join(process.cwd(), "public/");
const postNames = fs.readdirSync(directoryPath);
const postData = postNames.map((title) => {
  return matter(fs.readFileSync(directoryPath + "/" + title, "utf8")).data;
});

file system(fs)을 사용하는 것이
좋은 방법인지는 의문이다...


별도 변수

별도의 변수 파일을 만들면 아래와 같다

{
  "post-slug-name-test-1": {
    "title": "테스트 제목 1",
    "desc": "테스트 설명 123",
    "date": "2024-01-01 23:59:59",
    "thumbnail": "imageHashId1234",
    "md": "postId5678"
  }
}

반복문으로

for (const [key, value] of Object.entries(data)){ ... }

데이터를 처리해서 사용할 수 있다



아직 공부중...

여러 상황을 더 마주해야
어떤 방식이 최선이라는 것을 깨닫을 것 같다.

아직은 편한 방식이나...
원하는 결과만 나오는 방식을 사용하고 있다.

이후 차차 효율, 유지보수, 간결함을 더욱 고려해서 수정해야 할 것 같다.