페어 활동 기록_Day12_윤우_현정 - boostcampwm-2022/web33-Mildo GitHub Wiki

✂️ 분배된 이슈

🚩 구현 목표

🍀 세부 목표

  • 로그 지우기
  • 위도 경도 좌표 데이터베이스에 저장
  • 주요 50곳의 장소에 대해 데이터베이스에서 최신 데이터 가져오기

🖥️ 구현 내용

📖 학습 내용

🩺 의사결정

50개의 데이터를 불러오는 방식

  1. 데이터베이스를 시간 순서로 정렬 후 가져오기

    • 데이터가 점점 많아질 경우 정렬 속도가 느려질 것 같음
  2. 최근 시간을 서버에 변수로 저장하기

    • crontab 서버에서 시간을 변수로 가지고 있는데, 이렇게 되면 api 서버에선 시간이 저장된 변수를 접근할 수 없음
  3. API에서 데이터를 불러올 때마다 area 스키마에 updatedAt 같은 필드를 생성해서 50개의 데이터를 모두 업데이트

    • 한 번 불러올 때마다 50개의 데이터를 모두 업데이트 해야 됨 → 비효율적

    • 24시간 이내의 데이터를 불러올 때는 Embeded 형식으로 넣으면 됨

      ex) { 오전1시: 2022-11-22T00:20:00, 오전2시: … }

  4. 시간 컬렉션을 만들어서 그 컬렉션에 계속 최근 시간을 넣기

  5. redis 사용 (챌린지)

    • 최근 시간을 가지고 있는 것보다 최근 장소 50곳 또는 24시간 이내 장소 밀도를 모두 업데이트하여 저장
    • 24시간 이내의 정보를 빠르게 제공해주는 것이 우리 서비스에 있어서 중요한 부분이기 때문에 가장 적합하다고 보임
    • 이걸 하려면 크론탭 서버를 빨리 구축해야 함
    • 러닝커브가 발생할 것 같음
    • RabbitMQ라는 메시지 큐 기반 데이터베이스도 있는데 러닝커브가 적다고 함

🚧 Trouble Shooting

객체 string 타입 접근 에러

for (const areaName in AREA_NAMES) {
  const newArea = new Area({
    areaName: areaName,
    latitude: AREA_NAMES[areaName][0],
    longitude: AREA_NAMES[areaName][1]
  });

  newArea.save();
}
  • 객체를 순회할 때 areaName 이라는 string 타입으로 접근

  • 하지만 타입스크립트에서는 string 타입의 key 사용을 허용하지 않는다.

  • 따라서 string 타입이 아닌 string literal 타입의 key로 접근해야 한다.

    ex) string 타입과 string literal 타입의 차이

    const obj = {
      foo: "hello",
    }
    
    // propertyName은 string literal 타입
    const propertyName = "foo"
    // b, c는 string 타입
    let b = "Hello World"
    const c: string = "Hello World"
    
    console.log(obj[propertyName]) // ok!
    console.log(obj["foo"]) // ok!
    
  • 객체를 string 타입으로 접근하려면 index signature 를 선언한 interface를 객체의 타입으로 지정해줘야 한다.

    type ObjType = {
      [index: string]: string; // index signature
      foo: string;
      bar: string;
    }
    
    const obj: ObjType = {
      foo: "hello",
      bar: "world",
    }
    
    const propertyName1 = "foo"
    const propertyName2: string = "foo"
    
    console.log(obj[propertyName1]) // ok
    console.log(obj[propertyName2]) // ok
    
  • index signature 를 설정해주지 않으면 미리 지정한 string literal(AllowedKeys) 로 강제 캐스팅해서 컴파일 오류를 없앨 수 있다. 강제적으로 string literal 타입으로 접근하게 하는 것이다.

    type AllowedKeys = '서울역' | '용산역' | '이태원';
    
    interface t {
    	// [key: string]: string;
      서울역: string;
      용산역: string;
      이태원: string;
    }
    
    const obj: t = {
      서울역: '1',
      용산역: '2',
      이태원: '3'
    };
    
    for(const key in obj){
      const b = obj[key as AllowedKeys]; // index signature를 사용하지 않으면 as를 이용하여 string literal로 강제 형변환을 해야한다.
    }
    
  • index signature 를 설정해주었을 때 objstring 타입으로 접근할 수 있다.

    type AllowedKeys = '서울역' | '용산역' | '이태원';
    
    interface t {
    	[key: string]: string;
      서울역: string;
      용산역: string;
      이태원: string;
    }
    
    const obj: t = {
      서울역: '1',
      용산역: '2',
      이태원: '3'
    };
    
    const obj2 = {
      서울역: '1',
      용산역: '2',
      이태원: '3'
    };
    
    for(const key in obj){
      const b = obj[key]; // index signature를 사용하여 key가 string type이라도 객체에 접근할 수 있다.
    }
    

교훈

  • object literal(obj2)로 type 지정없이 선언할 경우 object literal(obj2)의 key는 string 타입이 아니라 string literal 타입이다.
  • 객체를 순회할 때 string 변수(여기서는 key)로 접근을 한다면, index signature 를 선언한 객체의 타입을 무조건 선언해주자

참고 사이트

❓ 궁금한 점

  • 30분마다 저장하면 9시, 10시, 현재 11시 이럴때 어떤 시간을 가져와야 할까?

🎸 기타