언더독 풀스택 Node.js 질의응답

김민지·2024년 11월 13일
0

Node.js

목록 보기
8/8

1. MongoDB

Q1. DB의 종류가 매우 다양한데, 그 중에서 mongoDB의 장점이나 업계 현황이 궁금하다.

Q2. MongoDB Interface 같은 것이 있을 것 같은데 강의에서는 잘 나와있지 않다.


A1. 몽고디비는 크기가 큰 데이터를 처리하는데 유용한 NoSQL 데이터베이스입니다!

MongoDB란?

데이터베이스 종류 중 하나로, 관계형 데이터베이스와 달리 고정된 스키마가 없는 NoSQL(Not Only SQL) 데이터베이스입니다. NoSQL은 다양한 방식으로 데이터를 저장할 수 있다는 의미이며, 몽고디비는 JSON 구조와 유사한 문서 기반 저장 방식을 채택했습니다. 문서 단위 저장 방식은 유연한 스키마 설계를 가능하게하므로 몽고디비의 장점 중 하나입니다.

MongoDB의 특징과 장점

1. 자유로운 스키마
문서 기반 데이터는 JSON 형식의 필드와 값 쌍으로 구성되어 있으며, 각 문서마다 다른 필드나 데이터 형식을 가질 수 있습니다.
➡️ 즉, 필요한 필드를 손쉽게 추가하거나 삭제할 수 있습니다.


예를 들어 소셜 미디어 인증 방식이 다양해지면서 회원 정보 필드가 자주 추가되는 상황에서, 몽고디비는 이러한 변경을 빠르게 처리할 수 있습니다.

  • JSON 형식
    JSON은 데이터를 구조화하고 저장하기 위해 사용되는 가볍고 읽기 쉬운 형식입니다. 주로 웹 애플리케이션에서 데이터를 교환하는 데 많이 사용되는데, 서버와 클라이언트 간의 데이터 전송에도 적합하기 때문입니다. JSON은 중괄호 {}로 묶인 객체와 배열 형태를 사용하여, 텍스트 기반으로 정보를 표현합니다. 예를 들어, 책 정보를 JSON으로 표현하면 다음과 같습니다:
{
  "BookId": "9992-192",
  "Title": "안녕 MongoDB",
  "Year": 1998
}


2. 수평적 확장성
데이터를 여러 서버에 나누어 저장하는 샤딩(sharding)기술을 지원해 대규모 데이터와 트래픽을 처리할 수 있습니다. 서버 용량이 부족할 경우 다른 서버를 추가하는 방식으로 간단히 확장할 수 있으며, 이 과정에서 별도의 분산 로직 구현이 필요하지 않습니다.

➡️ 관계형 데이터베이스와 달리 몽고디비는 분산 솔루션을 제공해 편리하게 확장할 수 있습니다.

3. 고가용성 및 복제(확장성)
몽고디비는 데이터를 여러 서버에 복제하여 한 서버에 장애가 발생해도 다른 서버에서 검색할 수 있도록 고가용성을 보장합니다.
*고가용성: 시스템이 중단 없이 지속적으로 서비스를 제공하는 능력, 사용자가 언제든지 서비스를 사용할 수 있게 하는 데 중점을 둔다.

몽고디비는 데이터가 하나의 Replica set에 모두 담기 어려울 정도로 증가하면, 데이터를 샤딩하여 여러 서버에 분산 저장할 수 있습니다. 이 샤딩 작업은 서비스 중단없이 온라인으로 진행되며, 특정 샤드에 데이터가 과도하게 쏠릴 경우 다른 샤드로 데이터를 옮겨 균등하게 저장하도록 합니다. 이 과정을 밸런싱이라 합니다.
이러한 온라인 밸런싱 기능을 통해 단일 Replica set에서 샤드 클러스트로 전환이 가능하며, 샤드의 확장과 축소도 모두 온라인으로 처리할 수 있습니다.

4. 다양한 인덱스 지원
문서의 필드와 하위 필드에 인덱스를 생성할 수 있어 쿼리 능력이 향상됩니다. 인덱스를 사용하지 않는다면 모든 문서를 스캔해야 하므로, 인덱스를 통해 쿼리 성능을 최적화합니다.

5. 데이터 집계 및 분석 도구
몽고디비는 집계 파이프라인을 통해 대규모 데이터를 쉽게 분석하고 조작할 수 있습니다. 이로 인해 대량의 데이터 집계나 복잡한 연산을 효율적으로 수행할 수 있습니다.

6. _ id필드와 Object
몽고디비는 각 문서에 고유한 _ id 필드를 자동으로 생성하여 관리하며, Object형식으로 시간별 정렬이 가능합니다. 고유성을 보장하고, 사용자가 직접 Object 지정할 수도 있습니다.

MongoDB의 업계 활용 현황

위에서 말한 장점들, 자유로운 스키마와 확장성을 이유로 널리 사용됩니다. 특히 애플리케이션이 자주 업데이트되고, 확장성을 필요로 하며, 데이터 구조가 유동적인 분야에서 인기를 끌고 있습니다.

MongoDB 그래픽 유저 인터페이스

A2. 몽고디비의 그래픽 유저 인터페이스입니다. 자세한 내용은 MongoDB Atlas를 검색해보세요!

더 자세한 내용이 궁금하다면! (참고자료)

패스트캠퍼스_라인이 몽고디비를 도입한 이유

티스토리_몽고디비 특징 & 비교 & 구조

Velog_몽고디비만의 특징은 뭘까?

티스토리_카카오와 몽고디비 내용정리

codenary_몽고디비 사용 기업


2. 비동기처리

Q1. 비동기처리 부분에서 화살표 함수에 중괄호가 필요한지 이해가 되지 않았다.
Q2. 화살표 함수를 사용할 때와 사용하지 않을 때 this를 사용하는 방법이 다른 것으로 아는데 이것에 대해서도 더 자세하게 설명해줬으면 좋겠다.

화살표 함수에 중괄호가 필요한 이유

A1. 비동기 함수에서 중괄호가 필요한지 여부는 return과 관련이 있습니다.
특히 Promise나 setTimeout 같은 비동기 코드 내에서 사용하는 경우, 중괄호가 있냐 없냐에 따라 반환되는 값이 달라집니다.

중괄호가 없는 화살표 함수

const asyncFunc = () => Promise.resolve("Hello");

asyncFunc().then(result => console.log(result)); // "Hello"

여기서의 반환값은 무엇인가요?
여기서는 Promise.resolve("Hello")가 자동으로 반환되어 then 메서드에서 사용할 수 있습니다.

중괄호가 있는 화살표 함수

const asyncFunc = () => {
  Promise.resolve("Hello");
};

asyncFunc().then(result => console.log(result)); // undefined

여기서는 Promise.resolve("Hello")가 자동으로 반환되지 않아서 then 메서드에서 result는 undefined가 됩니다. 중괄호가 있는 경우는 return을 명시적으로 작성해야 Promise를 반환할 수 있습니다.

따라서 비동기 처리에서 중괄호가 없으면 자동으로 값이 반환되고, 중괄호가 있으면 return을 명시적으로 작성해야 합니다.

➡️ 중괄호가 없는 경우: 한 줄 코드에서는 return을 자동으로 포함합니다.
➡️ 중괄호가 있는 경우: 여러 줄 코드에서 return을 직접 작성해야 합니다.

화살표 함수와 일반 함수의 this 동작 차이

A2. this가 함수를 어떻게 호출했느냐에 따라 동적으로 결정됩니다. 하지만, 화살표 함수는 예외입니다.

일반함수에서의 this

  • 일반함수에서 this가 바인딩 되는 상황
  1. 함수 실행시에는 전역(window) 객체를 가리킨다.
  2. 메소드 실행시에는 메소드를 소유하고 있는 객체를 가리킨다.
  3. 생성자 실행시에는 새롭게 만들어진 객체를 가리킨다.
const person = {
  name: "Alice",
  greet: function() {
    console.log(this.name); // "Alice"
  }
};

person.greet(); // this는 person을 가리킴

전역 함수로 호출했을 때 결과가 달라지는 것을 확인할 수 있습니다.

function greet() {
  console.log(this); // 전역 객체 (브라우저에서는 window 객체)
}

greet();

➡️ 일반 함수는 어떻게 호출되었는지에 따라 this에 바인딩할 객체가 동적으로 결정된다.

화살표 함수에서의 this
화살표 함수의 this는 언제나 상위 스코프의 this를 가리킨다.
이를 this의 lexical binding이라고 한다.

const person = {
  name: "Alice",
  greet: () => {
    console.log(this.name); // undefined, 전역 객체의 this
  }
};

person.greet(); // 상위 스코프의 this를 가져와 사용하므로, 전역 객체를 가리킴

위 예제에서 화살표 함수 greet의 this는 객체 person을 가리키지 않고, 상위 스코프(여기서는 전역)의 this를 참조하게 되어 undefined가 출력됩니다.

➡️ 화살표 함수는 함수를 선언할 때 this에 바인딩할 객체가 정적으로 결정된다.

일반 함수와 화살표 함수에서 this가 유용한 상황들

  • 객체 메서드에서 this를 가리켜야 할 때
    객체의 메서드로서 내부 속성에 접근하려면 일반 함수를 사용하는 것이 적합합니다.
const person = {
  name: "Alice",
  greet: function() {
    console.log(`Hello, ${this.name}`);
  }
};

person.greet(); // "Hello, Alice"
  • 콜백 함수에서의 this 문제 해결
    콜백 함수로 setTimeout이나 이벤트 핸들러를 사용할 때는 this가 문맥에 따라 전역 객체를 가리킬 수 있습니다. 이때는 화살표 함수가 유용합니다.
function Person(name) {
  this.name = name;
}

Person.prototype.sayHello = function() {
  setTimeout(() => {
    console.log(`Hello, ${this.name}`); // this는 Person 인스턴스를 가리킴
  }, 1000);
};

const person = new Person("Alice");
person.sayHello(); // "Hello, Alice"

여기서 화살표 함수를 사용했기 때문에 this는 Person 인스턴스를 가리킵니다.

  • 이벤트 핸들러에서 this 문제 해결
    DOM 이벤트 핸들러에서도 this가 이벤트를 발생시킨 요소를 가리키지만, 이 안에서 다른 스코프의 this에 접근하고 싶을 때 화살표 함수가 유용합니다.
const button = document.querySelector("button");

button.addEventListener("click", function() {
  setTimeout(() => {
    console.log(this); // button 요소
  }, 1000);
});

화살표 함수를 사용하지 않으면 this가 다른 값으로 바뀔 수 있어 의도한 동작이 달라질 수 있습니다.

요약

  • 일반 함수: this가 호출된 문맥에 따라 동적으로 결정됩니다. 객체의 메서드에서 사용하기에 적합합니다.

  • 화살표 함수: this가 상위 스코프에서 고정됩니다. 콜백 함수나 비동기 함수에서 상위 스코프의 this가 필요할 때 사용하면 유용합니다.

참고자료

Github_화살표 함수와 일반 함수의 차이

f-lab_일반 함수와 화살표 함수의 차이점 이해하기


3. Node.js

Q1. Nodejs에서 module이 일반적으로 사용하는 객체 개념이랑 같은 것인지 이해가 되지 않았다.
Q2. Global module은 require없이 사용하고 __dirname, __ filename이 있는데 이 내용에 대해서 잘 이해가 되지 않았다.


A1. 모듈과 객체 개념은 역할과 사용법이 다릅니다!
Node.js에서 "모듈"은 코드의 재사용을 위해 독립적으로 관리되는 코드 블록을 의미합니다. 이 모듈들은 module.exports와 require() 함수를 사용하여 서로 가져오고 내보낼 수 있습니다.

모듈이란?

  • 모듈은 특정 기능을 담고 있는 파일입니다.
  • 목적: 파일 간 코드 재사용과 관리의 용이성
  • 내보내기: module.exports 로 함수를 외부에 공개
  • 불러오기: require()를 사용해 다른 파일에서 모듈 사용 가능

예시: math.js 모듈 파일

const add = (a, b) => a + b;
module.exports = { add };

다른 파일에서 사용

const math = require('./math');
console.log(math.add(2, 3)); // 5

객체와의 차이

모듈은 Node.js에서 파일 단위로 정의되며, 파일 간의 코드를 가져와 실행하기 위한 단위입니다.
객체와 다르게, 모듈은 module.exports로 외부에 공개하는 부분만 접근이 가능합니다.
➡️ 모듈은 코드의 캡슐화 단위이고, 객체는 데이터와 기능을 묶는 구조체라는 차이가 있습니다.

객체는 데이터와 기능을 구조화하는 기본 데이터 구조입입니다.
속성과 메서드를 묶어 관련 있는 데이터와 기능을 하나의 단위로 관리합니다. 프로그램 내에서 활용하고 주로 특정 데이터 집합이나 데이터와 연관된 동작을 함께 묶어 관리할 때 사용합니다.
객체는 코드 내에서 자유롭게 생성, 변경할 수 있습니다.

const car = {
    brand: "Toyota",
    model: "Camry",
    startEngine: function() {
        console.log("Engine started");
    }
};

console.log(car.brand); // "Toyota"
car.startEngine(); // "Engine started"

위 예제에서 car 객체는 brand, model이라는 속성과 startEngine이라는 메서드를 가집니다.

모듈과 객체 차이점 표

특성객체모듈
구조코드 내부에서 선언된 데이터와 메서드 묶음독립적인 파일 단위 코드 블록
생성과 관리코드 내에서 동적으로 생성, 수정 가능파일 단위로 관리, 주로 코드의 재사용과 관리 목적
접근 방법객체 자체의 속성과 메서드로 접근require를 통해 필요한 모듈 파일을 불러옴
재사용성코드 내에서 한정적으로 사용다른 파일에서 불러와 재사용 가능
라이프사이클객체를 생성할 때마다 새로운 인스턴스가 생성됨한 번 로드된 모듈은 동일 인스턴스가 계속 사용됨
의도데이터와 기능의 그룹화를 위해 사용파일 간 의존성을 관리하고 코드 재사용성을 위해 사용

Global Module의 dirname과 filename

Node.js에서 Global Module은 별도로 require 하지 않아도 어디서나 사용할 수 있는 전역 객체들을 의미합니다. dirname과 filename도 이러한 전역 객체들 중 하나로, 각 파일의 경로 정보를 관리하는 특수한 전역 변수입니다.

1. __dirname

__dirname은 현재 실행 중인 파일의 디렉토리 경로를 나타냅니다. 이 값은 파일이 실행되는 위치에 따라 동적으로 바뀌며, 특정 파일이 어느 디렉토리에 있는지 파악할 때 주로 사용합니다.

console.log(__dirname);

위 코드를 실행하면 현재 파일이 위치한 디렉토리의 절대 경로가 출력됩니다. 예를 들어, 파일이 /users/username/project/main.js에 있다면 /users/username/project가 출력됩니다.

  • 왜 사용할까?
    require를 제외하고 경로를 받는 모든 함수는 현재 작업 디렉토리 기준으로 상대경로를 처리합니다. 따라서 프로세스를 어느 디렉토리에서 실행하느냐에 따라 상대경로가 적절할 수도 또는 없는 경로를 가리킬 수 있습니다.

따라서 작성된 모듈 기준으로 상대경로를 적용하길 원하는데 __dirname은 현재 실행되는 모듈의 디렉토리 경로입니다.
이렇게 사용하면 프로세스를 실행한 디렉토리와 관계없이 모듈 기준으로 상대 경로를 지정해줄 수 있습니다.

__dirname은 파일 경로를 동적으로 설정해야 할 때 유용합니다. 예를 들어, 현재 파일의 위치를 기준으로 다른 파일을 불러오거나 저장하는 경우가 있습니다.

const path = require('path');
const filePath = path.join(__dirname, 'data', 'file.txt');
console.log(filePath); // /users/username/project/data/file.txt

2. __filename
filename은 현재 실행 중인 파일의 전체 경로를 나타내며, 파일 이름을 포함한 절대 경로를 반환합니다.

console.log(__filename);

이 코드를 실행하면 현재 파일의 전체 경로가 출력됩니다. 예를 들어, /users/username/project/main.js가 표시됩니다.
파일 경로를 확인하거나 로깅하는 용도로 사용됩니다. 특히 파일 이름까지 포함한 경로가 필요할 때 유용합니다.

  • 왜 사용할까?
    __filename은 현재 파일의 절대 경로와 파일명을 제공하여 파일 위치를 기준으로 한 정확한 참조를 가능하게 합니다. 이를 통해, 상대 경로로 인한 혼란 없이 파일 경로가 필요한 작업을 안정적으로 수행할 수 있습니다. 예를 들어, 파일을 읽거나 특정 경로에서 파일을 직접 가져올 때 유용하며, 대규모 프로젝트에서는 로그와 디버깅에 활용하여 코드 출처를 명확히 파악하는 데 도움을 줍니다.

__dirname__filename의 활용 차이점

  • __dirname은 파일이 위치한 디렉토리 경로까지만 알려주고, __filename은 파일의 전체 경로를 제공합니다.
  • 두 변수 모두 Node.js 환경에서 파일 경로나 파일명을 동적으로 사용할 때 유용합니다.

참고자료

Velog_기본 객체와 모듈
티스토리_node.js 설치 및 실행, 모듈과 코어 모듈, 브라우저와의 차이점
medium_ __dirname은 왜 사용하는걸까


도움이 되었길 바랍니다! 더 궁금한 점이 있으면 언제든지 물어보세요. 😊

profile
안녕하세요

0개의 댓글