<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>luna.log</title>
        <link>https://velog.io/</link>
        <description>열심히</description>
        <lastBuildDate>Sat, 27 May 2023 17:05:01 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. luna.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/luna_0219" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[13주차] Python Data Analysis Project 2]]></title>
            <link>https://velog.io/@luna_0219/13%EC%A3%BC%EC%B0%A8-Python-Data-Analysis-Project-2</link>
            <guid>https://velog.io/@luna_0219/13%EC%A3%BC%EC%B0%A8-Python-Data-Analysis-Project-2</guid>
            <pubDate>Sat, 27 May 2023 17:05:01 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>본 자료는 심민경 코치님의 자료를 사용하여 정리하였습니다.</p>
</blockquote>
<h1 id="데이터-분석-기본-개념-살펴보기">데이터 분석 기본 개념 살펴보기</h1>
<h2 id="머신러닝">머신러닝</h2>
<p>데이터에 기반 $\rarr$ 숨겨진 패턴을 학습 $\rarr$ 결과를 예측하는 알고리즘 기법</p>
<h2 id="데이터-분석-단계">데이터 분석 단계</h2>
<p>데이터 수집 $\rarr$ 데이터 이해 및 전처리 $\rarr$ 모델링 &amp; 분석결과도출 $\rarr$ 시각화 및 보고서 작성</p>
<h2 id="머신러닝-분류">머신러닝 분류</h2>
<h3 id="지도학습">지도학습</h3>
<ul>
<li>답안지가 있어서 예측과 실제값을 비교해볼 수 있는 학습방식</li>
<li>분류, 회귀, 추천시스템, 텍스트 분석</li>
</ul>
<h3 id="비지도학습">비지도학습</h3>
<ul>
<li>예측결과의 답안이 없는 학습방식</li>
<li>클러스터링, 차원축소</li>
</ul>
<h2 id="연속형--범주형">연속형 &amp; 범주형</h2>
<p><img src="https://velog.velcdn.com/images/luna_0219/post/78d4f571-6573-453e-bbbd-9e118bb7e289/image.png" alt=""></p>
<h2 id="선형--비선형">선형 &amp; 비선형</h2>
<p><img src="https://velog.velcdn.com/images/luna_0219/post/c8b55bf1-e656-451c-af80-49f2bb648b9f/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[13주차] 프로젝트로 배우는 데이터 분석]]></title>
            <link>https://velog.io/@luna_0219/13%EC%A3%BC%EC%B0%A8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8%EB%A1%9C-%EB%B0%B0%EC%9A%B0%EB%8A%94-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%B6%84%EC%84%9D</link>
            <guid>https://velog.io/@luna_0219/13%EC%A3%BC%EC%B0%A8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8%EB%A1%9C-%EB%B0%B0%EC%9A%B0%EB%8A%94-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%B6%84%EC%84%9D</guid>
            <pubDate>Sat, 27 May 2023 17:01:05 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>본 자료는 Elice 플랫폼의 자료를 사용하여 정리하였습니다.</p>
</blockquote>
<h1 id="프로젝트-준비하기">프로젝트 준비하기</h1>
<h2 id="프로젝트와-데이터-분석">프로젝트와 데이터 분석</h2>
<h3 id="데이터와-정보">데이터와 정보</h3>
<ul>
<li>데이터 : 현실 세계의 일들을 관찰, 측정해서 얻은 값</li>
<li>정보 : 데이터를 처리해서 얻는 의미있는 값</li>
</ul>
<h3 id="데이터-분석이란">데이터 분석이란?</h3>
<ul>
<li>데이터를 활용하여 원하는 정보를 얻어내기 위한 일련의 과정</li>
</ul>
<h3 id="데이터-분석-프로젝트">데이터 분석 프로젝트</h3>
<p>문제정의 $\rarr$ 가설설정 $\rarr$ 데이터준비 $\rarr$ 데이터분석 $\rarr$ 결과 정리</p>
<h1 id="데이터-분석-시작하기">데이터 분석 시작하기</h1>
<h2 id="데이터-분석-프로세스">데이터 분석 프로세스</h2>
<h3 id="문제정의">문제정의</h3>
<ul>
<li>현재 풀고자 하는 문제가 무엇인지를 명확히 정의</li>
</ul>
<h3 id="가설설정">가설설정</h3>
<ul>
<li>문제를 해결하기 위한 데이터 분석의 토대인 가설 설정</li>
<li>문제와의 관련성 고려</li>
</ul>
<h3 id="데이터-준비">데이터 준비</h3>
<ul>
<li>풀고 싶은 문제에 대한 정보를 담고 있는 데이터셋을 선정</li>
<li>데이터 수집 및 전처리 과정<ul>
<li>데이터 수집<ul>
<li>풀고 싶은 문제에 대한 정보를 담고있는 데이터셋</li>
</ul>
</li>
<li>데이터 전처리<ul>
<li>데이터 정제</li>
<li>빠진 부분, 중복, 이상값제거, 형태변환 등의 초기데이터 전처리 시행</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="데이터-분석">데이터 분석</h3>
<ul>
<li>본격적인 데이터 분석</li>
<li>데이터 분석 프로젝트의 성공여부는 얼마나 데이터를 이해하고 있느냐에 좌우된다.</li>
<li>탐험적 데이터 분석(EDA)<ul>
<li>Exploratory Data Analysis</li>
<li>데이터의 특징을 찾고, 숨겨진 패턴을 발견하는 과정</li>
</ul>
</li>
</ul>
<h3 id="결과-정리">결과 정리</h3>
<ul>
<li>분석과정에서 알아낸 인사이트(Insight) 정리<ul>
<li>인사이트란 사물의 이면을 들여다보는 것이다.</li>
</ul>
</li>
</ul>
<h2 id="span-stylecolorred명확한-목표-설정과-목표에-맞는-흐름에-따른-데이터-분석을-진행해야-의미있는-데이터-분석이라-할-수-있다span"><span style="color:red">명확한 목표 설정과 목표에 맞는 흐름에 따른 데이터 분석을 진행해야 의미있는 데이터 분석이라 할 수 있다.</span></h2>
<h1 id="tip-데이터-분석-프로젝트">Tip 데이터 분석 프로젝트</h1>
<h2 id="프로젝트-주제소개">프로젝트 주제소개</h2>
<p>&quot;어떤 테이블을 담당해야 Tip을 가장 많이 받을 수 있을까?&quot;</p>
<h2 id="문제정의하기">문제정의하기</h2>
<ul>
<li>Tip이란?<ul>
<li>서비스 제공자에게 자발적으로 주는 돈을 의미</li>
</ul>
</li>
</ul>
<p><span style="color:skyblue">Tip 데이터셋 분석을 통해 높은 팁을 받는 테이블의 특징을 살펴보고, 가장 높은 Tip을 받기 위한 전략짜기</span></p>
<h2 id="가설-설정하기">가설 설정하기</h2>
<ul>
<li>정의한 문제 해결을 위한 가설 설정을 통해 필요한 데이터셋과 데이터 분석방향을 이해할 수 있다.</li>
</ul>
<p><span style="color:skyblue">예시가설1. 인원이 많은 테이블일수록 더 많은  팁을 줄 것이다.</span></p>
<ul>
<li>가설 설정의 주의점<ul>
<li>데이터 분석 시각을 너무 좁게 만들 위험성이 있다.</li>
<li>문제 해결을 위한 전체적인 방향의 개념으로 활용하되, 가설이 문제의 정답인 것처럼 생각해서는 안된다.</li>
</ul>
</li>
</ul>
<h2 id="데이터-준비하기">데이터 준비하기</h2>
<ul>
<li>설정한 가설을 바탕으로 필요한 데이터셋 선정 및 수집</li>
<li>수집한 데이터셋에 대해 이상치제거, 중복제거, 형태변환등의 기본 전처리 진행</li>
</ul>
<h2 id="데이터-분석하기">데이터 분석하기</h2>
<ul>
<li>탐색적 데이터 분석(EDA)를 통해 데이터의 특징 파악</li>
<li>파악한 특징을 바탕으로 하여 설정한 가설이 옳았는지 검증하기</li>
</ul>
<h2 id="결과-정리하기">결과 정리하기</h2>
<ul>
<li>분석 결과 정리 시 주의해야할 점<ul>
<li>데이터 특징(인사이트) 위주로 정리하기</li>
<li>설정한 가설이 옳았는지 검증 결과 정리하기</li>
<li>문제 해결을 위해 새롭게 발견한 해결 방안 정리하기</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[13주차] Python Data Analysis Project 1]]></title>
            <link>https://velog.io/@luna_0219/13%EC%A3%BC%EC%B0%A8-Python-Data-Analysis-Project-1</link>
            <guid>https://velog.io/@luna_0219/13%EC%A3%BC%EC%B0%A8-Python-Data-Analysis-Project-1</guid>
            <pubDate>Sat, 27 May 2023 16:52:28 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>본 자료는 심민경 코치님의 자료를 사용하여 정리하였습니다.</p>
</blockquote>
<h1 id="pandas">Pandas</h1>
<h2 id="pandas란">Pandas란?</h2>
<ul>
<li>데이터 처리와 분석에 사용되는 파이썬 라이브러리</li>
<li>Series(1차원)와 DataFrame(2차원)이라는 데이터 형식을 제공</li>
<li>데이터를 다룰 수 있는 ㅐㄴ장함수를 제공</li>
</ul>
<h2 id="pandas--데이터-입력--불러오기">Pandas : 데이터 입력 / 불러오기</h2>
<h3 id="판다스-라이브러리-호출">판다스 라이브러리 호출</h3>
<p><code>import pandas as pd</code></p>
<h3 id="데이터-객체-데이터-프레임으로-변환">데이터 객체 데이터 프레임으로 변환</h3>
<p><code>변수 = pd.DataFrame({&#39;열1&#39;:list1, ...})</code></p>
<h3 id="csv-파일-불러오기">CSV 파일 불러오기</h3>
<p><code>변수 = pd.read_csv(파일경로)</code></p>
<h2 id="pandas--series">Pandas : Series</h2>
<ul>
<li>인덱스와 값으로 구성된 1차원 배열</li>
<li>인덱스로 값에 접근 가능</li>
<li>딕셔너리를 활용하면, 인덱스를 문자로 활용 가능하다.</li>
</ul>
<h2 id="pandas--dataframe">Pandas : DataFrame</h2>
<ul>
<li>행 인덱스와 열 이름으로 구성된 2차원 배열</li>
<li><code>.iloc</code>으로 숫자를 이용해 값에 접근 가능</li>
<li>컬럼이름으로 특정 컬럼 불러오기 가능</li>
<li><code>.append</code>로 데이터프레임 위아래로 결합할 수 있다.<ul>
<li><code>.concat</code>도 가능하다.</li>
</ul>
</li>
<li><code>.isnull()</code>로 결측치 확인이 가능하다.<ul>
<li>결과는 데이터프레임에 <code>True/False</code>로 매핑된다.</li>
</ul>
</li>
<li><code>.dropna</code>로 결측치 제거가 가능하다.</li>
<li><code>.sort_values</code>로 정렬 가능하다.<ul>
<li><code>ascending</code>으로 오름차순/내림차순 선택이 가능하다.</li>
</ul>
</li>
<li>조건 연산자를 사용할 수 있다.<ul>
<li><code>df[열] = 값</code></li>
<li>결과는 <code>True/False</code>로 나온다.</li>
</ul>
</li>
<li>다중조건 검색이 가능하다.<ul>
<li><code>df[(df[열] == 값) &amp; (df[열] &gt; 값)]</code></li>
</ul>
</li>
<li>값 대체하기<ul>
<li><code>df.replace({대체될 값:대체할 값, ...}, inplace = True)</code></li>
</ul>
</li>
<li>함수 적용하기<ul>
<li><code>df.apply(함수)</code></li>
</ul>
</li>
<li>내장함수<ul>
<li>조건부로 집계하기
<code>df.groupby(열).sum()</code><ul>
<li><code>.max()</code>, <code>.min()</code>, <code>.mean()</code> 가능</li>
</ul>
</li>
<li>변수 별로 다른 집계하기
<code>df[열1, 열2].groupby(열).aggregate({열1: &#39;min&#39;, 열2: &#39;mean&#39;})</code></li>
<li>특정 그룹 정보만 선택
<code>df[열1, 열2].groupby(열).get_group(값)</code></li>
<li>함수 적용
<code>df[열1, 열2].groupby(열).apply(lambda x: x.mean() - x.min())</code></li>
<li>필터링하기
<code>df[열1, 열2].groupby(열).filter(함수)</code></li>
<li>pivot_table
<code>df.pivot_table(index = &#39;행&#39;, column = &#39;열&#39;, values = &#39;요약할 컬럼&#39;)</code><ul>
<li><code>aggfunc = [&#39;min&#39;, &#39;mean&#39;, &#39;max&#39;]</code>도 넣을 수 있다.</li>
</ul>
</li>
</ul>
</li>
</ul>
<h1 id="numpy">Numpy</h1>
<h2 id="numpy-1">Numpy</h2>
<ul>
<li>숫자 배열을 효과적으로 저장하고 가공할 수 있는 라이브러리</li>
</ul>
<h2 id="numpy--배열array">Numpy : 배열(Array)</h2>
<h3 id="1차원-배열-선언하기">1차원 배열 선언하기</h3>
<p><code>변수 = np.array([원소1, ...])</code>
<code>변수 = np.array(리스트객체)</code></p>
<h3 id="indexing--slicing">Indexing / Slicing</h3>
<p><code>변수[number]</code>
<code>변수[start:end]</code>
<code>변수[:: step_num]</code></p>
<h3 id="데이터형-확인">데이터형 확인</h3>
<p><code>변수.dtype</code></p>
<h3 id="특정-규칙으로-채워진-배열-선언하기">특정 규칙으로 채워진 배열 선언하기</h3>
<ul>
<li>1차원
<code>변수 = np.arange(시작값, 마지막값 + 1, step)</code>
<code>변수 = np.random.random(생성할 난수 갯수)</code></li>
<li>2차원
<code>변수 = np.random.random(생성할 난수 갯수, size = (행, 열))</code>
<code>변수 = np.random.randint(생성할 정수시작, 끝, size = (행, 열))</code></li>
</ul>
<h3 id="1차원-배열로-2차원-배열-만들기">1차원 배열로 2차원 배열 만들기</h3>
<p><code>변수 = np.reshape((행, 열))</code></p>
<h3 id="배열-붙이기">배열 붙이기</h3>
<ul>
<li>1차원
<code>변수 = np.concatenate([배열1, 배열2])</code></li>
<li>2차원
<code>변수 = np.concatenate([배열1, 배열2], axis = 0)</code> - 위/아래로 붙이기
<code>변수 = np.concatenate([배열1, 배열2], axis = 1)</code> - 양옆으로 붙이기</li>
</ul>
<h3 id="배열-분리하기">배열 분리하기</h3>
<p><code>변수1, 변수2 = np.split(변수, [위에 둘 행 개수], axis = 0)</code> - 위/아래 나누기
<code>변수1, 변수2 = np.split(변수, [왼쪽에 둘 행 개수], axis = 1)</code> - 양옆 나누기</p>
<h3 id="사칙연산">사칙연산</h3>
<ul>
<li>1차원<ul>
<li>원소 각각 적용</li>
<li><code>+</code>, <code>-</code>, <code>*</code>, <code>/</code> 가능</li>
<li><code>변수 + 숫자</code></li>
</ul>
</li>
<li>2차원<ul>
<li>원소 각각 적용</li>
<li><code>+</code>, <code>-</code>, <code>*</code>, <code>/</code> 가능</li>
<li><code>변수 + 숫자</code>, <code>변수 + 변수</code></li>
</ul>
</li>
</ul>
<h3 id="집계함수">집계함수</h3>
<ul>
<li>1차원<ul>
<li><code>np.sum(변수)</code></li>
<li><code>np.mean(변수)</code></li>
<li><code>np.max(변수)</code></li>
<li><code>np.min(변수)</code></li>
</ul>
</li>
<li>2차원<ul>
<li><code>np.sum(변수)</code> : 모든 원소</li>
<li><code>np.mean(변수)</code></li>
<li><code>np.max(변수, axis = 0)</code> : 열기준</li>
<li><code>np.min(변수, axis = 1)</code> : 행기준</li>
</ul>
</li>
</ul>
<h3 id="조건연산자">조건연산자</h3>
<ul>
<li><code>변수 &lt; 숫자</code> : <code>True/False</code>로 매핑된다.</li>
<li><code>변수1[변수1 &lt; 숫자]</code> : 해당되는 값만 나온다.</li>
</ul>
<h1 id="matplotlib">Matplotlib</h1>
<h3 id="matplotlib이란">Matplotlib이란?</h3>
<ul>
<li>시각화에 필요한 다양한 그래프 형식과 디자인 기능을 제공하는 라이브러리</li>
</ul>
<h3 id="matplotlib-사용하기">Matplotlib 사용하기</h3>
<pre><code class="language-python">import matplotlib.pyplot as plt  # 라이브러리 호출
fig, ax = plt.subplot()
plt.plot(x, y, options...)  # 라인 그래프
plt.scatter(x, y, options...)  # 산점도 그래프</code></pre>
<h3 id="대표적인-plot-옵션">대표적인 plot 옵션</h3>
<ul>
<li><code>color = &#39;색상&#39;</code> : 색상, <code>0 ~ 1</code>사이의 숫자, RGB 값 사용가능</li>
<li><code>linestyle = &#39;solid&#39;</code> : <code>solid</code>, <code>dashed</code>, <code>dashdot</code>, <code>dotted</code>등 사용가능</li>
<li><code>label = &#39;라벨&#39;</code> : 선 이름 지정</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[12주차] 파이썬으로 시작하는 데이터 분석]]></title>
            <link>https://velog.io/@luna_0219/12%EC%A3%BC%EC%B0%A8-%ED%8C%8C%EC%9D%B4%EC%8D%AC%EC%9C%BC%EB%A1%9C-%EC%8B%9C%EC%9E%91%ED%95%98%EB%8A%94-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%B6%84%EC%84%9D</link>
            <guid>https://velog.io/@luna_0219/12%EC%A3%BC%EC%B0%A8-%ED%8C%8C%EC%9D%B4%EC%8D%AC%EC%9C%BC%EB%A1%9C-%EC%8B%9C%EC%9E%91%ED%95%98%EB%8A%94-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%B6%84%EC%84%9D</guid>
            <pubDate>Sat, 27 May 2023 16:09:49 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>본 자료는 Elice 플랫폼의 자료를 사용하여 정리하였습니다.</p>
</blockquote>
<h1 id="numpy-사용해보기">Numpy 사용해보기</h1>
<h2 id="numpy-소개">Numpy 소개</h2>
<h3 id="numpy란">Numpy란?</h3>
<ul>
<li>Python에서 대규모 다차원 배열을 다룰 수 있게 도와주는 라이브러리</li>
</ul>
<h3 id="list와-차이점">list와 차이점</h3>
<ul>
<li>list에 비해 빠른 연산을 지원하고 메모리를 효율적으로 사용</li>
</ul>
<h3 id="배열-만들기">배열 만들기</h3>
<pre><code class="language-python">import numpy as np
np.array([1, 2, 3, 4, 5])  # array([1, 2, 3, 4, 5])</code></pre>
<h3 id="배열-데이터-타입">배열 데이터 타입</h3>
<pre><code class="language-python">np.array([1, 2, 3, 4], dtype = float)  # array([1., 2., 3., 4., 5.])
  or
numpy배열.astype(int)  # array([1, 2, 3, 4])</code></pre>
<ul>
<li>타입은 int, float, str, bool 등이 있다.</li>
</ul>
<h3 id="다양한-배열-만들기">다양한 배열 만들기</h3>
<ul>
<li><code>np.zeros(10, dtype = int)</code> : <code>0</code>으로 <code>1x10</code> 배열 만들기</li>
<li><code>np.ones((3,5), dtype = float)</code> : <code>1</code>로 <code>3x5</code> 배열 만들기(실수형태로)</li>
<li><code>np.arange(0, 20, 2)</code> : <code>0 &lt;= x &lt; 20</code>으로 2배수씩 채워서 배열 만들기</li>
<li><code>np.linspace(0, 1, 5)</code> : <code>0 ~ 1</code>을 5개로 나눠서 배열 만들기</li>
</ul>
<h3 id="난수로-채워진-배열만들기">난수로 채워진 배열만들기</h3>
<ul>
<li><code>np.random.random((2,2))</code> : 난수로 <code>2x2</code> 배열 만들기</li>
<li><code>np.random.normal(0, 1, (2,2))</code> : 평균이 <code>0</code>이고 표준편차가 <code>1</code>인 값으로 <code>2x2</code> 배열 만들기</li>
<li><code>np.random.randint(0, 10, (2,2))</code> : <code>0</code>부터 <code>10</code>까지 값으로 <code>2x2</code> 배열 만들기</li>
</ul>
<h3 id="배열의-기초">배열의 기초</h3>
<ul>
<li><code>x2.ndim</code> : 몇차원인지</li>
<li><code>x2.shape</code> : <code>?x?</code> 배열인지</li>
<li><code>x2.size</code> : 원소가 몇개인지</li>
<li><code>x2.dtype</code> : 데이터타입이 뭔지</li>
</ul>
<h2 id="indexing--slicing">Indexing / Slicing</h2>
<ul>
<li><code>배열[위치]</code></li>
<li><code>배열[시작:끝]</code></li>
</ul>
<h2 id="모양바꾸기">모양바꾸기</h2>
<ul>
<li><code>배열.reshape((행, 열))</code> : shape를 <code>행x열</code>로 변경</li>
<li><code>np.concatenate([배열1, 배열2], axis = 0)</code> : 행을 기준으로 배열을 이어붙인다.(axis를 1로 설정하면 열을 기준으로 삼는다.)</li>
<li><code>a, b = np.split(배열, [인덱스], axis = 0)</code> : 행을 기준으로 인덱스 부분에서 나눈다.(axis를 1로 설정하면 열을 기준으로 삼는다.)</li>
</ul>
<h2 id="numpy-연산">Numpy 연산</h2>
<h3 id="기본연산">기본연산</h3>
<ul>
<li><code>배열 + 5</code> : 배열 모든 값에 +5</li>
<li><code>배열 - 5</code> : 배열 모든 값에 -5</li>
<li><code>배열 * 5</code> : 배열 모든 값에 x5</li>
<li><code>배열 / 5</code> : 배열 모든 값에 /5
<span style="color:red">행렬끼리도 가능하다.</span></li>
</ul>
<h2 id="브로드캐스팅">브로드캐스팅</h2>
<h3 id="shape이-다른-array끼리-연산">shape이 다른 array끼리 연산</h3>
<ul>
<li><code>matrix + 5</code> : matrix의 모든 값에 +5</li>
<li><code>matrix + np.array([1, 2, 3])</code> : matrix행 마다 [1, 2, 3]을 더한다.</li>
<li><code>np.arange(3).reshape((3, 1)) + np.arange(3)</code> : <code>3x1</code>과 <code>1x3</code>을 더한다.</li>
</ul>
<h2 id="집계함수--마스킹연산">집계함수 &amp; 마스킹연산</h2>
<h3 id="집계함수">집계함수</h3>
<ul>
<li><code>np.sum(배열)</code> : 합</li>
<li><code>np.min(배열)</code> : 최소값</li>
<li><code>np.max(배열)</code> : 최대값</li>
<li><code>np.mean(배열)</code> : 평균값
<span style="color:red">배열뒤에 axis로 행 또는 열 별 집계가 가능하다.</span></li>
</ul>
<h3 id="마스킹연산">마스킹연산</h3>
<ul>
<li><code>배열 &lt; 3</code> : 값을 다 비교하고 값 위치에 True/False를 채운다.</li>
<li><code>배열[배열 &lt; 3]</code> : True인 값만 출력</li>
</ul>
<h1 id="pandas-기본-알아보기">Pandas 기본 알아보기</h1>
<h2 id="pandas란">pandas란?</h2>
<ul>
<li>구조화된 데이터를 효과적으로 처리하고 저장</li>
<li>Array 계산에 특화된 numpy를 기반으로 설계</li>
</ul>
<h2 id="series">Series</h2>
<ul>
<li>numpy array가 보강된 형태</li>
<li>Data와 Index를 가지고 있다.<pre><code class="language-python">import pandas as pd
pd.Series([1, 2, 3, 4], index = [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;d&#39;], name = &#39;Title&#39;)</code></pre>
</li>
<li>딕셔너리를 Series에 넣을 수 있다.</li>
</ul>
<h2 id="dataframe">DataFrame</h2>
<ul>
<li>여러 개의 Series가 모여서 행과 열을 이룬 데이터
<code>pd.DataFrame(...)</code></li>
</ul>
<h2 id="저장과-불러오기">저장과 불러오기</h2>
<h3 id="저장">저장</h3>
<p><code>df.to_csv(파일명)</code>
<code>df.to_excel(파일명)</code></p>
<h3 id="불러오기">불러오기</h3>
<p><code>변수명 = pd.read_csv(파일명)</code>
<code>변수명 = pd.read_excel(파일명)</code></p>
<h2 id="indexing--slicing-1">Indexing / Slicing</h2>
<ul>
<li><code>.loc</code> : 인덱스를 이용해 인덱싱</li>
<li><code>.iloc</code> : 정수를 이용해 인덱싱</li>
</ul>
<h2 id="새로운-컬럼-추가">새로운 컬럼 추가</h2>
<p><code>df[컬럼명] = np.nan</code>
<code>df.loc[0, 컬럼명] = 값</code></p>
<h2 id="컬럼-선택하기">컬럼 선택하기</h2>
<p><code>df[컬럼명]</code>
<code>df[[컬럼1, 컬럼2]]</code></p>
<h2 id="누락된-데이터-체크">누락된 데이터 체크</h2>
<ul>
<li><code>df.isnull()</code> : 비어있으면 True</li>
<li><code>df.notnull()</code> : 값이 있으면 True</li>
<li><code>df.dropna()</code> : 비어있는 값이 있는 행 삭제</li>
<li><code>df[컬럼명] = df[컬럼명].fillna(값)</code> : 비어있으면 값을 채워준다.</li>
</ul>
<h2 id="값으로-정렬하기">값으로 정렬하기</h2>
<ul>
<li><code>df.sort_values(컬럼명, ascending = True)</code> : 오름차순 정렬</li>
<li><code>df.sort_values([컬럼1, 컬럼2])</code> : 컬럼 2개로 정렬</li>
</ul>
<h1 id="pandas-심화-알아보기">Pandas 심화 알아보기</h1>
<h2 id="조건으로-검색하기">조건으로 검색하기</h2>
<h3 id="masking-연산">Masking 연산</h3>
<p><code>df[&quot;A&quot;] &lt; 0.5</code></p>
<h3 id="조건-선언">조건 선언</h3>
<p><code>df[(df[&quot;A&quot;] &lt; 0.5) &amp; (df[&quot;B&quot; &gt; 0.3)]</code>
or
<code>df.query(&quot;A &lt; 0.5 and B &gt; 0.3&quot;)</code></p>
<h3 id="문자열로-검색">문자열로 검색</h3>
<p><code>df[&quot;Animal&quot;].str.contains(&quot;Cat&quot;)</code>
or
<code>df.Animal.str.match(&quot;Cat&quot;)</code></p>
<h2 id="함수로-데이터-처리하기">함수로 데이터 처리하기</h2>
<p><code>df[컬럼명].apply(함수)</code></p>
<h2 id="apply-기능에서-데이터-값만-대체하고-싶을-때">apply 기능에서 데이터 값만 대체하고 싶을 때</h2>
<p><code>df.Sex.replace({&quot;Male&quot;:0, &quot;Female&quot;:1}, inplace = True)</code></p>
<h2 id="그룹으로-묶기">그룹으로 묶기</h2>
<p><code>df.groupby(컬럼명)</code></p>
<ul>
<li><code>aggregate</code> : 집계를 한번에
<code>df.groupby(컬럼명).aggregate({&#39;data1&#39;:&#39;min&#39;, &#39;data2&#39;:np.sum})</code></li>
<li><code>filter</code> : 필터링
<code>df.groupby(컬럼명).filter(함수)</code></li>
<li><code>apply</code> : 함수 적용
<code>df.groupby(컬럼명).apply(lambda x: x.max() - x.min())</code></li>
<li><code>get_group</code> : 그룹에서 Key로 데이터 가져오기
<code>df.groupby(컬럼명).get_group(값)</code></li>
</ul>
<h2 id="multiindex">MultiIndex</h2>
<p><code>index = [[&#39;A&#39;, &#39;A&#39;, &#39;B&#39;, &#39;B&#39;], [1, 2, 1, 2]]</code></p>
<ul>
<li>Columns도 가능하다.</li>
</ul>
<h2 id="pivot_table">pivot_table</h2>
<p><img src="https://velog.velcdn.com/images/luna_0219/post/5bd160af-6dce-46c8-8407-d952ee3c698d/image.png" alt=""></p>
<h1 id="matplotlib-데이터-시각화">Matplotlib 데이터 시각화</h1>
<h2 id="matplotlib이란">Matplotlib이란?</h2>
<ul>
<li>파이썬에서 데이터를 그래프나 차트로 시각화할 수 있는 라이브러리
<img src="https://velog.velcdn.com/images/luna_0219/post/b871c265-09c7-4f50-a8e3-0f551e7d0e78/image.png" alt=""></li>
</ul>
<h2 id="저장하기">저장하기</h2>
<ul>
<li>위의 그림에서 아래 코드 추가<pre><code class="language-python">    fig.set_dip(300)
    fig.savefig(파일명)</code></pre>
</li>
</ul>
<h2 id="그래프-여러개-그리기">그래프 여러개 그리기</h2>
<p><img src="https://velog.velcdn.com/images/luna_0219/post/32a9d4a0-2c28-494d-bddc-a8fb9f6f1d78/image.png" alt=""></p>
<h2 id="그래프-스타일">그래프 스타일</h2>
<h3 id="라인강조">라인강조</h3>
<p><img src="https://velog.velcdn.com/images/luna_0219/post/228d8552-c65d-4001-84b6-51b47e314064/image.png" alt=""></p>
<h3 id="라인스타일">라인스타일</h3>
<p><img src="https://velog.velcdn.com/images/luna_0219/post/5a0a8b02-03d5-44e8-bf79-88c7ae3dcc4d/image.png" alt=""></p>
<h3 id="라인색상">라인색상</h3>
<p><img src="https://velog.velcdn.com/images/luna_0219/post/886f3454-902e-4e56-b430-f74ab09447a7/image.png" alt=""></p>
<h3 id="라인마커">라인마커</h3>
<p><img src="https://velog.velcdn.com/images/luna_0219/post/31c43749-048b-4331-b3c8-4559d0aecd95/image.png" alt=""></p>
<h3 id="축경계-조정">축경계 조정</h3>
<p><img src="https://velog.velcdn.com/images/luna_0219/post/33316ff3-5e94-49fb-b8dc-dc9a496088c7/image.png" alt=""></p>
<h3 id="범례">범례</h3>
<p><img src="https://velog.velcdn.com/images/luna_0219/post/cf2b9b6d-2364-4665-9b09-9e8ddfc62d59/image.png" alt=""></p>
<h2 id="선점도-그래프scatter">선점도 그래프(Scatter)</h2>
<p><img src="https://velog.velcdn.com/images/luna_0219/post/63a0a6a3-e4a3-4ff4-b7c8-e8180aba509f/image.png" alt=""><img src="https://velog.velcdn.com/images/luna_0219/post/48cd2ccc-17a4-4bec-9ffd-b0a748d49a9a/image.png" alt=""></p>
<h2 id="막대-그래프bar">막대 그래프(Bar)</h2>
<p><img src="https://velog.velcdn.com/images/luna_0219/post/b11530fc-e2d5-455d-b312-ea3a9834d45b/image.png" alt=""><img src="https://velog.velcdn.com/images/luna_0219/post/451bace1-8dd2-4d7b-b195-f03785996192/image.png" alt=""></p>
<h2 id="histogram">Histogram</h2>
<p><img src="https://velog.velcdn.com/images/luna_0219/post/d6b6c0c1-a344-4914-9d47-12361b8db9bf/image.png" alt=""></p>
<h2 id="matplotlib-with-pandas">Matplotlib with Pandas</h2>
<p><img src="https://velog.velcdn.com/images/luna_0219/post/9e7af6b3-1d80-4f74-8d48-03b9be8e30d5/image.png" alt=""><img src="https://velog.velcdn.com/images/luna_0219/post/f434e80b-d194-477e-9342-86415a25b5b2/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[12주차] Python Data Analysis 2]]></title>
            <link>https://velog.io/@luna_0219/12%EC%A3%BC%EC%B0%A8-Python-Data-Analysis-2</link>
            <guid>https://velog.io/@luna_0219/12%EC%A3%BC%EC%B0%A8-Python-Data-Analysis-2</guid>
            <pubDate>Sat, 27 May 2023 11:05:52 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>본 자료는 심민경 코치님의 자료와 Elice 플랫폼의 자료를 사용하여 정리하였습니다.</p>
</blockquote>
<h1 id="자료구조-2">자료구조 2</h1>
<h2 id="딕셔너리">딕셔너리</h2>
<h3 id="딕셔너리-특징">딕셔너리 특징</h3>
<ul>
<li>키와 값의 순서쌍으로 구성</li>
<li>키는 중복 X</li>
<li><code>딕셔너리 이름 = {키1:값1, 키2:값2, ..., 키n:값n}</code> 형태</li>
</ul>
<h3 id="딕셔너리-메소드">딕셔너리 메소드</h3>
<ul>
<li><code>.get(key)</code> : 키에 해당하는 값 반환</li>
<li><code>.keys()</code> : 키 전부 출력</li>
<li><code>.values()</code> : 값 전부 출력</li>
<li><code>.items()</code> : 딕셔너리 출력</li>
</ul>
<h3 id="갯수-확인">갯수 확인</h3>
<p><code>len(딕셔너리)</code></p>
<h3 id="요소-추가">요소 추가</h3>
<p><code>딕셔너리이름[새로 추가할 키] = 값</code></p>
<h3 id="요소-수정">요소 수정</h3>
<p><code>딕셔너리이름[수정할 키] = 새로운 값</code></p>
<h3 id="요소-삭제">요소 삭제</h3>
<ul>
<li>특정요소 삭제
<code>del 딕셔너리이름[삭제할 키]</code></li>
<li>모든 요소 삭제
<code>딕셔너리이름.clear()</code></li>
</ul>
<h2 id="set">Set</h2>
<h3 id="set-특징">Set 특징</h3>
<ul>
<li>순서도, 중복도 없는 자료형</li>
<li><code>set이름 = {값1, 값2, ..., 값3}</code> 형태</li>
</ul>
<h3 id="set-메소드">Set 메소드</h3>
<ul>
<li><code>.add(&#39;새요소&#39;)</code> : 요소 1개 추가</li>
<li><code>.update(&#39;새요소1&#39;, &#39;새요소2&#39;, ..., &#39;새요소n&#39;)</code> : 요소 여러 개 추가</li>
<li><code>.remove(&#39;기존요소&#39;)</code> : 특정요소 삭제</li>
<li><code>.clear()</code> : 전체요소 삭제</li>
</ul>
<h3 id="set--교집합합집합차집합">Set : 교집합/합집합/차집합</h3>
<ul>
<li>교집합 연산<pre><code class="language-python">    set1 &amp; set2
    set1.intersection(set2)</code></pre>
</li>
<li>합집합 연산<pre><code class="language-python">    set1 | set2
    set1.union(set2)</code></pre>
</li>
<li>차집합 연산<pre><code class="language-python">    set1 - set2
    set1.difference(set2)</code></pre>
</li>
<li>XOR도 가능하다.</li>
</ul>
<h2 id="복합자료형-비교">복합자료형 비교</h2>
<p><img src="https://velog.velcdn.com/images/luna_0219/post/3fc51d91-5634-4813-af4b-ac4446d3eade/image.png" alt=""></p>
<h1 id="파일-입출력">파일 입/출력</h1>
<h2 id="csv">CSV</h2>
<h3 id="csv-장점">CSV 장점</h3>
<ul>
<li>같은 데이터를 저장하는 데 용량을 적게 소모한다.</li>
</ul>
<h3 id="csv-단점">CSV 단점</h3>
<ul>
<li>데이터 오염에 취약하다.</li>
</ul>
<h3 id="python에서-csv-열기">python에서 CSV 열기</h3>
<pre><code class="language-python">import csv
with open(&#39;movies.csv&#39;) as file:
  reader = csv.reader(file, delimiter = &#39;,&#39;)
  for row in reader:
    print(row[0])</code></pre>
<h3 id="판다스로-csv-열기">판다스로 CSV 열기</h3>
<pre><code class="language-python">import pandas as pd
변수명 = pd.read_csv(파일경로)</code></pre>
<h2 id="json">JSON</h2>
<h3 id="json이란">JSON이란?</h3>
<ul>
<li>&quot;키-값&quot;으로 이루어진 데이터 오브젝트를 전달</li>
<li>사람이 읽고 쓰고, 기계가 분석하고 생성하기 용이</li>
<li>개방형 표준 포맷이고, 구조에 제한이 없다.</li>
<li>웹 환경에서 데이터를 주고받는 가장 표준적인 방식</li>
<li>키를 이용하여 원하는 데이터만 빠르게 추출 가능</li>
<li>데이터가 쉽게 오염되지 않는다.</li>
<li>다른 포맷에 비해 용량이 조금 큰 편이다.</li>
</ul>
<h3 id="json-라이브러리-호출">JSON 라이브러리 호출</h3>
<p><code>import json</code></p>
<h3 id="json을-python-딕셔너리로-변환">JSON을 Python 딕셔너리로 변환</h3>
<p><code>변수명 = json.loads(json명, strict = False)</code></p>
<h3 id="python-딕셔너리를-json으로-변환">Python 딕셔너리를 JSON으로 변환</h3>
<p><code>변수명 = json.dumps(딕셔너리, ensure_ascii = False)</code></p>
<h3 id="json-파일-읽어오기">JSON 파일 읽어오기</h3>
<p><code>변수명 = json.load(open(json명, &#39;r&#39;, encoding = &#39;utf-8&#39;))</code></p>
<ul>
<li>with open을 사용하는 경우<pre><code class="language-python">    with open(json명, &#39;r&#39;, encoding = &#39;utf-8&#39;) as f:
        변수명 = json.load(f)</code></pre>
</li>
</ul>
<h1 id="대용량-데이터-처리">대용량 데이터 처리</h1>
<h2 id="iterable">Iterable</h2>
<ul>
<li>차례로 하나 씩 반복해서 반환할 수 있는 객체</li>
<li>List, Set, Tuple, Dictionary</li>
</ul>
<h2 id="iterator">Iterator</h2>
<ul>
<li>값을 차례대로 꺼낼 수 있는 객체</li>
<li>next() 메소드로 데이터를 순차적으로 호출할 수 있다.</li>
<li>List는 iterator가 아니지만, for문에서 임시로 iterator로 쓰인다<pre><code class="language-python">y = iter(x)
next(y)</code></pre>
</li>
</ul>
<h2 id="generator">Generator</h2>
<ul>
<li>Iterator를 생성해주는 함수</li>
</ul>
<h1 id="유용한-파이썬-함수">유용한 파이썬 함수</h1>
<h2 id="lambda-함수">Lambda 함수</h2>
<ul>
<li>한 줄짜리 이름 없는 함수</li>
<li><code>lambda 필요한 동작, 인수</code> 형태
<code>lambda r: r*r*pi</code></li>
</ul>
<h2 id="assert-함수">assert 함수</h2>
<ul>
<li>assert안에 연산을 검증해준다.</li>
</ul>
<h2 id="map-함수">map 함수</h2>
<ul>
<li>원소를 함수에 대입한 결과를 반환
<code>map(함수, 인자가 들어있는 리스트)</code></li>
<li>함수부분에 lambda를 사용해도 된다.</li>
</ul>
<h2 id="filter-함수">filter 함수</h2>
<ul>
<li>함수 결과가 True인 경우 결과를 반환
<code>filter(함수, 인자가 들어있는 리스트)</code></li>
<li>함수부분에 lambda를 사용해도 된다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[12주차] 데이터 분석을 위한 파이썬]]></title>
            <link>https://velog.io/@luna_0219/12%EC%A3%BC%EC%B0%A8-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%B6%84%EC%84%9D%EC%9D%84-%EC%9C%84%ED%95%9C-%ED%8C%8C%EC%9D%B4%EC%8D%AC1</link>
            <guid>https://velog.io/@luna_0219/12%EC%A3%BC%EC%B0%A8-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%B6%84%EC%84%9D%EC%9D%84-%EC%9C%84%ED%95%9C-%ED%8C%8C%EC%9D%B4%EC%8D%AC1</guid>
            <pubDate>Sat, 27 May 2023 10:33:57 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>본 자료는 Elice 플랫폼의 자료를 사용하여 정리하였습니다.</p>
</blockquote>
<h1 id="트럼프-대통령-트윗으로-시작하는-데이터처리">트럼프 대통령 트윗으로 시작하는 데이터처리</h1>
<h2 id="리스트-순회">리스트 순회</h2>
<h3 id="for-in">for, in</h3>
<ul>
<li>배열 반복<pre><code class="language-python">    fruits = [&quot;사과&quot;, &quot;바나나&quot;, &quot;키위&quot;]
    for fruit in fruits:
          print(fruit + &quot;는 맛있어&quot;)</code></pre>
</li>
<li>범위 반복<pre><code class="language-python">    for num in range(10):
        print(num)</code></pre>
<h3 id="인덱싱">인덱싱</h3>
</li>
<li>배열 인덱싱<pre><code class="language-python">    fruits = [&quot;사과&quot;, &quot;바나나&quot;, &quot;키위&quot;, &quot;배&quot;]
    last_fruit = fruits[-1]
    tropical_fruits = fruits[1:3]
    no_apple = fruits[1:]
    np_pear = fruits[:3]</code></pre>
</li>
<li>문자열 인덱싱<pre><code class="language-python">    word = &quot;superman&quot;
    print(word[3])  # &#39;e&#39;
    print(word[-2])  # &#39;a&#39;
    print(word[5:])  # &#39;man&#39;
    print(word[:5])  # &#39;super&#39;</code></pre>
</li>
</ul>
<h2 id="문자열-함수">문자열 함수</h2>
<ul>
<li><code>startswith()</code><pre><code class="language-python">    word = &quot;superman&quot;
    print(word.startswith(&#39;s&#39;))  # True</code></pre>
</li>
<li><code>split()</code><pre><code class="language-python">    fruits = &quot;사과,귤,배&quot;
    print(fruits.split(&quot;,&quot;))  # [&quot;사과&quot;, &quot;귤&quot;, &quot;배&quot;]</code></pre>
</li>
<li><code>append()</code><pre><code class="language-python">    numbers = []
    numbers.append(1)  # [1]
    numbers.append(2)  # [1, 2]</code></pre>
</li>
<li><code>upper(), lower()</code><ul>
<li>원래 문자열을 직접 수정하지 않는다.(다른 변수에 담거나 같은 변수에 담을 것)<pre><code class="language-python">  intro = &quot;Hello&quot;
  print(intro.upper())  # &quot;HELLO&quot;
  print(intro.lower())  # &quot;hello&quot;</code></pre>
</li>
</ul>
</li>
<li><code>replace()</code><ul>
<li>특정 문자를 없애는 것도 가능하다.<pre><code class="language-python">  intro = &quot;Hello, my name is Elice&quot;
  print(intro.replace(&quot;Elice&quot;, &quot;엘리스&quot;))  # &quot;Hello, my name is 엘리스&quot;</code></pre>
</li>
</ul>
</li>
</ul>
<h1 id="영어-단어-모음으로-시작하는-텍스트-파일-분석">영어 단어 모음으로 시작하는 텍스트 파일 분석</h1>
<h2 id="파일-다루기">파일 다루기</h2>
<h3 id="파일-열기닫기">파일 열기/닫기</h3>
<pre><code class="language-python">      file = open(&#39;data.txt&#39;)
      content = file.read()
      file.close()</code></pre>
<h3 id="파일-자동으로-닫기">파일 자동으로 닫기</h3>
<pre><code class="language-python">      with open(&#39;data.txt&#39;) as file:
          content=file.read()</code></pre>
<h3 id="줄-단위로-읽기">줄 단위로 읽기</h3>
<pre><code class="language-python">      contents = []
      with open(&#39;data.txt&#39;) as file:
          for line in file:
              contents.append(line)</code></pre>
<h3 id="파일의-모드쓰기모드로-열기">파일의 모드(쓰기모드로 열기)</h3>
<pre><code class="language-python">      with open(&#39;data.txt&#39;, &#39;w&#39;) as file:
          file.write(&#39;Hello&#39;)</code></pre>
<h2 id="데이터-구조-다루기">데이터 구조 다루기</h2>
<h3 id="튜플-vs-리스트">튜플 vs 리스트</h3>
<ul>
<li>공통점<ul>
<li>순서가 있는 원소들의 집합</li>
</ul>
</li>
<li>차이점<ul>
<li>각 원소의 값을 수정할 수 없다. (인덱싱 X)</li>
<li>원소의 개수를 바꿀 수 없다. (append() X)</li>
</ul>
</li>
</ul>
<h3 id="리스트로-리스트-만들기">리스트로 리스트 만들기</h3>
<pre><code class="language-python">words = [&#39;life&#39;, &#39;love&#39;, &#39;faith&#39;]
first_letters = [word[0] for word in words]</code></pre>
<h3 id="특정-원소-걸러내기">특정 원소 걸러내기</h3>
<pre><code class="language-python">numbers = [1, 3, 4, 5, 6, 7]
even = [n for n in numbers if n%2 == 0]</code></pre>
<h3 id="데이터-정렬하기">데이터 정렬하기</h3>
<pre><code class="language-python">numbers = [-1, 3, -4, 5, 6, 100]
sort_by_abs = sorted(numbers, key=abs)</code></pre>
<ul>
<li>key에는 reverse, lambda등이 들어간다.</li>
</ul>
<h2 id="그래프-다루기">그래프 다루기</h2>
<h3 id="matplotlib">matplotlib</h3>
<ul>
<li>파이썬에서 그래프를 그릴 수 있게 하는 라이브러리</li>
<li>꺾은선 그래프, 막대 그래프 등을 모두 지원한다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[12주차] Python Data Analysis 1]]></title>
            <link>https://velog.io/@luna_0219/12%EC%A3%BC%EC%B0%A8-Python-Data-Analysis-1</link>
            <guid>https://velog.io/@luna_0219/12%EC%A3%BC%EC%B0%A8-Python-Data-Analysis-1</guid>
            <pubDate>Sat, 27 May 2023 10:06:28 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>본 자료는 심민경 코치님의 자료를 사용하여 정리하였습니다.</p>
</blockquote>
<h1 id="python-review">Python Review</h1>
<h2 id="객체-지향-프로그래밍">객체 지향 프로그래밍</h2>
<ul>
<li>클래스에서 정의한 객체를 상호연결해 문제를 해결하는 과정</li>
</ul>
<h2 id="객체란">객체란?</h2>
<ul>
<li>클래스에서 정의한 것을 토대로 메모리(실제 저장공간)에 할당된 것</li>
<li>프로그램에서 사용되는 데이터 또는 식별자에 의해 참조되는 공간을 의미</li>
<li>변수, 자료구조, 함수 또는 메소드가 될 수 있다.</li>
</ul>
<h2 id="객체의-구성요소">객체의 구성요소</h2>
<ul>
<li>속성 : 자신의 상태를 표현하는 정적인 성질</li>
<li>행위 : 객체 내부 혹은 다른 객체와 상호작용하는 행위</li>
<li>같은 속성, 다른 속성값</li>
<li>미리 지정된 행위 : 외부요청에 따라 객체는 미리 정해진 일을 스스로 처리
<span style="color:red">$\rarr$ 자신의 데이터를 가지고 필요한 처리를 스스로 수행하는 연관된 정보(변수, 함수)들의 묶음</span></li>
</ul>
<h2 id="클래스">클래스</h2>
<ul>
<li>공통의 속성을 갖되, 서로 다른 속성값을 지니면서 공통의 행위를 수행하는 같은 종류의 객체를 생성하기 위해 정의되는 틀</li>
</ul>
<h2 id="함수function-vs-메소드method">함수(Function) vs 메소드(Method)</h2>
<h3 id="함수">함수</h3>
<p><img src="https://velog.velcdn.com/images/luna_0219/post/b2035ed5-e9b0-4706-8f22-b2162371b23a/image.png" alt=""></p>
<ul>
<li>내장함수<ul>
<li>파이썬 내부에 호출 형태와 동작 내용이 미리 정의된 함수</li>
<li>print 등</li>
</ul>
</li>
</ul>
<h3 id="메소드">메소드</h3>
<ul>
<li>함수와 다르게 인자를 넣어 주지 않아도 된다.</li>
</ul>
<h2 id="모듈">모듈</h2>
<ul>
<li>전역변수, 함수, 클래드 등을 모아놓은 .py확장자를 가진 파일</li>
<li>다른 파이썬 파일에서 모듈을 import명령어를 이용해 불러올 수 있다.</li>
</ul>
<h2 id="패키지라이브러리">패키지(라이브러리)</h2>
<ul>
<li>모듈을 모아놓은 폴더</li>
</ul>
<h1 id="자료구조-1">자료구조 1</h1>
<h2 id="자료형data-type">자료형(Data Type)</h2>
<ul>
<li>하나의 값을 나타내는 데이터의 유형</li>
<li>기본자료형(데이터 하나)<ul>
<li>정수형, 실수형, 복소수형, 논리형, 문자열</li>
</ul>
</li>
<li>복합자료형(다수의 데이터 묶음)<ul>
<li>리스트, 튜플, 딕셔너리, 집합</li>
</ul>
</li>
</ul>
<h2 id="문자열">문자열</h2>
<ul>
<li>문자 혹은 문자들의 묶음</li>
<li>같은 종류의 따옴표로 감싸진 문자들</li>
<li>문자열 조작<ul>
<li>인덱싱<ul>
<li>문자열을 구성하는 문자들의 순번(인덱스 값)에 따라 해당문자를 얻어오는 연산</li>
<li>첫 번째 문자에 대한 인덱스 값이 <code>0</code>번</li>
<li>마지막 문자는 <code>-1</code>로 시작, 왼쪽으로 하나씩 이동(세글자의 경우 <code>-3</code>, <code>-2</code>, <code>-1</code>)</li>
<li><code>문자열[인덱스]</code> 형태</li>
</ul>
</li>
<li>슬라이싱<ul>
<li>범위 표현으로 문자열을 구성하는 부분 문자열을 얻는 연산</li>
<li>문자열의 시작 인덱스부터 끝 인덱스이전까지 부분문자열</li>
<li><code>문자열[시작:끝]</code> 형태</li>
</ul>
</li>
</ul>
</li>
<li>문자열 메소드<ul>
<li><code>문자열.upper()</code> : 대문자로 변환</li>
<li><code>문자열.lower()</code> : 소문자로 변환</li>
<li><code>문자열.replace(찾을 문자열, 새 문자열)</code> : 문자열 대체</li>
<li><code>문자열.startswith(특정 문자열)</code> : 시작문자열 체크</li>
<li><code>문자열.split(구분자)</code> : 구분자를 기준으로 잘라서 리스트로 반환</li>
</ul>
</li>
</ul>
<h2 id="리스트">리스트</h2>
<ul>
<li>저장 순서가 있는 변수들의 묶음</li>
<li>다수의 데이터를 모아 하나의 이름으로 저장</li>
<li>반복문과 함께 사용하면 효율적으로 데이터에 접근할 수 있다.</li>
<li>n개의 요소(element)를 갖는 리스트 선언문</li>
<li><code>리스트 이름 = [값1, 값2, ..., 값3]</code> 형태</li>
<li>리스트 조작<ul>
<li>인덱싱<ul>
<li>유효한 순번에 따라 각 요소 데이터를 개별적으로 선택해 접근가능</li>
<li><code>리스트이름[인덱스]</code> 형태</li>
</ul>
</li>
<li>슬라이싱<ul>
<li>범위를 지정해서 리스트를 구성하는 일부요소를 또 다른 리스트로 생성하는 연산</li>
<li><code>리스트이름[시작 인덱스:끝 인덱스]</code> 형태</li>
</ul>
</li>
</ul>
</li>
<li>리스트 내장함수<ul>
<li><code>len(리스트 이름)</code> : 데이터의 개수 확인</li>
<li><code>sorted(리스트 이름, reverse=false)</code> : 정렬<ul>
<li>reverse가 true면 내림차순 정렬</li>
</ul>
</li>
<li><code>리스트이름.append(값)</code> : 맨 마지막에 값 추가</li>
</ul>
</li>
</ul>
<h2 id="for-반복문">For 반복문</h2>
<ul>
<li>지정된 횟수만큼 반복하거나, 일정 범위를 일정한 간격으로 증감하며 반복<pre><code class="language-python">    for 변수 in 범위표현식:
        수행할 문장</code></pre>
</li>
<li>범위 for 반복문<pre><code class="language-python">    for 변수 in range(start, end, step):
        수행할 문장</code></pre>
</li>
<li>List for 반복문<pre><code class="language-python">    for 변수 in list:
        수행할 문장</code></pre>
</li>
</ul>
<h2 id="튜플">튜플</h2>
<ul>
<li>리스트와 유사한 복합자료형</li>
<li>한 번 정의된 이후, 튜플에 포함된 요소를 수정, 삭제가 불가능하다.</li>
<li>튜플에 새 요소를 추가할 수 없다.</li>
<li><code>튜플이름 = (값1, 값2, ..., 값n)</code> 형태</li>
<li>튜플 인덱싱, 슬라이싱, 연결<ul>
<li>리스트와 같은 방식으로 인덱싱, 슬라이싱 가능</li>
<li>튜플에 정의된 후 요소를 수정하거나, 추가할 수 없지만 연결은 가능</li>
<li><code>새로운 튜플이름 = 튜플1 + 튜플2</code> 형태</li>
<li><code>새로운 튜플이름 = 튜플 * 반복 수</code> 형태</li>
</ul>
</li>
</ul>
<h2 id="파일-입출력">파일 입/출력</h2>
<ul>
<li>pandas 라이브러리를 활용해 csv파일을 데이터프레임으로 읽어올 수 있다.</li>
<li>판다스 라이브러리 호출
<code>import pandas as pd</code></li>
<li>특정 경로에 저장된 csv파일을 데이터 프레임으로 생성
<code>변수명 = pd.read_csv(파일경로)</code></li>
</ul>
<h2 id="데이터-시각화">데이터 시각화</h2>
<ul>
<li>matplotlib 라이브러리 활용(numpy 배열 기반)<pre><code class="language-python">    import numpy as np
     import matplotlib as mpl
         or
     import matplotlib.pyplot as plt</code></pre>
</li>
<li>데이터프레임에 저장된 특정컬럼을 리스트 or 배열로 저장<pre><code class="language-python">    변수명 = list(데이터프레임 명[컬럼명])
        or
    변수명 = np.array(데이터프레임 명[컬럼명])</code></pre>
</li>
<li>히스토그램 그리기
<code>plt.hist(변수명, bins=18, color=&#39;#800080&#39;)</code></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[11주차] SQL로 데이터 다루기 2]]></title>
            <link>https://velog.io/@luna_0219/11%EC%A3%BC%EC%B0%A8-SQL%EB%A1%9C-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%8B%A4%EB%A3%A8%EA%B8%B0-2</link>
            <guid>https://velog.io/@luna_0219/11%EC%A3%BC%EC%B0%A8-SQL%EB%A1%9C-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%8B%A4%EB%A3%A8%EA%B8%B0-2</guid>
            <pubDate>Tue, 16 May 2023 18:48:27 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>본 자료는 Elice 플랫폼의 자료를 사용하여 정리하였습니다.</p>
</blockquote>
<h1 id="데이터-그룹-짓기">데이터 그룹 짓기</h1>
<h2 id="group-by">GROUP BY</h2>
<ul>
<li><code>SELECT COUNT(*) FROM 테이블명 GROUP BY 컬럼명;</code></li>
</ul>
<h1 id="데이터-그룹에-조건-적용하기">데이터 그룹에 조건 적용하기</h1>
<h2 id="group-by--having">GROUP BY / HAVING</h2>
<ul>
<li><code>SELECT COUNT(*) FROM 테이블명 GROUP BY 컬럼명 HAVING 조건;</code></li>
</ul>
<h1 id="두-개의-테이블에서-조회하기">두 개의 테이블에서 조회하기</h1>
<h2 id="inner-join">INNER JOIN</h2>
<ul>
<li><code>SELECT * FROM 테이블명1 INNER JOIN 테이블명2;</code></li>
</ul>
<h1 id="조건을-적용해-두-개의-테이블-조회하기">조건을 적용해 두 개의 테이블 조회하기</h1>
<h2 id="inner-join-1">INNER JOIN</h2>
<ul>
<li><code>SELECT * FROM 테이블명1 INNER JOIN 테이블명2 ON 연결할 조건;</code></li>
</ul>
<h1 id="left-join">LEFT JOIN</h1>
<h2 id="left-join-1">LEFT JOIN</h2>
<ul>
<li><code>SELECT * FROM 테이블명1 LEFT JOIN 테이블명2 ON 연결할 조건;</code></li>
</ul>
<h2 id="inner-join-vs-left-join">INNER JOIN vs LEFT JOIN</h2>
<p><img src="https://velog.velcdn.com/images/luna_0219/post/020a3c8d-cc88-482d-a888-40a9518e9bc5/image.png" alt=""></p>
<h1 id="right-join">RIGHT JOIN</h1>
<h2 id="right-join-1">RIGHT JOIN</h2>
<ul>
<li><code>SELECT * FROM 테이블명1 RIGHT JOIN 테이블명2 ON 연결할 조건;</code></li>
</ul>
<h2 id="left-join-vs-right-join">LEFT JOIN vs RIGHT JOIN</h2>
<p><img src="https://velog.velcdn.com/images/luna_0219/post/52c0f135-f5d3-49d5-8ff9-e445d0244724/image.png" alt=""></p>
<h1 id="서브쿼리">서브쿼리</h1>
<h2 id="서브쿼리-정의">서브쿼리 정의</h2>
<ul>
<li>하나의 쿼리 안에 포함된 또 하나의 쿼리</li>
<li>메인 쿼리가 서브쿼리를 퐇마하는 종속적인 관계</li>
</ul>
<h2 id="서브쿼리의-특징">서브쿼리의 특징</h2>
<ul>
<li>알려지지 않은 기준을 이용한 검색에 유용</li>
<li>메인쿼리가 실행되기 이전에 한 번만 실행</li>
<li>한 문장에 여러 번 사용 가능</li>
</ul>
<h2 id="서브쿼리를-사용한-예시">서브쿼리를 사용한 예시</h2>
<pre><code class="language-sql">SELECT * 
FROM employee
WHERE 급여 &gt; (SELECT 급여
             FROM employee
             WHERE 이름 = &#39;elice&#39;);</code></pre>
<h2 id="서브쿼리-사용-시-주의사항">서브쿼리 사용 시 주의사항</h2>
<ul>
<li>서브쿼리는 괄호와 함께 사용되어야한다.</li>
<li>서브쿼리 안에서 ORDER BY 절은 사용할 수 없다.</li>
<li>서브쿼리는 연산자의 오른쪽에 사용되어야 한다.</li>
<li>서브쿼리는 오로지 SELECT 문으로만 작성할 수 있다.</li>
</ul>
<h1 id="반환에-따른-분류">반환에 따른 분류</h1>
<h2 id="단일-행-서브쿼리-정의">단일 행 서브쿼리 정의</h2>
<ul>
<li>결과가 한 행만 나오는 서브쿼리</li>
<li>서브쿼리가 결과를 1개의 값만 반환하고, 이 결과를 메인쿼리로 전달하는 쿼리</li>
</ul>
<h2 id="단일-행-서브쿼리-기본-문법">단일 행 서브쿼리 기본 문법</h2>
<pre><code class="language-sql">SELECT * 
FROM employee
WHERE 급여 &gt; (SELECT 급여
             FROM employee
             WHERE 사원번호 = 1);</code></pre>
<ul>
<li>연산자는 <code>=</code>, <code>&lt;&gt;</code>, <code>&gt;</code>, <code>&gt;=</code>, <code>&lt;</code>, <code>&lt;=</code>가 있다.</li>
</ul>
<h2 id="다중-행-서브쿼리-정의">다중 행 서브쿼리 정의</h2>
<ul>
<li>결과를 2개 이상 반환</li>
</ul>
<h2 id="다중-행-서브쿼리-기본-문법">다중 행 서브쿼리 기본 문법</h2>
<pre><code class="language-sql">SELECT * 
FROM employee
WHERE 급여 IN (SELECT MAX(급여)
              FROM employee
              GROUP BY 부서번호);</code></pre>
<ul>
<li>연산자는 <code>IN</code>, <code>ANY</code>, <code>ALL</code>이 있다.</li>
</ul>
<h2 id="다중-행-연산자-사용-예시">다중 행 연산자 사용 예시</h2>
<pre><code class="language-sql">1 in (1, 2, 3, 4)
10 &lt;any (1, 2, 3, 4)
99 &gt;=all (99, 100, 101)</code></pre>
<h1 id="위치에-따른-분류">위치에 따른 분류</h1>
<h2 id="스칼라-서브쿼리-정의">스칼라 서브쿼리 정의</h2>
<ul>
<li>SELECT 절에서 사용하는 서브쿼리</li>
<li>오직 한 행만 반환</li>
<li>마치 JOIN을 사용한 것과 같은 결과를 나타낸다.</li>
</ul>
<h2 id="스칼라-서브쿼리-사용-방법">스칼라 서브쿼리 사용 방법</h2>
<pre><code class="language-sql">SELECT student.name, (SELECT math
                      FROM middle_test as m
                      WHERE m.student_id = students.student_id) AS middle_avg
FROM students;</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[11주차] SQL로 데이터 다루기 1]]></title>
            <link>https://velog.io/@luna_0219/11%EC%A3%BC%EC%B0%A8-SQL%EB%A1%9C-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%8B%A4%EB%A3%A8%EA%B8%B0-1</link>
            <guid>https://velog.io/@luna_0219/11%EC%A3%BC%EC%B0%A8-SQL%EB%A1%9C-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%8B%A4%EB%A3%A8%EA%B8%B0-1</guid>
            <pubDate>Tue, 16 May 2023 18:35:25 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>본 자료는 Elice 플랫폼의 자료를 사용하여 정리하였습니다.</p>
</blockquote>
<h1 id="sql이란">SQL이란?</h1>
<h2 id="데이터베이스란">데이터베이스란?</h2>
<ul>
<li>여러사람이 공유해 사용할 목적으로 통합하여 관리되는 데이터의 모음</li>
</ul>
<h2 id="데이터베이스를-제어하는-방법">데이터베이스를 제어하는 방법</h2>
<ul>
<li>데이터베이스에 접근하고 조작하기 위한 표준언어인 SQL을 이용</li>
</ul>
<h1 id="테이블에서-데이터검색하기">테이블에서 데이터검색하기</h1>
<h2 id="select-문">SELECT 문</h2>
<ul>
<li><code>SELECT 컬럼명 FROM 테이블명;</code></li>
<li>모든 컬럼을 검색하려면 <code>*</code>을 사용</li>
</ul>
<h2 id="select-문-중복제거">SELECT 문 중복제거</h2>
<ul>
<li><code>SELECT DISTINCT 컬럼명 FROM 테이블명;</code></li>
</ul>
<h2 id="조건을-추가하여-select">조건을 추가하여 SELECT</h2>
<ul>
<li><code>SELECT 컬럼명 FROM 테이블명 WHERE 조건;</code></li>
<li>조건에는 비교연산자, AND/OR, BETWEEN, IN등 사용가능</li>
</ul>
<h1 id="데이터에서-유사한-값-찾기">데이터에서 유사한 값 찾기</h1>
<h2 id="like">LIKE</h2>
<ul>
<li><code>SELECT name FROM student WHERE name LIKE &#39;%민%&#39;;</code></li>
<li><code>%</code>는 어떤 값도 상관없다는 뜻</li>
</ul>
<h1 id="데이터-정렬하기">데이터 정렬하기</h1>
<h2 id="order-by">ORDER BY</h2>
<ul>
<li><code>SELECT 컬럼명 FROM 테이블명 ORDER BY 컬럼명 ASC;</code></li>
<li>ASC 또는 DESC를 사용한다.</li>
</ul>
<h1 id="데이터-삽입하기">데이터 삽입하기</h1>
<h2 id="insert-문">INSERT 문</h2>
<ul>
<li><code>INSERT INTO 테이블명(컬럼명) VALUES(추가할 데이터);</code></li>
<li>컬럼명은 생략 가능하다.</li>
</ul>
<h1 id="테이블의-데이터-수정하기">테이블의 데이터 수정하기</h1>
<h2 id="update-문">UPDATE 문</h2>
<ul>
<li><code>UPDATE 테이블명 SET 변경할값 WHERE 조건;</code></li>
</ul>
<h1 id="테이블의-데이터-삭제하기">테이블의 데이터 삭제하기</h1>
<h2 id="delete-문">DELETE 문</h2>
<ul>
<li><code>DELETE FROM 테이블명 WHERE 조건;</code></li>
</ul>
<h1 id="sql과-함수">SQL과 함수</h1>
<h2 id="count">COUNT</h2>
<ul>
<li>검색된 결과의 데이터의 개수를 가져오는 내장함수</li>
<li>NULL인 데이터는 제외</li>
<li><code>SELECT COUNT(컬럼명) FROM 테이블명;</code></li>
</ul>
<h2 id="limit">LIMIT</h2>
<ul>
<li>테이블에서 출력하고자 하는 데이터의 개수를 제한하는 명령</li>
<li><code>SELECT 컬럼명 FROM 테이블명 LIMIT 제한할숫자;</code></li>
<li>제한할 숫자에 <code>2, 5</code> 처럼 적으면 2번째 줄부터 5번째 줄까지 출력이라는 뜻이다.</li>
</ul>
<h2 id="sum">SUM</h2>
<ul>
<li>지정한 컬럼의 값을 모두 더해주는 내장함수</li>
<li><code>SELECT SUM(컬럼명) FROM 테이블명;</code></li>
</ul>
<h2 id="avg">AVG</h2>
<ul>
<li>지정한 컬럼의 평균값을 더해주는 내장함수</li>
<li><code>SELECT AVG(컬럼명) FROM 테이블명;</code></li>
</ul>
<h2 id="max">MAX</h2>
<ul>
<li>지정한 컬럼의 최대값을 더해주는 내장함수</li>
<li>문자형도 가능하다.</li>
<li><code>SELECT MAX(컬럼명) FROM 테이블명;</code></li>
</ul>
<h2 id="min">MIN</h2>
<ul>
<li>지정한 컬럼의 최소값을 더해주는 내장함수</li>
<li>문자형도 가능하다.</li>
<li><code>SELECT MIN(컬럼명) FROM 테이블명;</code></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[11주차] SQL 2 - Group, Join, Subquery]]></title>
            <link>https://velog.io/@luna_0219/11%EC%A3%BC%EC%B0%A8-SQL-2-Group-Join-Subquery</link>
            <guid>https://velog.io/@luna_0219/11%EC%A3%BC%EC%B0%A8-SQL-2-Group-Join-Subquery</guid>
            <pubDate>Tue, 16 May 2023 18:24:04 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>본 자료는 심민경 코치님의 자료를 사용하여 정리하였습니다.</p>
</blockquote>
<h1 id="데이터-집계함수">데이터 집계함수</h1>
<ul>
<li>COUNT : 개수</li>
<li>MAX : 최대값</li>
<li>MIN : 최소값</li>
<li>SUM : 합계</li>
<li>AVG : 평균값</li>
<li>VARIANCE : 분산</li>
<li>STDDEV : 표준편차</li>
</ul>
<h1 id="group-by">Group by</h1>
<ul>
<li>집계할 대상의 그룹을 특정변수를 기준으로 나눈다.</li>
<li>Group by는 WHERE 뒤, Order by 앞에 위치한다.</li>
</ul>
<h1 id="having">Having</h1>
<ul>
<li>집계결과 값에 조건식 더하기</li>
<li>Having은 Group by 뒤, Order by 앞에 위치한다.</li>
</ul>
<h1 id="join">JOIN</h1>
<h2 id="테이블-결합">테이블 결합</h2>
<p><img src="https://velog.velcdn.com/images/luna_0219/post/57774216-7b0b-4b24-9f6b-bc90d4c8f711/image.png" alt=""></p>
<h1 id="서브쿼리subquery">서브쿼리(Subquery)</h1>
<ul>
<li>메인쿼리 안에 있는 또 다른 SELECT 문장</li>
<li>소괄호로 둘러 싼 형태로 작성</li>
<li>종류<ul>
<li>스칼라 서브쿼리 : SELECT 절에 서브쿼리 사용</li>
<li>인라인 뷰 : FROM 절에 서브쿼리 사용</li>
<li>중첩 서브쿼리 : WHERE 절에 서브쿼리 사용
<span style="color:red">$\rarr$ 안티조인은 중첩서브쿼리에 NOT을 붙인것이다.</span></li>
</ul>
</li>
</ul>
<h1 id="distinct">Distinct</h1>
<ul>
<li>키워드 중복제거</li>
<li>SELECT 바로 뒤에 위치</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[11주차] 데이터베이스 기초 - 데이터베이스 구현하기]]></title>
            <link>https://velog.io/@luna_0219/11%EC%A3%BC%EC%B0%A8-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EA%B8%B0%EC%B4%88-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@luna_0219/11%EC%A3%BC%EC%B0%A8-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EA%B8%B0%EC%B4%88-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 16 May 2023 17:18:48 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>본 자료는 Elice 플랫폼의 자료를 사용하여 정리하였습니다.</p>
</blockquote>
<h1 id="dcl">DCL</h1>
<h2 id="데이터제어어data-control-language">데이터제어어(Data Control Language)</h2>
<ul>
<li>데이터베이스에 접근하는 권한을 관리하는 등의 데이터제어</li>
<li>GRANT : 데이터베이스 권한 부여</li>
<li>REVOKE : 데이터베이스 권한 회수
<span style="color:red">아래 명령어는 TCL이라고 분류하기도 한다.</span></li>
<li>COMMIT : 트랜잭션 작업을 반영하여 저장</li>
<li>ROLLBACK : 트랜잭션 작업을 취소하여 이전 상태로 돌린다.</li>
</ul>
<h1 id="인덱스index">인덱스(Index)</h1>
<h2 id="인덱스">인덱스</h2>
<ul>
<li>데이터베이스 테이블의 검색속도를 향상 시키기 위한 자료구조</li>
<li>모든 데이터를 조회한다면 인덱스가 불필요하다.</li>
</ul>
<h2 id="장단점">장단점</h2>
<ul>
<li>장점<ul>
<li>테이블을 조회하는 속도와 성능이 올라간다.</li>
</ul>
</li>
<li>단점<ul>
<li>인덱스를 관리하기 위한 추가 작업이 필요</li>
<li>인덱스를 저장 할 추가 저장공간 필요</li>
<li>경우에 따라 검색 성능이 저하될 수 있다.</li>
</ul>
</li>
</ul>
<h2 id="인덱스를-사용하면-좋은-경우">인덱스를 사용하면 좋은 경우</h2>
<ul>
<li>규모가 큰 테이블</li>
<li>데이터의 삽입, 수정, 삭제 작업이 많지 않은 경우</li>
<li>WHERE 조건절이나 ORDER BY(정렬), JOIN을 자주 하는 컬럼</li>
<li>데이터의 중복도가 낮은 컬럼</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[11주차] 데이터베이스 기초 - 데이터 모델링]]></title>
            <link>https://velog.io/@luna_0219/11%EC%A3%BC%EC%B0%A8-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EA%B8%B0%EC%B4%88-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%AA%A8%EB%8D%B8%EB%A7%81</link>
            <guid>https://velog.io/@luna_0219/11%EC%A3%BC%EC%B0%A8-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EA%B8%B0%EC%B4%88-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%AA%A8%EB%8D%B8%EB%A7%81</guid>
            <pubDate>Tue, 16 May 2023 17:12:02 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>본 자료는 Elice 플랫폼의 자료를 사용하여 정리하였습니다.</p>
</blockquote>
<h1 id="이상현상과-정규화">이상현상과 정규화</h1>
<h2 id="이상현상이란">이상현상이란?</h2>
<ul>
<li>잘못된 데이터베이스 설계로 발생하는 오류</li>
</ul>
<h2 id="이상현상-종류">이상현상 종류</h2>
<ul>
<li>삽입이상 : 데이터를 삽입할 때 불필요한 내용까지 삽입해야 하는 문제</li>
<li>갱신이상 : 중복된 데이터 중 일부만 갱신되어 발생하는 문제</li>
<li>삭제이상 : 어떤 데이터를 삭제할 때 다른 유용한 정보도 함께 삭제되는 문제</li>
</ul>
<h2 id="함수종속성">함수종속성</h2>
<ul>
<li>속성들간의 종속관계</li>
<li>완전함수종속, 부분함수종속, 이행함수종속등이 있으며 함수 종속성에 대하 알아야 이상현상을 제거하기 위한 정규화를 이해할 수 있다.</li>
</ul>
<h2 id="정규화">정규화</h2>
<ul>
<li>이상현상을 제거하기 위해 데이터베이스를 구조화하는 과정</li>
<li>데이터간의 종속성을 제거하여 중복되는 데이터를 줄인다.</li>
<li>데이터의 일관성과 무결성을 보장</li>
<li>1차 ~ 5차 정규화, 보이스코드 정규화가 있다.</li>
</ul>
<h1 id="1차-정규화1nf">1차 정규화(1NF)</h1>
<ul>
<li>테이블의 컬럼이 하나의 값만 갖도록 도메인을 원자값으로 설정하는 과정</li>
</ul>
<h1 id="2차-정규화2nf">2차 정규화(2NF)</h1>
<h2 id="이상현상">이상현상</h2>
<ul>
<li>삽입이상 : 한번도 대여를 하지 않은 고객을 삽입할 수 없다.</li>
<li>갱신이상 : 하나의 튜플에서만 이름을 변경하면 데이터의 불일치가 발생</li>
<li>삭제이상 : 브랜드 대여 기록을 삭제하면 고객의 데이터가 완전히 사라진다.</li>
</ul>
<h2 id="부분함수종속">부분함수종속</h2>
<ul>
<li><p>기본키를 구성하는 속성 중 일부가 결정자 역할을 하는 경우
<span style="color:red">$\rarr$ 고객 테이블과 대여 테이블로 분리하여 부분함수종속을 제거</span>
<img src="https://velog.velcdn.com/images/luna_0219/post/1cf4c1a6-96f3-42d1-990c-1b025e744ebc/image.png" alt=""></p>
</li>
<li><p>부분함수종속을 제거하고 완전함수종속이 되도록 테이블을 분해하는 과정</p>
</li>
</ul>
<h1 id="3차-정규화">3차 정규화</h1>
<h2 id="이상현상-1">이상현상</h2>
<ul>
<li>삽입이상 : 고객이나 대여이력이 없는 경우 새로운 회사가 만든 브랜드를 삽입할 수 없다.</li>
<li>갱신이상 : 브랜드명이 변경되는 경우 데이터의 불일치가 발생</li>
<li>삭제이상 : 고객의 대여기록을 삭제하면 회사의 데이터가 완전히 사라진다.</li>
</ul>
<h2 id="이행함수종속">이행함수종속</h2>
<ul>
<li>X $\rarr$ Y, Y $\rarr$ Z 라는 종속관계가 있을 때, X $\rarr$ Z가 성립하는 경우
<span style="color:red">$\rarr$ 대여 테이블과 회사 테이블로 분해하여 이행함수종속을 제거</span>
<span style="color:red">$\rarr$ 대여 테이블과 가격 테이블을 분해하여 이행함수종속을 제거</span>
<img src="https://velog.velcdn.com/images/luna_0219/post/552e979b-c232-4147-af03-fdec0b748f8b/image.png" alt=""></li>
<li>이행함수종속을 제거하도록 테이블을 분해하는 과정</li>
</ul>
<h1 id="정규화-정리">정규화 정리</h1>
<p><img src="https://velog.velcdn.com/images/luna_0219/post/206a7acd-0d03-40e4-b3e2-ff6d410b48ae/image.png" alt=""></p>
<h2 id="bncf">BNCF</h2>
<ul>
<li>결정자이면서 후보키가 아닌 것</li>
</ul>
<h2 id="다치종속">다치종속</h2>
<ul>
<li>키로 묶여있어서 쓸모없는 데이터가 추가되어야 하는 문제</li>
</ul>
<h2 id="조인종속">조인종속</h2>
<ul>
<li>테이블을 분해하고 다시 합쳤을 때 불필요한 튜플이 발생</li>
</ul>
<h2 id="역정규화">역정규화</h2>
<ul>
<li>정규화된 데이터베이스의 성능을 개선하기 위해 다시 통합하여 구조를 재구성</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[11주차] 데이터베이스 기초 - 구성하기]]></title>
            <link>https://velog.io/@luna_0219/11%EC%A3%BC%EC%B0%A8-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EA%B8%B0%EC%B4%88-%EA%B5%AC%EC%84%B1%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@luna_0219/11%EC%A3%BC%EC%B0%A8-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EA%B8%B0%EC%B4%88-%EA%B5%AC%EC%84%B1%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 16 May 2023 16:53:49 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>본 자료는 Elice 플랫폼의 자료를 사용하여 정리하였습니다.</p>
</blockquote>
<h1 id="제약조건">제약조건</h1>
<h2 id="정의">정의</h2>
<ul>
<li>테이블에 잘못된 데이터가 입력되는 것을 방지하기 위한 규칙</li>
<li>제약조건을 통해 무결성을 지킬 수 있다.</li>
</ul>
<h2 id="not-null">NOT NULL</h2>
<ul>
<li>널(NULL) 값 비허용</li>
<li>데이터를 입력하지 않으면 에러가 발생</li>
<li>아무것도 명시하지 않는 경우 기본값은 널 값 허용</li>
</ul>
<h2 id="unique">UNIQUE</h2>
<ul>
<li>중복 값 비허용</li>
<li>똑같은 값이 있으면 에러가 발생</li>
<li>NULL 값은 허용</li>
</ul>
<h2 id="default">DEFAULT</h2>
<ul>
<li>기본값 설정</li>
</ul>
<h2 id="check">CHECK</h2>
<ul>
<li>값의 범위를 제한</li>
</ul>
<h2 id="제약조건-정의">제약조건 정의</h2>
<ul>
<li><code>CONSTRAINT 제약조건이름 제약조건(적용할 속성);</code></li>
</ul>
<h2 id="제약조건-추가">제약조건 추가</h2>
<ul>
<li><code>ALTER TABLE 테이블명 ADD CONSTRAINT 제약조건이름 제약조건(적용할 속성);</code></li>
</ul>
<h2 id="제약조건-삭제">제약조건 삭제</h2>
<ul>
<li><code>ALTER TABLE 테이블명 DROP CONSTRAINT 제약조건이름;</code></li>
</ul>
<h1 id="키key">키(key)</h1>
<h2 id="키key-1">키(key)</h2>
<ul>
<li>조건에 만족하는 튜플을 찾거나, 정렬할 때 기준이 되는 속성</li>
<li>기본키, 외래키, 후보키, 대체키, 슈퍼키 등이 있다.</li>
</ul>
<h2 id="기본키">기본키</h2>
<ul>
<li>서로 다른 튜플을 유일하게 식별할 수 있는 기준이 되는 속성</li>
<li>중복 X, 널값 X</li>
<li>테이블 당 1개만 설정</li>
</ul>
<h2 id="외래키">외래키</h2>
<ul>
<li>다른 테이블의 기본키를 참조하는 속성으로 테이블의 관계를 정의</li>
<li>참조되는 테이블의 기본키에 없는 값은 지정할 수 없다.</li>
</ul>
<h2 id="기본키외래키-지정">기본키/외래키 지정</h2>
<pre><code class="language-sql">PRIMARY KEY / 
FOREIGN KEY (참조할 속성) REFERENCES 참조되는 테이블(참조되는 속성)</code></pre>
<h2 id="그외-키">그외 키</h2>
<ul>
<li>후보키 : 기본키가 될 수 있는 키로 유일성과 최소성을 만족(기본키 $\subset$ 후보키)</li>
<li>대체키 : 후보키 중에 기본키가 아닌 키(대체키 $\subset$ 후보키)</li>
<li>슈퍼키 : 유일성은 만족하지만 최소성은 만족하지 않는 키</li>
</ul>
<h2 id="무결성-제약조건">무결성 제약조건</h2>
<ul>
<li>개체 무결성 : 기본키는 널 값과 중복 값을 가질 수 없다.</li>
<li>참조 무결성 : 외래키는 널이거나 참조되는 기본키 값과 동일해야한다.</li>
</ul>
<h1 id="데이터-모델링">데이터 모델링</h1>
<h2 id="정의-1">정의</h2>
<ul>
<li>현실 세계에 존재하는 데이터를 데이터베이스화하는 과정</li>
</ul>
<h2 id="데이터-모델과-구성요소">데이터 모델과 구성요소</h2>
<h3 id="데이터-모델">데이터 모델</h3>
<ul>
<li>현실세계의 데이터를 단순화, 추상화하여 표현한 모델<h3 id="구성요소">구성요소</h3>
</li>
<li>개체(Entity)</li>
<li>속성(Attribute)</li>
<li>관계(Relationship)</li>
</ul>
<h2 id="과정">과정</h2>
<ul>
<li>개념적 설계 : 현실세계를 추상적 개념으로 표현하는 과정</li>
<li>논리적 설계 : DBMS가 처리할 수 있는 데이터구조(스키마)를 설계</li>
<li>물리적 설계 : DBMS에 테이블을 저장할 구조를 설계</li>
</ul>
<h1 id="er다이어그램peter-chen">ER다이어그램(Peter Chen)</h1>
<h2 id="정의-2">정의</h2>
<ul>
<li>ERD(Entity-Relationship Diagram) 개체-관계 다이어그램<ul>
<li>현실 세계의 데이터를 개체와 관계형태의 다이어그램으로 나타내는 것</li>
</ul>
</li>
</ul>
<h2 id="peter-chen">Peter Chen</h2>
<p><img src="https://velog.velcdn.com/images/luna_0219/post/67a062da-7b7c-421b-aa65-38f269954b61/image.png" alt=""></p>
<h2 id="관계-추가하기">관계 추가하기</h2>
<p><img src="https://velog.velcdn.com/images/luna_0219/post/09661251-3a5e-48e0-9d75-71b47c7f3ceb/image.png" alt=""></p>
<h1 id="er다이어그램ie">ER다이어그램(IE)</h1>
<h2 id="ieinformation-engineering">IE(Information Engineering)</h2>
<p><img src="https://velog.velcdn.com/images/luna_0219/post/07c14e7a-813f-4611-839c-5cacf0eded0a/image.png" alt=""></p>
<h2 id="까마귀발crows-foot-표기법">까마귀발(crow&#39;s foot) 표기법</h2>
<p><img src="https://velog.velcdn.com/images/luna_0219/post/6e96b043-aa7a-42b4-b817-8850a0dca04c/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[11주차] 데이터베이스 기초 - 개요]]></title>
            <link>https://velog.io/@luna_0219/11%EC%A3%BC%EC%B0%A8-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EA%B8%B0%EC%B4%88-%EA%B0%9C%EC%9A%94</link>
            <guid>https://velog.io/@luna_0219/11%EC%A3%BC%EC%B0%A8-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EA%B8%B0%EC%B4%88-%EA%B0%9C%EC%9A%94</guid>
            <pubDate>Tue, 16 May 2023 15:09:16 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>본 자료는 Elice 플랫폼의 자료를 사용하여 정리하였습니다.</p>
</blockquote>
<h1 id="데이터베이스-소개">데이터베이스 소개</h1>
<h2 id="데이터와-정보">데이터와 정보</h2>
<ul>
<li>데이터 : 현실세계에서 수집된 단순한 사실과 값들을 모아 놓은 것</li>
<li>정보 : 데이터를 특정 목적에 의해 해석하거나 가공한 형태</li>
</ul>
<h2 id="데이터베이스-정의">데이터베이스 정의</h2>
<ul>
<li>데이터들의 집합<ul>
<li>한 조직 안에서 여러 사용자와 응용프로그램이 공동으로 사용하는 데이터들을 통합하여 저장하고 운영하는 데이터</li>
</ul>
</li>
</ul>
<h2 id="데이터베이스의-필요성">데이터베이스의 필요성</h2>
<ul>
<li>파일처리시스템의 한계<ul>
<li>데이터구조가 바뀌면 응용프로그램의 구조도 바뀌어야한다. <span style="color:red">데이터 종속</span></li>
<li>응용프로그램 별로 데이터를 생성할 수 있기 때문에 데이터가 <span style="color:red">중복</span>될 수 있다.</li>
<li>데이터 <span style="color:red">무결성</span>을 지킬 수 없다.</li>
</ul>
</li>
</ul>
<h2 id="데이터베이스의-특징">데이터베이스의 특징</h2>
<ul>
<li>실시간 접근성<ul>
<li>사용자가 원할 때 언제든지 접근 가능해야 한다.</li>
</ul>
</li>
<li>지속적인 변화<ul>
<li>데이터의 삽입, 삭제, 갱신을 통해 최신데이터를 유지해야한다.</li>
</ul>
</li>
<li>동시공유<ul>
<li>여러 사용자가 동시에 이용할 수 있어야 한다.</li>
</ul>
</li>
<li>내용에 대한 참조<ul>
<li>데이터가 저장된 물리적인 위치가 아닌 값을 가지고 검색할 수 있어야 한다.</li>
</ul>
</li>
</ul>
<h1 id="데이터베이스의-종류">데이터베이스의 종류</h1>
<h2 id="데이터베이스-구분">데이터베이스 구분</h2>
<ul>
<li>RDB : 관계형 모델을 기반으로 SQL을 이용해 데이터를 관리한다.</li>
<li>NoSQL : 데이터 간의 관계를 정의하지 않고 RDB보다 유연한 모델을 이용한다.</li>
</ul>
<h2 id="관계형-데이터베이스">관계형 데이터베이스</h2>
<ul>
<li>데이터를 행과 열을 가지는 테이블로 표현</li>
<li>테이블간의 관계를 이용해 데이터를 효과적으로 관리하여 데이터의 무결성을 보장</li>
<li>정의된 테이블(스키마)에 맞게 데이터가 삽입되므로 데이터의 안정성을 보장</li>
<li>데이터의 구조가 일관적인 경우에 주로 사용</li>
</ul>
<h2 id="rdbms의-종류">RDBMS의 종류</h2>
<ul>
<li>MySQL, PostgreSQL, MariaDB 등</li>
</ul>
<h2 id="nosql">NoSQL</h2>
<ul>
<li>데이터를 저장할 수 있는 유형의 제한이 없다.</li>
<li>새로운 유형의 데이터를 추가하기 용이</li>
<li>데이터의 구조가 일관적이지 않고 자주 변경되는 경우에 적합</li>
<li>대용량의 데이터를 더 빠르게 처리할 수 있다.</li>
</ul>
<h2 id="nosql의-종류">NoSQL의 종류</h2>
<ul>
<li>MongoDB, Redis, Apache Cassandra 등</li>
</ul>
<h1 id="관계형-데이터베이스-만들기">관계형 데이터베이스 만들기</h1>
<h2 id="구성요소">구성요소</h2>
<ul>
<li>테이블은 행과 열로 구성</li>
<li>속성을 데이터의 특성을 나타내는 가장 작은 논리적 단위를 의미</li>
<li>튜플은 속성이 모여 구성된 각각의 행을 의미</li>
<li>속성이 가질 수 있는 값의 집합을 도메인이라고 한다.</li>
</ul>
<h2 id="관계">관계</h2>
<ul>
<li>관계가 있다면 하나의 속성으로 테이블을 연결해서 데이터를 효과적으로 관리</li>
</ul>
<h2 id="테이블-정의하기">테이블 정의하기</h2>
<pre><code class="language-sql">CREATE TABLE 테이블명(
    속성1    데이터타입,
    속성2    데이터타입,
    ...
);</code></pre>
<h2 id="정의된-테이블-확인">정의된 테이블 확인</h2>
<pre><code class="language-sql">SHOW TABLES;    -- 데이터베이스의 테이블 목록을 확인
DESC 테이블명;    -- 테이블의 구조를 확인</code></pre>
<h2 id="sql-작성규칙">SQL 작성규칙</h2>
<ul>
<li>SQL문법은 대문자로 작성하는 것을 권장</li>
<li>테이블명, 속성명은 소문자로 작성하는 것을 권장</li>
<li>이름은 항상 의미가 잘 드러나도록 작성</li>
<li>이름에 여러 단어를 혼합하는 경우 <code>_</code>를 이용해 구분</li>
<li><code>--</code>을 이용해 주석을 나타낼 수 있다.</li>
<li>명령어 끝에는 세미콜론(<code>;</code>)을 작성</li>
</ul>
<h2 id="데이터-삽입하기">데이터 삽입하기</h2>
<p><code>INSERT INTO 테이블명(속성1, ...) VALUES(속성값1, ...);</code></p>
<h2 id="데이터-출력하기">데이터 출력하기</h2>
<p><code>SELECT 속성1, ... FROM 테이블명;</code></p>
<h1 id="데이터베이스-정의어">데이터베이스 정의어</h1>
<h2 id="sqlstructured-query-language">SQL(Structured Query Language)</h2>
<ul>
<li>데이터 정의어(DLL) : 테이블과 같은 데이터 구조 정의</li>
<li>데이터 조작어(DML) : 데이터 조회 및 검색</li>
<li>데이터 제어어(DCL) : 데이터베이스에 접근하는 권한 관리</li>
</ul>
<h2 id="데이터-타입">데이터 타입</h2>
<ul>
<li>VARCHAR, INT, FLOAT, DATETIME 등</li>
</ul>
<h2 id="테이블-수정하기">테이블 수정하기</h2>
<pre><code class="language-sql">-- 컬럼 추가
ALTER TABLE customer ADD COLUMN birthday DATE NULL;
-- 컬럼 수정
ALTER TABLE customer MODIFY COLUMN id varchar(15) NULL;
-- 컬럼 이름 변경
ALTER TABLE customer CHANGE COLUMN name korean_name varchar(10) NOT NULL;
-- 컬럼 삭제
ALTER TABLE customer DROP COLUMN address;
-- 테이블 이름 변경
ALTER TABLE customer RENAME member;</code></pre>
<h2 id="테이블-삭제하기">테이블 삭제하기</h2>
<p><code>DROP TABLE 테이블명</code></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[11주차] SQL 1 - DB 이해 및 관리, SQL]]></title>
            <link>https://velog.io/@luna_0219/11%EC%A3%BC%EC%B0%A8-SQL1-DB-%EC%9D%B4%ED%95%B4-%EB%B0%8F-%EA%B4%80%EB%A6%AC-SQL</link>
            <guid>https://velog.io/@luna_0219/11%EC%A3%BC%EC%B0%A8-SQL1-DB-%EC%9D%B4%ED%95%B4-%EB%B0%8F-%EA%B4%80%EB%A6%AC-SQL</guid>
            <pubDate>Tue, 16 May 2023 14:52:27 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>본 자료는 심민경 코치님의 자료를 사용하여 정리하였습니다.</p>
</blockquote>
<h1 id="데이터베이스">데이터베이스</h1>
<h2 id="db란">DB란?</h2>
<ul>
<li>구조화된 데이터의 집합</li>
</ul>
<h2 id="dbms를-통한-데이터-관리">DBMS를 통한 데이터 관리</h2>
<ul>
<li>데이터베이스의 데이터 조작과 관리 극대화</li>
<li>여러 응용프로그램이 동시에 공유가능</li>
</ul>
<h2 id="rdb">RDB</h2>
<h3 id="관계형-데이터-모델">관계형 데이터 모델</h3>
<ul>
<li>데이터 간 관계에 초점을 두고, 데이터의 독립특성으로 데이터를 나눠서 관리하는 방식</li>
</ul>
<h3 id="구성요소">구성요소</h3>
<ul>
<li>개체 : Table</li>
<li>속성 : Column</li>
<li>관계 : Foreign Key</li>
</ul>
<h3 id="sql">SQL</h3>
<ul>
<li>관계형 데이터베이스에서 데이터를 다루고 관리하는데 사용하는 데이터베이스 질의언어</li>
</ul>
<h1 id="sql-dml">SQL DML</h1>
<h2 id="select">SELECT</h2>
<ul>
<li>데이터를 조회하는 문장</li>
<li>모든 열(Column)을 조회<ul>
<li><code>SELECT * FROM 테이블명;</code></li>
</ul>
</li>
<li>일부 컬럼을 조회<ul>
<li><code>SELECT 컬럼명 FROM 테이블명;</code></li>
</ul>
</li>
</ul>
<h2 id="select--where-조건">SELECT + WHERE 조건</h2>
<ul>
<li>테이블에서 원하는 데이터만 조회<ul>
<li><code>SELECT * FROM 테이블명 WHERE 조건;</code></li>
</ul>
</li>
<li>AND/OR, 조건연산자, IN, BETWEEN 등 사용가능</li>
</ul>
<h2 id="order-by">ORDER BY</h2>
<ul>
<li>조회결과를 정렬, 앞에 둔 변수가 정렬 우선순위가 높다.<ul>
<li><code>SELECT * FROM 테이블명 ORDER BY 컬럼명;</code></li>
</ul>
</li>
<li>ORDER BY의 기본값은 오름차순(asc)이며 컬럼명 뒤에 desc를 붙이면 내림차순으로 정렬된다.</li>
</ul>
<h2 id="insert">INSERT</h2>
<ul>
<li>테이블에 데이터를 입력<ul>
<li><code>INSERT INTO 테이블명(컬럼명...) VALUES(값...);</code></li>
</ul>
</li>
<li>VALUES 부분을 SELECT로 해도 된다.</li>
</ul>
<h2 id="delete">DELETE</h2>
<ul>
<li>데이터를 삭제<ul>
<li><code>DELETE FROM 테이블명 WHERE 조건;</code></li>
</ul>
</li>
</ul>
<h2 id="update">UPDATE</h2>
<ul>
<li>데이터를 수정<ul>
<li><code>UPDATE 테이블명 SET 변경값 WHERE 조건;</code></li>
</ul>
</li>
</ul>
<h1 id="sql-기본함수">SQL 기본함수</h1>
<h2 id="숫자형-함수">숫자형 함수</h2>
<ul>
<li>ABS(n) : 절대값 반환</li>
<li>LN(n) : 자연로그값 반환</li>
<li>ROUND(n, i) : i+1번째 반올림</li>
<li>TRUNC(n, i) : i자리까지만 출력</li>
</ul>
<h2 id="문자형-함수">문자형 함수</h2>
<ul>
<li>CONCAT(char1, char2) : 두 문자 결합</li>
<li>SUBSTR(char, n1, n2) : n1부터 n2길이만큼 자르기</li>
<li>TRIM(char) : 양쪽 끝 공백 제거</li>
</ul>
<h2 id="형-변환-함수">형 변환 함수</h2>
<ul>
<li>TO_NUMBER(char) : 문자를 숫자로</li>
<li>TO_CHAR(n, format) : 숫자를 format에 맞게 문자로</li>
<li>TO_CHAR(date, format) : 날짜를 format에 맞게 문자로</li>
<li>TO_DATE(char, format) : 문자를 format에 맞게 날짜로</li>
</ul>
<h2 id="case-표현식">CASE 표현식</h2>
<pre><code class="language-sql">CASE WHEN 변수 조건1 THEN 결과1
     WHEN 변수 조건2 THEN 결과2
     ...
     ELSE 결과n
     END 결과를 담을 변수 이름
FROM 테이블명;</code></pre>
<h2 id="데이터-집계함수">데이터 집계함수</h2>
<ul>
<li>COUNT(expr) : 개수</li>
<li>MAX(expr) : 최대값</li>
<li>MIN(expr) : 최소값</li>
<li>SUM(expr) : 합계</li>
<li>AVG(expr) : 평균값</li>
<li>VARIANCE(expr) : 분산</li>
<li>STDDEV(expr) : 표준편차</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[8주차] Node.js와 MongoDB 2 - Express.js와 MongoDB로 웹 서비스 만들기 2]]></title>
            <link>https://velog.io/@luna_0219/8%EC%A3%BC%EC%B0%A8-Node.js%EC%99%80-MongoDB-2-Express.js%EC%99%80-MongoDB%EB%A1%9C-%EC%9B%B9-%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%A7%8C%EB%93%A4%EA%B8%B0-2</link>
            <guid>https://velog.io/@luna_0219/8%EC%A3%BC%EC%B0%A8-Node.js%EC%99%80-MongoDB-2-Express.js%EC%99%80-MongoDB%EB%A1%9C-%EC%9B%B9-%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%A7%8C%EB%93%A4%EA%B8%B0-2</guid>
            <pubDate>Sat, 22 Apr 2023 18:43:18 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>본 자료는 Elice 플랫폼의 자료를 사용하여 정리하였습니다.</p>
</blockquote>
<h1 id="회원가입-구현하기">회원가입 구현하기</h1>
<h2 id="회원가입-설명">회원가입 설명</h2>
<ul>
<li>이메일, 이름, 패스워드의 간단한 정보만 사용<ul>
<li>이메일 형식 확인</li>
<li>비밀번호 최소길이 확인</li>
<li>패스워드와 패스워드 확인 일치여부 확인</li>
</ul>
</li>
</ul>
<h2 id="비밀번호-저장방법">비밀번호 저장방법</h2>
<ul>
<li><p>Hash</p>
<ul>
<li>문자열을 되돌릴 수 없는 방식으로 암호화</li>
<li>로그인 시 전달된 비밀번호를 Hash하여 저장된 값과 비교</li>
</ul>
</li>
<li><p>Hash 사용하기</p>
<pre><code class="language-javascript">const hash = crypto.createHash(&#39;sha1&#39;);    // sha224, sha256 등 사용가능
hash.update(password);
hash.digest(&#39;hex&#39;);</code></pre>
</li>
</ul>
<h2 id="회원가입-구현하기-1">회원가입 구현하기</h2>
<ol>
<li>회원가입 페이지 구현</li>
<li>script를 이용해 이메일 형식, 비밀번호 확인 문자 확인</li>
<li>form을 이용해 post 요청 전송</li>
<li>회원가입 처리 및 redirect</li>
</ol>
<h1 id="passportjs와-로그인">passport.js와 로그인</h1>
<h2 id="passportjs란">passport.js란?</h2>
<ul>
<li>Express.js 어플리케이션에 간단하게 사용자 인증 기능을 구현하게 도와주는 패키지</li>
<li>유저 세션 관리 및 다양한 로그인 방식 추가 가능</li>
</ul>
<h2 id="passport-local">passport-local</h2>
<ul>
<li>passport는 다양한 로그인 방식을 구현하기 위해 strategy라는 인터페이스를 제공</li>
<li>passport-local은 username, password를 사용하는 로그인의 구현체</li>
</ul>
<h2 id="로그인-기능-구현하기">로그인 기능 구현하기</h2>
<ol>
<li>로그인 화면 구성하기</li>
<li>passport-local strategy로 로그인 구현하기</li>
<li>passport.js 설정하기</li>
<li>passport로 요청 처리하기</li>
</ol>
<h1 id="session-store">Session Store</h1>
<h2 id="session이란">Session이란?</h2>
<ul>
<li>웹 서버가 클라이언트의 정보를 구분하여 서버에 저장하고, 클라이언트 요청 시 Session ID를 사용하여 클라이언트의 정보를 다시 확인하는 기술</li>
</ul>
<h2 id="session-작동방식">Session 작동방식</h2>
<ol>
<li>서버는 세션을 생성하고 Session ID를 클라이언트에게 전달</li>
<li>클라이언트는 요청 시 Session ID를 함께 요청에 담아서 전송</li>
<li>서버는 전달받은 Session ID로 해당하는 세션을 찾아 클라이언트 정보 확인</li>
</ol>
<h2 id="expressjs의-session">Express.js의 Session</h2>
<ul>
<li>Express-session 패키지로 자동으로 session 동작 구현</li>
</ul>
<h2 id="session-store-사용-이유">Session Store 사용 이유</h2>
<ul>
<li>express-session은 session을 메모리에 저장한다. (재부팅 시 모든 로그인 해제)</li>
<li>서버 간 세션정보를 공유하지 않는다.</li>
</ul>
<h2 id="session-store-구성">Session Store 구성</h2>
<p><img src="https://velog.velcdn.com/images/luna_0219/post/9ecc6f5d-fbe3-4de7-9114-3011b02a3bce/image.png" alt=""></p>
<h2 id="mongodb를-session-store로-사용하기">MongoDB를 Session Store로 사용하기</h2>
<pre><code class="language-javascript">const MongoStore = require(&#39;connect-mongo&#39;);

app.use(session({
  secret: &#39;secret&#39;,
  resave: false,
  saveUninitialized: true,
  store: MongoStore.create({
    mongoUrl: &#39;mongoUrl&#39;,
  }),
}));</code></pre>
<ul>
<li><code>connect-mongo</code> 패키지를 사용해 express-session 설정 시 store 옵션에 전달하고, mongoUrl을 설정</li>
<li>세션데이터를 몽고디비에 저장하고 관리하는 기능을 자동으로 수행해준다.</li>
</ul>
<h1 id="회원과-게시글의-연동">회원과 게시글의 연동</h1>
<h2 id="회원과-게시글-연동-기능-설명">회원과 게시글 연동 기능 설명</h2>
<ul>
<li>게시글 작성 시 로그인된 회원정보를 작성자로 추가</li>
<li>게시글 - 작성자는 populate하여 사용하도록 구현</li>
<li>게시글 수정, 삭제 시 로그인된 유저와 작성자가 일치하는지 확인</li>
<li>작성자의 게시글 모아보기 기능 구현</li>
</ul>
<h2 id="postschema-수정">PostSchema 수정</h2>
<ul>
<li>populate를 사용하기 위해 ObjectID 사용</li>
</ul>
<h2 id="게시글-등록-요청-수정">게시글 등록 요청 수정</h2>
<pre><code class="language-javascript">const author = await User.find({
  shortId: req.user.shortId,
});
if (!author) {
  throw new Error(&#39;No User&#39;);
}

await Post.create({
  title,
  content,
  author,
});</code></pre>
<ul>
<li><code>req.user</code>에는 strategy에서 최소한의 정보로 저장한 shortId, email, username만 가지고 있다.</li>
<li>Post 생성 시 user의 ObjectID를 전달해야 하는데, 이를 위해 User에서 shortId로 회원을 검색하여 한 번 더 검증한다.</li>
<li>type: ObjectID로 선언된 필드에 객체가 주어지면 자동으로 ObjectID을 사용한다.</li>
</ul>
<h2 id="게시글에-작성자-연동">게시글에 작성자 연동</h2>
<pre><code class="language-javascript">// ./routes/posts.js

router.get(&#39;/&#39;, ... {
  ...
  const posts = await Post.find({})
    .populate(&#39;author&#39;);

res.render(&#39;posts/list&#39;, { posts });

// ./views/posts/list.pug
...
  td post.author.name</code></pre>
<ul>
<li>게시글 find 시 populate를 추가하여 ObjectID로 저장된 author를 각 게시글에 주입</li>
<li>사용 시 <code>post.author.{field}</code>로 사용 가능하다.</li>
</ul>
<h2 id="게시글-수정-삭제-시-유저확인">게시글 수정, 삭제 시 유저확인</h2>
<pre><code class="language-javascript">const post = await Post.find({ shortId, }).populate(&#39;author&#39;)

if (post.author.shortId !== req.user.shortId) {
  throw new Error(&#39;Not Authorized&#39;);
}</code></pre>
<ul>
<li>게시글 수정, 삭제 시 작성자를 populate하여 로그인된 사용자와 일치하는지 확인</li>
</ul>
<h2 id="작성자-게시글-모아보기-기능-구현">작성자 게시글 모아보기 기능 구현</h2>
<ul>
<li>기본적으로 MongoDB는 Document 검색 시, 전체 문서를 하나씩 확인한다.
$\rarr$ 비효율적, 속도 저하의 원인</li>
<li>Index<ul>
<li>쿼리를 효육적으로 수행하여 성능을 향상시키게 할 수 있다.</li>
</ul>
</li>
</ul>
<h3 id="author에-index-설정하기">author에 index 설정하기</h3>
<pre><code class="language-javascript">author: {
  types: Schema.Types.ObjectId,
  ref: &#39;User&#39;,
  required: true,
  index: true,
},</code></pre>
<ul>
<li>PostSchema의 author 속성에 <code>index: true</code> 옵션을 사용하면 mongoose가 자동으로 MongoDB에 인덱스를 생성해준다.</li>
<li>이미 데이터가 많은 상태에서 인덱스를 추가할 시 작업 시간이 길어져, MongoDB가 응답하지 않을 수 있다.</li>
<li>따라서, 예상되는 인덱스를 미리 추가하는 것이 좋다.</li>
</ul>
<h3 id="회원-게시글-라우팅-추가하기">회원 게시글 라우팅 추가하기</h3>
<pre><code class="language-javascript">// ./routes/users.js

router.get(&#39;/:shortId/posts&#39;, ... =&gt; {
  ...
  const { shortId } = req.params;
  const user = await User.find({ shortId });
  const posts = await Post.find({ author: user }).populate(&#39;author&#39;);
  res.render(&#39;posts/list&#39;, { posts, user });
});</code></pre>
<ul>
<li>RESTful 한 구성을 위해, 회원 $\rarr$ 게시글의 경로를 <code>/users/{userId}/posts</code>로 구성</li>
<li>게시글 목록 view는 기존에 작성한 posts/list.pug를 재활용한다.</li>
</ul>
<h3 id="게시글-목록-화면-수정">게시글 목록 화면 수정</h3>
<pre><code>h2= user ? `${user.name}의 게시글`: &quot;전체 게시글&quot;
...
td: a(href=`/users/${post.author.shortId}/posts`) = post.author.name</code></pre><ul>
<li>게시글 목록 화면을 재활용하기 위해 수정</li>
<li>유저의 게시글인 경우 <code>&quot;###의 게시글&quot;</code>이라는 제목 사용</li>
<li>게시글의 사용자 이름에 유저의 게시글 link 추가</li>
</ul>
<h1 id="csr로-댓글-기능-구현하기">CSR로 댓글 기능 구현하기</h1>
<h2 id="csr을-구현하는-방법">CSR을 구현하는 방법</h2>
<ol>
<li>페이지 로드 시 필요한 리소스를 클라이언트에 선언</li>
<li>클라이언트에서 필요한 데이터를 비동기 호출</li>
<li>클라이언트가 전달받은 데이터를 가공, 리소스를 사용하여 화면에 표시</li>
</ol>
<h2 id="클라이언트에-리소스-선언---html-template">클라이언트에 리소스 선언 - HTML Template</h2>
<ul>
<li>브라우저에 표시되지 않는 HTML Element를 작성해두고, JavaScript로 이를 화면에 반복적으로 그릴 수 있게 하는 기술</li>
</ul>
<h2 id="댓글-화면-작성하기">댓글 화면 작성하기</h2>
<pre><code>// posts/view.pug

...
table
  thead
    tr
      td(colspan=&quot;2&quot;)
        input#content(type=&quot;text&quot;)
      td: button(onclick=&quot;writeComment()&quot;)
        댓글 작성
  tbody#comments
template#comment-template
  tr
    td.content
    td.author
    td.createdAt</code></pre><ul>
<li>게시글 상세 화면 하단에 댓글작성, 목록 화면 추가</li>
<li>HTML Template 사용하여 한 개의 댓글이 표시될 모양을 선언</li>
<li>JavaScript로 조작하기 위해 id, class를 선언하는 것이 유용하다.</li>
</ul>
<h2 id="데이터-비동기-호출---api-작성하기">데이터 비동기 호출 - API 작성하기</h2>
<ul>
<li>지금까지는 HTTP 응답으로 HTML을 전송하는 방식</li>
<li>CSR에서는 데이터만 주고받을 수 있는 API를 구성해야 한다.(JSON 사용)</li>
</ul>
<h2 id="게시글에-댓글-추가하기">게시글에 댓글 추가하기</h2>
<pre><code class="language-javascript">const CommentSchema = new Schema({
  content: String,
  author: {
    type: Schema.Types.ObjectId,
    ref: &#39;User&#39;,
  },
}, {
  timestamps: true,
});

const PostSchema = new Schema({
  ...
  comments: [CommentSchema],</code></pre>
<ul>
<li>mongoose의 sub-schema를 이용하여 Post 스키마에 Comment를 배열로 추가</li>
<li>populate를 사용할 때, ObejctID만 저장하는 것과는 다르게 Comment의 내용을 게시글이 포함하게 된다.</li>
<li>sub-schema 내부에서도 populate가 가능하다.</li>
</ul>
<h2 id="api-작성하기">API 작성하기</h2>
<h3 id="댓글-작성">댓글 작성</h3>
<pre><code class="language-javascript">...
router.post(&#39;/posts/:shortId/comments&#39;, ... {
  const { shortId } = req.params;
  const { content } = req.body;
  const authro = await User.findOne({ shortId: req.user.shortId });

  await Post.updateOne({ shortId }, {
    $push: { comments: {
      content,
      author,
    }},
  });

  res.json({ result: &#39;success&#39; });
});</code></pre>
<ul>
<li>api 라우터를 추가하고, RESTful하게 <code>api/posts/{postId}/comments</code> 경로로 댓글 작성 기능 구현</li>
<li>게시글 업데이트 시 <code>$push</code>를 사용하여 comments 배열에 새로 작성된 댓글 추가 $\rarr$ 동시에 들어오는 요청에 대해 정확하게 처리</li>
<li>api는 render 하지 않고 json으로 응답</li>
</ul>
<h3 id="댓글-목록">댓글 목록</h3>
<pre><code class="language-javascript">...
router.post(&#39;/posts/:shortId/comments&#39;, ... {
  const { shortId } = req.params;
  const post = await Post.findOne({ shortId });

  await User.populate(post.comments, {
    path: &#39;authro&#39;
  });

  res.json(post.comments);
});</code></pre>
<ul>
<li><code>/api/posts/{postId}/comments</code>로 RESTful 경로 설정</li>
<li>find에 populate하지 않고 User (model)의 populate를 사용하는 방법도 가능하다.</li>
</ul>
<h2 id="데이터-비동기-호출---fetch로-클라이언트에서-api-호출하기">데이터 비동기 호출 - fetch로 클라이언트에서 API 호출하기</h2>
<ul>
<li>브라우저는 비동기 HTTP 요청을 fetch 함수를 이용해 제공</li>
<li>jQuery의 Ajax와 유사한 기능</li>
<li>fetch를 이용하면 간단하게 JavaScript로 HTTP요청을 비동기 처리할 수 있다.</li>
</ul>
<h2 id="fetch로-api-호출하고-처리하기">fetch로 API 호출하고 처리하기</h2>
<h3 id="댓글-작성하기">댓글 작성하기</h3>
<pre><code>...
script.
  function writeComment() {
    const input = document.querySelector(&#39;#content&#39;)
    const content = input.value;
    fetch(&#39;/api/posts/#{post.shortId}/comments&#39;, {
      method: &#39;post&#39;,
      headers: { &#39;Content-Type&#39;: &#39;application/json&#39; },
      body: JSON.stringify({ content }),
    })
    .then(() =&gt; {
      if (res.ok) {
        input.value = &#39;&#39;;
          loadComments();
      } else {
        alert(&#39;오류가 발생했습니다.&#39;);
      }
    });</code></pre><ul>
<li>댓글 작성 버튼 클릭 시 <code>writeComment()</code> 실행</li>
<li><code>input#content</code>에서 내용을 읽어 fetch로 댓글 작성 api 호출</li>
<li>호출 결과의 성공 여부를 확인하여, 댓글 다시 불러오기 실행</li>
</ul>
<h3 id="댓글-목록-불러오기">댓글 목록 불러오기</h3>
<pre><code class="language-javascript">// 댓글 목록 api 호출하기
script.
  loadComments();
  function loadComments() {
    document
      .querySelector(&#39;#comments&#39;)
      .innerHTML = &#39;&#39;, // 이전 목록 삭제
    fetch(&#39;/api/posts/#{post.shortId}/comments&#39;)
      .then((res) =&gt; {
        if (res.ok) {
          return res.json();
        } else {
          throw new Error(&#39;댓글을 불러오지 못했습니다.&#39;);
        }
    })
    .then((comments) =&gt; {
      comments.forEach(addComment);
    });
    .catch((err) =&gt; alert(err.message));
  }

// HTML Template 사용하여 댓글 화면에 표시하기
function addComment(comment) {
  const template = document.querySelector(&#39;#comment-template&#39;);
  const node = document.importNode(template.content, true);
  node.querySelector(&#39;.content&#39;).textContent = comment.content;
  node.querySelector(&#39;.authro&#39;).textContent = comment.author.name;
  node.querySelector(&#39;.createdAt&#39;).textContent = comment.createdAt;
  document.querySelector(&#39;#comments&#39;).appendChild(node);
}</code></pre>
<h1 id="mongodb-aggregation">MongoDB Aggregation</h1>
<h2 id="aggregation이란">Aggregation이란?</h2>
<ul>
<li>MongoDB에서 Document들을 가공하고, 연산하는 기능</li>
<li>RDBMS에서 SQL로 수행할 수 있는 기능들을 유사하게 구현할 수 있다.</li>
</ul>
<h2 id="aggregation을-사용하는-이유">Aggregation을 사용하는 이유</h2>
<ul>
<li>MongoDB의 find는 검색필터링과 정렬이외의 기능을 제공하지 않는다.</li>
<li>다른 Collection에서 데이터를 가져오거나 검색된 데이터를 그룹화하는 등의 작업에 필요</li>
</ul>
<h2 id="간단한-aggregation-예제">간단한 Aggregation 예제</h2>
<pre><code class="language-javascript">db.posts.aggregate([
  { $group: { _id: &#39;$authro&#39;, count { $sum: 1 } } },
  { $match: { sum: { $gt: 10 } } },
  { $lookup: { from: &#39;users&#39;, localField: &#39;_id&#39;, foreignField: &#39;_id&#39;, as: &#39;users&#39; } },
]);</code></pre>
<ul>
<li>aggregation은 Stage들의 배열로 이루어지고 각 Stage는 순차적으로 수행된다.</li>
</ul>
<ol>
<li>작성자별 게시글 수를 취합하고</li>
<li>게시글 수가 10개보다 많은 작성자를 찾아서</li>
<li>해당 작성자를 회원 collection에서 검색한다.</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[8주차] Node.js와 MongoDB 2 - Express.js와 MongoDB로 웹 서비스 만들기]]></title>
            <link>https://velog.io/@luna_0219/8%EC%A3%BC%EC%B0%A8-Node.js%EC%99%80-MongoDB-2-Express.js%EC%99%80-MongoDB%EB%A1%9C-%EC%9B%B9-%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@luna_0219/8%EC%A3%BC%EC%B0%A8-Node.js%EC%99%80-MongoDB-2-Express.js%EC%99%80-MongoDB%EB%A1%9C-%EC%9B%B9-%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Sat, 22 Apr 2023 18:42:44 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>본 자료는 Elice 플랫폼의 자료를 사용하여 정리하였습니다.</p>
</blockquote>
<h1 id="template-engine">Template Engine</h1>
<h2 id="template-engine이란">Template Engine이란?</h2>
<ul>
<li>서버에서 클라이언트로 보낼 HTML의 형태를 미리 템플릿으로 저장</li>
<li>동작 시에 미리 작성된 템플릿에 데이터를 넘어서 완성된 HTML 생성</li>
<li>템플릿엔진은 템플릿 작성문법과 작성된 템플릿을 HTML로 변환하는 기능을 제공
<img src="https://velog.velcdn.com/images/luna_0219/post/bd16f27e-9128-4bfc-8584-23fcef2a1446/image.png" alt=""></li>
</ul>
<h2 id="expressjs의-템플릿엔진">Express.js의 템플릿엔진</h2>
<ul>
<li>EJS - html과 유사한 문법</li>
<li>Mustache - 간단한 데이터 치환정도만 제공</li>
<li>Pug - 들여쓰기 표현식 이용</li>
</ul>
<h2 id="pug란">Pug란?</h2>
<ul>
<li>들여쓰기 표현식 사용 $\rarr$ 가독성이 올라가고 개발생산성이 올라간다.</li>
<li>문법적 실수를 줄일 수 있다.</li>
<li>layout, include, mixin 등 강력한 기능을 제공한다.</li>
</ul>
<h2 id="pug문법">Pug문법</h2>
<pre><code>html
  head
    title = title
  body
    h1#greeting 안녕하세요
    a.link(href=&quot;/&quot;) 홈으로</code></pre><ul>
<li>닫기 태그를 사용하지 않고 들여쓰기로 문법을 구분한다.</li>
<li><code>=</code>를 이용해 전달받은 변수를 사용할 수 있다.</li>
<li>id나 class는 태그 바로 뒤에 사용한다.</li>
</ul>
<h3 id="pug문법---each-if">pug문법 - each, if</h3>
<pre><code>each item in arr
  if item.name == &#39;new&#39;
    h1 New Document
  else
    h1 = `${item.name}`</code></pre><h3 id="pug문법---layout">pug문법 - layout</h3>
<pre><code>// layout.pug

html
  head
    title = title
  body
    block content    // layout은 block을 포함한 템플릿


// main.pug
extends layout        // extends로 아래 부분에 작성한 HTML 태그가 block부분에 포함된다.
block content
  h1 Main Page</code></pre><h3 id="pug문법---include">pug문법 - include</h3>
<pre><code>// title.pug

h1 = title

// main.pug

extends layout
  block content
    include title        // 자주 반복되는 구문에 사용
    div.content
      안녕하세요
    pre
      include. article.txt        // 텍스트 파일도 가능하다.</code></pre><h3 id="pug문법---mixin">pug문법 - mixin</h3>
<pre><code>// listItem.pug

mixin listItem(title, name)
  tr
    td title
    td name

// main.pug

include listItem
table
  tbody
    listItem(&#39;제목&#39;, &#39;이름&#39;)        // 파라미터로 값을 넘겨받아 사용한다.</code></pre><h2 id="expressjs와-pug-연동">Express.js와 pug 연동</h2>
<pre><code class="language-javascript">// app.js

app.set(&#39;views&#39;, path.join(__dirname, &#39;views&#39;));    // 템플릿이 저장되는 디렉토리 지정
app.set(&#39;view engine&#39;, &#39;pug&#39;);        // 템플릿 엔진 지정

// request handler

res.render(&#39;main&#39;, {    // res.render는 화면을 그리는 기능이다.
  title: &#39;Hello Express&#39;,        // res.render(템플릿 이름, 템플릿에 전달되는 값)
});
</code></pre>
<h2 id="expressjs의-applocals">Express.js의 app.locals</h2>
<pre><code class="language-javascript">// app.js

app.locals.appName = &#39;Express&#39;        // render함수에 전달되지 않은 값이나 함수를 사용(템플릿에 전역으로 사용될 값을 지정)

// main.pug

h1 = appName</code></pre>
<h2 id="express-generator-사용-시-템플릿-엔진-지정하기">express-generator 사용 시 템플릿 엔진 지정하기</h2>
<p><code>$ express --view=pug myapp</code></p>
<h1 id="게시판-crud-만들기">게시판 CRUD 만들기</h1>
<h2 id="게시판에서의-crud">게시판에서의 CRUD</h2>
<h3 id="create">Create</h3>
<ul>
<li>게시글 작성</li>
<li>제목, 내용, 작성자, 작성시간 등의 정보를 기록</li>
<li>제목과 내용은 최소 n글자 이상</li>
</ul>
<h3 id="read">Read</h3>
<ul>
<li>게시글의 목록과 게시글의 상세를 볼 수 있어야 한다.</li>
<li>게시글 목록은 제목과 작성시간을 간략하게 보여준다.</li>
<li>게시글 상세는 제목, 작성자, 내용, 작성시간, 수정시간 등을 상세하게 보여준다.</li>
</ul>
<h3 id="update">Update</h3>
<ul>
<li>게시글 수정(작성자만 가능)</li>
<li>제목과 내용이 수정되고 수정시간이 기록</li>
<li>제목과 내용은 최소 n글자 이상</li>
</ul>
<h3 id="delete">Delete</h3>
<ul>
<li>게시글 삭제(작성자만 가능)</li>
<li>삭제 후 게시글 목록과 상세에서 사라져야 한다.</li>
</ul>
<h2 id="shortid">shortID</h2>
<pre><code class="language-javascript">const { nanoid } = require(&#39;nanoid&#39;);    // 중복없는 문자열을 생성해주는 패키지
const shortId = {
  type: String,
  default: () =&gt; {
    return nanoid();    // ObjectId를 대체할 아이디 생성
  },
  required: true,
  index: true,
}
module.exports = shortId;</code></pre>
<h2 id="게시글-작성">게시글 작성</h2>
<h3 id="게시글-작성-흐름">게시글 작성 흐름</h3>
<ol>
<li><code>/posts?write=true</code>로 작성페이지 접근</li>
<li>`<form action='/posts' method="post"> 이용해 post 요청 전송</li>
<li><code>router.post</code> 이용하여 post 요청 처리</li>
<li><code>res.redirect</code> 이용하여 post 완료 처리</li>
</ol>
<h3 id="작성페이지-만들기">작성페이지 만들기</h3>
<pre><code class="language-javascript">// ./routes/posts.js

const { Router } = require(&#39;express&#39;);

const router = Router();

router.get(&#39;/&#39;, (req, res, next) =&gt; {
  if (req.query.write) {
    res.render(&#39;posts/edit&#39;);
    return;
  }
  ...
});
...
module.exports = router;

// ./views/posts/edit.pug

...
form(action=&quot;/posts&quot;, method=&quot;post&quot;)
  table
    tbody
      tr
        th 제목
        td: input(type=&quot;text&quot; name=&quot;title&quot;)
      tr
        th 내용
        td: textarea(name=&quot;content&quot;)
      td
        td(colspan=&quot;2&quot;)
          input(type=&quot;submit&quot; value=&quot;등록&quot;)</code></pre>
<h3 id="post-요청-처리하기">POST 요청 처리하기</h3>
<pre><code class="language-javascript">const { Post } = require(&#39;./models&#39;);
...
router.post(&#39;/&#39;, async (req, res, next) =&gt; {
  const { title, content } = req.body;
  try {
    await Post.create({
      title,
      content,
    });
    res.redirect(&#39;/&#39;);
  } catch (err) {
    next(err);
  }
});</code></pre>
<h2 id="게시글-목록-및-상세">게시글 목록 및 상세</h2>
<h3 id="게시글-목록-및-상세-흐름">게시글 목록 및 상세 흐름</h3>
<ol>
<li><code>/posts</code>로 목록페이지 접근</li>
<li><code>&lt;a href=&#39;/posts/:shortId&#39;&gt;</code> 이용하여 상세 URL Link</li>
<li><code>router.get(&#39;/:shortId&#39;)</code> path parameter 이용하여 요청 처</li>
</ol>
<h3 id="게시글-목록-구현하기">게시글 목록 구현하기</h3>
<pre><code class="language-javascript">// ./routes/posts.js

router.get(&#39;/&#39;, async (req, res, next) =&gt; {
  const posts = await Post.find({});
  res.render(&#39;posts/list&#39;, { posts });
});

// ./views/posts/list.pug

...
table
  tbody
    each post in posts
      tr
        td
          a(href=`/posts/${post.shortId}`)
            = post.title
        td= post.author
        td= formatDate(post.createdAt)
  tfoot
    tr
      td(colspan=&quot;3&quot;)
        a(href=&quot;/posts?write=true&quot;)
          등록하기</code></pre>
<h3 id="formatdate-함수-추가하기">formatDate 함수 추가하기</h3>
<pre><code class="language-javascript">// app.js

const dayjs = require(&#39;dayjs&#39;);

app.locals.formatDate = (date) =&gt; {
  return dayjs(date).format(&#39;YYYY-MM-DD HH:mm:ss&#39;);
}</code></pre>
<h3 id="게시글-상세-구현하기">게시글 상세 구현하기</h3>
<pre><code class="language-javascript">// ./routes/posts.js

router.get(&#39;/:shortId&#39;, async (req, res, next) =&gt; {
  const { shortId } = req.params;
  const post = await Post.findOne({ shortId });
  if (!post) {
    next(new Error(&#39;Post NotFound&#39;));
    return;
  }
  ...
  res.render(&#39;posts/view&#39;, { post });
});

// ./views/posts/view.pug

...
table
  tbody
    tr
      td(colspan=&quot;2&quot;)= post.title
    tr
      td= post.author
      td= formatDate(post.createdAt)
    tr
      td(colspan=&quot;2&quot;): pre= post.content
    tr
      td: a(href=`/posts/${post.shortId}?edit=true`)
        수정
      td
        button(onclick=`deletePost(&quot;${post.shortId}&quot;)`)
          삭제</code></pre>
<h2 id="게시글-수정">게시글 수정</h2>
<h3 id="게시글-수정-흐름">게시글 수정 흐름</h3>
<ol>
<li><code>/posts/{shortId}?edit=true</code>로 수정페이지 접근</li>
<li>작성페이지를 수정페이지로도 동작하도록 작성</li>
<li><code>&lt;form action=&quot;/posts/:shortId&quot; method=&quot;post&quot;&gt;</code>로 post 요청 전송<ul>
<li>html form은 put을 지원하지 않기 때문에 post를 사용한다.</li>
</ul>
</li>
</ol>
<h3 id="수정-페이지-만들기">수정 페이지 만들기</h3>
<pre><code class="language-javascript">// ./routes/posts.js

router.get(&#39;/:shortId&#39;, async (req, res, next) =&gt; {
  ...
  if (req.query.edit) {
    res.render(&#39;posts/edir&#39;, { post });
  }
  ...
});

// ./views/posts/edit.pug
...
- var action = post ? `/posts/${post.shortId}` : &quot;/posts&quot;
form(action=action, method=&quot;post&quot;)
  table
    tbody
      tr
        th 제목
        td: input(type=&quot;text&quot; name=&quot;title&quot; value=post&amp;&amp;post.title)
      tr
        th 내용
        td: textarea(name=&quot;content&quot;)= post&amp;&amp;post.content
      td
        td(colspan=&quot;2&quot;)
          - var value = post ? &quot;수정&quot; : &quot;등록&quot;
          input(type=&quot;submit&quot; value=value)</code></pre>
<h3 id="수정-요청-처리하기">수정 요청 처리하기</h3>
<pre><code class="language-javascript">// ./routes/posts.js

...
router.post(&#39;/:shortId&#39;, async (req, res, next) =&gt; {
  const { shortId } = req.params;
  const { title, content } = req.body;
  const post = await Post.findOneAndUpdate({ shortId }, { title, content });
  if (!post) {
    next(new Error(&#39;Post NotFound&#39;));
    return;
  }
  res.redirect(`/posts/${shortId}`);
}</code></pre>
<h2 id="게시글-삭제">게시글 삭제</h2>
<h3 id="게시글-삭제-흐름">게시글 삭제 흐름</h3>
<ol>
<li>게시글 상세 페이지에 삭제 버튼 추가</li>
<li>html form은 DELETE를 지원하지 않는다.</li>
<li>JavaScript fetch 함수로 HTTP DELETE 요청 전송</li>
<li>router.delete의 응답을 fetch에서 처리</li>
</ol>
<h3 id="http-delete-요청-전송-및-응답-처리">HTTP Delete 요청 전송 및 응답 처리</h3>
<pre><code>// posts/view.pug

td
  button.delete(
    onclick=&#39;deletePost(&quot;${post.shortId}&quot;)&#39;
  ) 삭제
...
script(type=&quot;text/javascript&quot;).
  function deletePost(shortId) {
    fetch(&#39;/posts/&#39; + shortId, { method: &#39;delete&#39; })
      .then((res) =&gt; {
        if (res.ok) {
          alert(&#39;삭제되었습니다.&#39;);
          window.location.href = &#39;/posts&#39;;
        } else {
          alert(&#39;오류가 발생했습니다.&#39;);
          console.log(res.statusText);
        }
      })
      .catch((err) =&gt; {
        console.log(err);
        alert(&#39;오류가 발생했습니다.&#39;);
      });
  }</code></pre><h3 id="delete-요청-처리하기">DELETE 요청 처리하기</h3>
<pre><code class="language-javascript">// ./routes/posts.js

const { Post } = require(&#39;./models&#39;);
...
router.delete(&#39;/:shortId&#39;, async (req, res, next) =&gt; {
  const { shortId } = req.params;
  try {
    await Post.delete({ shortId });
    res.send(&#39;OK&#39;);
  } catch (err) {
    nexst(err);
  }
});</code></pre>
<h1 id="async-request-handler">Async Request Handler</h1>
<h2 id="request-handler의-오류처리">request handler의 오류처리</h2>
<h3 id="request-handler에서-오류를-처리하기-위한-방법">request handler에서 오류를 처리하기 위한 방법</h3>
<ol>
<li><code>promise().catch(next)</code></li>
<li><code>async function</code>, <code>try ~ catch</code>, <code>next</code></li>
</ol>
<h2 id="async-request-handler-1">async request handler</h2>
<ul>
<li><code>try ~ catch</code>, <code>next</code>를 자동으로 할 수 있도록 구성</li>
<li><code>asyncHandler</code>는 requestHandler를 매개변수로 갖는 함수형 미들웨어이다.</li>
<li>전달된 requestHandler는 try ~ catch로 감싸져 asyncHandler 내에서 실행되고, throw 되는 에러는 자옹으로 오류처리 미들웨어로 전달되도록 구성된다.<pre><code class="language-javascript">const asyncHandler = (requestHandler) =&gt; {
return async (req, res, next) =&gt; {
  try {
    await requestHandler(req, res);
  } catch (err) {
    next(err);
  }
}
}
</code></pre>
</li>
</ul>
<hr>
<p>router.get(&#39;/&#39;, asyncHandler(async (req, res) =&gt; {
  const posts = await Posts.find({});
  if (posts.length &lt; 1) {
    throw new Error(&#39;Not Found&#39;);
  }
  res.render(&#39;posts/list&#39;, { posts });
});</p>
<pre><code>



# Pagination
## Pagination 이란?
- 데이터를 균일한 수로 나누어 페이지로 분리하는 것

## 사용방법
```javascript
router.get(... =&gt; {
  const page = Number(req.query.page || 1);  // 현재 페이지
  const perPage = Number(req.query.perPage || 10);  // 페이지 당 게시글 수</code></pre><ul>
<li><code>/posts?page=1&amp;perPate=10</code> 일반적으로 url query를 사용해 전달한다.</li>
<li>query는 문자열로 전달되기 때문에 Number로 형변환이 필요하다.</li>
</ul>
<pre><code class="language-javascript">router.get(... =&gt; {
  ...
  const total = await Post.countDocument({});
  const posts = await Post.find({});
    .sort({ createdAt: -1 })
    .skip(perPage * (page -1))        // 검색 시 포함하지 않을 데이터 수
    .limit(perPage);        // 검색 결과 수 제한
const totalPage = Math.ceil(total / perPage);</code></pre>
<ul>
<li>MongoDB의 limit와 skip을 사용하여 pagination 구현가능</li>
<li>pagination시에는 데이터의 순서가 유지될 수 있도록 sort를 사용할 수 있도록 한다.</li>
<li>게시글 수 / 페이지 당 게시글 수 = 총 페이지 수</li>
</ul>
<pre><code>mixin pagination(path)
  p
    - for(let i = 1; i &lt;= totalPage; i++)
    a(href=`${path}?page=${i}&amp;perPage=${perPage}`)
      if i == page
        b= i
      else
        = i
    = &quot; &quot;
---
include pagination
tr
  td
    +pagination(&#39;/posts&#39;)</code></pre><ul>
<li>pagination을 mixin으로 선언</li>
<li>pagination이 필요한 페이지에서 해당 템플릿을 include한 후, +pagination으로 mixin을 사용한다.</li>
<li>현재 페이지는 b 태그로 굵게 표시한다.</li>
</ul>
<h1 id="pm2-process-manager">PM2 Process Manager</h1>
<h2 id="pm2란">PM2란?</h2>
<ul>
<li>Node.js 작업을 관리해주는 Process Manager</li>
<li>node 명령어로 실행 시 오류 발생이나 실행 상태 관리를 할 수 없다.</li>
<li>pm2는 작업관리를 위한 다양한 유용한 기능을 제공해준다.</li>
</ul>
<h2 id="pm2를-사용하는-이유">PM2를 사용하는 이유</h2>
<ul>
<li>안정적인 프로세스 실행 - 오류발생 시 자동 재실행</li>
<li>빠른 개발환경 - 소스코드 변경 시 자동 재실행</li>
<li>배포 시 편리한 관리 - pm2에 모든 프로세스를 한 번에 관리</li>
</ul>
<h2 id="pm2-사용방법">PM2 사용방법</h2>
<ul>
<li><code>$ pm2 init simple</code> 혹은 <code>$ pm2 init</code> 명령어를 이용하여 pm2 설정파일 예제를 만들 수 있다.</li>
<li>예제를 수정하여 설정파일을 생성한 후, <code>$ pm2 start</code> 명령어를 실행하면 어플리케이션을 pm2 데몬으로 실행해준다.</li>
<li>개발 시 watch 옵션을 사용하여 파일 변경 시 서버 자동 재실행 구성을 할 수 있다.<pre><code class="language-javascript">module.exports = {
apps : [{
  name: &#39;simple-board&#39;,
  script: &#39;./bin/www&#39;,
  watch: &#39;.&#39;,
  ignore_watch: &#39;views&#39;,
}],
};
</code></pre>
</li>
</ul>
<hr>
<p>$ pm2 start</p>
<pre><code>

## PM2 Example
![](https://velog.velcdn.com/images/luna_0219/post/56472f18-eaf9-4614-92fa-9e1ab98a2199/image.png)</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[7주차] Node.js와 MongoDB 2 - MongoDB와 Mongoose]]></title>
            <link>https://velog.io/@luna_0219/7%EC%A3%BC%EC%B0%A8-Node.js%EC%99%80-MongoDB-2-MongoDB%EC%99%80-Mongoose</link>
            <guid>https://velog.io/@luna_0219/7%EC%A3%BC%EC%B0%A8-Node.js%EC%99%80-MongoDB-2-MongoDB%EC%99%80-Mongoose</guid>
            <pubDate>Sun, 16 Apr 2023 16:41:56 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>본 자료는 Elice 플랫폼의 자료를 사용하여 정리하였습니다.</p>
</blockquote>
<h1 id="mongodb">MongoDB</h1>
<h2 id="mongodb란">MongoDB란?</h2>
<ul>
<li>대표적인 NoSQL, Document DB</li>
<li>Mongo는 Humongous에서 따온 말로, 엄청나게 큰 DB라는 의미
<span style="color:skyblue">$\rarr$ 대용량 데이터를 처리하기 좋다.</span></li>
</ul>
<h2 id="rdb와-nosql">RDB와 NoSQL</h2>
<h3 id="rdb">RDB</h3>
<ul>
<li>Relational DataBase 관계형 데이터베이스</li>
<li>자료들의 관계를 주요하게 다룬다.</li>
<li>SQL 질의어를 사용하기 위해 데이터를 구조화해야한다.</li>
</ul>
<h3 id="nosql을-사용하는-이유">NoSQL을 사용하는 이유</h3>
<ul>
<li>스키마에 정의된 데이터가 아니면 저장할 수 없는 제약이 따른다.</li>
<li>NoSQL은 사전작업 없이 데이터베이스를 사용할 수 있다.</li>
</ul>
<h2 id="mongodb-기본개념">MongoDB 기본개념</h2>
<p><code>Database</code> $\rarr$ <code>Collection</code> $\rarr$ <code>Document</code></p>
<h3 id="database">Database</h3>
<ul>
<li>하나 이상의 Collection을 가질 수 있는 저장소</li>
<li>SQL에서의 database와 유사하다.</li>
</ul>
<h3 id="collection">Collection</h3>
<ul>
<li>하나 이상의 Document가 저장되는 공간</li>
<li>SQL에서의 table과 유사하다.</li>
<li>하지만, Collection이 Document의 구조를 정의하지 않는다.</li>
</ul>
<h3 id="document">Document</h3>
<ul>
<li>MongoDB에 저장되는 자료</li>
<li>SQL에서 row와 유사하지만 구조제약 없이 유연하게 저장가능</li>
<li>JSON과 유사한, BSON을 사용하여 다양한 자료형을 지원</li>
<li>objectID<ul>
<li>각 Document의 유일한 키값, SQL의 primary key와 유사하다.</li>
<li>Document 생성 시 자동으로 생성되는 값이다. (timestamp + random value + auto increment)</li>
</ul>
</li>
</ul>
<h2 id="mongodb-사용방법">MongoDB 사용방법</h2>
<ul>
<li>MongoDB</li>
<li>MongoDB Cloud</li>
<li>MongoDB Compass (GUI로 DB설정 가능)</li>
</ul>
<h1 id="mongoose-odm">Mongoose ODM</h1>
<h2 id="mongoose-odm이란">Mongoose ODM이란?</h2>
<ul>
<li>Object Data Modeling</li>
<li>MongoDB의 Collection에 집중하여 관리하도록 도와주는 패키지</li>
<li>Collection을 모델화하여, 관련기능들을 쉽게 사용할 수 있도록 도와준다.</li>
</ul>
<h2 id="mongoose-odm을-사용하는-이유">Mongoose ODM을 사용하는 이유</h2>
<ul>
<li>연결관리<ul>
<li>MongoDB의 기본 Node.js 드라이버는 연결상태를 관리하기 어렵다.</li>
<li>Mongoose를 사용하면 간단하게 데이터베이스와의 연결상태를 관리해준다.</li>
</ul>
</li>
<li>스키마관리<ul>
<li>스키마 정의가 필요없는건 NoSQL의 장점이지만, 데이터 형식을 미리 정의해야 코드작성과 프로젝트 관리에 유용하다.</li>
<li>Mongoose는 Code-Level에서 스키마를 정의하고 관리할 수 있게 해준다.</li>
</ul>
</li>
<li>Populate<ul>
<li>MongoDB는 기본적으로 Join을 제공하지 않는다.</li>
<li>Join과 유사한 기능을 사용하려면 aggregate라는 복잡한 쿼리를 해야 하지만, Mongoose는 populate를 사용하여 간단하게 구현할 수 있다.</li>
</ul>
</li>
</ul>
<h1 id="mongoose-odm-사용하기">Mongoose ODM 사용하기</h1>
<h2 id="스키마-정의하기">스키마 정의하기</h2>
<ul>
<li>Code-Level에서 관리가능</li>
<li>형식을 미리 지정하고 체크가 가능하다.</li>
<li>timestamps 옵션을 사용하면 생성, 수정시간을 자동으로 기록해준다.<pre><code class="language-javascript">const { Schema } = require(&#39;mongoose&#39;);
const PostSchema = new Schema({
title: String,
content: String,
}, {
timestamps: true,
});
module.exports = PortSchema;</code></pre>
</li>
</ul>
<h2 id="모델-만들기">모델 만들기</h2>
<ul>
<li>스키마를 사용할 수 있는 모델로 만들어야한다.</li>
<li>모델의 이름을 지정할 수 있다.<pre><code class="language-javascript">const mongoose = require(&#39;mongoose&#39;);
const PostSchema = require(&#39;./schema/board&#39;);
exports.Post = mongoose.model(&#39;Post&#39;, PostSchema);</code></pre>
</li>
</ul>
<h2 id="데이터베이스-연결하기">데이터베이스 연결하기</h2>
<ul>
<li>connect 함수를 이용하여 간단하게 데이터베이스에 연결할 수 있다.</li>
<li>mongoose는 자동으로 연결을 관리해주어 직접 연결 상태를 체크하지 않아도 모델사용 시 연결 상태를 확인하여 사용이 가능할 때 작업을 실행한다.<pre><code class="language-javascript">const mongoose = require(&#39;mongoose&#39;);
mongoose.connect(&#39;mongodb://localhost:27017/myapp&#39;);</code></pre>
</li>
</ul>
<h2 id="모델-사용하기---간단한-crud">모델 사용하기 - 간단한 CRUD</h2>
<ul>
<li>CREATE - <code>Create</code></li>
<li>READ - <code>find</code>, <code>findById</code>, <code>findOne</code></li>
<li>UPDATE - <code>updateOne</code>, <code>updateMany</code>, <code>findByIdAndUpdate</code>, <code>findOneAndUpdate</code></li>
<li>DELETE - <code>deleteOne</code>, <code>deleteMany</code>, <code>findByIdAndDelete</code>, <code>findOneAndDelete</code></li>
</ul>
<h2 id="create">CREATE</h2>
<ul>
<li>Document를 생성하고 반환해준다.<pre><code class="language-javascript">const { Post } = require(&#39;./models&#39;);
</code></pre>
</li>
</ul>
<p>async function main() {
  const created = await Post.create({
    title: &#39;first title&#39;,
    content: &#39;second title&#39;,
  });</p>
<p>  const multipleCreated = await Post.create([
    item1,
    item2
  ]);
}</p>
<pre><code>
## FIND (READ)
- query를 사용하여 검색하거나 findById를 사용하면 Document를 검색할 수 있다.
```javascript
const { Post } = require(&#39;./models&#39;);

async function main() {
  const listPost = await Post.find(query);
  const onePost = await Post.findOne(query);
  const postById = await Post.findById(id);
}</code></pre><h2 id="update">UPDATE</h2>
<ul>
<li>update~ 함수의 경우 수정 결과를 반환해준다.</li>
<li>find~ 함수의 경우 검색된 Document에 업데이트를 반영하여 반환해준다.<pre><code class="language-javascript">async function main() {
const updateResult = await Post.updateOne(query, {
  ...
});
const updateResults = await Post.updateMany(query, {
  ...
});
const postById = await Post.findByIdAndUpdate(id, {
  ...
});
const onePost = await Post.findOneAndUpdate(query, {
  ...
});</code></pre>
</li>
</ul>
<h2 id="delete">DELETE</h2>
<ul>
<li><p>delete~ 함수의 경우 삭제 결과를 반환해준다.</p>
</li>
<li><p>find~ 함수의 경우 검색된 Document에 삭제를 반영하여 반환해준다.</p>
<pre><code class="language-javascript">async function main() {
const deleteResult = await Post.deleteOne(query);

const deleteResults = await Post.deleteMany(query);

const onePost = await Post.findOneAndDelete(query);

const postById = await Post.findByIdAndDelete(query);
}</code></pre>
</li>
</ul>
<h2 id="populate">populate</h2>
<ul>
<li>Document 안에 Document를 담지 않고, ObjectID를 가지고 reference하여 사용할 수 있는 방법을 제공한다.</li>
<li>Document에는 reference되는 ObjectID를 담고, 사용할 때 populate하여 하위 Document처럼 사용할 수 있게 해준다.<pre><code class="language-javascript">const Post = new Schema({
...
user: {
  type: Schema.Types.ObjectId,
  ref: &#39;User&#39;
},
comments: [{
  type: Schema.Types.ObjectId,
  ref: &#39;Comment&#39;,
}],
});
</code></pre>
</li>
</ul>
<p>const post = await Post.find().populate([&#39;user&#39;, &#39;comments&#39;]);</p>
<p>// post.user.name, post.comments[0].content</p>
<pre><code>
## 자주 사용되는 query
- `{key: value}`로 exact match
- `$lt`, `$lte`, `$gt`, `$gte`를 사용하여 range query 작성 가능
- `$in`을 사용하여 다중 값으로 검색
- `$or`을 사용하여 다중 조건 검색
```javascript
Person.find({
  name: &#39;kyubum&#39;,
  age: {
    $lt: 20,
    $gte: 10,
  },
  languages: {
    $in: [&#39;ko&#39;, &#39;en&#39;],
  },
  $or: [
    { statue: &#39;ACTIVE&#39; },
    { isFresh: true },
  ],
});</code></pre><h1 id="expressjs--mongoose-odm">Express.js + Mongoose ODM</h1>
<h2 id="mongoose-odm-커넥션-이벤트">Mongoose ODM 커넥션 이벤트</h2>
<ul>
<li><code>connected</code> - 연결 완료</li>
<li><code>disconnected</code> - 연결이 끊김</li>
<li><code>reconnected</code> - 재연결 완료</li>
<li><code>reconnecteFailed</code> - 재연결 시도 횟수 초과<pre><code class="language-javascript">mongoose.connect(&#39;----&#39;);
</code></pre>
</li>
</ul>
<p>mongoose.connection.on(&#39;connected&#39;, () =&gt; {
});</p>
<p>mongoose.connection.on(&#39;disconnected&#39;, () =&gt; {
});</p>
<p>mongoose.connection.on(&#39;reconnected&#39;, () =&gt; {
});</p>
<p>mongoose.connection.on(&#39;reconnecteFailed&#39;, () =&gt; {
});
```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[7주차] Node.js와 MongoDB 1 - Express.js와 REST API]]></title>
            <link>https://velog.io/@luna_0219/7%EC%A3%BC%EC%B0%A8-Node.js%EC%99%80-MongoDB-1-Express.js%EC%99%80-REST-API</link>
            <guid>https://velog.io/@luna_0219/7%EC%A3%BC%EC%B0%A8-Node.js%EC%99%80-MongoDB-1-Express.js%EC%99%80-REST-API</guid>
            <pubDate>Sun, 16 Apr 2023 16:03:28 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>본 자료는 Elice 플랫폼의 자료를 사용하여 정리하였습니다.</p>
</blockquote>
<h1 id="expressjs의-middleware">Express.js의 Middleware</h1>
<h2 id="middleware란">Middleware란?</h2>
<ul>
<li>Express.js 동작의 핵심</li>
<li>HTTP 요청과 응답 사이에서 단계별 동작을 수행해주는 함수</li>
</ul>
<h2 id="middleware-동작원리">Middleware 동작원리</h2>
<ul>
<li>HTTP 요청이 들어온 순간부터 시작</li>
<li>미들웨어는 HTTP 요청과 응답개체를 처리하거나, 다음 미들웨어를 실행</li>
<li>HTTP 응답이 마무리될 때까지 미들웨어 동작 사이클이 실행</li>
</ul>
<h1 id="middleware의-작성과-사용">Middleware의 작성과 사용</h1>
<h2 id="작성법">작성법</h2>
<ul>
<li><p><code>req</code>, <code>res</code>, <code>next</code>를 가진 함수를 작성하면 해당 함수는 미들웨어로 동작할 수 있다.</p>
<ul>
<li><code>req</code> - HTTP 요청을 처리하는 객체</li>
<li><code>res</code> - HTTP 응답을 처리하는 객체</li>
<li><code>next</code> - 다음 미들웨어를 실행하는 함수</li>
</ul>
</li>
<li><p>작성</p>
<pre><code class="language-javascript">const logger = (req, res, next) =&gt; {
  console.log(`Request ${req.path}`);
  next();   // next() 함수가 없으면 미들웨어 사이클이 멈추기 때문에 주의!!!!
}</code></pre>
</li>
</ul>
<h2 id="route-handler와-middleware">Route Handler와 middleware</h2>
<ul>
<li>Route Handler도 미들웨어의 한 종류</li>
<li>Route Handler는 라우팅 함수(get, post, put, delete 등)에 적용된 미들웨어</li>
<li>path parameter 사용 가능</li>
</ul>
<h2 id="사용법">사용법</h2>
<ul>
<li><p>적용되는 위치에 따라 어플리케이션 미들웨어, 라우터 미들웨어, 오류처리 미들웨어로 분류가능</p>
</li>
<li><p>어플리케이션 미들웨어</p>
<ul>
<li>use나 http method함수로 연결</li>
<li>순차적으로 적용<pre><code class="language-javascript">app.use(함수명)
app.get(&#39;/&#39;, (req, res, next) =&gt; {
res.send(&#39;test&#39;);
});</code></pre>
</li>
</ul>
</li>
<li><p>라우터 미들웨어</p>
<ul>
<li>router 객체에 미들웨어가 적용되는 것 외에는 어플리케이션 미들웨어와 동일</li>
<li>특정 경로의 라우팅에만 적용하기 위한 방법<pre><code class="language-javascript">router.use(함수명)
router.get(&#39;/&#39;, (req, res, next) =&gt; {
res.send(&#39;test&#39;);
});
app.use(&#39;/admin&#39;, router);</code></pre>
</li>
</ul>
</li>
<li><p>미들웨어 서브스택</p>
<ul>
<li>use나 http method 함수에 여러개의 미들웨어로 동시에 적용가능<pre><code class="language-javascript">app.use(함수명1, 함수명2)
app.use(&#39;/admin&#39;, auth, router);
app.get(&#39;/&#39;, logger, (req, res, next) =&gt; {
res.send(&#39;test&#39;);
});</code></pre>
</li>
</ul>
</li>
<li><p>오류처리 미들웨어</p>
<ul>
<li>일반적으로 마지막에 위치하는 미들웨어</li>
<li><code>err</code>, <code>req</code>, <code>res</code>, <code>next</code> 네가지 인자를 가진다.</li>
<li>앞선 미들웨어에서 next함수에 인자가 전달되면 실행된다.</li>
</ul>
</li>
<li><p>함수형 미들웨어</p>
<pre><code class="language-javascript">const auth = (memberType) =&gt; {
return (req, res, next) =&gt; {
  if (!checkMember(req, memberType)) {
    next(new Error(`member not ${memberType}`));
    return;
  }
  next();
}
}
</code></pre>
</li>
</ul>
<p>app.use(&#39;/admin&#39;, auth(&#39;admin&#39;), adminRouter);
app.use(&#39;/users&#39;, auth(&#39;memver&#39;), userRouter);</p>
<p>```</p>
<h1 id="rest-api">REST API</h1>
<h2 id="rest-api란">REST API란?</h2>
<ul>
<li>REST + API</li>
<li>REST 아키텍처를 준수하는 웹 API</li>
<li>Restful API라고도 한다.</li>
</ul>
<h2 id="api란">API란?</h2>
<ul>
<li>Application Programming Interface</li>
<li>서비스나 프로그램간에 미리 정해진 기능을 실행할 수 있도록 하는 규약</li>
</ul>
<h2 id="rest란">REST란?</h2>
<ul>
<li>REpresentational State Transfer</li>
<li>웹에서 자료를 전송하기 위한 표현방법에 대한 아키텍처</li>
</ul>
<h1 id="json">JSON</h1>
<h2 id="json이란">JSON이란?</h2>
<ul>
<li>JavaScript Object Notation</li>
<li>객체를 표현하는 표현식</li>
</ul>
<h2 id="object">Object</h2>
<ul>
<li><code>{&quot;key&quot;: &quot;value&quot;}</code>로 표현한다.</li>
</ul>
<h2 id="array">Array</h2>
<ul>
<li><code>[item1, item2]</code>로 표현한다.</li>
</ul>
<h1 id="expressjs로-rest-api-구현하기">Express.js로 REST API 구현하기</h1>
<h2 id="mvc-패턴">MVC 패턴</h2>
<ul>
<li>MVC 패턴은 웹 서비스의 가장 대표적인 프로젝트 구성 패턴</li>
<li>프로젝트의 기능들을 어떻게 분리할지에 대한 하나의 구성방법</li>
<li>Model - View - Controller를 구붖ㄴ하여 프로젝트 구조를 구성하는 것</li>
</ul>
<h2 id="model">Model</h2>
<ul>
<li>Model은 데이터에 접근하는 기능 또는 데이터 그 자체를 의미한다.</li>
<li>데이터의 읽기, 쓰기는 Model을 통해서만 이루어지도록 구성해야 한다.</li>
</ul>
<h2 id="view">View</h2>
<ul>
<li>View는 데이터를 표현하는 기능을 의미한다.</li>
<li>주로 Controller에 의해 데이터를 전달받고 전달받은 데이터를 화면에 표시한다</li>
</ul>
<h2 id="controller">Controller</h2>
<ul>
<li>Controller는 Model을 통해 데이터에 접근하여 처리결과를 View로 전달해준다.</li>
<li>웹 서비스에선 주로 라우팅 함수가 해당 기능을 수행한다.</li>
</ul>
<h1 id="postman-사용하기">Postman 사용하기</h1>
<h2 id="postman이란">Postman이란?</h2>
<ul>
<li>API를 테스트할 수 있는 도구</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[7주차] Node.js와 MongoDB 1 - 웹과 Express.js]]></title>
            <link>https://velog.io/@luna_0219/7%EC%A3%BC%EC%B0%A8-Node.js%EC%99%80-MongoDB-1-%EC%9B%B9%EA%B3%BC-Express.js</link>
            <guid>https://velog.io/@luna_0219/7%EC%A3%BC%EC%B0%A8-Node.js%EC%99%80-MongoDB-1-%EC%9B%B9%EA%B3%BC-Express.js</guid>
            <pubDate>Sun, 16 Apr 2023 12:13:42 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>본 자료는 박민 코치님의 자료와 Elice 플랫폼의 자료를 사용하여 정리하였습니다.</p>
</blockquote>
<h1 id="웹의-이해">웹의 이해</h1>
<h2 id="웹이란">웹이란?</h2>
<ul>
<li>사전적 의미 - World Wide Web, 인터넷상에서 동작하는 모든 서비스</li>
<li>일방적 의미 - 웹 브라우저로 접속해서 이용하는 서비스, 웹사이트</li>
</ul>
<h1 id="웹-서비스-동작-방식">웹 서비스 동작 방식</h1>
<ul>
<li>웹 서비스는 기본적으로 HTTP 요청과 응답의 반복으로 이루어진다.</li>
<li>HTTP 요청은 사용자가 어떤 데이터가 필요한지를 서버에게 알리는 역할</li>
<li>HTTP 응답은 HTTP 요청에 해당하는 적절한 데이터를 전달하는 역할 
<img src="https://velog.velcdn.com/images/luna_0219/post/3c346c60-e9f3-4034-bdca-034e7ec0dc00/image.png" alt=""></li>
</ul>
<h2 id="http-요청-예시">HTTP 요청 예시</h2>
<ul>
<li>어떤 사용자가, 어떤 데이터를 필요로 하는지 등을 담고있다.
<img src="https://velog.velcdn.com/images/luna_0219/post/c31ccb0e-9120-4cba-9ae8-1db1260461f1/image.png" alt=""></li>
</ul>
<h2 id="http-응답-예시">HTTP 응답 예시</h2>
<ul>
<li>사용자가 요청한 데이터와, 어떤 데이터가 전송되는지 등을 담고 있다.
<img src="https://velog.velcdn.com/images/luna_0219/post/0ecee56c-cd7c-4ffc-a940-74ca2757d6c0/image.png" alt=""></li>
</ul>
<h2 id="백엔드와-프론트엔드">백엔드와 프론트엔드</h2>
<ul>
<li>백엔드는 사용자에게 보이지 않는 데이터 가공 등의 기능을 주로 담당한다. (서버)</li>
<li>프론트엔드는 사용자가 직접 사용하게 되는 웹 페이지를 주로 담당한다. (클라이언트)</li>
</ul>
<h2 id="정적-웹과-동적-웹">정적 웹과 동적 웹</h2>
<h3 id="정적-웹">정적 웹</h3>
<ul>
<li>Web 1.0</li>
<li>사용자와 상호작용하지 않는 페이지 - 단방향 통신</li>
<li>Link를 통한 페이지 이동 정도만 가능</li>
<li>일반적으로 변하지 않는 html파일로 제공</li>
</ul>
<h3 id="동적-웹">동적 웹</h3>
<ul>
<li>Web 2.0</li>
<li>사용자와 상호작용을 한다. - 양방향 통신</li>
<li>사용자가 다양한 기능을 수행할 수 있다.</li>
<li>프론트엔드와 백엔드가 유기적으로 통신하여 등장
<span style="color:red">$\rarr$ 현대적인 웹은 대부분 동적 웹</span></li>
</ul>
<h2 id="동적-웹의-두-가지-구현방법">동적 웹의 두 가지 구현방법</h2>
<h3 id="csr-client-side-rendering">CSR (Client-Side Rendering)</h3>
<ul>
<li>프론트엔드에서 사용자가 페이지에서 보는 동적인 부분을 대부분 처리하는 방식</li>
</ul>
<h3 id="ssr-server-side-rendering">SSR (Server-Side Rendering)</h3>
<ul>
<li>백엔드에서 페이지 대부분의 영역을 처리해서 프론트엔드로 전달하는 방식</li>
</ul>
<h2 id="csr의-특징">CSR의 특징</h2>
<p><img src="https://velog.velcdn.com/images/luna_0219/post/e9a65c2a-ab3d-410e-91c8-391262f3913a/image.png" alt=""></p>
<ul>
<li>사이트가 변하는 부분들을 프론트엔드에서 처리</li>
<li>프론트엔드 코드에 페이지 리소스들이 미리 정의되어 있다.</li>
<li>서버와의 통신은 API통신을 이용</li>
<li>빠른 반응이지만 페이지의 내용은 API호출이 완료된 후에 보여진다.
<span style="color:red">$\rarr$ 프로젝트 구성이 복잡하고 개발 사이즈가 커진다.</span></li>
</ul>
<h2 id="ssr의-특징">SSR의 특징</h2>
<p><img src="https://velog.velcdn.com/images/luna_0219/post/8e27f8fd-846d-41d4-9fd6-8f1ac3827c2f/image.png" alt=""></p>
<ul>
<li>사이트가 변하는 부분들을 백엔드에서 처리</li>
<li>백엔드에서 HTML파일을 작성해서 프론트엔드로 전달</li>
<li>CSR에 비해 쉬운 구성, 작은 개발사이즈</li>
<li>로딩이 완료되면 페이지와 데이터가 한 번에 표시된다.</li>
<li>상대적으로 사용자가 보기엔 로딩이 느려보인다.</li>
<li>페이지 이동할때마다 다시 로딩하기 때문에 페이지가 깜박인다.</li>
</ul>
<h1 id="웹-프레임워크">웹 프레임워크</h1>
<h2 id="웹-프레임워크란">웹 프레임워크란?</h2>
<ul>
<li>웹 서비스에 필요한 기능들을 제공해주는 다양한 도구들의 모음</li>
</ul>
<h2 id="웹-프레임워크를-사용하는-이유">웹 프레임워크를 사용하는 이유</h2>
<ul>
<li>웹 서비스를 구성하기 위해서는 매우 많은 기능이 필요하다.</li>
<li>이러한 기능들을 하나씩 직접 만드는 것에는 너무나 큰 비용이 발생</li>
<li>웹 서비스는 많은 부분이 정형화되어 있다.</li>
<li>프레임워크를 사용하여 정형화된 부분을 간단하게 구현</li>
<li>필요한 부분만 집중해서 개발할 수 있다.</li>
</ul>
<h2 id="웹-프레임워크의-기본-구성요소">웹 프레임워크의 기본 구성요소</h2>
<ul>
<li>웹 서비스의 정형화된 구성을 많은 웹 프레임워크가 기본적으로 제공한다.</li>
<li>HTTP 요청처리, HTTP 응답처리, 라우팅, HTML Templating</li>
</ul>
<h2 id="웹-프레임워크---http-요청처리">웹 프레임워크 - HTTP 요청처리</h2>
<ul>
<li>HTTP 요청을 처리할 수 있다.</li>
<li>어떤 데이터를 필요롤 하는지, 어떤 사용자로부터 요청이 수신되었는지 등</li>
</ul>
<h2 id="웹-프레임워크---http-응답처리">웹 프레임워크 - HTTP 응답처리</h2>
<ul>
<li>HTTP 응답을 처리할 수 있다.</li>
<li>응답데이터가 어떤 형식인지, 응답 상태가 정상적인지 등</li>
</ul>
<h2 id="웹-프레임워크---라우팅">웹 프레임워크 - 라우팅</h2>
<ul>
<li>HTTP 요청을 분기하는 방법을 제공한다.</li>
<li>HTTP 요청 URL에 해당하는 알맞은 응답의 경로를 미리 설정한다.</li>
</ul>
<h2 id="웹-프레임워크---html-templating">웹 프레임워크 - HTML Templating</h2>
<ul>
<li>SSR을 구현하기 위한 방법을 제공</li>
<li>SSR에서 응답으로 보낼 HTML을 서버에서 작성하기 위해, HTML Templating을 통해 미리 페이지의 뼈대를 작성가능</li>
</ul>
<h2 id="nodejs의-웹-프레임워크">Node.js의 웹 프레임워크</h2>
<ul>
<li>Express.js</li>
<li>Koa.js</li>
<li>Nest.js 등</li>
</ul>
<h1 id="expressjs-시작하기">Express.js 시작하기</h1>
<h2 id="expressjs를-사용하는-이유">Express.js를 사용하는 이유</h2>
<ul>
<li>Node.js의 웹 프레임워크 중 가장 유명한 웹 프레임워크</li>
<li>필요에 따라 유연하게 구조 설정 가능</li>
<li>다양한 미들웨어를 통해 필요한 기능을 간단하게 추가 가능</li>
<li>모든 동작이 명시적으로 구성되기 때문에, 웹 프레임워크의 동작방식을 이해하기 가장 좋은 프레임워크</li>
</ul>
<h2 id="npm-init으로-시작하기">npm init으로 시작하기</h2>
<ul>
<li><p>Express.js 설치</p>
<ol>
<li><code>npm init</code></li>
<li><code>npm install express</code></li>
</ol>
</li>
<li><p>Express.js 시작하기</p>
<pre><code class="language-javascript">const express = require(&quot;express&quot;);
const app = express();
</code></pre>
</li>
</ul>
<p>app.get(&#39;/&#39;, (req, res) =&gt; {
  res.send(&#39;Hello World&#39;);
});</p>
<p>app.listen(3000);</p>
<pre><code>&lt;span style=&quot;color:red&quot;&gt;$\rarr$ Express.js를 처음부터 작성할 수 있는 방법&lt;/span&gt;


## nodemon으로 자동 실행하기
- 코드를 수정하면 자동으로 재실행된다.
- nodemon 설치
  1. `npm init` 입력
  2. `npm install nodemon` 입력
  3. package.json 파일 수정
      * script에 `&quot;start&quot;: &quot;nodemon ./index.js&quot;` 추가
  4. `npm start` 입력

## express-generator 사용하기
- 설치하기
  1. `npm install -g express-generator`
  2. `express my-web`
  3. `cd my-web`
  4. `npm install`
  5. `npm start`
  &lt;span style=&quot;color:red&quot;&gt;$\rarr$ 프로젝트 자동 작성&lt;/span&gt;





# Express.js의 구조
- 기본구조 알아보기
  + my-web
    * app.js - Express.js의 가장 기본이 되는 파일, 웹 어플리케이션의 기능을 정의
    * bin/www - Express.js 실행부분을 담당, 포트와 실행오류 등을 정의
    * package.json - 프로젝트 의존성 및 스크립트 정의
    * public - 코드를 통하지 않고, 직접 제공되는 파일 디렉토리
    * routes - 라우팅 파일 디렉토리
    * views - HTML Template 디렉토리



# Express.js 동작방식
## 동작방식
1. app.js $\rarr$ app.use
2. routes/index.js $\rarr$ router.get
3. routes/index.js $\rarr$ res.render
4. views/index.jade

## app.js
- app 객체
  + app.use() - 미들웨어를 사용하기 위한 함수
  + app.listen() - http 서버를 생성해주는 함수
  + app.locals - app에서 사용할 공통 상수

## 라우팅
### app 라우팅
```javascript
app.get(&#39;/&#39;, (req, res) =&gt; {
  res.send(&#39;Hello World&#39;);
});</code></pre><ul>
<li>get, post, put, delete, all 사용가능</li>
<li>첫 번째 인자는 라우팅을 실행할 URL</li>
<li>마지막 인자는 라우팅이 실행될 때 작동하는 함수</li>
</ul>
<h3 id="expressrouter">Express.Router</h3>
<ul>
<li>app라우팅은 그룹화를 지원하지 않는다.</li>
<li>Express.Router로 라우팅을 모듈화할 수 있다.<pre><code class="language-javascript">// users.js 파일
const router = express.Router();
router.get(&#39;/board&#39;, (req, res) =&gt; {
res.send(&#39;Hello board&#39;);
});
</code></pre>
</li>
</ul>
<p>module.exports = router;</p>
<p>// index.js 파일
const express = require(&#39;express&#39;);
const usersRouter = require(&#39;./routes/users.js&#39;);
const app = express();</p>
<p>app.get(&#39;/&#39;, (req, res) =&gt; {
  res.send(&#39;hello&#39;);
});</p>
<p>app.use(&#39;/users&#39;, usersRouter); // /users URL을 usersRouter로 사용
app.listen(8080);</p>
<pre><code>- app라우팅과 동일한 동작을 한다.

## 라우팅 - path parameter 사용
- 주소의 일부를 변수처럼 사용 가능하다.
```javascript
/users/:id   // /users/123, /users/456 등...
/messages/:from-:to    // /messages/123-456 등...</code></pre><h2 id="request-handler">Request Handler</h2>
<ul>
<li>설정된 라우팅 경로에 해당하는 요청이 들어오면 Request Handler 함수가 실행된다.</li>
<li>HTTP 메소드 함수의 마지막 인자</li>
</ul>
<h2 id="request-handler---request-객체">Request Handler - Request 객체</h2>
<ul>
<li><code>req.params</code> - /path/:id에서 :id를 req.params.id로 사용</li>
<li><code>req.queries</code> - /path?page=2에서 page부분을 req.queries.page로 사용</li>
<li><code>req.body</code> - res.body에 요청데이터가 저장되어 들어온다.</li>
<li><code>req.get(&#39;&#39;)</code> - HTTP Request의 헤더 값을 가져올 수 있다. req.get(&#39;Authorization&#39;) 등</li>
</ul>
<h2 id="request-handler---response-객체">Request Handler - Response 객체</h2>
<ul>
<li><code>res.send()</code> - text형식의 HTTP 응답을 전송</li>
<li><code>res.json()</code> - json형식의 HTTP 응답을 전송</li>
<li><code>res.render()</code> - HTML Template를 사용하여 화면을 전송</li>
<li><code>res.set()</code> - HTTP 응답의 헤더를 설정</li>
<li><code>res.status()</code> - HTTP 응답의 상태값을 설정</li>
</ul>
<h1 id="tip---http모듈로-server열기">Tip - http모듈로 Server열기</h1>
<pre><code class="language-javascript">const http = require(&#39;http&#39;);
const server = http.createServer((req, res) =&gt; {
  console.log(req);
  res.end(&#39;Node Server!!&#39;);
});
server.listen(8080);</code></pre>
]]></description>
        </item>
    </channel>
</rss>