<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>ja_efan.log</title>
        <link>https://velog.io/</link>
        <description>이것저것.</description>
        <lastBuildDate>Sun, 12 Jan 2025 06:35:52 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>ja_efan.log</title>
            <url>https://velog.velcdn.com/images/ja_efan/profile/ef6d4790-3a11-478d-8d08-c8f875509e86/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. ja_efan.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/ja_efan" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Git Hook과 pre-commit 패키지 ]]></title>
            <link>https://velog.io/@ja_efan/Git-Hook%EA%B3%BC-pre-commit-%ED%8C%A8%ED%82%A4%EC%A7%80</link>
            <guid>https://velog.io/@ja_efan/Git-Hook%EA%B3%BC-pre-commit-%ED%8C%A8%ED%82%A4%EC%A7%80</guid>
            <pubDate>Sun, 12 Jan 2025 06:35:52 GMT</pubDate>
            <description><![CDATA[<h1 id="git-hook">Git Hook</h1>
<hr>
<blockquote>
<p><strong>Git Hook</strong>은 Git에서 제공하는 <strong>사용자 정의 스크립트</strong>로,
특정 Git 이벤트가 발생할 때 자동으로 실행되도록 설정할 수 있다.<br>이를 통해 Git 워크플로를 자동화하고 품질 관리, 작업 표준화 등을 실현할 수 있다.</p>
</blockquote>
<p>git hook을 사용하기 위한 전체적인 플로우는 다음과 같다.</p>
<ol>
<li><strong>Git Hook의 사용 목적 결정</strong><ol>
<li>커밋 메시지 형식 검증 ✅</li>
<li>코드 포맷팅 검사</li>
<li>테스트 실행</li>
<li>린트 검사</li>
<li>etc.</li>
</ol>
</li>
<li><strong>Git Hook의 종류 선택</strong><ol>
<li>pre-commit: git commit 전에 실행</li>
<li>commit-msg: 커밋 메시지 검증 ✅</li>
<li>pre-push: git push 전에 실행</li>
<li>pre-rebase: rebase 전에 실행</li>
<li>etc.</li>
</ol>
</li>
<li><strong>Hook 스크립트 작성</strong><ol>
<li>프로젝트 디렉토리에 Hook 스크립트를 작성 ✅</li>
<li>Python, Bash, Node.js 등을 사용</li>
</ol>
</li>
<li><strong>Git Hook 설정 파일 구성</strong>
기본적으로 Git Hook은 ./git/hooks 디렉토리에 저장<ol>
<li>스크립트를 ./git/hoooks 디렉토리에 직접 배치</li>
<li><code>pre-commit</code> 라이브러리를 사용해 쉽게 관리 ✅</li>
</ol>
</li>
</ol>
<h1 id="pre-commit-패키지">pre-commit 패키지</h1>
<hr>
<p>해당 리포지토리에서는 <code>pre-commit</code>을 사용하여 <strong>커밋 메시지 검증</strong>을 목적으로 한다.</p>
<ol>
<li><p><code>pre-commit</code>을 사용하는 경우 프로젝트 디렉토리 구조</p>
<pre><code class="language-markdown"> project
 ├── .git
 │     └── hooks
 │          └── commit-msg.sample
 │          └── pre-commit.sample
 │          └── pre-push.sample
 │          └── pre-rebase.sample
 │
 ├── .pre-commit-config.yaml
 │
 ├── scripts
 │     └── commit-msg-check.py
 │     └── ...
 └── ...</code></pre>
<ul>
<li><code>pre-commit</code> 라이브러리를 사용할 경우 <strong><code>.git/hooks</code></strong> 디렉토리는 따로 건드리지 않아도 되며,</li>
<li><em><code>scripts</code>*</em> 디렉토리와 <strong><code>.pre-commit-config.yaml</code></strong> 파일은 아래 플로우에 따라 자연스럽게 생성하게 된다.</li>
</ul>
</li>
<li><p><strong>pre-commit 설치</strong></p>
<pre><code class="language-bash"> pip install pre-commit</code></pre>
</li>
<li><p><strong>프로젝트 루트에 <code>.pre-commit-config.yaml</code>  파일 작성</strong></p>
<pre><code class="language-yaml"> repos:
 - repo: local
     hooks:
     - id: commit-msg-check
         name: Commit Message Check
         entry: python3 scripts/commit-msg-check.py
         language: system
         stages: [commit-msg]</code></pre>
</li>
<li><p><strong>프로젝트 루트에 <code>scripts</code> 디렉토리 생성</strong></p>
<pre><code class="language-bash"> bash mkdir scripts</code></pre>
</li>
<li><p><strong><code>scripts/commit-msg-check.py</code> 파일 작성</strong></p>
<pre><code class="language-python"> #!/usr/bin/env python3
 import re
 import sys

 # Git이 전달한 커밋 메시지 파일 경로 읽기
 commit_msg_filepath = sys.argv[1]

 # 커밋 메시지 파일의 내용을 읽음
 with open(commit_msg_filepath, &#39;r&#39;) as file:
     commit_msg = file.read().strip()

 print(f&quot;검사할 커밋 메시지: {commit_msg}&quot;)

 # 커밋 메시지 패턴 정의
 pattern = r&quot;^\[(feat|fix|docs|style|refactor|test|chore)\] .+ #[a-zA-Z0-9]+-[0-9]+$&quot;

 # 정규식 검증
 if not re.match(pattern, commit_msg):
     print(&quot;❌ 커밋 메시지가 컨벤션에 맞지 않습니다.&quot;)
     print(&quot;예시: [feat] 사용자 로그인 기능 추가 #PROJ-123&quot;)
     sys.exit(1)

 print(&quot;✅ 커밋 메시지가 컨벤션에 맞습니다.&quot;)
</code></pre>
<table>
<thead>
<tr>
<th>Type</th>
<th>의미</th>
<th>예시</th>
</tr>
</thead>
<tbody><tr>
<td><code>feat</code></td>
<td>새로운 기능 추가</td>
<td><code>feat: 사용자 프로필 기능 추가</code></td>
</tr>
<tr>
<td><code>fix</code></td>
<td>버그 수정</td>
<td><code>fix: 로그인 로직 버그 수정</code></td>
</tr>
<tr>
<td><code>docs</code></td>
<td>문서 수정</td>
<td><code>docs: README.md 업데이트</code></td>
</tr>
<tr>
<td><code>style</code></td>
<td>코드 스타일 변경 (기능에 영향 없음)</td>
<td><code>style: 파일 인덴트 정리</code></td>
</tr>
<tr>
<td><code>refactor</code></td>
<td>코드 리팩토링 (기능 변화 없음)</td>
<td><code>refactor: 불필요한 변수 제거</code></td>
</tr>
<tr>
<td><code>test</code></td>
<td>테스트 코드 추가, 수정</td>
<td><code>test: API 테스트 추가</code></td>
</tr>
<tr>
<td><code>chore</code></td>
<td>기타 작업 (설정 파일, 빌드 스크립트 등)</td>
<td><code>chore: 프로젝트 의존성 업데이트</code></td>
</tr>
</tbody></table>
</li>
<li><p><strong>Git Hook 활성화</strong></p>
<pre><code class="language-bash"> pre-commit install --hook-type commit-msg</code></pre>
</li>
<li><p><strong>테스트 및 디버깅</strong></p>
<ul>
<li><p>의도한 Hook이 제대로 동작하는지 테스트</p>
<pre><code class="language-bash">  # 지정한 패턴에 맞지 않는 메시지 
  git commit -m &quot;내 마음대로 커밋 메시지 작성&quot; 

  # ❌ 커밋 메시지가 컨벤션에 맞지 않습니다.
  # 예시: [feat] 사용자 로그인 기능 추가 #PROJ-123&quot;

  # 지정한 패턴에 맞는 메시지
  git commit -m &quot;[docs] README.md 파일 수정 (사용 방법 작성) #githook-02&quot;

  # passed </code></pre>
</li>
<li><p>필요하면 로그 출력 등을 추가해 디버깅</p>
</li>
</ul>
</li>
<li><p><strong>팀과 공유 (optional)</strong></p>
<ul>
<li><strong><code>.pre-commit-config.yaml</code></strong>과 관련 스크팁트를 저장소에 포함해 팀원에게 공윻</li>
<li>추가적으로 팀원들에게 pre-commit 설치 및 활성화 방법을 안내</li>
</ul>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Tableau] Chapter 04. 데이터 시각화 기본 차트, 무작정 따라 그리기 (2)]]></title>
            <link>https://velog.io/@ja_efan/Tableau-Chapter-04.-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%8B%9C%EA%B0%81%ED%99%94-%EA%B8%B0%EB%B3%B8-%EC%B0%A8%ED%8A%B8-%EB%AC%B4%EC%9E%91%EC%A0%95-%EB%94%B0%EB%9D%BC-%EA%B7%B8%EB%A6%AC%EA%B8%B0-2</link>
            <guid>https://velog.io/@ja_efan/Tableau-Chapter-04.-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%8B%9C%EA%B0%81%ED%99%94-%EA%B8%B0%EB%B3%B8-%EC%B0%A8%ED%8A%B8-%EB%AC%B4%EC%9E%91%EC%A0%95-%EB%94%B0%EB%9D%BC-%EA%B7%B8%EB%A6%AC%EA%B8%B0-2</guid>
            <pubDate>Sun, 29 Dec 2024 14:28:21 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>상관관계를 보여주는 스캐터 플롯, 분포를 나타내는 박스 플롯과 히스토그램, 
패턴을 찾아볼 수 있는 하이라이트 테이블을 그려보면서 태블로의 다양한 차트를 연습한다.</p>
</blockquote>
<h2 id="15-상관관계를-시각화하는-차트-스캐터-플롯">15. 상관관계를 시각화하는 차트, 스캐터 플롯</h2>
<ul>
<li>스캐터 플롯(scatter plot)은 X축과 Y축으로 구성된 평면에 점을 흩뿌리는 방식으로 데이터를 표현하는 차트로 ‘<strong>산점도</strong>’라고 부르기도 한다.</li>
<li>이전 차트들과 달리, 2개의 측정값을 한 화면에 올린 후 그 둘의 관계에 집중하는 표현 방식</li>
</ul>
<h3 id="스캐터-플롯-그리기">스캐터 플롯 그리기</h3>
<ol>
<li><p>첫 번째 측정값 선택</p>
<ol>
<li>Discount</li>
</ol>
</li>
<li><p>두 번째 측정값 선택</p>
<ol>
<li><p>계산된 필드 만들기</p>
 <img src = "https://velog.velcdn.com/images/ja_efan/post/b7d8ba6b-cdf3-4b60-9cf5-93e18eca3cfc/image.png" width=30%>


</li>
</ol>
</li>
</ol>
<pre><code>    &lt;img src = &quot;https://velog.velcdn.com/images/ja_efan/post/4a3d818d-18c8-43ce-bb9e-3417533026ab/image.png&quot; width=50%&gt;


    &lt;img src = &quot;https://velog.velcdn.com/images/ja_efan/post/bca9c273-51fa-4d22-bcca-84a7087e752d/image.png&quot; width=30%&gt;


2. Profit Ratio 선택

    &lt;img src = &quot;https://velog.velcdn.com/images/ja_efan/post/2ee4cb6d-8e61-456c-aa18-9985ff722450/image.png&quot; width=70%&gt;</code></pre><ol start="3">
<li><p>(필요시) [행과 열 바꾸기] </p>
 <img src = "https://velog.velcdn.com/images/ja_efan/post/2a8f36b8-eb5a-4f7c-9b5e-dba98e19dfa2/image.png" width=70%>


</li>
</ol>
<pre><code>+ Discount의 집계를 ‘평균’으로 변경

&lt;img src = &quot;https://velog.velcdn.com/images/ja_efan/post/da1ccbc0-38e8-4f2c-8c52-9365e79b8078/image.png&quot; width=70%&gt;


&lt;img src = &quot;https://velog.velcdn.com/images/ja_efan/post/787e63c2-29c6-4167-8db2-01ebb5f6654a/image.png&quot; width=30%&gt;</code></pre><ol start="4">
<li><p>분기하고자 하는 차원을 마크 카드의 [세부 정보]로 이동 </p>
<ol>
<li><p>Product Name 필드를 [세부 정보]로 이동</p>
<ol>
<li><p>4년동안 회사에서 판매한 물건의 할인율-수익률 관계를 제품 수준으로 분기 </p>
</li>
<li><p>제품 별 할인율에 따른 수익률 표현 </p>
<img src = "https://velog.velcdn.com/images/ja_efan/post/c026caf5-3427-471d-a558-cf13ea55c809/image.png" width=70%>


</li>
</ol>
</li>
</ol>
</li>
</ol>
<pre><code>2. 요약 수치 확인

    &lt;img src = &quot;https://velog.velcdn.com/images/ja_efan/post/11327775-78db-4d47-8660-4995a2dc5b59/image.png&quot; width=50%&gt;


    &lt;img src = &quot;https://velog.velcdn.com/images/ja_efan/post/c1c1daec-e668-4084-b41c-9a2cac53f89a/image.png&quot; width=50%&gt;


    (이렇게 기본 집계를 평균으로 선택하면 되는 듯)</code></pre><ol start="5">
<li><p>(필요시) 분석 패널을 선택한 후 추세선을 d&amp;d</p>
<p> 추세선(trend line) : 전체적인 경향과 두 측정 값의 관계를 가장 선명하게 보여주기 위한 표현</p>
<p> 다음 섹션에 계속</p>
</li>
</ol>
<h2 id="16-추세선-활용하기">16. 추세선 활용하기</h2>
<ul>
<li><p>추세선 선택</p>
  <img src = "https://velog.velcdn.com/images/ja_efan/post/8f845d18-59be-4347-9053-97e59bb56094/image.png" width=20%>


</li>
</ul>
<pre><code>&lt;img src = &quot;https://velog.velcdn.com/images/ja_efan/post/66090472-41f0-43d5-9729-36f9be5d63a1/image.png&quot; width=70%&gt;</code></pre><ul>
<li><p>추세선 tooltip</p>
  <img src = "https://velog.velcdn.com/images/ja_efan/post/89a9427c-f744-4073-af6d-93171460b524/image.png" width=50%>


</li>
</ul>
<pre><code>- 할인율이 1단위 증가할 때 수익률은 1.2 단위 낮아진다.

    → 고객에게 1% 추가 할인 제공 시 수익률이 1.2% 감소한다는 결과.

- **R2**과 **p-value** 확인 가능</code></pre><ul>
<li><p>추세선 편집</p>
<ul>
<li><p>다항식으로 수정</p>
  <img src = "https://velog.velcdn.com/images/ja_efan/post/293b33e7-328d-4489-b809-8c250c4bbb69/image.png" width=50%>


</li>
</ul>
</li>
</ul>
<pre><code>    &lt;img src = &quot;https://velog.velcdn.com/images/ja_efan/post/7b0a04b2-0a76-42f6-8cca-322d0efebbb3/image.png&quot; width=70%&gt;</code></pre><blockquote>
<p>❗ <strong>분석 패널의 추세선을 통해 그 관계를 더욱 선명히 드러낼 수 있다.</strong> </p>
</blockquote>
<h2 id="17-분포를-시각화하는-차트-1---박스-플롯">17. 분포를 시각화하는 차트 #1 - 박스 플롯</h2>
<ul>
<li>데이터 분석의 기본은 필드 내 값들의 분포를 파악하는 것 부터 시작된다.</li>
<li>필드가 가진 값들의 분포를 살펴보면서 현상을 이해하고 비정상적인 수치를 확인하는 것이 EDA의 핵심 과정</li>
<li>이 작업에 사용할 수 있는 차트가 <strong>박스 플롯(box plot)</strong>과 <strong>히스토그램</strong></li>
</ul>
<h3 id="박스-플롯-그리기">박스 플롯 그리기</h3>
<img src = "https://velog.velcdn.com/images/ja_efan/post/efc1e416-e2d1-42cf-8342-b912eba6d602/image.png" width=70%>


<ol>
<li>측정값(Score) 클릭</li>
<li>차원(Student ID)을 마크 카드의 [세부 정보]로 d&amp;d</li>
<li>차트 유형을 [원]으로 변경 </li>
<li>분석 패널로 이동 후 박스 플롯을 d&amp;d</li>
<li>마크 카드의 [크기] 선택 후 원 크기 조정</li>
</ol>
<h3 id="박스-플롯-뜯어보기">박스 플롯 뜯어보기</h3>
<img src = "https://velog.velcdn.com/images/ja_efan/post/764d2fb4-2df2-4e1d-b6e2-7b3b0fe7c639/image.png" width=40%>


<ul>
<li>데이터 포인트(원)</li>
<li>박스(box)와 수염(whisker)<ul>
<li>박스와 수염의 길이는 데이터의 분포에 따라 결정</li>
</ul>
</li>
<li>상한 (Q3 + 1.5*IQR)</li>
<li>Q3</li>
<li>Q2(중앙값)</li>
<li>Q1</li>
<li>하한 (Q1 - 1.5*IQR)<ul>
<li>IQR(Interqurtile Range, 사분범위): Q3 - Q1</li>
</ul>
</li>
<li>이상치(Outlier)<ul>
<li>상한 초과 or 하한 미만</li>
</ul>
</li>
</ul>
<h2 id="18-분포를-시각화하는-차트-2---히스토그램">18. 분포를 시각화하는 차트 #2 - 히스토그램</h2>
<ul>
<li>히스토그램(histogram)은 박스 플롯과 함께 분포를 시각화하는 차트</li>
<li>‘구간차원’이라는 바구니 안에 관측치를 담아서 바 차트 형태로 표현하는 시각화 기법</li>
</ul>
<h3 id="히스토그램-그리기-01">히스토그램 그리기 01</h3>
<img src= "https://velog.velcdn.com/images/ja_efan/post/f84acc5c-f4c7-476f-a31d-b29ea3c2d8d5/image.png" width=70%>


<ol>
<li>분석의 대상이 되는 측정값(Scores) 우클릭</li>
<li>팝업 메뉴에서 [만들기] → [구간차원] 클릭</li>
<li>구간 차원 크기를 5로 입력</li>
<li>생성된 구간차원을 열 선반 위로 d&amp;d</li>
<li>차원(Student ID)을 <code>option</code>키를 누른 채로 행 선반 위로 d&amp;d 후 [카운트(고유)] 집계 선택</li>
<li>(필요시) 열 선반 구간 차원을 우클릭 후 [연속형]으로 변환</li>
</ol>
<h3 id="히스토그램-그리기-02">히스토그램 그리기 02</h3>
<img src = "https://velog.velcdn.com/images/ja_efan/post/31a7fc2e-46dc-4008-93f2-8e656f8fc854/image.png" width=70%>


<ol>
<li>분석 대상이 되는 측정값(Scores) 선택</li>
<li>작업창 오른쪽 상단 [표현 방식] 클릭</li>
<li>[히스토그램] 선택</li>
<li>(필요시) 자동으 생성된 구간 차원을 우클릭 후 편집을 통해 크기 조정 </li>
</ol>
<ul>
<li>특정 필드의 값이 가운데 집중되어 있는지, 오른쪽으로 쏠려 있는지 (left-skewed), 왼쪽으로 쏠려 있는지 (right-skewed) 등을 쉽게 파악할 수 있음 (강점)</li>
<li>[퀵 테이블 계산]의 [구성 비율] 선택으로 구간 별 구성 비율을 파악 할 수 있다.</li>
</ul>
<img src = "https://velog.velcdn.com/images/ja_efan/post/7d0ffd94-cca9-4906-b3ad-b7ddb2146a9a/image.png" width=70%>


<img src = "https://velog.velcdn.com/images/ja_efan/post/1304f466-0cef-4c41-a85d-59adb4f70108/image.png" width=70%>


<h2 id="19-테이블을-직관적으로-표현하는-방식-하이라이트-테이블">19. 테이블을 직관적으로 표현하는 방식, 하이라이트 테이블</h2>
<ul>
<li>테이블 형식의 데이터 표현은 숫자 자체가 눈에 잘 들어오지 않는다는 단점이 명확</li>
<li>하이라이트 테이블(highlight table)은 여러 개의 숫자가 하나의 테이블 속에서 복잡하게 나타날 때 색상을 통해 어디가 높고 어디가 낮은지를 한 눈에 보여준다.</li>
</ul>
<h3 id="하이라이트-테이블-그리기-01-정공법">하이라이트 테이블 그리기 01 (정공법)</h3>
<img src = "https://velog.velcdn.com/images/ja_efan/post/7e615e68-20d7-4293-b0cf-d99283c6c9e0/image.png" width=70%>


<ol>
<li>원하는 차원을 행 또는 열 선반에 d&amp;d: <strong>테이블의 틀 구성</strong></li>
<li>측정값을 마크 카드의 [레이블]위에 d&amp;d: <strong>테이블 완성</strong></li>
<li>앞서와 동일한 측정값을 마크 카드의 [색상]위에 d&amp;d</li>
<li>마크 카드에서 차트 유형을 [사각형]으로 변경 </li>
</ol>
<h3 id="하이라이트-테이블-그리기-02-빌트인-차트-이용">하이라이트 테이블 그리기 02 (빌트인 차트 이용)</h3>
<img src = "https://velog.velcdn.com/images/ja_efan/post/977e3bae-7f2d-4d94-af9c-e2bd749ef8ce/image.png" width=70%>


<ol>
<li><p>표현하기 원하는 측정값을 선택</p>
</li>
<li><p>테이블 구성에 필요한 모든 차원을 cmd 키를 누른 채로 선택</p>
</li>
<li><p>태블로 작업창 오른쪽 상단 [표현 방식] 선택</p>
</li>
<li><p>표현 방식 오른쪽 상단 [하이라이트 테이블] 선택</p>
</li>
<li><p>(추가) 분석 패널 → [요약] → [총계] d&amp;d</p>
 <img src = "https://velog.velcdn.com/images/ja_efan/post/90525dbf-68ec-4145-a878-ed2b4439fa0e/image.png" width=70%>


</li>
</ol>
<ol start="6">
<li><p>(추가) Address Region 필드를 Address SD 앞에 추가 후 [총계]를 [소계] 위로 d&amp;d</p>
 <img src = "https://velog.velcdn.com/images/ja_efan/post/d468181a-3da4-46d3-9ca2-07e260270768/image.png" width=70%>


</li>
</ol>
<pre><code>- 소계는 행 또는 열이 2개 이상의 차원으로 나뉘어 있을 때 만들 수 있는 부분합 개념</code></pre><blockquote>
<p>❗<strong>소계는 행 또는 열이 2개 이상의 차원으로 나뉘어 있을 때 만들 수 있는 부분합 개념</strong></p>
</blockquote>
<h3 id="2개-이상의-측정값으로-하이라이트-테이블-만들기">2개 이상의 측정값으로 하이라이트 테이블 만들기</h3>
<img src = "https://velog.velcdn.com/images/ja_efan/post/38624e9e-d145-4aee-8b43-e6b1aa70e74d/image.png" width=70%>


<ol>
<li><p>원하는 차원을 행 또는 열로 d&amp;d (테이블 틀 구성)</p>
</li>
<li><p>첫 번째 측정값을 마크 카드의 [레이블]위로 d&amp;d</p>
</li>
<li><p>두 번째 측정값을 화면 안쪽 첫 번째 측정값이 표기된 숫자 위로 d&amp;d</p>
</li>
<li><p>(필요시) 세 번째 측정 값을 두 번째 측정값과 동일한 방식으로 d&amp;d</p>
</li>
<li><p>마크 카드의 [텍스트]에 있는 ‘측정값’ 필드를 cmd 키를 누른 채로 마크 카드의 [색상]위로 복제 </p>
</li>
<li><p>차트 유형을 [사각형]으로 변경</p>
</li>
<li><p>(추가) 각 측정 값에 대하여 서로 다른 색상 체계 적용 </p>
<ol>
<li><p>[색상]에 올라간 ‘측정값’ 필드 우클릭 후 [별도의 범례 사용] 선택 </p>
</li>
<li><p>색상 지정 가능</p>
<img src = "https://velog.velcdn.com/images/ja_efan/post/77e55e50-6a47-4f3b-8823-3e87af6b49f3/image.png" width=70%>



</li>
</ol>
</li>
</ol>
<h3 id="하이라이트-테이블을-통한-패턴-찾기">하이라이트 테이블을 통한 패턴 찾기</h3>
<ul>
<li>하이라이트 테이블을 활용하여 패턴을 확인할 수 있다.</li>
<li>‘패턴을 찾는다’ 는 것은 어떠한 경향성을 찾아서 일반화하고 이를 기반으로 예측하고 의사결정을 하는 데이터 분석의 본질과 맞닿아 있다.</li>
<li>대표적인 하이라이트 테이블 예시 → 깃허브 잔디</li>
</ul>
</br>

<blockquote>
<p><strong>어디로?태블로!</strong> 스터디
<strong>Let&#39;s 태블로, 쉽게 따라하는 데이터 시각화</strong>, 최정민, 류지호, 생능북스</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Tableau] Chapter 03. 데이터 시각화 기본 차트, 무작정 따라 그리기 (1)]]></title>
            <link>https://velog.io/@ja_efan/Chapter-03.-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%8B%9C%EA%B0%81%ED%99%94-%EA%B8%B0%EB%B3%B8-%EC%B0%A8%ED%8A%B8-%EB%AC%B4%EC%9E%91%EC%A0%95-%EB%94%B0%EB%9D%BC-%EA%B7%B8%EB%A6%AC%EA%B8%B0-1</link>
            <guid>https://velog.io/@ja_efan/Chapter-03.-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%8B%9C%EA%B0%81%ED%99%94-%EA%B8%B0%EB%B3%B8-%EC%B0%A8%ED%8A%B8-%EB%AC%B4%EC%9E%91%EC%A0%95-%EB%94%B0%EB%9D%BC-%EA%B7%B8%EB%A6%AC%EA%B8%B0-1</guid>
            <pubDate>Thu, 26 Dec 2024 07:01:17 GMT</pubDate>
            <description><![CDATA[<h2 id="08-필드를-시트-위에-올리는-방법">08. 필드를 시트 위에 올리는 방법</h2>
<ul>
<li>드래그 앤 드롭을 활용하여 필드를 원하는 위치로 가져가면 데이터가 표현된다.</li>
<li>태블로에서 필드의 위치를 옮겨 화면을 만들어 가는 방식을 간단히 줄여 ‘<strong>drag &amp; drop</strong>’이라고 한다.</li>
</ul>
<img src="https://velog.velcdn.com/images/ja_efan/post/8c35400b-8156-4822-8958-0a8127e1aecf/image.png" width=70%>


<img src ="https://velog.velcdn.com/images/ja_efan/post/5f74932d-0b66-4dce-a69a-0826a78c5c91/image.png" width=70%>


<img src = "https://velog.velcdn.com/images/ja_efan/post/3855346d-83d3-45a4-b158-477093a6d7c4/image.png" width=70%>


<h2 id="09-데이터-시각화-기본-차트-1---바-차트">09. 데이터 시각화 기본 차트 #1 - 바 차트</h2>
<ul>
<li>바 차트(bar chart)는 모든 데이터 표현 방식 중 가장 기본이 되는 차트이다.</li>
<li>바 차트는 막대의 길이를 통해 대상의 크기를 표현</li>
</ul>
<h3 id="바-차트-그리기"><strong>바 차트 그리기</strong></h3>
<ol>
<li><p>표현하기 원하는 측정값(sales)을 더블클릭</p>
 <img src ="https://velog.velcdn.com/images/ja_efan/post/fa7166c7-4d26-404f-94d0-95090f52fb2b/image.png" width=70%>



</li>
</ol>
<ol start="2">
<li><p>바 차트를 분기할 차원(product category)을 더블클릭 </p>
 <img src= "https://velog.velcdn.com/images/ja_efan/post/2a8e187b-20d1-4615-a5e4-11bcf055ec43/image.png" width=70%>


</li>
</ol>
<ol start="3">
<li><p>가로 방향 바 차트를 만드는 경우 상단의 [행과 열 바꾸기] 클릭 </p>
 <img src= "https://velog.velcdn.com/images/ja_efan/post/0855a80d-f9fc-4397-ac68-cbbc0cf85dfc/image.png" width=70%>


</li>
</ol>
<ol start="4">
<li><p>상단의 [마크 레이블 표시] 클릭</p>
 <img src ="https://velog.velcdn.com/images/ja_efan/post/db4d3bc8-2e2a-4229-abce-e2504fba63e6/image.png" width=70%>



</li>
</ol>
<h3 id="반드시-확인해야-하는-두-가지-사실">반드시 확인해야 하는 두 가지 사실</h3>
<ul>
<li><p>sales 필드를 선택했을 뿐인데 행 선반에는 ‘합계(sales)’가 보임</p>
</li>
<li><p>Why?</p>
<ul>
<li>태블로는 전체를 먼저 보여줌(엑셀과의 차이점)</li>
<li>태블로는 기본적으로 집계를 통해 측정값을 표현</li>
<li>사용자가 sales 필드를 행 또는 열 선반에 가져다 놓으면 
<code>SELECT SUM(sales) FROM orders;</code> 쿼리가 실행되고 그 결과가 표현 됨</li>
<li><strong>‘태블로는 항상 집계한다.’</strong></li>
</ul>
</li>
<li><p>집계는 항상 합계인가? NO</p>
<ul>
<li><p>다양한 집계 값을 선택 가능 (기본값은 <strong>합계</strong>)</p>
  <img src= "https://velog.velcdn.com/images/ja_efan/post/35788538-1711-4cae-bdf8-5ce3c8e5d7ef/image.png" width=30%>



</li>
</ul>
</li>
</ul>
<h2 id="10-마크-카드-활용하기">10. 마크 카드 활용하기</h2>
<img src= "https://velog.velcdn.com/images/ja_efan/post/e276a2d6-b7cf-4425-bed8-39822f0ced97/image.png" width=30%>


<ul>
<li><p><strong>색상</strong></p>
<ul>
<li><p>기본</p>
<img src= "https://velog.velcdn.com/images/ja_efan/post/727e0b3b-af0a-44ed-a460-83fd214e2acb/image.png" width=70%>


</li>
</ul>
</li>
</ul>
<pre><code>- 불연속형 데이터 색상 → 알록달록한 다양한 색상

&lt;img src=&quot;https://velog.velcdn.com/images/ja_efan/post/d9047a86-e127-42c7-a69b-a907c6823d5a/image.png&quot; width=70%&gt;


- 연속형 데이터 색상 추가 → 그라데이션

&lt;img src=&quot;https://velog.velcdn.com/images/ja_efan/post/96325222-5d00-49e8-b73e-5d07c64c0cf3/image.png&quot; width=70%&gt;</code></pre><ul>
<li><p><strong>크기</strong></p>
  <img src="https://velog.velcdn.com/images/ja_efan/post/ddee7925-7800-404b-a539-f3660bdd236a/image.png" width=70%>


</li>
</ul>
<ul>
<li><p><strong>레이블</strong></p>
<ul>
<li><p>[마크 레이블 표시] 와 동일한 효과</p>
</li>
<li><p>다만, 조금 더 세밀한 설정이 가능</p>
<img src="https://velog.velcdn.com/images/ja_efan/post/04a64a6f-69b7-4140-87e3-612adf16d2d3/image.png" width=70%>


</li>
</ul>
</li>
</ul>
<pre><code>기본 레이블 설정

&lt;img src=&quot;https://velog.velcdn.com/images/ja_efan/post/6c3c014a-65bd-4488-8eec-167879c4997d/image.png&quot; width=70%&gt;


커스텀 레이블 설정</code></pre><ul>
<li><p><strong>세부 정보</strong></p>
<ul>
<li><p>추가적인 필드로 화면을 나누고 싶은데, 색상, 크기, 레이블 등을 표시하고 싶지 않거나 표현할 필요가 없는 경우 사용</p>
<img src="https://velog.velcdn.com/images/ja_efan/post/30852e7c-1344-40cc-81d6-75b1a5873ce4/image.png" width=70%>


</li>
</ul>
</li>
</ul>
<pre><code>Customer Segment 필드를 ‘세부 정보’에 올린 경우 

&lt;img src=&quot;https://velog.velcdn.com/images/ja_efan/post/14058774-3ded-4c30-83f8-46c4beefc5af/image.png&quot; width=70%&gt;


Customer Segment 필드를 ‘색상’에 올린 경우 </code></pre><ul>
<li><p><strong>도구 설명</strong></p>
<ul>
<li><p>화면에 표현되는 것에는 변화가 없지만, 차트 위에 마우스를 올리면 작은 정보 상자(tooltip)에 추가 정보가 나타남</p>
</li>
<li><p>독자에게 조금 더 자세한 정보를 제공하는 경우 사용</p>
<img src="https://velog.velcdn.com/images/ja_efan/post/b89d93a1-f1ac-48d3-a25b-ef93fdafdc20/image.png" width=50%>


</li>
</ul>
</li>
</ul>
<pre><code>시도별 매출에 Profit 필드를 도구 설명에 추가</code></pre><h2 id="11-데이터-시각화-기본-차트-2---라인-차트">11. 데이터 시각화 기본 차트 #2 - 라인 차트</h2>
<ul>
<li>바 차트와 함께 비즈니스 대시보드에서 가장 많이 활용되는 차트</li>
<li>시계열 흐름을 표현할 때 라인 차트를 활용하는 것이 일반적</li>
</ul>
<h3 id="라인-차트-그리기"><strong>라인 차트 그리기</strong></h3>
<img src="https://velog.velcdn.com/images/ja_efan/post/553be642-f69c-40f7-a1f1-596fededc08b/image.png" width=70%>


<ol>
<li>표현하려는 측정값(Sales)을 더블 클릭</li>
<li>바 차트를 분기해줄 날짜 차원 필드(Order Date) 더블 클릭 </li>
<li>상단 [마크 레이블 표시] 클릭</li>
</ol>
<ul>
<li><p><strong>태블로가 두 필드의 데이터에 따라 더 나은 표현 방식으로 데이터를 표현 해줌</strong></p>
<ul>
<li><p>마음에 들지 않으면 변경 가능 (라인 차트 → 바 차트)</p>
  <img src="https://velog.velcdn.com/images/ja_efan/post/1760de0d-11c5-4e18-9c72-bca2eb350668/image.png" width=70%>


</li>
</ul>
</li>
</ul>
<ul>
<li><p>드릴다운 (Drilldown)</p>
<ul>
<li><p>계층 구조에서 세부 수준으로 내려가는 것</p>
</li>
<li><p>필드 앞 <strong>[+]</strong> 기호</p>
</li>
<li><p>ex. 대표적으로 <strong>날짜 관련 필드</strong>: 년 → 분기 → 월 → …</p>
<img src="https://velog.velcdn.com/images/ja_efan/post/3c35562e-f1c4-4be0-a51c-c14e823f23d3/image.png" width=70%>


</li>
</ul>
</li>
</ul>
<pre><code>&lt;img src=&quot;https://velog.velcdn.com/images/ja_efan/post/330e1b53-69bc-46ce-8a85-ae560540d52a/image.png&quot; width=70%&gt;


- 드릴다운으로 월 필드까지 생성 후 라인차트를 연속형으로 구성

&lt;img src=&quot;https://velog.velcdn.com/images/ja_efan/post/18a5b559-29ee-4dd8-bfdf-cec7a634066b/image.png&quot; width=70%&gt;</code></pre><h2 id="12-라인-차트-vs-영역-차트">12. 라인 차트 vs. 영역 차트</h2>
<ul>
<li>영역 차트(area chart) 또한 라인 차트와 마찬가지로 시간의 흐름에 따른 측정값 변화를 살펴보기에 적합</li>
<li>라인 차트는 단순히 포인트를 연결하는 방식, 영역 차트는 포인트 연결 후 아래 영역을 모두 채움</li>
</ul>
<h3 id="영역-차트-그리기"><strong>영역 차트 그리기</strong></h3>
<img src = "https://velog.velcdn.com/images/ja_efan/post/3e7dcbdc-fcf3-49ca-b7a0-1e01f5ed4719/image.png" width=70%>


<ol>
<li><p>라인 차트를 그린다.</p>
</li>
<li><p>마크 카드의 드롭다운 메뉴에서 차트 유형을 [영역]으로 변경</p>
 <img src = "https://velog.velcdn.com/images/ja_efan/post/37df3156-8517-4f58-8c68-e17e413f7566/image.png" width=30%>


</li>
</ol>
<ul>
<li>영역 차트는 카테고리 별 항목의 추이를 쉽고 빠르게 확인 가능</li>
<li>라인 차트 만큼 선명하지는 않음</li>
</ul>
<img src="https://velog.velcdn.com/images/ja_efan/post/89579e35-83ee-4dc7-b3fb-7a788f886577/image.png" width=70%>


<img src="https://velog.velcdn.com/images/ja_efan/post/fa292b74-64b3-45ab-8f03-8bb1726c1727/image.png" width=70%>


<ul>
<li>태블로의 영역 차트는 기본적으로 카테고리 별 값을 모두 누적하여 표현 → 누적하지 않은 영역 차트 가능</li>
</ul>
<img src = "https://velog.velcdn.com/images/ja_efan/post/eed9fda6-73ac-42e3-9c1b-89c3eb123da9/image.png" width=30%>


<img src="https://velog.velcdn.com/images/ja_efan/post/b0630190-e747-44df-9e8b-8128b6d3a4ee/image.png" width=70%>


<h2 id="13-데이터-시각화-기본-차트-3---파이-차트">13. 데이터 시각화 기본 차트 #3 - 파이 차트</h2>
<ul>
<li>파이 차트(pie chart)는 각 항목이 전체의 몇 %를 차지하고 있는지, 구성 비율을 살펴보는 차트</li>
</ul>
<h3 id="파이-차트-그리기-i">파이 차트 그리기 I</h3>
<img src="https://velog.velcdn.com/images/ja_efan/post/a783d53f-2144-4920-962c-56e06744c715/image.png" width=70%>


<ol>
<li><p>표현하기 원하는 측정값(Sales) 더블 클릭 </p>
</li>
<li><p>바 차트를 분기해줄 차원(Customer Segment)을 마크 카드의 [색상]으로 이동 </p>
</li>
<li><p>차트 유형을 [파이 차트]로 변경</p>
</li>
<li><p>행 선반의 집계된 측정값을 마크 카드의 [각도]로 이동</p>
</li>
<li><p>[마크 레이블 표시]</p>
</li>
<li><p>[퀵 테이블 계산] → [구성 비율]</p>
 <img src="https://velog.velcdn.com/images/ja_efan/post/0866d6cb-ff54-4d77-bc0d-1321107f4a91/image.png" width=50%>


</li>
</ol>
<pre><code>&lt;img src=&quot;https://velog.velcdn.com/images/ja_efan/post/44dc3cf1-17fa-4ad8-a0af-2b6144cccd53/image.png&quot; width=70%&gt;</code></pre><blockquote>
<p>❗ <strong>‘테이블 계산’</strong>은 태블로가 제공하는 4가지 계산 방법 중 하나.
작동하는 원리가 복잡하고 어려우므로 완벽한 이해가 쉽지 않다.
<strong>→ 잘 쓰기만 하자.</strong></p>
</blockquote>
<h2 id="14-파이-차트는-좋은-데이터-시각화-방식이-아니다">14. 파이 차트는 좋은 데이터 시각화 방식이 아니다?</h2>
<ul>
<li>파이 차트로 데이터를 표현하는 방식이 사람들에게 직관적으로 다가오지 않는다. (의견)<ul>
<li>사람의 눈이 ‘각도’라는 시각적 요소의 크고 작음을 인식하는 것에 적합하지 않다.</li>
<li>카테고리 별 구성 비율이 비슷하다면 파이 차트로는 직관적인 구분이 가지 않는다.</li>
<li>반면, 바 차트의 경우 직관적으로 길고 짧음의 차이로 인해 직관적인 구분이 가능하다.</li>
</ul>
</li>
</ul>
<h3 id="대체-시각화-표현">대체 시각화 표현</h3>
<ul>
<li><p><strong>트리맵(tree map)</strong></p>
  <img src="https://velog.velcdn.com/images/ja_efan/post/30db3fb3-826d-4d0b-938e-086ea7810b8a/image.png" width=70%>


</li>
</ul>
<pre><code>- 파이 차트의 한계를 근본적으로 극복하지 못함
    - ‘넓이’ 또한 사람의 눈으로 직관으로 인식되지 않음
    - 구성 비율이 낮은 항목은 적절한 표현이 되지 않음 (일부 히든 레이블)
    - 음수에 대한 개념이 없음 → 음수 값이 존재하는 측정값 사용 불가</code></pre><ul>
<li><p><strong>바 차트</strong></p>
  <img src="https://velog.velcdn.com/images/ja_efan/post/c38f77a9-d1f2-402e-8537-d353b7f95ae2/image.png" width=70%>


</li>
</ul>
<pre><code>- 바 차트 구성 후 구성 비율을 적용하여 비율을 보여주는 방식
- 많이 사용하는 데에는 그만한 이유가 다 있다.</code></pre><ul>
<li><strong>도넛 차트</strong><ul>
<li>가운데 적절한 숫자를 넣어 각도 만으로 인식하기 어려운 수치를 텍스트로 표현 가능</li>
<li>Chapter 9 에서 실습</li>
</ul>
</li>
</ul>
<blockquote>
<p><strong>어디로?태블로!</strong> 스터디
<strong>Let&#39;s 태블로, 쉽게 따라하는 데이터 시각화</strong>, 최정민, 류지호, 생능북스</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Tableau] Chapter 02. 태블로는 어떤 도구인가요?]]></title>
            <link>https://velog.io/@ja_efan/Tableau-Chapter-02.-%ED%83%9C%EB%B8%94%EB%A1%9C%EB%8A%94-%EC%96%B4%EB%96%A4-%EB%8F%84%EA%B5%AC%EC%9D%B8%EA%B0%80%EC%9A%94</link>
            <guid>https://velog.io/@ja_efan/Tableau-Chapter-02.-%ED%83%9C%EB%B8%94%EB%A1%9C%EB%8A%94-%EC%96%B4%EB%96%A4-%EB%8F%84%EA%B5%AC%EC%9D%B8%EA%B0%80%EC%9A%94</guid>
            <pubDate>Mon, 23 Dec 2024 00:32:16 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h3 id="학습목표">학습목표</h3>
<p><strong>태블로의 다양한 제품들이 어떻게 연계되어 활용되는지 이해한다.
데이터 연결창 - 데이터 준비창 - 데이터 작업창으로 이어지는 태블로의 인터페이스를 둘러보고, 각 창에서 진행되는 핵심적인 작업이 무엇인지 살펴본다.
태블로와 엑셀의 차이점을 비교하며, 각 도구가 가지는 특성과 장단점을 파악한다.</strong></p>
</blockquote>
<h2 id="04-태블로-제품군에-대한-이해">04. 태블로 제품군에 대한 이해</h2>
<h3 id="데이터-전처리-태블로-프렙-빌더">데이터 전처리: 태블로 프렙 빌더</h3>
<ol>
<li><strong>데이터 정제 작업(Data Cleaning)</strong><ul>
<li>온전한 분석 결과를 얻기 위해서는 질 높은 데이터가 필요</li>
<li>다양한 이유로 불완전한 모습을 보이는 데이터를 보완하고 정리</li>
</ul>
</li>
<li><strong>데이터 구성 작업(Data Composition)</strong><ul>
<li>데이터 분석 시 다수의 테이블에서 정보를 가져와야 하는 경우가 존재</li>
<li>테이블을 결합하여 가져오는 작업 수행</li>
</ul>
</li>
</ol>
<h3 id="데이터-시각화-태블로-데스크탑-프로페셔널과-태블로-데스크탑-퍼블릭">데이터 시각화: 태블로 데스크탑 프로페셔널과 태블로 데스크탑 퍼블릭</h3>
<ul>
<li><p>프렙 빌더로 준비된 데이터를 태블로 데스크탑 위로 올려서 분석 화면을 구성</p>
<p>  <strong>→ 태블로 데스크탑: 데이터를 불러와 시각화 화면을 구성하는 역할</strong> </p>
</li>
<li><p>프로페셔널 vs. 퍼블릭</p>
<ul>
<li>일반적으로 <strong>프로페셔널 → 기업</strong> / <strong>퍼블릭 → 개인</strong> 이 주로 사용</li>
<li>퍼블릭 버전은 서버 데이터 연결을 지원하지 않음</li>
<li><del>퍼블릭 버전은 로컬 PC에 작업 결과물 저장 불가</del> 
(2024.1.2 버전부터 지원하는 듯 하다.)<pre><code> &lt;img src=&quot;https://velog.velcdn.com/images/ja_efan/post/3e31f3b4-15df-4bed-a586-d039cdf03cf8/image.png&quot; widht=30%&gt; </code></pre></li>
<li>이 외에도 기능적인 차이가 존재하지만 데이터 시각화 화면을 구성은 퍼블릭으로도 충분</li>
</ul>
</li>
</ul>
<h3 id="시각화-결과-공유-태블로-서버클라우드-태블로-퍼블릭-태블로-리더">시각화 결과 공유: 태블로 서버(클라우드), 태블로 퍼블릭, 태블로 리더</h3>
<ul>
<li>태블로 데스크탑으로 분석 시각화 화면 구성 완료 → ‘공유’</li>
<li>태블로 서버(클라우드) vs. 태블로 퍼블릭 vs. 태블로 리더<ul>
<li><strong>태블로 서버(Tableau Server)와 태블로 클라우드(Tableau Cloud)</strong><ul>
<li>닫힌 플랫폼 (closed platform)</li>
<li>태블로 데스크탑에서 활용한 데이터셋과 분석 화면을 공유하는 플랫폼</li>
<li>공유의 범위를 사용자의 속성에 따라 제어 가능</li>
</ul>
</li>
<li><strong>태블로 퍼블릭(Tableau Public)</strong><ul>
<li>열린 플랫폼(open platform)</li>
<li>태블로 데스크탑 퍼블릭 버전의 유일한 공유 플랫폼</li>
</ul>
</li>
<li><strong>태블로 리더(Tableau Reader)</strong><ul>
<li>태블로 워크북 파일을 열어서 내용을 확인할 수 있는 프로그램</li>
<li>화면 편집, 설정 수정 및 편집 작업 불가능</li>
<li>likes Acrobat Reader</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="05-태블로-데스크탑-설치">05. 태블로 데스크탑 설치</h2>
<p><del>학생용 라이선스 (프로페셔널 1년 제공)</del>
<del><a href="https://www.tableau.com/ko-kr/academic/students">https://www.tableau.com/ko-kr/academic/students</a></del> 
<del>본인은 졸업생이라 인증이 되지 않는다..</del></p>
<p><strong>태블로 데스크탑 퍼블릭</strong></p>
<p><a href="https://public.tableau.com/app/discover">https://public.tableau.com/app/discover</a></p>
<p>step 01. 계정 생성</p>
<p>step 02. 로그인 </p>
<p>step 03. Tableau Desktop Public Edition 다운로드 및 설치 
<img src= "https://velog.velcdn.com/images/ja_efan/post/f2247f08-b25c-4c82-b7c2-48e6819e2d0f/image.png" width=70%> 
<img src = "https://velog.velcdn.com/images/ja_efan/post/9928ee0e-1c42-4a8f-8b90-7b3093bb2b03/image.png" width=70%>
<img src = "https://velog.velcdn.com/images/ja_efan/post/536761f7-e91e-4ce5-a895-f10ea6b8f078/image.png" width=70%></p>
<h2 id="06-태블로-인터페이스-소개">06. 태블로 인터페이스 소개</h2>
<h3 id="데이터-연결창-시작-페이지">데이터 연결창 (시작 페이지)</h3>
<img src = "https://velog.velcdn.com/images/ja_efan/post/f325a6e6-c496-4313-8825-0963c4a45ce0/image.png" width =70%>


<ul>
<li>왼쪽 파란색 배경 부분에 데이터를 연결할 수 있는 다양한 커넥터(Connector)<ul>
<li>퍼블릭 버전이기 때문에 서버 커넥터가 단촐</li>
</ul>
</li>
<li>가운데 부분에 과거 워크북 히스토리</li>
<li>오른쪽 부분에는 각종 리소스와 최신 정보 포함</li>
</ul>
<h3 id="데이터-준비창-데이터-원본-페이지">데이터 준비창 (데이터 원본 페이지)</h3>
<ul>
<li><p>보조자료의 <strong><em>Superstore KR - VizLab 2022.xlsx</em></strong> 연결</p>
  <img src = "https://velog.velcdn.com/images/ja_efan/post/c628343e-c252-464b-bc92-8177a34fd434/image.png" width=70%>

<ul>
<li><p><strong><em>Orders</em></strong> 시트 드래그 앤 드롭</p>
<ul>
<li>하단에 데이터 미리보기<ul>
<li>데이터 필드 속성</li>
<li>샘플 데이터 100개 확인 가능</li>
<li>데이터 수정 불가 (태블로 원칙, 어떤 경우에도 데이터 원본을 건드리지 않음)</li>
</ul>
</li>
</ul>
<img src = "https://velog.velcdn.com/images/ja_efan/post/1d7795db-0093-4e3c-8547-bd283e303e20/image.png" width=70%>


</li>
</ul>
</li>
</ul>
<ul>
<li><p>보조자료의 <strong><em>2022년 06월 교통카드통계자료.xls</em></strong> 연결</p>
<ul>
<li><p>지하철 시간대별 이용현황 시트 드래그 앤 드롭</p>
<img src = "https://velog.velcdn.com/images/ja_efan/post/c8e025ef-f0eb-4945-a927-e7f8e50f8de6/image.png" width=70%>


</li>
</ul>
</li>
</ul>
<pre><code>- ‘데이터 해석기’ 확인 가능
    - 데이터 해석기
        - 엑셀과 텍스트 파일 같은 파일 형식의 데이터 원본을 불러올 경우 사용할 수 있는 기능
        - 태블로 친화적(Tableau-friendly)이지 않은 데이터를 태블로 분석이 용이한 태블로 친화적인 형식으로 변경

            &lt;img src = &quot;https://velog.velcdn.com/images/ja_efan/post/2cbff394-373b-402f-bb8b-4c79f25d3481/image.png&quot; width=70%&gt;


            필드명 구조가 일정하지 않음 

            &lt;img src = &quot;https://velog.velcdn.com/images/ja_efan/post/f49da459-c647-4a98-b63a-f62810cdb8ac/image.png&quot; width=70%&gt;


            데이터 구조를 정화하게 파악하지 못함 

            &lt;img src = &quot;https://velog.velcdn.com/images/ja_efan/post/cca2c2ea-ccdd-4a39-89fc-595b6185fef9/image.png&quot; width=50%&gt;


            데이터 해석기 사용

            &lt;img src = &quot;https://velog.velcdn.com/images/ja_efan/post/c137cb94-ea93-417a-a062-53e3681e81b8/image.png&quot; width=70%&gt;


            데이터 해석기 사용 후 데이터 구조 파악 완료</code></pre><ul>
<li>데이터 연결 (라이브 / 추출) 관련 내용은 태블로 데스크탑 퍼블릭 버전에서 지원하지 않음<ul>
<li>간단히 말하자면, 데이터와의 연결을 라이브(실제 원본 데이터 기준)으로 하느냐, 추출한 데이터(사본)로 하느냐를 선택</li>
</ul>
</li>
</ul>
<h3 id="데이터-작업창-작업-영역">데이터 작업창 (작업 영역)</h3>
<ul>
<li><p>실질적인 시각화 작업이 이루어지는 공간</p>
</li>
<li><p>좌측 하단의 <code>시트 1</code>을 눌러 작업창으로 이동</p>
  <img sr c= "https://velog.velcdn.com/images/ja_efan/post/a42fda15-fdbb-4fcc-9151-3844232b2de8/image.png" width=70%>



</li>
</ul>
<h2 id="07-태블로-vs-엑셀">07. 태블로 vs. 엑셀</h2>
<p><strong>태블로</strong> </p>
<ul>
<li>데이터 시각화 도구</li>
</ul>
<p><strong>엑셀</strong></p>
<ul>
<li>스프레드시트(spreadsheet)</li>
<li>데이터 원본 그 자체</li>
</ul>
<p>본질적인 차이점 </p>
<ol>
<li>데이터 표현 방식 <ol>
<li>엑셀: <strong>테이블</strong> 형식의 데이터 표현 </li>
<li>태블로: <strong>차트</strong> 형식의 데이터 표현 </li>
</ol>
</li>
<li>데이터 편집 가능성 <ol>
<li>엑셀: 데이터 <strong>편집 가능</strong> </li>
<li>태블로: 데이터 <strong>편집 불가</strong></li>
</ol>
</li>
<li>계산 수행 방식 <ol>
<li>엑셀: 값을 <strong>있는 그대로 표현</strong> </li>
<li>태블로: 숫자를 <strong>집계해서 요약</strong>  </li>
</ol>
</li>
</ol>
<blockquote>
<p>❗ <strong>Tableau aggregate always.</strong></p>
</blockquote>
<blockquote>
<p><strong>어디로?태블로!</strong> 스터디
<strong>Let&#39;s 태블로, 쉽게 따라하는 데이터 시각화</strong>, 최정민, 류지호, 생능북스</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Tableau] Chapter01. 데이터 시각화는 무엇인가요?]]></title>
            <link>https://velog.io/@ja_efan/Tableau-Chapter01.-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%8B%9C%EA%B0%81%ED%99%94%EB%8A%94-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80%EC%9A%94</link>
            <guid>https://velog.io/@ja_efan/Tableau-Chapter01.-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%8B%9C%EA%B0%81%ED%99%94%EB%8A%94-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80%EC%9A%94</guid>
            <pubDate>Sun, 22 Dec 2024 14:45:44 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h3 id="학습-목표">학습 목표</h3>
<p><strong>데이터 시각화의 개념을 이해 
데이터 시각화의 목적과 시각화 전략에 대해 학습</strong></p>
</blockquote>
<h2 id="01-데이터-시각화-개념">01. 데이터 시각화 개념</h2>
<hr>
<p>학술적 의미의 <strong>데이터 시각화</strong> </p>
<ul>
<li>데이터에 숨어 있는 중요한 정보를 사람의 시각인지 뇌 신경계가 쉽게 찾아낼 수 있도록 데이터 표현 형식을 바꾸는 것</li>
</ul>
<p>→ 인간의 본능적 시각 속성 (preattentive attributes)을 극대화하는 것</p>
<p><strong>Data literacy:</strong> 데이터에서 중요한 의미를 발견하는 능력</p>
<p>⇒ <strong>데이터를 더 잘 읽을 수 있게 하고, 그 의미가 제대로 전달될 수 있도록 하기 위한 핵심 역량</strong>이 데이터 시각화</p>
<h2 id="02-데이터-시각화의-필요성과-역할">02. 데이터 시각화의 필요성과 역할</h2>
<hr>
<p>데이터는 4차 산업혁명의 핵심이자 가치 창출을 위한 리소스 </p>
<p>향후 기업 활동의 핵심 자산 </p>
<p><strong>비즈니스 분석 (business analytics)</strong> </p>
<p>: 데이터에 기반한 기업 경영 활동 </p>
<p><strong>비즈니스 분석 절차</strong> </p>
<p>가설 수립 (EDA) → 가설 검증 (A/B 테스트 ) → 모니터링 (Dashboard) → 스토리텔링 (Presentation)</p>
<ol>
<li><p><strong>데이터를 확실하게 이해하기 위해 데이터 시각화가 필요하다.</strong></p>
<p> 비즈니스 목표 설정 후에 “<strong>데이터 이해</strong>“ 절차가  따라온다.</p>
<ul>
<li><p>데이터 이해 == 데이터 탐색</p>
</li>
<li><p>전통적인 데이터 탐색 → 평균, 분산, 표준편차, 첨도, 왜도 등의 <strong>기술 통계</strong></p>
<ul>
<li>Anscombe’s Quartet 데이터셋을 보면 기술 통계로 나타난 4종류의 데이터셋이 평균, 표준편차, 상관계수에서 모두 동일한 값을 가진다.</li>
<li>하지만, 데이터를 시각화해서 표현해 본다면 모두 다른 양상을 가지는 데이터임을 알 수 있다.</li>
</ul>
</li>
<li><p><em>→ 전통적인 방법의 기술 통계만으로 데이터를 완전히 이해하기는 어렵다.*</em></p>
</li>
</ul>
</li>
<li><p><strong>데이터 품질을 확인하기 위해 데이터 시각화가 활용된다.</strong></p>
<p> 박스 플롯을 이용한 이상치 탐지 (Anomaly Detection)</p>
</li>
<li><p><strong>상대방과의 소통을 위해 데이터 시각화가 필요하다.</strong></p>
<p> 데이터를 분석하는 이유는 결국 분석된 결과를 바탕으로 누군가와 소통하기 위함이다.</p>
<p> 성공적인 데이터 시각화는 상대방을 설득하고, 소통을 안정적으로 이끌어나간다.</p>
<p> ex. 로즈 다이어그램 by 나이팅게일</p>
</li>
</ol>
<h2 id="03-데이터-시각화의-전략">03. 데이터 시각화의 전략</h2>
<hr>
<p><strong>데이터 시각화는 데이터에 ‘맥락’을 담아 ‘의미’를 전달하는 과정</strong></p>
<p><del>깊이 있는 데이터 탐색과 이를 기반으로 하는 다양한 시각화 결과물</del> </p>
<p><del>→ 상대방의 메시지 이해도 상승</del> </p>
<p><del>→ 말하는 사람과 듣는 사람의 감정을 동기화</del> </p>
<p><del>→ 유대감 및 호감 생성</del></p>
<p><del>→ 상대방을 스토리에 몰입하게 만듦</del></p>
<p><del>→ 원하는 행동의 변화를 이끌어냄</del> </p>
<p>시각화된 데이터는 <strong>누군가를 설득하고 행동을 변화시키기 위한 콘텐츠</strong>이다.</p>
<p><strong>상대방을 충분히 고려하여, 그들의 눈높이에 맞춰 전달</strong>되어야 한다.</p>
<p>잘 만들어진 시각화 화면에는 <strong>육하원칙(5W1H)</strong>이 담겨있다.</p>
<blockquote>
<p><strong>어디로?태블로!</strong> 스터디 
<strong>Let&#39;s 태블로, 쉽게 따라하는 데이터 시각화</strong>, 최정민, 류지호, 생능북스</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[알고리즘] 그래프 탐색 알고리즘 (DFS, BFS)]]></title>
            <link>https://velog.io/@ja_efan/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EA%B7%B8%EB%9E%98%ED%94%84-%ED%83%90%EC%83%89-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-DFS-BFS</link>
            <guid>https://velog.io/@ja_efan/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EA%B7%B8%EB%9E%98%ED%94%84-%ED%83%90%EC%83%89-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-DFS-BFS</guid>
            <pubDate>Wed, 01 May 2024 05:21:17 GMT</pubDate>
            <description><![CDATA[<h2 id="graph">Graph</h2>
<hr>
<p>그래프는 데이터의 요소들이 노드(Node)로 표현되고, 이 노드들 사이의 관계를 간선(Edge)으로 연결한 구조를 가진다. 
컴퓨터 과학에서 그래프는 네트워크, 소셜 미디어 상호작용, 웹사이트의 페이지 구조 등 다양한 현실 세계의 문제를 모델링하는 데 널리 사용된다. 
<img src = "https://velog.velcdn.com/images/ja_efan/post/19d3f836-f69d-4f32-9855-ce1a4fc42847/image.jpeg
" width = 70%></p>
</br>

<h2 id="graph-search-algorithm">Graph Search Algorithm</h2>
<hr>
<p>그래프를 효과적으로 탐색하고 분석하는 것은 알고리즘의 세계에서 중요한 주제 중 하나이다. 
그래프 탐색 알고리즘은 <u>그래프의 모든 노드를 체계적으로 검사(탐색)</u>하기 위한 방법을 제공하며,
이를 통해 경로 찾기, 사이클 검출, 연결 요소 찾기 등의 다양한 문제들을 해결할 수 있다.</p>
<p>그래프 탐색 알고리즘은 크게 두 가지로 나눌 수 있다. </p>
<ul>
<li><strong>깊이 우선 탐색 (Depth-First Search, DFS)</strong></li>
<li><strong>너비 우선 탐색 (Breadth-First Search, BFS)</strong></li>
</ul>
<p>DFS는 노드를 가능한 한 깊숙이 탐색하다가 막히면 되돌아가 다른 경로를 탐색하는 방식으로, 미로 찾기나 퍼즐 게임같은 문제에 적합하하다.
반면, BFS는 레벨별로 노드를 탐색하며 최단 경로를 찾는 데 유용하게 사용된다. </p>
</br>

<h2 id="깊이-우선-탐색-depth-first-search-dfs">깊이 우선 탐색 (Depth-First Search, DFS)</h2>
<hr>
<p>DFS는 그래프의 모든 노드를 방문하기 위한 그래프 탐색 알고리즘이다. 
이 방법은 노드를 방문하고, 갈 수 있는 한 깊게 노드를 탐색해 나가다가 더 이상 탐색할 수 없는 지점에 도달하면, 
가장 최근에 탐색했던 분기점으로 돌아가서 다른 경로를 탐색하는 방법으로 진행된다. 
이러한 방식 때문에 &#39;Backtracking&#39;이라고도 불린다.</p>
<p>DFS를 구현하는 방식에는 크게 재귀(recursion)를 이용하는 방법과 스택(stack)을 이용하는 방법이 있다.</p>
<h3 id="재귀를-이용한-dfs">재귀를 이용한 DFS</h3>
<p>재귀를 이용해 DFS를 구현할 때에는 현재 노드를 방문 처리하고, 현재 노드에 인접한 노드 중에서 방문하지 않은 노드에 대해 재귀적으로 진행한다. 
재귀 호출은 스택의 동작을 모방한다.</p>
<p>아래 함수는 dict로 표현된 그래프(graph)와 현재 노드(v) 그리고 방문 여부를 확인할 리스트(visited)를 인자로 받아 
DFS를 수행한 뒤 노드 방문 순서를 리스트 형태로 return한다. </p>
<pre><code class="language-python">def recursive_dfs(graph:dict, v:int, visited:list) -&gt; list:
    visited.append(v) # 현재 노드 방문 처리
    for i in graph[v]: # 현재 노드와 인접 노드
        if i not in visited: # 방문하지 않은 노드라면
            recursive_dfs(graph, i, visited) # 재귀적으로 dfs 진행
       return visited # 방문 순서 return 

# test case (위의 그림에 나오는 그래프를 인접 리스트로 표현)
graph = {
    1: [2, 3],
    2: [1, 4, 5],
    3: [1, 6],
    4: [2],
    5: [2],
    6: [3],
}

print(recursive_dfs(graph, 1, [])) # [1,2,4,5,3,6]</code></pre>
<h3 id="스택을-이용한-dfs">스택을 이용한 DFS</h3>
<p>스택을 사용해 DFS를 구현할 때에는 초기 시작 노드를 스택에 넣어놓고, 스택이 빌 때까지 다음의 과정을 반복한다.
스택에서 하나의 노드를 꺼내(pop) 방문 처리하고, 해당 노드에 인접한 노드 중 방문하지 않은 노드를 스택에 추가(push)한다.</p>
<pre><code class="language-python">def stack_dfs(graph:dict, v:int) -&gt; list:
    visited = [] # 방문 여부 리스트 
    stack = [start] # 스택에 초기 시작 노드 추가 
    while stack: # 스택이 빌 때까지 반복
        vertex = stack.pop() # 스택에서 하나의 노드를 꺼냄
        if vertex not in visited: # 방문하지 않은 노드라면
            visited.append(vertex) # 방문 처리 
            stack.extend(reversed(graph[vertex])) # 인접한 노드들의 방문 순서를 지키기 위해 역순으로 스택에 추가(extend)

    return visited # 방문 순서 return 

 # test case 
 graph = {
    1: [2, 3],
    2: [1, 4, 5],
    3: [1, 6],
    4: [2],
    5: [2],
    6: [3],
}

print(stack_dfs(graph, 1) # [1,2,4,5,3,6]</code></pre>
<h3 id="dfs의-활용">DFS의 활용</h3>
<p>DFS는 여러가지 문제 해결에 사용된다. 예를 들어, 연결 요소 찾기, 사이클 검출, 경로 탐색, 그래프의 레이아웃 계산 등에 사용될 수 있다.
그래프의 구조를 파악하는 데 특히 유용하며, 퍼즐 게임이나 미로 찾기 같은 문제에서도 널리 사용된다.</p>
</br>

<h2 id="너비-우선-탐색-breadth-first-search-bfs">너비 우선 탐색 (Breadth-First Search, BFS)</h2>
<hr>
<p>BFS도 그래프의 모든 노드를 방문하는 데 사용되는 알고리즘으로, 시작 노드에서 가장 가까운 노드부터 차례대로 모든 노드를 방문하는 형식이다.
BFS는 주로 큐(queue)를 사용하여 각 노드를 순차적으로 탐색하고, 각 노드와 인접한 노드들을 다시 큐에 추가하는 방식으로 그래프를 탐색한다.
너비 우선 탐색 알고리즘은 최단 경로를 찾거나 그래프를 레벨별로 탐색할 때 유용하다.</p>
<h3 id="bfs의-기본-원리">BFS의 기본 원리</h3>
<ol>
<li>큐 초기화 :  시작 노드를 큐에 넣는다. </li>
<li>노드 방문 및 큐에서 제거 : 큐의 맨 앞 노드를 꺼내 방문 처리한다.</li>
<li>인접 노드 탐색 : 방문한 노드와 인접한 모든 노드를 확인하고, 아직 방문하지 않은 노드를 큐에 추가한다.</li>
<li>반복 실행 : 큐가 비어있을 때 까지 위의 과정을 반복한다.</li>
</ol>
<h3 id="bfs-구현-using-deque">BFS 구현 (using deque)</h3>
<pre><code class="language-python">from collections import deque

def bfs(graph:dict, start:int, visited:list) -&gt; list :
    dq = deque([start]) # 시작 노드를 큐에 추가 
    visited.append(start) # 시작 노드 방문 처리 

    while dq: # 큐가 빌 때 까지 반복
        v = dq.popleft() # 큐의 맨 앞 노드 pop
        for i in graph[v]: # pop한 노드와 인접한 노드들
            if i not in visited: # 방문하지 않은 노드라면
                dq.append(i) # 큐에 추가하고
                visited.append(i) # 방문 처리 
    return visited

# test case
graph = {
    1: [2, 3],
    2: [1, 4, 5],
    3: [1, 6],
    4: [2],
    5: [2],
    6: [3],
}

print(bfs(graph, 1, [])) # [1,2,3,4,5,6]
</code></pre>
<p>위의 코드에서 collections 모듈의 deque 객체를 사용하는 이유는 list 객체의 pop() 함수 사용보다 deque의 popleft() 함수가 효율적으로 동작하기 때문이다. </p>
<blockquote>
<p><strong>deque.popleft()</strong> vs. <strong>list.pop(0)</strong>
collections 모듈의 deque 객체는 양쪽 끝에서 요소를 추가하거나 제거할 수 있도록 설계된 자료구조로, 이중 연결 리스트로 구현된다. 
deque.popleft()는 deque의 맨 앞 요소를 제거하는 연산으로, 이 연산은 상수 시간인 O(1)에 수행된다. 따라서 요소의 수에 관계없이 항상 일정한 성능을 유지한다.
반면, Python의 list 객체는 동적 배열로 구현되어 있다. list.pop(0)을 사용하면 리스트의 첫 번째 요소를 제거하고, 나머지 요소들을 한 칸씩 옆으로 이동시켜야 한다. 이 작업은 O(N)의 시간 복잡도를 가지며, 리스트의 크기가 클수록 느려진다.</p>
</blockquote>
<h3 id="bfs의-활용">BFS의 활용</h3>
<ul>
<li>최단 경로 찾기 : BFS는 가중치가 없는 그래프에서 두 노드 간의 최단 경로를 찾는 데 사용될 수 있다. 
또한, 레벨 별로 탐색하므로 계층적 구조를 갖는 문제 해결에 적합하다. </li>
<li>연결 요소 : 그래프 내에서 각각 독립적으로 연결된 부분을 찾는 데 사용된다.</li>
<li>사이클 검증 : BFS를 이용하여 그래프 내 사이클의 존재 여부를 확인할 수 있다.</li>
</ul>
</br>

<hr>
<blockquote>
<p>with GPT-4</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Python] pandas.unstack()]]></title>
            <link>https://velog.io/@ja_efan/PYTHON-pandas.unstack</link>
            <guid>https://velog.io/@ja_efan/PYTHON-pandas.unstack</guid>
            <pubDate>Mon, 29 Apr 2024 14:15:05 GMT</pubDate>
            <description><![CDATA[<p>pandas의 unstack()함수는 pandas의 DataFrame이나 Series에서 사용되며, 데이터를 재구조화하여 더 읽기 쉽고 분석하기 편리한 형태로 변환하는 데 사용된다.
이 함수는 멀티인덱스(multi-index)를 가진 데이터에서 특정 레벨의 인덱스를 컬럼으로 옮겨 데이터를 재구성한다.</p>
<h2 id="기본-개념">기본 개념</h2>
<hr>
<p><strong>unstack()</strong> 은 주로 데이터를 피봇팅할 때 사용되며, &#39;긴 형식&#39;(long format)의 데이터를 &#39;넓은 형식&#39;(wide format)으로 변경한다. 이를 통해 데이터의 특정 측면을 더 잘 강조하거나, 특정 분석을 위해 데이터의 구조를 변경할 수 있다.</p>
<blockquote>
<p>*긴 형식&#39;(long format) 과 &#39;넓은 형식&#39;(wide format)</p>
</blockquote>
<ul>
<li><strong>&#39;긴 형식&#39;</strong> 은 <u>데이터가 수직적으로 길게 나열되는 형태</u>로,
각 행이 하나의 관측치를 대표하고 일반적으로 &#39;tidy data&#39;의 원칙을 따른다. 
이 형식에는 데이터에 중복이 적고, 데이터를 다루는 많은 라이브러리나 소프트웨어에서 요구하는 표준 형태이다. <ul>
<li>각 행은 하나의 관측치를 대표한다.</li>
<li>같은 변수의 데이터가 여러 행에 걸쳐 나타난다.</li>
<li>데이터를 추가하려면 행을 추가하면 된다.</li>
</ul>
</li>
<li><strong>&#39;넓은 형식&#39;</strong> 은 데이터가 <u>수평적으로 넓게 퍼져 있는 형태</u>로, 
각 변수가 하나의 열을 차지하고, 각 행이 여러 관측치를 포함할 수 있다. 
이 형식은 보다 직관적이고 시각적으로 이해하기 쉬울 수 있지만, 데이터 처리나 변환 작업이 복잡해질 수 있다. <ul>
<li>각 행이 하나 이상의 관측치를 대표할 수 있다. </li>
<li>변수의 수가 많아질수록 열의 수가 늘어난다.</li>
<li>하나의 관측치가 여러 열에 걸쳐 표현된다.</li>
</ul>
</li>
</ul>
<h2 id="사용-방법">사용 방법</h2>
<hr>
<p>unstack() 함수는 DataFrame의 Series 객체에 호출될 수 있으며, 선택하지 하지 않으면 <u>기본적으로 가장 마지막 레벨의 인덱스가 컬럼으로 변환</u>된다. </p>
<pre><code class="language-python"># 사용 예 
result = df.groupby([&#39;col1&#39;, &#39;col2&#39;]).size() #
result.unstack()</code></pre>
<h2 id="파라미터">파라미터</h2>
<hr>
<p><strong>level</strong> : 어떤 인덱스 레벨을 컬럼으로 바꿀지 결정한다. 기본값은 -1로, 가장 마지막 레벨이 선택된다. 인덱스 레벨 번호 또는 이름을 지정할 수 있다.</p>
<p><strong>fill_value</strong> : unstacking 과정에서 생성되는 결측치를 대체할 값이다. 예를 들어, 데이터 셋에서 모든 가능한 조합이 존재하지 않는 경우 결측치가 발생할 수 있는데, 이 값을 통해 특정 값으로 채울 수 있다. </p>
<pre><code class="language-python">import pandas as pd

# create DataFrame
df = pd.DataFrame(
    { &#39;values&#39; = range(6), 
      &#39;A&#39; : [&#39;foo&#39;, &#39;foo&#39;, &#39;foo&#39;, &#39;bar&#39;, &#39;bar&#39;, &#39;bar&#39;],
      &#39;B&#39; : [&#39;one&#39;, &#39;two&#39;, &#39;three&#39;, &#39;one&#39;, &#39;two&#39;, &#39;three&#39;]
    }
).set_index([&#39;A&#39;,&#39;B&#39;])

print(df)

# unstack
unstacked = df.unstack(level=&#39;B&#39;)
print(unstacked)</code></pre>
<img src = "https://velog.velcdn.com/images/ja_efan/post/cdda7892-44df-40ca-9fa7-8a0003f921bd/image.jpeg" width = 70%>



<p>이 예시에서는 A와 B를 인덱스로 가지는 DataFrame에 대헤 unstack() 함수를 사용하여 B 인덱스를 컬럼으로 변환한다. 결과적으로 B의 각 값(&#39;one&#39;, &#39;two&#39;, &#39;three&#39;)이 컬럼으로 재배치되고, A의 각 값에 따라 세분화되어 표시된다. </p>
<p>이러한 unstack() 함수는 특히 시계열 데이터나 계층적 인덱스를 가진 복잡한 데이터에서 매우 유용하게 사용될 수 있으며, 데이터를 분석하기 위한 다양한 형태로 쉽게 변환할 수 있도록 도와준다. </p>
</br>

<blockquote>
<p>with GPT-4</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ML] Linear Regression]]></title>
            <link>https://velog.io/@ja_efan/ML-Linear-Regression</link>
            <guid>https://velog.io/@ja_efan/ML-Linear-Regression</guid>
            <pubDate>Fri, 26 Apr 2024 12:28:52 GMT</pubDate>
            <description><![CDATA[<h2 id="linear-regression">Linear Regression</h2>
<hr>
<p><strong>선형 회귀</strong>는 하나 이상의 독립 변수(입력 변수)와 종속 변수(결과 변수) 사이의 <u><strong>선형 관계</strong></u>를 모델링한다.</p>
<p>이러한 선형 회귀의 목적은 주어진 독립 변수의 값에 대해 &lt;종속 변수의 값을 <strong>예측</strong>하거나, 변수 간의 관계를 <strong>이해</strong>하는 데 있다.</p>
</br>

<h2 id="선형-회귀의-형태">선형 회귀의 형태</h2>
<hr>
<h3 id="단순-선형-회귀-simple-linear-regression">단순 선형 회귀 (Simple Linear Regression)</h3>
<p>단순 선형 회귀는 <strong>한 개의 독립 변수(x)</strong>와 <strong>한 개의 종속 변수(y)</strong> 사이의 선형 관계를 분석/모델링 한다.
이 관계는 다음과 같은 수식을 갖는다.
$$
y = \beta_{0} + \beta_{1} x + \epsilon
$$
$\beta_{0}$는 bias(절편), $\beta_{1}$는 기울기(독립 변수의 영향력, $x$의 회귀 계수, $\epsilon$은 오차(error)항이다.
이 모델은 주로 독립 변수가 종속 변수에 미치는 직접적인 영향을 예측하는 데 사용된다.</p>
<img src = "https://velog.velcdn.com/images/ja_efan/post/c273727b-0a3a-4108-9b2b-f78a2f1e6306/image.png" width = 70%>

<h3 id="다중-선형-회귀-multiple-linear-regression">다중 선형 회귀 (Multiple Linear Regression)</h3>
<p>다중 선형 회귀는 <strong>두 개 이상의 독립 변수</strong>를 사용하여 <strong>하나의 종속 변수</strong>를 예측하는 모델이다.
단순 선형 회귀를 확장한 형태로, 다음과 같은 수식을 갖는다.
$$
y = \beta_{0} + \beta_{1} x_{1} + \beta_{2} x_{2}+...+ \beta_{n} x_{n} + \epsilon
$$
이 모델은 복잡한 현실 세계의 데이터에서 여러 변수들이 어떻게 상호 작용하는지 이해하는 데 유용하다.</p>
<img src = "https://velog.velcdn.com/images/ja_efan/post/931337a9-4222-4f6a-9bf1-77919829e27f/image.png" width = 70%>

<h3 id="단변량-선형-회귀-univariate-linear-regression">단변량 선형 회귀 (Univariate Linear Regression)</h3>
<p>단변량 선형 회귀는 <strong>종속 변수가 하나</strong>인 선형 회귀 모델을 말한다. 
이는 단순 선형 회귀와 다중 선형 회귀 모두를 포함할 수 있으며, 중요한 점은 하나의 모델이 하나의 종속 변수의 값을 예측하거나 설명한다는 것이다.</p>
<h3 id="다변량-선형-회귀-multivariate-linear-regression">다변량 선형 회귀 (Multivariate Linear Regression)</h3>
<p>다변량 선형 회귀는 <strong>두 개 이상의 종속 변수</strong>를 동시에 예측하기 위해 사용되는 모델로, 여러 개의 회귀 방정식으로 구성 된다.
이 모델은 각각의 종속 변수마다 하나의 방정식을 가지며, 각 방정식은 다수의 독립 변수들로 부터 영향을 받는다. 
다변량 선형 회귀 모델의 일반적인 형태(수식)는 다음과 같다.</p>
<p>$$
y_{1} = \beta_{10} + \beta_{11} x_{1} + \beta_{12} x_{2} + ... + \beta_{1n} x_{n} + \epsilon_{1},
\
y_{2} = \beta_{20} + \beta_{21} x_{1} + \beta_{22} x_{2} + ... + \beta_{2n} x_{n} + \epsilon_{2},
\
:
\
y_{m} = \beta_{m0} + \beta_{m1} x_{1} + \beta_{m2} x_{2} + ... + \beta_{mn} x_{n} + \epsilon_{m}
$$
이러한 구조를 통해 다변량 선형 회귀는 복잡한 데이터 셋에서 여러 결과 변수(종속 변수)를 동시에 예측하고, 서로 다른 변수 간의 상호 작용을 이해하는데 유용하다.</p>
<p>아래 예시는 한 개의 독립 변수 $x_1$과 두 종속 변수 $y_1, y_2$의 다변량 선형 회귀를 나타내는 그래프이다.
<img src = "https://velog.velcdn.com/images/ja_efan/post/e543df08-4be6-48dd-8454-650ccb715523/image.png"
 width = 70%>
 다변량 선형 회귀 모델은 두 개 이상의 종속 변수를 표현해야 하기 때문에, 한 평면에 표현하기가 복잡한 경향이 있다. 
 따라서 각 종속 변수에 대해 별도의 그래프를 생성하여, 해당 종속 변수와 모든 독립 변수 간의 관계를 표시한다. </p>
<p> 개별 종속 변수 그래프에서 회귀선 주변의 음영은 회귀선의 <strong>신뢰 구간</strong>을 나타낸다. 
 이 음영은 데이터에 대한 <strong>회귀선의 불확실성</strong>을 표현하며, 일반적으로는 95% 신뢰 구간을 사용한다. 
 이는 회귀선이 실제로 위치할 가능성이 높은 구간을 시각적으로 보여준다. 
 즉, 이 음영 안에 실제 회귀선이 존재할 확률이 95%라는 의미이다. 
 <u>데이터의 분산이 클 수록 음영이 넓어지며, 데이터가 회귀선을 잘 따르고 분산이 작을수록 음영이 좁아진다.</u> </p>
<p>아래의 히트맵 예시는 세 개의 독립 변수 $x_1, x_2, x_3$와 두 개의 종속 변수 $y_1, y_2$ 간의 상관 계수를 나타낸다. 
<img src = "https://velog.velcdn.com/images/ja_efan/post/68262ea7-25e8-4c98-8417-1fef61a12495/image.png" width = 70%></p>
</br>

<h2 id="regularization">Regularization</h2>
<hr>
<p>회귀 모델에서 <strong>정규화(regularization)</strong> 는 <u>overfitting(과적합)을 방지</u>하고, 모델의 <u>일반화 성능 향상</u>을 위해 사용되는 기법이다.</p>
<blockquote>
<p><em>fyi.</em> 
<strong>Overfitting(과적합)</strong> 은 모델이 훈련 데이터에 지나치게 잘 맞춰져 있어 새로운 데이터에 대한 예측 성능이 좋지 않은 현상을 말한다. 
반대되는 개념으로 <strong>Underfitting(과소적합)</strong>이 있다. 
이는 모델이 훈련 데이터의 패턴이나 구조를 충분히 학습하지 못해 데이터의 본질적인 관계를 반영하지 못하는 현상을 의미한다. </p>
</blockquote>
<p>정규화에서는 <u>모델의 복잡성</u>에 대해 페널티를 부과하여 과적합을 방지한다.
모델의 복잡성의 페널티를 부과하는 방법 중 <strong>Ridge</strong>와 <strong>Lasso</strong>에 대해 알아보자.</p>
<h3 id="ridge-regression-l2-regularization">Ridge Regression (L2 Regularization)</h3>
<p>릿지 회귀는 선형 회귀의 일종으로, 과적합을 방지하기 위해 L2 정규화를 추가한 모델이다. 
특히 이 방법은 독립 변수가 많거나, 일부 변수들이 강하게 상관관계를 가질 때 유용하다.
릿지 회귀는 회귀 계수의 크기를 축소하여 모델의 복잡성을 줄이고, 더 일반화된 모델을 만드는 데  도움을 준다. </p>
<h4 id="기본-원리">기본 원리</h4>
<p>릿지 회귀의 기본 아이디어는 회귀 계수의 제곱합에 페널티를 부여하여 계수 값을 감소시키는 것이다. 
이 페널티 항은 모델의 복잡성을 줄이며, 데이터의 노이즈에 대한 민감도를 줄인다. (일반화 성능을 높인다는 얘기)</p>
<h4 id="수학적-표현-objective-function--loss-function">수학적 표현 (objective function / loss function)</h4>
<p>$$
J(\beta) = ||Y-\beta X||^2 + \alpha ||\beta||^2
$$</p>
<ul>
<li>$||Y-\beta X||^2$ 는 잔차 제곱합(Residual Sum of Squares, RSS)으로, 모델의 오차를 나타낸다.</li>
<li>$\alpha$는 정규화 정도를 조절하는 하이퍼 파라미터로, $\alpha$값에 따라 정규화 정도가 달라진다.<ul>
<li>$\alpha$값이 크면, 로스 함수 내에서 정규화 영향이 커지고 계수의 크기가 크게 감소한다. <ul>
<li>$\alpha$값이 작으면, 정규화 영향이 작아지고 계수의 크기가 작게 감소한다. </li>
</ul>
</li>
</ul>
</li>
<li>$||\beta||^2$는 회귀 계수의 제곱합으로, 정규화 항이다.</li>
</ul>
<h4 id="하이퍼-파라미터-alpha">하이퍼 파라미터 $\alpha$</h4>
<p>릿지 회귀에서 $\alpha$는 매우 중요한 역할을 한다. $\alpha$가 0에 가까우면 릿지 회귀는 일반 선형 회귀와 동일해지며,
$\alpha$가 매우 크면 모든 계수가 거의 0에 수렴하여 데이터의 변동을 설명하지 못하게 된다. 
따라서 적절한 $\alpha$값을 선택하는 것이 중요하며, 이는 주로 교차 검증을 통해 최적화 한다.</p>
<h4 id="장점">장점</h4>
<ul>
<li>회귀 모델의 과적합 방지</li>
<li>회귀 모델의 일반화 성능 향상</li>
<li>변수간 상관관계가 높은 경우에도, 안정적인 계수 추정<h4 id="단점">단점</h4>
</li>
<li>$\alpha$값의 설정 필요성과 이로 인한 추가 계산 필요 </li>
<li>모든 변수를 사용하므로, 효율성이 떨어질 수 있음</li>
</ul>
<h3 id="lasso-regression-l1-regularization">Lasso Regression (L1 Regularization)</h3>
<p>라쏘 회귀도 선형 회귀의 일종으로, 과적합을 방지하고 모델을 단순화 하기 위해 사용되는 정규화 기법이다. 
&quot;LASSO&quot;는 &quot;Least Absolute Shrinkage and Selection Operator&quot;의 약자로, 하이퍼 파라미터를 사용하여 회귀 계수를 <strong>축소</strong>하는 것이 핵심이다.</p>
<h4 id="기본-원리-1">기본 원리</h4>
<p>라쏘 회귀의 기본 원리는 회귀 계수의 절대값을 페널티로 추가함으로써, 일부 회귀 계수를 정확히 0으로 만드는 것이다. 
이 접근 방식은 불필요하거나 중요하지 않은 특성(독립 변수)의 계수를 제거함으로써 모델을 단순화하고, 결과적으로 더 나은 일반화 성능을 낸다.</p>
<h4 id="수학적-표현-objective-function--loss-function-1">수학적 표현 (objective function / loss function)</h4>
<p>$$
J(\beta) = ||Y-\beta X||^2 + \alpha ||\beta||
$$</p>
<p>전체적인 식의 구조는 릿지와 비슷하지만 정규화 항이 $||\beta||$로 회귀 계수의 절대값을 나타낸다. </p>
<h4 id="하이퍼-파라미터-alpha-1">하이퍼 파라미터 $\alpha$</h4>
<p>라쏘 회귀에서도 $\alpha$는 매우 중요한 하이퍼 파라미터로, 그 값에 따라 모델의 복잡성과 과적합 경향성이 달라진다. 
릿지와 마찬가지로 $\alpha$가 0에 가까울수록 일반 선형 회귀와 같아지며, $\alpha$가 매우 크면 많은 회귀 계수들이 0으로 수렴하여 모델이 너무 단순해질 수 있다. 따라서 교차 검증을 통한 적절한 $\alpha$값 선정이 중요하다.</p>
<h4 id="장점-1">장점</h4>
<ul>
<li>자동 변수 선택을 통핸 모델의 일반화 성능 향상</li>
<li>과적합 방지</li>
<li>모델 해석이 용이 (중요한 속성만 포함하고 있음)</li>
</ul>
<h4 id="단점-1">단점</h4>
<ul>
<li>하이퍼 파라미터 $\alpha$에 의존하는 경향</li>
<li>그룹 효과 무시 (서로 관련 있는 변수가 있을 경우, 하나만 선택 후 나머지는 무시)</li>
<li>비선형 관계 처리 부족 (기본적으로 선형 관계를 모델링)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[알고리즘] Dynamic Programming]]></title>
            <link>https://velog.io/@ja_efan/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-Dynamic-Programming</link>
            <guid>https://velog.io/@ja_efan/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-Dynamic-Programming</guid>
            <pubDate>Tue, 23 Apr 2024 14:15:42 GMT</pubDate>
            <description><![CDATA[<h2 id="dynamic-programming-동적계획법">Dynamic Programming (동적계획법)</h2>
<hr>
<p>DP는 복잡한 문제를 작은 하위 문제로 나누어 해결하는 <strong>알고리즘 설계 기법</strong>이다.</p>
<blockquote>
<p><em>fyi.</em> <strong>알고리즘 기법과 알고리즘 설계 기법</strong></p>
<p>1.알고리즘 기법</p>
<p><u>주어진 문제를 해결하기 위한 명확한 절차나 방법론</u>을 의미한다. </p>
<p>구체적으로는 입력을 받아서 출력을 생성하는 명령의 유한한 순서로 구성되어 있으며, 이를 통해 문제를 해결하거나 계산을 수행한다.</p>
<p>(ex. 정렬 알고리즘, 탐색 알고리즘, 최단 경로 알고리즘 등)</p>
</br>

<p>2.알고리즘 설계 기법</p>
<p><u>알고리즘 설계 기법은 알고리즘을 개발하고 설계하는 데 사용되는 방법론이나 전략</u>을 말한다. </p>
<p>이는 효율적인 알고리즘을 설계하는 데 필요한 접근 방식을 제공하며, 다양한 유형의 문제에 적용할 수 있는 일반적인 틀이나 패턴을 포함한다. </p>
<p>(ex.분할 정복, 동적 프로그래밍, 그리디 알고리즘, 백트래킹 등)</p>
</blockquote>
<p>따라서 정확히 말하면 다이나믹 프로그래밍은 그 자체로 알고리즘이 아닌, <u>알고리즘을 설계하는 방법론 중 하나</u>이다.</p>
</br>

<h2 id="dp의-사용-조건">DP의 사용 조건</h2>
<hr>
<p>DP가 적용되기 위해서는 아래의 2가지 조건을 만족해야 한다.</p>
<ol>
<li>하위 문제의 중복 (Overlapping Subproblems)</li>
<li>최적 부분 구조 (Optimal Substructure)</li>
</ol>
<h3 id="1-하위-문제의-중복">1. 하위 문제의 중복</h3>
<p>이 조건은 주어진 문제가 하위 문제들로 나누어질 수 있어야 한다는 것을 의미한다. 다시 말해, 문제를 해결하는 과정에서 동일한 작은 문제들을 여러 번 해결해야 하는 경우가 발생해야 한다는 것이다. 이런 특성을 가진 문제들은 동적 프로그래밍을 사용함으로써, 한 번 계산한 하위 문제의 결과를 저장하고 필요할 때마다 재사용함으로써 계산 시간을 크게 단축시킬 수 있다.</p>
<blockquote>
<p>예시 : </p>
<p>피보나치 수열 계산에서 F(n) = F(n-1) + F(n-2)를 계산하기 위해 F(n-1)과 F(n-2)가 다시 F(n-3)과 F(n-2)를 필요로 하며, 이러한 중복 계산을 <strong>Memoization</strong> 또는 <strong>Tablulation</strong>을 통해 효율적으로 처리할 수 있다.</p>
<p><img src = "https://velog.velcdn.com/images/ja_efan/post/c26d106e-96e4-448b-95a2-05ad02b4d552/image.png
" width = 70%></p>
</blockquote>
<h3 id="2-최적-부분-구조">2. 최적 부분 구조</h3>
<p>최적 부분 구조는 큰 문제의 최적 해결책이 그 문제를 구성하는 작은 문제들의 최적 해결책에서 파생될 수 있다는 성질을 말한다. 즉, 전체 문제의 최적 해가 하위 문제의 최적 해들로부터 구성될 수 있어야 한다. 이 조건이 충족되면, 작은 문제들을 해결함으로써 점차적으로 전체 문제의 최적 해를 구축해 나갈 수 있다. </p>
<blockquote>
<p>예시 :</p>
<p>최소 비용 경로 문제에서 어떤 점 A에서 점 B까지의 최소 비용 경로는 A에서 C까지의 최소 비용 경로와 C에서 B까지의 최소 비용 경로를 합친 것이다. </p>
<p><img src = "https://velog.velcdn.com/images/ja_efan/post/ea1660db-b81b-4573-a34c-e7eb1fa4c9ce/image.png
" width = 80%></p>
</blockquote>
</br>

<h2 id="dp-사용하기">DP 사용하기</h2>
<hr>
<p>DP는 특정한 경우에 사용하는 알고리즘이 아니라 하나의 방법론이므로 다양한 문제 해결에 적용될 수 있다. </p>
<p>그래서 DP를 적용할 수 있는 문제인지를 파악하는 것부터 코드로 구현하는 과정 까지의 난이도가 다양하다. </p>
<p>일반적으로 DP를 사용하기 전에는 아래의 과정을 거쳐 진행할 수 있다.</p>
<ol>
<li>DP로 해결 가능한 문제인지 확인</li>
<li>문제의 변수 파악</li>
<li>변수 간 관계식 설정 (점화식)</li>
<li>메모하기(Memoization or Tabluation)</li>
<li>기저 상태 파악</li>
<li>구현</li>
</ol>
<h3 id="1-dp로-풀-수-있는-문제인지-확인">1. DP로 풀 수 있는 문제인지 확인</h3>
<p>현재 직면한 문제가 더 작은 문제들로 구성된 하나의 함수로 표현될 수 있는지를 판단해야 한다.</p>
<p>즉, 위에서 언급한 <u>조건들을 충족하는 문제인지를 체크</u>해야 한다.</p>
<p>보통 특정 데이터 내 최대화/최소화 계산을 하거나, 특정 조건 내 데이터를 카운트해야 한다거나 확률 등의 계산의 경우 DP로 해결 할 수 있는 경우가 많다.</p>
<h3 id="2-문제의-변수-파악">2. 문제의 변수 파악</h3>
<p>DP는 현재 변수에 따라 그 결과 값을 찾고 그것을 전달하여 재사용하는 과정을 거친다. 즉, <u>문제 내 변수를 알아내야 한다</u>는 것이다.</p>
<p>이것을 영어로 <u>&#39;state&#39;를 결정한다</u>고 한다.</p>
<p>(&#39;state&#39;에 대해서는 다음에 자세하게 알아보자.)</p>
<h3 id="3-변수-간-관계식-설정점화식">3. 변수 간 관계식 설정(점화식)</h3>
<p>변수들에 의해 결과 값이 달라지지만 동일한 변수 값인 경우 결과는 동일하다. 또한 우리는 그 결과 값을 그대로 이용할 것이므로 그 관계식을 만들어낼 수 있어야 한다.</p>
<p>즉, <u>결과 값들의 관계를 함수로 표현</u>하는 것이다.</p>
<p>그러한 식을 <strong>점화식</strong>이라고 부르며, 이를 통해 우리는 짧은 코드 내에서 반복/재귀를 통해 문제가 해결되도록 구현할 수 있게 된다. </p>
<p>예를 들어, 피보나치 수열에서의 점화식은 F(n) = F(n-1) + F(n-2) 이다. </p>
<h3 id="4-메모하기">4. 메모하기</h3>
<p>변수 간 관계식 까지 성공적으로 정의했다면, <u>변수의 값에 따른 결과를 저장</u>해야 한다. 이것을 &#39;메모&#39;한다고 하여 <strong>Memoization</strong>이라고 부른다.</p>
<p>미리 선언된 배열에 변수 값에 따른 결과 값을 저장하고, 그 저장된 값을 재사용하는 방식으로 문제를 해결해 나간다. </p>
<p>이 결과 값을 저장할 때는 주로 배열을 사용하며, 변수의 개수에 따라 배열의 차원이 결정된다.</p>
<h3 id="5-기저-상태-파악">5. 기저 상태 파악</h3>
<p>이제, <u>가장 작은 문제의 상태</u>를 알아야 한다. 보통 몇 가지 예시를 직접 손으로 테스트하여 구성하는 경우가 많다. </p>
<p>피보나치 수열의 경우 F(0) = 0, F(1) = 1 인 것이다. 이후 두 숫자를 더해가며 값을 구하지만 가장 작은 문제는 n=0, n=1인 경우로 볼 수 있다.</p>
<p>해당 문제의 기저 문제를 파악한 뒤, 배열 등에 미리 저장해두면 된다. </p>
<h3 id="6-구현">6. 구현</h3>
<p>개념과 DP를 사용하는 조건, DP문제를 해결하는 과정을 모두 익혔으니 실제로 코드로 어떻게 구현하는지 알아보자. </p>
<p>DP의 구현은 크게 두 가지로 구분할 수 있다. </p>
<ol>
<li>Top-Down(Memoization) </li>
<li>Bottom-Up(Tabulation)</li>
</ol>
<h4 id="1-top-down">1. Top-Down</h4>
<p>Top-Down 접근법은 재귀적(recursion) 방식으로 문제를 해결한다. 이 방식은 큰 문제를 시작으로 더 작은 하위 문제로 나누어가면서 문제를 해결한다. </p>
<p>각 하위 문제의 결과는 한 번 계산 되면 메모리에 저장되며, 같은 하위 문제가 다시 발생하면 저장된 값을 재사용한다. </p>
<p>이 과정을 &#39;Memoization&#39;이라고 한다.</p>
<p>장점 :</p>
<ul>
<li>문제의 자연스러운 재귀적 구조를 그대로 활용할 수 있어 개념적으로 이해하기 쉽다.</li>
<li>필요한 하위 문제만을 해결하기 때문에 불필요한 계산을 줄일 수 있다.</li>
</ul>
<p>단점 :</p>
<ul>
<li>재귀 호출의 스택 오버플로우 위험이 있다.</li>
<li>함수 호출에 따른 오버헤드가 있어, 때로는 비효율적일 수 있다.</li>
</ul>
<pre><code class="language-python"># Top-Down : Memoization
def fibonacci_TD(n:int) -&gt; int:

    # 기저 상태 n=0 -&gt; 0, n=1 -&gt; 1
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else :
        return fibonacci_TD(n-1) + fibonacci_TD(n-2)

# test case 
print(fibonacci_TD(10)) # 55
print(fibonacci_TD(5)) # 5</code></pre>
<h4 id="2-bottom-up">2. Bottom-Up</h4>
<p>Bottom-Up 접근법은 반복문을 사용하여 가장 작은 하위 문제부터 시작하여 점차적으로 큰 문제로 나아가면서 문제를 해결한다. </p>
<p>이 방식을 &#39;Tabulation&#39;이라고 하며, 각 하위 문제의 결과는 테이블(주로 배열)에 저장된다.</p>
<p>장점 : </p>
<ul>
<li>모든 하위 문제를 체계적으로 해결하기 때문에, 계산이 빠르고 효율적일 수 있다.</li>
<li>재귀 호출의 오버헤드가 없으며, 스택 오버플로우의 위험이 없다.</li>
</ul>
<p>단점 :</p>
<ul>
<li>불필요한 하위 문제까지 해결할 수 있으며, 이는 때로 비효율적일 수 있다.</li>
<li>문제의 해결 과정을 반복문으로 직접 구현해야하므로, 코드가 복잡해질 수 있다.</li>
</ul>
<pre><code class="language-python"># Bottom-Up: Tabulation
def fibonacci_BU(n:int) -&gt; int:

    # tabulation을 위한 list 정의
    dp = list()
    # 기저 상태 n=0 -&gt; 0, n=1 -&gt; 1
    dp.append(0)
    dp.append(1)

    for i in range(2, n+1):
        # 점화식 정의 : F(n) = F(n-1) + F(n-2)
        x = dp[i-1] + dp[i-2]
        # 결과 저장 
        dp.append(x)

    return dp[n]

# test case 
print(fibonacci_BU(10)) # 55
print(fibonacci_BU(5)) # 5</code></pre>
<h4 id="3-top-down-vs-bottom-up">3. Top-Down vs. Bottom-Up</h4>
<p>Top-Down과 Bottom-Up은 모두 동적 프로그래밍의 유효한 접근 방식이다. 각 방식의 선택은 문제의 특성, 개발자의 선호도, 그리고 특정 상황에서의 효율성 등을 고려하여 결정해야 한다.</p>
<p>일반적으로, <u>재귀적 구조가 명확하고 특정 하위 문제만 필요한 경우에는 <strong>Top-Down</strong></u>이 적합할 수 있으며, </p>
<p><u>문제를 체계적으로 접근해야 하거나 모든 가능한 경우를 고려해야 하는 경우에는 <strong>Bottom-Up</strong></u>이 더 적합할 수 있다.</p>
</br>

<blockquote>
<p><em>Ref.</em></p>
<p><a href="https://hongjw1938.tistory.com/47">https://hongjw1938.tistory.com/47</a></p>
<p><a href="https://velog.io/@boyeon_jeong/%EB%8F%99%EC%A0%81%EA%B3%84%ED%9A%8D%EB%B2%95Dynamic-Programming">https://velog.io/@boyeon_jeong/%EB%8F%99%EC%A0%81%EA%B3%84%ED%9A%8D%EB%B2%95Dynamic-Programming</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[알고리즘] LRU 알고리즘]]></title>
            <link>https://velog.io/@ja_efan/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-LRU-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98</link>
            <guid>https://velog.io/@ja_efan/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-LRU-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98</guid>
            <pubDate>Mon, 22 Apr 2024 12:26:24 GMT</pubDate>
            <description><![CDATA[<h1 id="lru-알고리즘-least-recently-used-algorithm">LRU 알고리즘 (Least Recently Used Algorithm)</h1>
<hr>
<h2 id="페이지-교체-알고리즘">페이지 교체 알고리즘</h2>
<hr>
<p><strong>페이지 교체 알고리즘</strong>(page replacement algorithm)은 페이징 기법으로 메모리를 관리하는 운영체제에서, 페이지 부재가 발생하여 새로운 페이지를 할당하기 위해 현재 할당된 페이지 중 어느 것과 교체할지를 결정하는 방법이다. </p>
<p>이 알고리즘이 사용되는 시기는 페이지 부재가 발생해 새로운 페이지를 적재 해야하나 페이지를 적재할 공간이 없어 이미 적재되어 있는 페이지 중 교체할 페이지를 정할 때 사용된다. 빈 페이지가 없는 상황에서 메모리에 적재된 페이지와 적재할 페이지를 교체함으로 페이지 부재 문제를 해결할 수 있다.</p>
<p>페이지 교체 알고리즘의 예로는, FIFO, LFU, LRU 알고리즘 등이 있다. </p>
<p>오늘은 그 중 LRU 알고리즘에 대해 공부한다.</p>
</br>

<h2 id="lru-알고리즘">LRU 알고리즘</h2>
<hr>
<p>LRU(Least Recently Used)는 <strong>가장 오랫동안 참조되지 않은 페이지를 교체</strong>하는 알고리즘이다.
이는 가장 오래된 페이지는 앞으로도 사용 확률이 낮다는 가설에 의해 만들어진 알고리즘이라고 한다.</p>
<h2 id="lru-알고리즘-원리">LRU 알고리즘 원리</h2>
<hr>
<p>LRU를 구현하기 위해서는 캐시가 가득 찼을 때, 가장 오랫동안 참조되지 않은 페이지를 찾아서 없애는 과정이 필요하다. </p>
<p>페이지를 새로 참조할 때 마다 캐시 리스트에 페이지 번호를 추가(append)하면, 캐시 리스트의 0번 인덱스의 원소가 가장 오랫동안 참조되지 않은 페이지 번호가 된다.</p>
<p>따라서 LRU의 원리를 파이썬의 List를 사용해 생각해보면, 다음과 같이 설명할 수 있다.</p>
<p>캐시의 크기가 3이라면 캐시 리스트의 길이는 3이고, 캐시 리스트에 이미 3개의 페이지 번호가 들어있다면, 0번 인덱스의 페이지 번호를 지우고(pop) 새로운 페이지 번호를 추가(apppend)해주는 방식이다. </p>
<p>캐시 사이즈는 3이고, 참조 값의 순서가 [1,2,1,3,4,1,5,4]인 예시를 그림으로 그려보면 다음과 같다. </p>
<img src = "https://velog.velcdn.com/images/ja_efan/post/29441e50-d10f-4e99-91ab-334ab3b721fc/image.png" width = 70%>


<blockquote>
<p>Cache Hit &amp; Cache Miss </p>
</blockquote>
<ul>
<li>Cache Hit : CPU가 참조하고자 하는 메모리가 캐시에 존재하는 경우 </li>
<li>Cache Miss : CPU가 참조하고자 하는 메모리가 캐시에 존재하지 않는 경우 </li>
</ul>
</br>

<h2 id="lru-적용-문제">LRU 적용 문제</h2>
<p>프로그래머스의 <a href="https://school.programmers.co.kr/learn/courses/30/lessons/17680">[1차] 캐시</a> (#17680)문제가 LRU 알고리즘을 사용하도록 되어있다. 
<img src="https://velog.velcdn.com/images/ja_efan/post/1caf6d6d-cff8-446d-b83b-2f3e6e766ab1/image.png" width=70%></p>
<p>이 문제에 대한 내 솔루션은 다음과 같다.
city에 대해서 &#39;Cache hit&#39; 의 경우 cache에 존재하던 city의 index를 pop()해주고, 다시 cache에 city를 append()해 LRU알고리즘을 구현했다.</p>
<pre><code class="language-python"># 17680
# https://school.programmers.co.kr/learn/courses/30/lessons/17680

def solution(cacheSize, cities):
    &quot;&quot;&quot;
    [1차] 캐시 : 
    DB 캐시를 적용할 때 캐시 크기에 따른 실행시간 측정 프로그램 작성

    Args :
    - cacheSize : 0이상 30이하의 정수 
    - cities : 도시 이름으로 이루어진 문자열 배열(list), len(cities) &lt;= 100,000
        각 도시 이름은 공백, 숫자, 특수문자 등이 없는 영문자로 구성, 대소문가 구분 x. 도시 이름은 최대 20자.

    Returns : 입력된 도시 이름 배열을 순서댇로 처리할 때, &#39;총 실행시간&#39; 출력 

    !! 캐시 교체 알고리즘은 LRU(Least Recently Used)를 사용
    &quot;&quot;&quot;

    cache = []
    time = 0
    if cacheSize == 0 :
        time = 5 * len(cities)
    else :
        for city in cities:
            city = city.lower()
            if city in cache: # cache hit !! -&gt; time += 1
                time += 1
                cache.pop(cache.index(city))
                cache.append(city)
            else : # chche miss -&gt; tmie += 5
                time += 5
                if len(cache) == cacheSize :
                    cache.pop(0)
                    cache.append(city)
                else : 
                    cache.append(city)
    return time

# test case 
# 50
print(solution(3, [&quot;Jeju&quot;, &quot;Pangyo&quot;, &quot;Seoul&quot;, &quot;NewYork&quot;, &quot;LA&quot;, &quot;Jeju&quot;, &quot;Pangyo&quot;, &quot;Seoul&quot;, &quot;NewYork&quot;, &quot;LA&quot;])) 
# 21
print(solution(3, [&quot;Jeju&quot;, &quot;Pangyo&quot;, &quot;Seoul&quot;, &quot;Jeju&quot;, &quot;Pangyo&quot;, &quot;Seoul&quot;, &quot;Jeju&quot;, &quot;Pangyo&quot;, &quot;Seoul&quot;])) # 21
# 60
print(solution(2,[&quot;Jeju&quot;, &quot;Pangyo&quot;, &quot;Seoul&quot;, &quot;NewYork&quot;, &quot;LA&quot;, &quot;SanFrancisco&quot;, &quot;Seoul&quot;, &quot;Rome&quot;, &quot;Paris&quot;, &quot;Jeju&quot;, &quot;NewYork&quot;, &quot;Rome&quot;])) # 60
# 52
print(solution(5, [&quot;Jeju&quot;, &quot;Pangyo&quot;, &quot;Seoul&quot;, &quot;NewYork&quot;, &quot;LA&quot;, &quot;SanFrancisco&quot;, &quot;Seoul&quot;, &quot;Rome&quot;, &quot;Paris&quot;, &quot;Jeju&quot;, &quot;NewYork&quot;, &quot;Rome&quot;])) # 52
# 16
print(solution(2, [&quot;Jeju&quot;, &quot;Pangyo&quot;, &quot;NewYork&quot;, &quot;newyork&quot;] )) # 16
# 25
print(solution(0, [&quot;Jeju&quot;, &quot;Pangyo&quot;, &quot;Seoul&quot;, &quot;NewYork&quot;, &quot;LA&quot;] )) # 25
# 27 
print(solution(3, [&quot;A&quot;, &quot;B&quot;, &quot;C&quot;, &quot;A&quot;, &quot;D&quot;, &quot;G&quot;, &quot;A&quot;] ))
# 21
print(solution(3, [&#39;a&#39;,&#39;b&#39;,&#39;a&#39;,&#39;c&#39;,&#39;d&#39;])) # 5 + 5 + 1 + 5 + 5 </code></pre>
</br>

<blockquote>
<p><em>Ref.</em>
<a href="https://dailylifeofdeveloper.tistory.com/355">https://dailylifeofdeveloper.tistory.com/355</a>
<a href="https://ko.wikipedia.org/wiki/%ED%8E%98%EC%9D%B4%EC%A7%80_%EA%B5%90%EC%B2%B4_%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98">https://ko.wikipedia.org/wiki/%ED%8E%98%EC%9D%B4%EC%A7%80_%EA%B5%90%EC%B2%B4_%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[SQL | 순위 함수 (RANK)]]></title>
            <link>https://velog.io/@ja_efan/SQL-%EC%88%9C%EC%9C%84-%ED%95%A8%EC%88%98-RANK</link>
            <guid>https://velog.io/@ja_efan/SQL-%EC%88%9C%EC%9C%84-%ED%95%A8%EC%88%98-RANK</guid>
            <pubDate>Thu, 18 Apr 2024 13:38:19 GMT</pubDate>
            <description><![CDATA[<h2 id="순위-함수">순위 함수</h2>
<hr>
<p>MySQL 8.0부터 Window함수를 지원하면서 보다 편리하게 순위를 매길 수 있게 되었다. 순위 함수는 Window 함수 중 비집계 함수이며 OVER절과 함께 사용해야 한다. 오늘은 RANK, DENSE_RANK, PERCENT_RANK, ROW_NUMBER 총 4가지 순위 함수를 알아보려 한다.</p>
</br>

<h2 id="rank">RANK</h2>
<hr>
<p>파티션 내 현재 행의 순위를 반환한다. 동점인 경우 동일한 순위를 반환한다. 공동 순위가 존재하는 경우, 다음 순위는 그 수만큼 건너뛰어 매겨진다. (ex. 1,2,2,4)</p>
<pre><code class="language-sql">RANK() OVER (
    PRATITION BY &lt;EXPR&gt; [{,&lt;EXPR&gt;...}]
    ORDER BY &lt;EXPR&gt; [ASC|DESC], [{,&lt;EXPR&gt;...}]
)</code></pre>
<p>예시 데이터로 급여(SAL)를 기준으로 사원 정보를 내림차순으로 순위를 매겨 나열하면 다음과 같다.</p>
<pre><code class="language-sql">SELECT *, RANK() OVER (
    ORDER BY SAL DESC) AS SAL_RANK 
FROM HR_EMPLOYEES;</code></pre>
<p>*<em>실행 결과 *</em>
<img src= 'https://velog.velcdn.com/images/ja_efan/post/be74bcb7-8fd4-4f80-8ea2-f40954eaa5b3/image.png' width=70%></p>
<p>김민석 팀원과 김송이 팀장이 같은 급여를 받아 공동 순위(2)가 발생했고, 그 다음 순위인 김연주 팀원과 양성태 팀원도 공동 순위(4)로 매겨진 것을 확인할 수 있다.</p>
</br>

<h2 id="dense_rank">DENSE_RANK</h2>
<hr>
<p>파티션 내 현재 행의 순위를 반환한다. 동점인 경우 동일한 순위를 반환한다. 공동 순위가 존재해도 다음 순위는 연속된 값으로 이어진다. (ex. 1,2,2,3...)</p>
<pre><code class="language-sql">DENSE_RANK() OVER (
    PARTITION BY &lt;EXPR&gt; [{,&lt;EXPR&gt;...}]
    ORDER BY &lt;EXPR&gt; [ASC|DESC], [{,&lt;EXPR&gt;...}]
)</code></pre>
<p>예시 데이터로 급여를 기준으로 사원 정보를 내림차순으로 순위를 매겨 나열하면 다음과 같다.</p>
<pre><code class="language-sql">SELECT *, DENSE_RANK() OVER (
    ORDER BY SAL DESC) AS SAL_RANK 
FROM HR_EMPLOYEES; </code></pre>
<p><strong>실행 결과</strong> 
<img src = 'https://velog.velcdn.com/images/ja_efan/post/4bf96e52-b24b-449f-8dea-4312957a95f7/image.png' width=70%></p>
<p>김민석 팀원과 김송이 팀장이 같은 급여를 받아 공동 순위(2)가 발생했고, 그 다음 순위인 김연주 팀원과 양성태 팀원도 공동 순위(3)로 매겨진 것을 확인할 수 있다.</p>
</br>

<h2 id="percent_rank">PERCENT_RANK</h2>
<hr>
<p>PERCENT_RANK는 백분율 순위를 구할 수 있다. 반환 값의 범위는 0에서 1까지이며, 아래 수식의 결과로 계산된 행의 상태 순위를 반환한다.</p>
<pre><code class="language-sql">(rank - 1) / (rows -1)</code></pre>
<p>수식에서 rank는 행의 순위이고, rows는 파티션 행의 수이다. partition 내의 첫 행은 항상 0을 반환한다. 또한, 동일한 rank에 대해서는 같은 값을 반환한다.</p>
<pre><code class="language-sql">PERCENT_RANK() OVER (
    PARTITION BY &lt;EXPR&gt; [{,&lt;EXPR&gt;...}]
    ORDER BY &lt;EXPR&gt; [ASC|DESC], [{,&lt;EXPR&gt;...}]
)</code></pre>
<p>예시 데이터로 직급(POSITION)별로 사원 정보를 급여 기준으로 내림차순으로 백분율 순위를 매겨 나열하면 다음과 같다. 백분율 순위 값의 소숫점 자릿수는 2가 되도록 반올림한다.(소숫점 셋째자리에서 반올림)</p>
<pre><code class="language-sql">SELECT *, ROUND(PERCENT_RANK() OVER(
    PARTITION BY POSITION 
    ORDER BY SAL), 2) AS SAL_RANK 
FROM HR_EMPLOYEES;</code></pre>
<p><strong>실행 결과</strong> 
<img src = 'https://velog.velcdn.com/images/ja_efan/post/080ced63-8c81-4140-b69b-86cde4c791b9/image.png' width=70%></p>
</br>

<h2 id="row_number">ROW_NUMBER</h2>
<hr>
<p>파티션 내 현재 행의 수를 반환한다. 행 마다 다른 값을 할당하여, 중복된 값을 반환하지 않 는다. 공동 순위를 허용하지 않고, 정렬 기준이 2개 이상일 때 사용하기 좋다.</p>
<pre><code class="language-sql">ROW_NUMBER () OVER (
    PARTITION BY &lt;EXPR&gt; [{,&lt;EXPR&gt;...}]
    ORDER BY &lt;EXPR&gt; [ASC|DESC], [{,&lt;EXPR&gt;...}]
)</code></pre>
<p>예시 데이터로 급여 기준으로 사원 정보를 내림차순으로 정렬하되, 급여가 같은 경우 사원 번호를 기준으로 오름차순으로 정렬하면 다음과 같다.</p>
<pre><code class="language-sql">SELECT *, ROW_NUMBER() OVER(
    ORDER BY SAL DESC, EMP_NO ASC) AS SAL_RANK 
FROM HR_EMPLOYEES;</code></pre>
<p><strong>실행 결과</strong>
<img src = "https://velog.velcdn.com/images/ja_efan/post/2f198f05-d77e-4202-b225-947aae0f5196/image.png" width=70%></p>
<p>급여가 같은 김민석 팀원과 김솜이 팀장은 EMP_NO를 기준으로 정렬된다.
마찬가지로 김연주 팀원과 양성태 팀원도 급여가 동일하므로 EMP_NO를 기준으로 정렬된 것을 확인할 수 있다.</p>
<p></br></br></p>
<blockquote>
<p>REFERENCE.
<a href="https://passwd.tistory.com/entry/MySQL-%EC%88%9C%EC%9C%84-%ED%95%A8%EC%88%98">https://passwd.tistory.com/entry/MySQL-%EC%88%9C%EC%9C%84-%ED%95%A8%EC%88%98</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[SQL | Flow Control Functions - 조건문]]></title>
            <link>https://velog.io/@ja_efan/SQL-Flow-Control-Functions-%EC%A1%B0%EA%B1%B4%EB%AC%B8</link>
            <guid>https://velog.io/@ja_efan/SQL-Flow-Control-Functions-%EC%A1%B0%EA%B1%B4%EB%AC%B8</guid>
            <pubDate>Mon, 29 Jan 2024 05:50:54 GMT</pubDate>
            <description><![CDATA[<h2 id="흐름-제어-연산자">흐름 제어 연산자</h2>
<hr>
<p>MySQL의 4가지의 흐름 제어 연산자가 있다.</p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody><tr>
<td>CASE</td>
<td>Case operator</td>
</tr>
<tr>
<td>IF()</td>
<td>if/else construct</td>
</tr>
<tr>
<td>IFNULL()</td>
<td>Null if/else construct</td>
</tr>
<tr>
<td>NULLIF()</td>
<td>Return NULL if expr1=expr2</td>
</tr>
</tbody></table>
</br>

<h2 id="case">CASE</h2>
<hr>
<h3 id="형식-1">형식 1</h3>
<pre><code class="language-sql">CASE value WHEN compare_value THEN result [WHEN campare_value THEN result ...][ELSE result] END</code></pre>
<h3 id="형식-2">형식 2</h3>
<pre><code class="language-sql">CASE WHEN condition THEN result [WHEN condition THEN result...][ELSE result] END</code></pre>
<p>첫 번째 형식의 CASE는 value와 compare_value의 비교 값이 True일 경우 result를 반환한다.</p>
<p>두 번째 CASE는 해당 절의 첫 번째 condition이 True일 경우 result를 반환한다.</p>
<p>만약 비교 값이나 condition이 True가 아닌 경우 ELSE 키워드 뒤에 오는 result가 반환되고, 만약 ELSE가 없을 경우 NULL이 반환된다.</p>
<h3 id="예제">예제</h3>
<pre><code class="language-sql">SELECT CASE 1 WHEN 1 THEN &#39;one&#39; WHEN 2 THEN &#39;two&#39; ELSE &#39;more&#39; END;
# 결과 : one

SELECT CASE WHEN 1&gt;0 THEN &#39;true&#39; ELSE &#39;false&#39; END;
# 결과 : true

SELECT CASE BINARY &#39;B&#39; WHEN &#39;a&#39; THEN 1 WHEN &#39;b&#39; THEN 2 END;
# 결과 : NULL</code></pre>
</br>

<h2 id="if">IF()</h2>
<hr>
<h3 id="형식">형식</h3>
<pre><code class="language-sql">IF(expr1, expr2, expr3)</code></pre>
<p>expr1이 True일 경우 (expr1 &lt;&gt; 0 and expr1 IS NOT NULL), IF()함수는 expr2를 반환하고 나머지 경우에는 expr3를 반환한다.</p>
<p>이중 IF문의 경우 다음과 같이 작성한다.</p>
<pre><code class="language-sql">IF(expr1, expr2, IF(expr3, expr4, expr5))</code></pre>
<p>expr1이 True일 경우 expr2를 반환하며, expr1이 False인 경우 expr3의 값에 따라 expr4 혹은 expr5를 반환한다.</p>
<p>Python으로 코드를 작성하면 다음과 같이 작성할 수 있다.</p>
<pre><code class="language-python">if expr1:
    expr2
elif expr3:
    expr4
else:
    expr5</code></pre>
<h3 id="예제-1">예제</h3>
<pre><code class="language-sql">SELECT IF(1&gt;2, 2,3);
# 결과 : 3

SELECT IF(1&lt;2, &#39;yes&#39;, &#39;no&#39;);
# 결과 : yes

SELECT IF(STRCMP(&#39;test&#39;,&#39;test1&#39;), &#39;no&#39;, &#39;yes&#39;);
# 결과 : no</code></pre>
<aside>
💡 STRCMP() 함수는 두 개의 비교 문자열이 동일할 경우 0을 반환하고, 다를 경우 1 혹은 -1을 반환한다. 1과 -1을 반환하는 경우는 나중에 자세히 다루어 보겠다.

</aside>

</br>

<h2 id="ifnull">IFNULL()</h2>
<hr>
<h3 id="형식-3">형식</h3>
<pre><code class="language-sql">IFNULL(expr1, expr2)</code></pre>
<p>expr1이 NULL이 아닌 경우 expr1을 반환하고, 나머지 경우 expr2를 반환한다.</p>
<h3 id="예제-2">예제</h3>
<pre><code class="language-sql">SELECT IFNULL(1,0);
# 결과 : 1

SELECT IFNULL(NULL, 10);
# 결과 : 10

SELECT IFNULL(1/0, 10);
# 결과 : 10

SELECT IFNULL(1/0, &#39;yes&#39;);
# 결과 : yes</code></pre>
</br>

<h2 id="nullif">NULLIF()</h2>
<hr>
<h3 id="형식-4">형식</h3>
<pre><code class="language-sql">NULLIF(expr1, expr2)</code></pre>
<p>expr1과 expr2가 동일한 경우 NULL을 반환한다. 나머지의 경우 expr1을 반환한다.</p>
<p>이는 다음과 같이 작성한 CASE문과 동일한 연산을 한다.</p>
<pre><code class="language-sql">CASE WHEN expr1=expr2 THEN NULL ELSE expr1 END</code></pre>
<h3 id="예제-3">예제</h3>
<pre><code class="language-sql">SELECT NULLIF(1,1);
# 결과 : NULL

SELECT NULLIF(1,3);
# 결과 : 1</code></pre>
<blockquote>
</blockquote>
<p>참고
<a href="https://dev.mysql.com/doc/refman/8.0/en/flow-control-functions.html#operator_case">https://dev.mysql.com/doc/refman/8.0/en/flow-control-functions.html#operator_case</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[DB | 5. 관계 데이터 모델 (part 2)]]></title>
            <link>https://velog.io/@ja_efan/DB-5.-%EA%B4%80%EA%B3%84-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%AA%A8%EB%8D%B8-part-2</link>
            <guid>https://velog.io/@ja_efan/DB-5.-%EA%B4%80%EA%B3%84-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%AA%A8%EB%8D%B8-part-2</guid>
            <pubDate>Fri, 26 Jan 2024 13:36:58 GMT</pubDate>
            <description><![CDATA[<h2 id="02-관계-데이터-모델의-제약">02 관계 데이터 모델의 제약</h2>
<p>기본적으로 관계 데이터 모델에서 정의하고 있는 기본 제약 사항은 <strong>&#39;키&#39;와 관련된 무결성 제약조건(integrity constraint)</strong>이다.</p>
<blockquote>
<p>데이터에서 말하는 <strong>무결성</strong>은 데이터에 결함이 없는 상태, 즉 데이터가 정확하고 유효하게 유지된 상태를 말한다.</p>
</blockquote>
<p>이러한 의미에서 무결성 제약조건의 주요 목적은 데이터베이스에 저장된 <strong>데이터의 무결성을 보장</strong>하고, 데이터베이스의 <strong>상태를 일관되게 유지</strong>하는데에 있다.</p>
<p>관계 데이터 모델이 포함하고 있는 무결성 제약조건에는 <strong>개체 무결성 제약조건</strong>과 <strong>참조 무결성 제약조건</strong>이 있다.</p>
<h3 id="1-개체-무결성-제약조건-entity-integrity-constraint">1. 개체 무결성 제약조건 (entity integrity constraint)</h3>
<p>개체 무결성 제약조건은 <strong>기본키를 구성하는 모든 속성은 널 값을 가지면 안 된다</strong>는 규칙이다.
관계 데이터 모델에서 릴레이션에 포함되어 있는 튜플들을 유일하게 구별하도록 릴레이션마다 기본키를 정의한다. 그런 기본키를 구성하는 속성들의 집합 전체 혹은 일부가 널 값을 수용하면 튜플의 유일성을 보장할 수 없어 기본키의 목적을 상실하게 된다.</p>
<p>이런 개체 무결성 제약조건을 만족시키려면 새로운 튜플이 삽입되는 연산과 기존 튜플의 기본키 속성 값이 변경되는 연산이 발생할 때 기본키에 널 값이 포함되는 상황에서의 연산의 수행을 거부하면 된다. 이러한 로직은 릴레이션을 생성할 때 기본키를 어떤 속성들로 구성할 것인지 결정하면서 함께 정해지게 된다.</p>
<h3 id="2-참조-무결성-제약조건-referential-integrity-constraint">2. 참조 무결성 제약조건 (referential integrity constraint)</h3>
<p>참조 무결성 제약조건이란 <strong>외래키는 참조할 수 없는 값을 가질 수 없다</strong>는 규칙이다.
일반적으로 외래키는 다른 릴레이션의 기본키를 참조하며, 릴레이션 간의 관계를 표현한다. 
이러한 외래키가 자신이 참조하는 릴레이션의 기본키와 상관없는 값을 가지게 되면 두 릴레이션의 관계는 무용지물이 된다. 따라서 외래키는 자신이 참조하는 릴레이션의 기본키 값으로 존재하는 값, 즉 참조 가능한 값만 가져야 한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[DB | 5. 관계 데이터 모델 (part 1)]]></title>
            <link>https://velog.io/@ja_efan/DB-5.-%EA%B4%80%EA%B3%84-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%AA%A8%EB%8D%B8</link>
            <guid>https://velog.io/@ja_efan/DB-5.-%EA%B4%80%EA%B3%84-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%AA%A8%EB%8D%B8</guid>
            <pubDate>Fri, 26 Jan 2024 13:19:31 GMT</pubDate>
            <description><![CDATA[<h2 id="01-관계-데이터-모델의-개념">01 관계 데이터 모델의 개념</h2>
<hr>
<h3 id="1기본-용어">1.기본 용어</h3>
<p>일반적으로 관계 데이터 모델에서는 하나의 개체에 관한 데이터를 <strong>릴레이션(Relation)</strong> 하나에 담아 데이터베이스에 저장한다. <u>즉, 릴레이션이란 관계형 데이터 모델에서 정보를 구분하여 저장하는 기본 단위이며, 2차원 테이블 형태로 표현한다..</u></p>
<p><img src='https://velog.velcdn.com/images/ja_efan/post/28d831a1-f1f5-4835-bfd0-6e2a79aa983e/image.png' width=70% height=70%></c></p>
<p>1-1. <strong>속성(attribute)</strong>
릴레이션의 <u>열(column)</u>에 해당하며, 각 속성은 서로 다른 이름을 이용해 구별한다. </p>
<p>1-2. <strong>튜플(tuple)</strong>
릴레이션의 <u>행(row)</u> 해당하며, 각 튜플은 유일한 개체이다.</p>
<p>1-3. <strong>도메인(domain)</strong>
하나의 속성이 가질 수 있는 모든 값의 집합을 해당 속성의 도메인이라고 한다.
관계 데이터 모델에서는 속성 값으로 더는 분해할 수 없는 <u>원자 값</u>만 사용할 수 있다.
가능한 값을 일일이 나열하여 도메인을 정의하기에는 한계가 있기 때문에 일반적으로 속성에 적합한 데이터 타입을 도메인으로 정의하는 경우가 많다.</p>
<p>1-4. <strong>널(null)</strong>
릴레이션에 있는 속성의 값을 모르거나, 적합한 값이 없는 경우에 널이라는 특별한 값을 사용할 수 있다. 널은 특정 속성에 해당하는 값이 없음을 나타내므로 숫자 0이나 공백과는 전혀 다른 값이다.</p>
<p>1-5. <strong>차수(degree)</strong>
하나의 릴레이션에서 속성의 개수를 해당 릴레이션의 차수라고 한다. </p>
<p>1-6. <strong>카디널리티(cardinality)</strong>
하나의 릴레이션에서 튜플의 개수를 해당 릴레이션의 카디널리티라고 한다.</p>
<h3 id="2릴레이션과-데이터베이스의-구성">2.릴레이션과 데이터베이스의 구성</h3>
<p>2-1. <strong>릴레이션 스키마(relation schema)</strong> 
릴레이션 스키마는 릴레이션의 이름과 속성들로 정의하는 릴레이션의 <u>논리적 구조</u>이다.
일반적으로 아래와 같은 형태로 표현한다.</p>
<pre><code>릴레이션_이름(속성1, 속성2, ..., 속성 n)</code></pre><p>이렇게 표현된 릴레이션 스키마를 보면 릴레이션의 이름이 무엇이고, 어떤 속성들로 구성되어 있는지 전체 구조를 쉽게 파악할 수 있다. </p>
<p>2-2. <strong>릴레이션 인스턴스(relation instance)</strong>
릴레이션 인스턴스는 어느 한 시점에 릴레이션에 존재하는 <u>튜플들의 집합</u>이다.
DBMS가 내부적으로 데이터 조작어를 이용하여 릴레이션 인스턴스의 <u>튜플을 검색하거나, 새로운 튜플의 삽입과 기존 튜플의 삭제 및 수정</u>을 진행한다. </p>
<p>2-3. <strong>데이터베이스 스키마와 데이터베이스 인스턴스</strong>
일반적으로 데이터베이스는 여러 개의 릴레이션으로 구성된다. 예를 들면, 학교 운영을 위한 데이터베이스는 학생 릴레이션, 교사 릴레이션, 강의 릴레이션 등으로 구성할 수 있다.</p>
<p>데이터베이스의 전체 구조를 의미하는 데이터베이스 스키마는 데이터베이스를 구성하는 <u>릴레이션 스키마의 집합</u>이다. 즉, 특정 데이터베이스 스키마를 설계한다는 것은 해당 데이터베이스에 필요한 릴레이션들의 스키마를 정의하는 것과 같은 의미이다.</p>
<p>데이터베이스 인스턴스는 어느 한 시점에 데이터베이스에 존재하는 <u>데이터 내용의 전체 집합</u>을 의미한다. 즉, 데이터베이스를 구성하는 모든 릴레이션의 인스턴스를 모아놓은 것이다.</p>
<p><img src='https://velog.velcdn.com/images/ja_efan/post/c721793f-f8fe-4ab4-97a7-d5755bda6877/image.png' width=70% height=70%></c></p>
<br/>

<h3 id="3-릴레이션의-특성">3. 릴레이션의 특성</h3>
<p>관계 데이터 모델의 릴레이션에는 4가지 중요한 특성이 있다. 
이 4가지 특성을 모두 만족하는 테이블만이 릴레이션으로 인정받을 수 있다.</p>
<blockquote>
</blockquote>
<ol>
<li><strong>튜플의 유일성</strong> : 하나의 릴레이션에는 동일한 튜플이 존재할 수 없다. 즉, 튜플의 중복이 불가하다.</li>
</ol>
<p>-&gt; 튜플마다 고유한 값을 갖는 속성을 <u>키(Key)</u>로 두어 각 튜플을 구분한다.
2. <strong>튜플의 무순서</strong> : 하나의 릴레이션에서 튜플의 순서는 무의미하다. 
3. <strong>속성의 무순서</strong> : 하나의 릴레이션에서 속성의 순서는 무의미하다.
4. <strong>속성의 원자성</strong> : 릴레이션의 속성 값으로 원자 값만 사용할 수 있다.</p>
<br/>

<h3 id="4-키의-종류">4. 키의 종류</h3>
<p><strong>키(Key)</strong> : 릴레이션의 튜플들을 유일하게 구별해주는 역할을 하며, 속성 또는 속성들의 집합으로 구성된다.</p>
<p><strong>키의 특성</strong></p>
<blockquote>
</blockquote>
<ul>
<li><strong>유일성(uniqueness)</strong> : 키가 갖추어야 하는 기본 특성으로, 하나의 릴레이션에서 키로 지정된 속성 값은 튜플마다 달라야 한다는 특성이다. 즉, 키 값이 같은 튜플은 존재할 수 없다는 것이다.</li>
<li><strong>최소성(minimality)</strong> : 꼭 필요한 최소한의 속성들로만 키를 구성하는 특성이다.</li>
</ul>
<p>4.1 <strong>슈퍼키(super key)</strong></p>
<p><u>유일성</u>을 만족하는 속성 또는 속성 집합.
즉, 튜플을 구분할 수 있는 하나의 속성 또는 속성 집합은 모두 슈퍼키이다.</p>
<p>4.2 <strong>후보키(candidate key)</strong></p>
<p><u>유일성</u>과 <u>최소성</u>을 모두 만족하는 속성 또는 속성 집합.
후보키는 튜플을 유일하게 구별하기 위해 꼭 필요한 최소한의 속성들로만 이루어지므로 슈퍼키 중에서 최소성을 만족하는 것이 후보키가 된다.
후보키가 되기위해 만족해야 하는 유일성과 최소성의 특성은 새로운 튜플이 삽입되거나 기존 튜플의 속성 값이 변경되어도 유지되어야 한다.</p>
<p>4.3 <strong>기본키(primary key)</strong></p>
<p>릴레이션에서 튜플을 구별하기 위해 여러 개의 후보키를 모두 사용할 필요는 없다. 
따라서 여러 후보키 중에서 기본적으로 사용할 키를 선택하는데, 그 키가 기본키이다.
각 튜플을 유일하게 구분하는 기본키인 만큼, 선택할 때 고려할만한 기준도 있다.</p>
<blockquote>
</blockquote>
<ol>
<li>널 값을 가질 수 있는 속성이 포함된 후보키는 기본키로 부적합하다.</li>
<li>값이 자주 변경되는 속성이 포함된 후보키는 기본키로 부적합하다.</li>
<li>단순한 후보키를 기본키로 선택한다.</li>
</ol>
<p>즉, non-nullable하고 값에 변화가 적으며 단순한 후보키를 기본키로 선택하는 것이 데이터베이스 사용에 있어 편리할 것이다.</p>
<p>4.4 <strong>대체키(alternate key)</strong></p>
<p>여러 후보키 중 기본키를 제외한 나머지 후보키를 대체키라고 한다.</p>
<p>4.5 <strong>외래키(foreign key)</strong></p>
<p>외래키는 어떤 릴레이션에 소속된 속성 또는 속성 집합이 다른 릴레이션의 기본키가 되는 키이다.
다시 말해 다른 릴레이션의 기본키를 그대로 참조하는 속성의 집합이 외래키이다.
이러한 외래키는 <u>릴레이션 간의 관계</u>를 올바르게 표현하기 위해 필요하다.</p>
<p>이때, 다른 릴레이션의 기본키를 외래키로 가지고 있는 릴레이션을 <u>&#39;참조하는 릴레이션&#39;</u>이라 하고,
기본키를 가진 릴레이션을 <u>&#39;참조되는 릴레이션&#39;</u>이라고 한다.</p>
<p>이러한 릴레이션 간의 관계에서 참조되는 릴레이션과 참조하는 릴레이션이 동일할 수도 있다. 즉, 외래키가 자신이 속한 릴레이션의 기본키를 참조하도록 정의할 수도 있는 것이다.</p>
<p>예를 들어보자면, 쇼핑몰의 &#39;고객 릴레이션&#39;에서 &#39;고객 아이디&#39;를 기본키로 갖고, &#39;고객 아이디&#39;를 참조하는 &#39;추천고객&#39;을 외래키로 갖는다면 참조되는 릴레이션도 &#39;고객 릴레이션&#39;이 되고 참조하는 릴레이션도 &#39;고객 릴레이션&#39;이 된다.</p>
<p>또한 외래키는 기본키를 참조하지만 기본키는 아니므로 널 값을 가질 수 있다. 
위의 예에서 &#39;추천고객&#39;필드는 의무사항이 아니므로(기본키가 아니므로) 널 값을 가질 수 있다. </p>
<blockquote>
</blockquote>
<p>reference. 데이터베이스개론 2판, 김연희, 한빛아카데미</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[SQL | 정규 표현식을 이용한 검색, REGEXP]]></title>
            <link>https://velog.io/@ja_efan/SQL-%EC%A0%95%EA%B7%9C-%ED%91%9C%ED%98%84%EC%8B%9D%EC%9D%84-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EA%B2%80%EC%83%89</link>
            <guid>https://velog.io/@ja_efan/SQL-%EC%A0%95%EA%B7%9C-%ED%91%9C%ED%98%84%EC%8B%9D%EC%9D%84-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EA%B2%80%EC%83%89</guid>
            <pubDate>Fri, 26 Jan 2024 06:51:47 GMT</pubDate>
            <description><![CDATA[<h2 id="regexp">REGEXP?</h2>
<hr>
<p>REGEXP는 <strong>Regular Expression(정규 표현식)을 이용한 검색</strong>을 제공한다.</p>
<p>REGEXP는 <strong>LIKE보다 다양한 검색</strong>을 할 수 있도록 도와준다.</p>
<p>REGEXP를 사용하면 SQL에서 정규표현식을 사용하여 기본 연산자보다 복잡한 문자열 조건을 이용하여 데이터를 검색할 수 있다.</p>
<h2 id="regular-expression정규표현식이란">Regular Expression(정규표현식)이란?</h2>
<hr>
<p>정규표현식은 특정한 규칙을 가진 <strong>문자열의 집합을 표현</strong>하는데 사용하는 형식 언어이다.</p>
<p>문자열을 처리하는 방법 중의 하나로, 특정한 조건의 문자를 ‘검색’하거나 ‘치환’하는 과정을 매우 간편하게 처리할 수 있도록 해주는 수단이다.</p>
<p>정규표현식은 <strong>pattern</strong>을 사용해서 문자열을 처리한다.</p>
<p>찾을 대상문자열에서 정규표현식을 사용해 해당 pattern과 일치하는 문자열을 검색하는 것이다.</p>
<p>pattern과 일치하는 문자열을 찾은 이후 추출하거나 치환할 수 있다.</p>
<h2 id="pattern-종류">Pattern 종류</h2>
<hr>
<h3 id="matching">Matching</h3>
<table>
<thead>
<tr>
<th>Pattern</th>
<th>기능</th>
<th>예시</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>.</td>
<td>문자 하나</td>
<td>“…”</td>
<td>문자열의 길이가 세 글자 이상인 것을 찾음.</td>
</tr>
<tr>
<td></td>
<td></td>
<td>OR,</td>
<td>(수직선)으로 구분된 문자에 해당하는 문자열을 찾음.</td>
</tr>
<tr>
<td>[]</td>
<td>[]안에 나열된 패턴에 해당하는 문자열을 찾음.</td>
<td>“[123]d”</td>
<td>대상 문자열에서 “1d” 또는 “2d” 또는 “3d”인 문자열을 찾음.</td>
</tr>
<tr>
<td>^</td>
<td>시작하는 문자열을 찾음.</td>
<td>“^Hi”</td>
<td>대상 문자열에서 “Hi”으로 시작하는 문자열을 찾음.</td>
</tr>
<tr>
<td>$</td>
<td>끝나는 문자열을 찾음.</td>
<td>“bye$”</td>
<td>대상 문자열에서 “bye”로 끝나는 문자열을 찾음.</td>
</tr>
</tbody></table>
<br/>

<h3 id="numbers-limit">Numbers Limit</h3>
<table>
<thead>
<tr>
<th>Pattern</th>
<th>기능</th>
<th>예시</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>*</td>
<td>0회 이상 나타나는 문자</td>
<td>“a*”</td>
<td>‘a’가 0번 이상 등장하는 문자열을 찾음. ‘b’, ‘a’, “aa” 모두 해당.</td>
</tr>
<tr>
<td>+</td>
<td>1회 이상 나타나는 문자</td>
<td>“b+”</td>
<td>‘b’가 1번 이상 등장하는 문자열을 찾음. “bye”, “bob” 모두 해당.</td>
</tr>
<tr>
<td>{m,n}</td>
<td>m회 이상 n회 이하 반복되는 문자</td>
<td>“c{1,3}”</td>
<td>‘c’가 1회 이상 2회 이하 반복되는 문자열을 찾음. “coke”, “cocacola” 모두 해당.</td>
</tr>
<tr>
<td>?</td>
<td>0 또는 1회 나타나는 문자</td>
<td>“[abc]?”</td>
<td>‘a’ 또는 ‘b’ 또는 ‘c’가 0~1회 등장하는 문자열을 찾음. “apple”, “bag”, ‘dog’ 모두 해당.</td>
</tr>
</tbody></table>
<br/>

<h3 id="string-group">String Group</h3>
<table>
<thead>
<tr>
<th>Pattern</th>
<th>기능</th>
<th>예시</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>[A-z] 또는 [:alpha:] 또는 \a</td>
<td>알파벳 대문자 또는 소문자인 문자열을 찾음.</td>
<td>“[A-z]+”</td>
<td>대상 문자열에서 알파벳이 한 개 이상인 문자열을 찾음.</td>
</tr>
<tr>
<td>[0-9] 또는 [:digit:] 또는 \d</td>
<td>숫자인 문자열을 찾음.</td>
<td>“^[0-9]+”</td>
<td>대상 문자열에서 한개 이상의 숫자로 시작하는 문자열을 찾음</td>
</tr>
<tr>
<td><br/></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody></table>
<h3 id="not">Not</h3>
<table>
<thead>
<tr>
<th>Pattern</th>
<th>기능</th>
<th>예시</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>[^문자]</td>
<td>[]안의 문자를 포함하지 않는 문자열을 찾음.</td>
<td>“[^abc]”</td>
<td>‘a’ 또는 ‘b’ 또는 ’c’를 포함하지 않는 문자열을 찾음. “cat”, “bye”, “coke” 모두 제외 됨.</td>
</tr>
</tbody></table>
<br/>

<h3 id="regexp-사용-예제">REGEXP 사용 예제</h3>
<pre><code class="language-sql"># &#39;a&#39; 또는 &#39;b&#39; 또는 &#39;c&#39;가 포함된 문자열을 찾고 싶을 때

# 정규표현식을 사용하지 않을 때 
SELECT * 
FROM [table_name]
WHERE [col_name] like &quot;%a%&quot;
OR [col_name] like &quot;%b%&quot;
OR [col_name] like &quot;%c%&quot;;

# 정규표현식을 사용할 때
SELECT * 
FROM [table_name]
WHERE [col_name] REGEXP &quot;a|b|c&quot;;

# &quot;hi&quot; 또는 &quot;hello&quot;로 시작하는 문자열을 찾고 싶을 때

# 정규표현식을 사용하지 않을 때
SELECT * 
FROM [table_name]
WHERE [col_name] like &quot;hi%&quot; 
OR [col_name] like &quot;hello%&quot;;

# 정규표현식을 사용할 때
SELECT * 
FROM [table_name]
WHERE [col_name] REGEXP &quot;^hi|^hello&quot;;

-------------------------------------------------------
-------------------------------------------------------

# 길이가 5글자인 문자열 중 2번째 자리부터 ab를 포함하는 문자열을 찾고 싶을 때

# 정규표현식을 사용하지 않을 때
SELECT * 
FROM [table_name]
WHERE CHAR_LENGTH([col_name])=7 AND SUBSTRING([col_name],2,2)=&quot;ab&quot;;

# 정규표현식을 사용할 때
SELECT *
FROM [table_name]
WHERE [col_name] REGEXP &quot;^.ab..$&quot;;

-------------------------------------------------------
-------------------------------------------------------

# 텍스트와 숫자가 섞여 있는 문자열에서 숫자로만 이루어진 문자열을 찾고 싶을 때

# 정규표현식을 사용하지 않을 때
SELECT * 
FROM [table_name]
WHERE [col_name] LIKE ????????????

# 정규표현식을 사용할 때
SELECT * 
FROM [table_name]
WHERE [col_name] REGEXP &quot;^[0-9]+$&quot; 
-- OR [col_name] REGEXP &quot;^[:digit:]+$&quot; 
-- OR [col_name] REGEXP &quot;^\d+$&quot; </code></pre>
<h2 id="주의사항">주의사항</h2>
<hr>
<p>정규표현식 검색을 이용할 때 절대 사용자에게 정규식 기능을 제공해서는 안된다. 각종 오류를 유발할 수 있고 SQL Injection에 취약해지기 때문에, 정규표현식의 검색은 개발자가 미리 정한 테두리 안에서 행해져야 한다.</p>
<br/>
<br/>



<blockquote>
<p>참고 
<a href="https://velog.io/@gillog/MySQL-REGEXPRegular-Expression%EC%A0%95%EA%B7%9C-%ED%91%9C%ED%98%84%EC%8B%9D">https://velog.io/@gillog/MySQL-REGEXPRegular-Expression정규-표현식</a>
    <a href="https://dev.mysql.com/doc/refman/8.0/en/regexp.html">https://dev.mysql.com/doc/refman/8.0/en/regexp.html</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[SQL | Common Table Expression, CTE]]></title>
            <link>https://velog.io/@ja_efan/SQL-Common-Table-Expression-CTE</link>
            <guid>https://velog.io/@ja_efan/SQL-Common-Table-Expression-CTE</guid>
            <pubDate>Thu, 25 Jan 2024 08:52:13 GMT</pubDate>
            <description><![CDATA[<h2 id="cte">CTE?</h2>
<hr>
<blockquote>
<p>A common table expression(CTE) is a named temporary result set that exists within the scope of a single statement and that can be referred to later within that statement, possibly multiple times.</p>
</blockquote>
<p>CTE는 단일 쿼리 내부에서 임시로 결과를 저장해 놓고, 해당 쿼리 내에서 반복적으로 사용 가능한 임시 결과 집합(테이블)이다.
즉, 임시로 쿼리 결과를 저장해 놓고, 여러번 참조해서 사용하는 용도로 사용한다.
메인 쿼리 내에서 정의되어 사용된다는 점이 서브 쿼리(파생 테이블)과 비슷하지만 재사용이 가능하다는 점에서 서브 쿼리와 차이가 있다.</p>
<p>CTE와의 비교 대상으로는 VIEW가 있다. 하지만 VIEW의 생성을 위해서는 권한이 필요하고, 이는 사전에 정의 되어야 한다. 반면 CTE는 권한이 필요 없으며 쿼리문이 끝날 때 까지만 지속되는 일회성 테이블이다.</p>
<h2 id="cte-특징">CTE 특징</h2>
<hr>
<p>쿼리의 가독성 향상</p>
<p>재사용성</p>
<p>향상된 성능..?</p>
<p>권한이 필요 없음 (비교 대상인 VIEW와의 차이점)</p>
<p>재귀 쿼리 생성 가능 : 계층적 데이터를 처리할 때 매우 유용</p>
<h2 id="cte-문법">CTE 문법</h2>
<hr>
<p>CTE를 사용하기 위한 문법은 다음과 같다. WITH 키워드와 AS 로 cte_name에 맵핑할 쿼리를 작성한 후 cte_name으로 지정한 테이블을 조회한다.</p>
<pre><code class="language-sql">WITH 
        cte1 AS (SELECT a,b FROM table1),
        cte2 AS (SELECT c,d FROM table2)

SELECT b,d FROM cte1 JOIN cte2
WHERE cte1.a = cte2.c;</code></pre>
<p>cte의 이름 지정 부분 뒤에 (column_list)가 오는 경우 생성되는 cte의 열(필드) 이름을 지정할 수 있다.</p>
<pre><code class="language-sql">WITH
        cte1 (col1, col2) AS (SELECT a,b FROM table1)

SELECT * FROM cte1;</code></pre>
<h2 id="cte-예제">CTE 예제</h2>
<hr>
<pre><code class="language-sql"># 한식당만 조회하는 CTE
WITH kor_restaurants AS (
        SELECT *
        FROM restaurants 
        WHERE rest_type = &#39;kor&#39;
)

SELECT rest_name, rest_id FROM kor_restaurants;</code></pre>
<p>CTE를 정의하는 부분의 쿼리를 보면 굉장히 간단한 쿼리이다. restaurants 테이블에서 rest_type 필드의 값이 ‘kor’인 식당만 조회하여 kor_restaurants에 저장해놓은 것이다.</p>
<p>정의된 CTE를 이용하는 쿼리를 보면 위에서 정의한 kor_restaurants에서 rest_name과 rest_id 필드의 값만 조회하는 것을 볼 수 있다.</p>
<h2 id="view-대신-cte">VIEW 대신 CTE</h2>
<hr>
<p>데이터베이스 사용자에게 VIEW를 생성할 권한이 없을 수 있다. CTE는 일반 SELECT와 마찬가지로 특정 권한을 요구하지 않는다.</p>
<p>또한 일반적인 경우 VIEW 대신 CTE를 사용하는 것이 단일 materialization만 필요하고(테이블이 cache처럼 임시로 저장된다는 의미) 생성된 임시 테이블을 메인 쿼리에서 여러 번 참조할 수 있기 때문에 더 빠르고 효율적이다.</p>
<p>단, 이로 인해 CTE를 무분별하게 사용할 경우, query performance가 오히려 더 떨어질 수도 있다.</p>
<p>Query optimizer가 execution plan을 계산할  때, CTE의 최적화를 고려하지 않기 때문에 CTE를 생성할 때 필요한 데이터를 미리 필터링하는 등 최적화를 고려한 쿼리 작성이 필요하다.</p>
<h2 id="recursive-cte">Recursive CTE</h2>
<hr>
<blockquote>
<p>A recursive common table expression is one having a subquery that refers to its own name.</p>
</blockquote>
<p>재귀 CTE는 CTE를 정의하는 서브 쿼리에 자기 자신을 참조하는 구문이 있는 형식으로 정의된다.</p>
<pre><code class="language-sql">WITH RECURSIVE cte (n) AS 
(
        SELECT 1
        UNION ALL
        SELECT n+1 FROM cte WHERE n &lt; 5
)
SELECT * FROM cte;

# 결과 
+------+
| n    |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
|    5 |
+------+</code></pre>
<p>쿼리를 분석해보자. </p>
<p>CTE를 정의하는 괄호 안의 쿼리를 서브 쿼리라고 하자.</p>
<p>서브 쿼리의 첫 SELECT 절은 CTE의 첫 row를 생성하고, 이는 자기 자신을 참조하지 않는다.</p>
<p>두 번째 SELECT 절은 첫 row를 제외한 추가 row들을 생성하는데, 이는 FROM 절에 있는 자기 자신(cte)를 참조한다. </p>
<p>이러한 재귀는 두 번째 SELECT 절에서 더 이상 새로운 row를 생성하지 않을 때 까지 반복되다 종료된다.</p>
<p>이때 더 이상 새로운 row를 생성하지 않을 조건은 WHERE 절에 작성된다.</p>
<p>따라서 recursive CTE의 구성은 nonrecursive SELECT 절과 recursive SELECT 절로 이루어져있다.</p>
<h2 id="recursive-cte-특징">Recursive CTE 특징</h2>
<hr>
<p>컬럼의 데이터 타입은 nonrecursive SELECT절에 의해 결정된다.</p>
<p>컬럼은 nullable하다.</p>
<p>nonreucursive part와 recursive part를 구분하는 키워드(위의 예시에서는 UNION ALL)에 따라 중복 허용 여부가 결정된다. (UNION DISTINCT 키워드 사용시 중복 제거)</p>
<p>Recursive part의 각 iteration은 오직 이전 iteration에서 생성된 row에 대해서만 동작한다.</p>
<blockquote>
<p>참고 
<a href="https://umanking.github.io/2021/07/13/mysql-cte/">https://umanking.github.io/2021/07/13/mysql-cte/</a>
<a href="https://dev.mysql.com/doc/refman/8.0/en/with.html">https://dev.mysql.com/doc/refman/8.0/en/with.html</a>
<a href="https://jjon.tistory.com/entry/MySQL-80-%EC%8B%A0%EA%B8%B0%EB%8A%A5-CTECommon-Table-Expression-%ED%99%9C%EC%9A%A9">https://jjon.tistory.com/entry/MySQL-80-신기능-CTECommon-Table-Expression-활용</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[DB | 4. 데이터 모델링]]></title>
            <link>https://velog.io/@ja_efan/DB-4.-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%AA%A8%EB%8D%B8%EB%A7%81</link>
            <guid>https://velog.io/@ja_efan/DB-4.-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%AA%A8%EB%8D%B8%EB%A7%81</guid>
            <pubDate>Sat, 13 Jan 2024 08:34:26 GMT</pubDate>
            <description><![CDATA[<h2 id="01-데이터-모델링과-데이터-모델의-개념">01 데이터 모델링과 데이터 모델의 개념</h2>
<p>데이터 모델링(data modeling)은 현실 세계에 존재하는 데이터를 컴퓨터 세계의 데이터베이스로 옮기는 변환 과정을 의미한다.</p>
<p>현실 세계의 데이터를 컴퓨터 세계로 옮기기 위해 필요한 작업 중 추상화(abstraction)라는 작업이 있다.
추상화는 현실 세계에 존재하는 개체로부터 중요한 개념을 분리하는 작업이다. 
즉, 우리는 추상화된 정보를 가지고 현실 세계의 개체를 유추할 수 있다.</p>
<ul>
<li><p><strong>개념적 모델링</strong></p>
<p>  개념적 모델링(conceptual modeling)은 현실 세계의 중요 데이터를 추출하여 개념 세계로 옮기는 작업을 말한다.</p>
</li>
<li><p><strong>논리적 모델링</strong></p>
<p>  논리적 모델링(logical modeling)은 개념 세계의 데이터를 데이터베이스에 저장할 구조를 결정하고, 해당하는 구조로 표현하는 작업을 말한다.</p>
</li>
</ul>
<p>⇒ 보통 두 모델링 단계를 통틀어 데이터 모델링이라고 부른다.</p>
<p>데이터 모델(data model)은 데이터 모델링의 결과를 표현하는 도구로, 개념적 데이터 모델과 논리적 데이터 모델이 있다. </p>
<ul>
<li><p><strong>개념적 데이터 모델</strong></p>
<p>  개념적 데이터 모델은 사람의 머리로 이해할 수 있도록 현실 세계를 개념적 모델링 하여 데이터베이스의 개념적 구조로 표현하는 도구이다.</p>
</li>
<li><p><strong>논리적 데이터 모델</strong></p>
<p>  논리적 데이터 모델은 개념적 구조를 논리적 모델링하여 데이터베이스의 논리적 구조로 표현하는 도구이다.</p>
</li>
</ul>
<p>일반적으로 데이터 모델은 데이터 구조(data structure), 연산(operation), 제약조건(contraint)으로 구성된다.</p>
<p>보통 개념적 데이터 모델링과 논리적 데이터 모델링을 통틀어 데이터 베이스 설계라고 한다.</p>
<h2 id="02-개체-관계-모델">02 개체-관계 모델</h2>
<p>개체-관계 모델은 1976년 Peter Chen이 제안한 것으로, 개체(entity)와 개체 간의 관계(relationship)를 이용해 현실 세계를 개념적 구조로 표현하는 방법이다.</p>
<p>현실 세계를 개체-관계 모델을 이용해 개념적으로 모델링하여 도식화한 것을 개체-관계 다이어그램(E-R diagram)이라 한다.</p>
<h3 id="1-개체">1. 개체</h3>
<p>개체(entity)는 중요한 데이터를 가지는 사람, 사물 혹은 개념이나 사건 등을 의미하며, 개념적 모델링을 하는데 있어 중요한 요소이다. </p>
<p>개체는 다른 개체와 구별되는 이름을 가지고 있고, 각 개체만의 고유한 특성이나 상태, 즉 속성을 하나 이상 갖는다.
개체를 고유의 이름과 속성들로 정의한 것을 개체 타입(entity type)이라하고, 개체를 구성하는 속성이 실제 값을 가짐으로써 실체화된 개체를 개체 인스턴스(entity instance)라고 한다.</p>
<p>특정 개체 타입에 대한 개체 인스턴스들을 모아 놓은 것을 개체 집합(entity set)이라하며, 데이터베이스에서 실제로 저장하고 관리하는 것은 이 개체 집합이라고 할 수 있다.</p>
<p>E-R 다이어그램에서 개체는 사각형으로 표현하고, 사각형 안에 개체의 이름을 표기한다.</p>
<h3 id="2-속성">2. 속성</h3>
<p>속성(attribute)은 개체가 가지고 있는 고유한 특성이다. 속성 그 자체만으로는 큰 의미가 없지만 관련 있는 속성들을 모아 개체를 구성하면 하나의 중요한 의미를 표현할 수 있다. 속성은 일반적으로 의미 있는 데이터의 가장 작은 논리적 단위로 인식된다.</p>
<p>E-R 다이어그램에서 속성은 타원으로 표현하고, 타원 안에 속성의 이름을 표기한다.</p>
<ol>
<li><p><strong>단일 값 속성과 다중 값 속성</strong></p>
<p> 특정 개체를 구성하는 속성의 값이 하나면 단일 값 속성(single-valued attribute)으로 분류한다. 
 즉, 한 개체가 특정 속성에 대해 갖는 값이 오직 하나인 속성을 의미한다.</p>
<p> 이와 달리 속성이 값을 여러 개 가질 수 있으면 다중 값 속성(multi-valued attribute)으로 분류한다.
 즉, 한 개체가 특정 속성에 대해 갖는 값이 두개 이상일 수 있는 속성을 의미한다.</p>
<p> 다중 값 속성은 E-R 다이어그램에서 이중 타원으로 표현한다.</p>
</li>
<li><p><strong>단순 속성과 복합 속성</strong></p>
<p> 단순 속성(simple attribute)은 의미를 더는 분해할 수 없는 속성이다.
 즉, 단순 속성의 값은 의미가 오직 하나이다. </p>
<p> 반면, 복합 속성(composite attribute)은 의미를 분해할 수 있어 값이 여러 개의 의미를 포함한다. 
 즉, 복합 속성은 여러 개의 단순 속성이 합쳐진 속성으로 볼 수 있다. </p>
</li>
<li><p><strong>유도 속성</strong></p>
<p> 값이 별도로 저장되는 것이 아니라 기존의 다론 속성 값에서 유도되어 결정되는 속성을 유도속성(derivated attribute)으로 분류한다. 
 속성 1과 속성 2의 계산으로 유도되는 속성 3이 있다고 가정한다면, 속성 1과 속성 2는 저장 속성(stored attribute)이고, 속성 3은 유도 속성이 된다.
 실제로 값을 가지고 있는 것은 저장 속성이고 유도 속성은 필요할 때마다 계산되므로 값을 따로 저장할 필요가 없다.</p>
<p> 유도 속성은 E-R 다이어그램에서 점선 타원으로 표현한다.</p>
</li>
<li><p><strong>널 속성</strong></p>
<p> 널(null) 값은 아직 결정되지 않았거나 모르는 값(unknown value)을 의미한다. 또는 해당되는 값이 없는, 즉 존재하지 않는 값의 경우도 널 값이라 한다. 이처럼 널 값은 값을 아직 갖지 않은 것이므로 공백(blank)이나 0(zero)과는 다르다. </p>
<p> 널 값이 허용되는 속성을 널 속성(null attribute)이라 한다. </p>
</li>
<li><p><strong>키 속성</strong></p>
<p> 개체를 구성하는 속성들 중에서 특별한 역할을 하는 속성이 있는데 바로 키 속성(key attribute)이다. 
 모든 개체 인스턴스의 키 속성 값이 다므르로 키 속성은 개체 집합에 존재하는 각 개체 인스턴스들을 식별하는데 사용한다.</p>
<p> 키 속성은 E-R 다이어그램에서 밑줄을 그어 표현한다.</p>
</li>
</ol>
<h3 id="3-관계">3. 관계</h3>
<p>관계(relationship)은 개체와 개체가 맺고 있는 의미 있는 연관성으로, 개체-관계 모델의 중요한 요소이다. 
관계는 개체 집합들 사이의 대응 관계(correspondence), 즉 매핑(mapping)을 의미한다.</p>
<p>관계를 여러 개체(타입) 사이에서 정의되는 관계 타입(relationship type)과 실제 속성 값으로 구성되어 있는 특정 개체 인스턴스들 간에 맺어진 실제 관계인 관계 인스턴스(relationship instance)로 구분하여 표현하기도 한다.</p>
<p>관계도 개체처럼 속성을 가질 수 있다. 관계를 맺음으로써 발생하는 중요한 데이터들이 관계의 속성이 된다.</p>
<p>관계는 E-R 다이어그램에서 마름모로 표현한다.</p>
<ol>
<li><p>관계의 유형</p>
<ol>
<li><p>일대일 관계</p>
<p> 개체 A의 각 개체 인스턴스가 개체 B의 개체 인스턴스 하나와 관계를 맺을 수 있고, 
 개체 B의 각 개체 인스턴스가 개체 A의 개체 인스턴스 하나와 관계를 맺을 수 있다.</p>
</li>
<li><p>일대다 관계</p>
<p> 개체 A의 각 개체 인스턴스가 개체 B의 개체 인스턴스 여러 개와 관계를 맺을 수 있고,
 개체 B의 각 개체 인스턴스는 개체 A의 개체 인스턴스 하나와만 관계를 맺을 수 있다.</p>
</li>
<li><p>다대다 관계</p>
<p> 개체 A의 각 개체 인스턴스가 개체 B의 개체 인스턴스 여러 개와 관계를 맺을 수 있고,
 개체 B의 각 개체 인스턴스가 개체 A의 개체 인스턴스 여러개와 관계를 맺을 수 있다.</p>
</li>
</ol>
</li>
<li><p>관계의 참여 특성</p>
<p> 개체 A와 B 사이의 관계에서, 개체 A의 모든 개체 인스턴스가 관계에 반드시 참여해야 된다면 개체 A가 관계에 ‘필수적 참여한다.’ 또는 ‘전체 참여한다.’라고 한다.</p>
<p> 개체 A의 개체 인스턴스 중 일부만 관계에 참여해도 되면 개체 A가 관계에 ‘선택적 참여한다.’ 또는 ‘부분 참여한다.’라고 한다.</p>
<p> 필수적 참여 관계는 E-R 다이어그램에서 이중선으로 표현한다.</p>
</li>
<li><p>관계의 종속성</p>
<p> 개체 B가 독자적으로 존재할 수 없고 다른 개체 A의 존재 여부에 의존적이라면, 개체 B가 개체 A에 종속되어 있다고 한다. 개체 B가 개체 A에 종석되면, 개체 A가 존재해야 개체 B가 존재할 수 있고 개체 A가 삭제되면 개체 B도 함께 삭제되어야 함을 의미한다. 이러한 종속을 특별히 존재 종속(existence dependence)이라 한다. </p>
<p> 이때, 다른 개체의 존재 여부에 의존적인 개체 B를 약한 개체(weak entity)라 하고, 다른 개체의 존재 여부를 결정하는 개체 A를 강한 개체(strong entity)라 한다. </p>
<p> 약한 개체는 E-R 다이어그램에서 이중 사각형으로 표현하고 약한 개체와 강한 개체가 맺는 관계는 이중 마름모로 표현한다.</p>
</li>
</ol>
<h3 id="4-e-r-다이어그램">4. E-R 다이어그램</h3>
<p>앞서 설명한 것처럼 E-R 다이어그램은 개체-관계 모델을 이용해 현실 세계를 개념적으로 모델링한 결과물을 도식화한 것이다.</p>
<img src='https://velog.velcdn.com/images/ja_efan/post/065c222f-4e7e-4629-a0af-c6e651ce9960/image.jpeg' width=10>


<h2 id="03-논리적-데이터-모델">03 논리적 데이터 모델</h2>
<h3 id="1-논리적-데이터-모델의-개념과-특성">1. 논리적 데이터 모델의 개념과 특성</h3>
<p>개체-관계 모델은 현실 세계를 사람들의 머릿속에 그릴 수 있는 개념적인 구조로 모델링하는 데 사용하므로 어떤 DBMS로 데이터베이스를 구축하든 상관이 없다. 하지만 E-R 다이어그램으로 표현된 개념적인 구조를 데이터베이스에 표현하는 형태를 결정하는 논리적 데이터 모델링에서는 DBMS 종류가 중요하다.</p>
<p>선택한 DBMS에 따라 사용자 입장에서 E-R 다이어그램으로 표현된 개념적 구조를 데이터베이스에 저장할 형태로 표현한 논리적 구조를 논리적 데이터 모델이라 한다. 쉽게 말해 논리적 데이터 모델은 논리적 데이터 모델링의 결과물이고, 사용자가 생각하는 데이터베이스의 모습 또는 구조이다. 그리고 논리적 데이터 모델로 표현된 데이터베이스의 논리적 구조가 바로 데이터베이스 스키마이다. </p>
<p>일반적으로 많이 사용되는 논리적 데이터 모델은 관계 데이터 모델로, 데이터베이스의 논리적 구조가 2차원 테이블 형태이다. 관계 데이터 모델은 5장에서 자세히 다루어진다.</p>
<h3 id="2-계층-데이터-모델">2. 계층 데이터 모델</h3>
<p>계층 데이터 모델(hierarchical data model)은 데이터베이스의 논리적인 구조가 트리(tree) 형태다. 개체는 사각형으로 나타내고 관계는 링크로 나타내는데, 링크는 일대다 관계만 표현할 수 있다. 그리고 두 개체 사이에 관계는 하나만 정의 가능하다.</p>
<p>일대다 관계를 맺는 개체들 사이에는 상하 관계가 성립한다. 상위에 있는 개체를 부모 개체, 하위에 있는 개체를 자식 개체라 하고, 이들 사이의 일대다 관계를 부모-자식 관계라 한다. 모든 자식 개체는 부모 개체를 하나만 가질 수 있다는 제약 사항이 존재한다.</p>
<p>계층 데이터 모델은 개체 사이의 관계를 정의할 때 여러 제약이 존재하기 때문에 개념적 구조를 논리적 구조로 사연스럽게 모델링하기 어려워 구조가 복잡해질 수 있다. 그리고 데이터 관련 연산이 쉽지 않다는 단점이 있다.</p>
<h3 id="3-네트워크-데이터-모델">3. 네트워크 데이터 모델</h3>
<p>네트워크 데이터 모델(network data model)은 데이터베이스의 논리적 구조가 그래프(graph) 또는 네트워크(network)형태다. 개체는 사각형으로 표현하고 관계는 화살표로 나타내는데, 화살표는 일대다 관계만 표현할 수 있다. 그래서 네트워크 데이터 모델은 두 개체 간의 관계를 여러 개 정의할 수 있어 관계를 이름으로 구별한다.</p>
<p>네트워크 데이터모델에서도 일대다 관계만 직접 표현할 수 있으므로 두 개체 사이의 일대다 관계들을 이용해 다대다 관계를 표현한다. 네트워크 데이터 모델에서는 일대다 관계의 대체들을 각각 오너(owner)와 멤버(member)라 부르고, 이들 사이의 관계를 오너-멤버 관계(owner-membership relationship)라 부른다. </p>
<p>네트워크 데이터 모델은 같은 개체들 사이의 관계를 두 개 이상 표현할 수 있어 계층 데이터 모델보다 개념적 구조를 논리적 구조로 좀 더 자연스럽게 모델링 할 수 있다. 그러나 계층 데이터 모델보다 구조가 훨씬 복잡해 질 수 있어, 데이터 처리 연산이 계층 데이터 모델보다 더 어려워지는 문제가 발생한다.</p>
<h3 id="4-객체-관련-모델">4. 객체 관련 모델</h3>
<p>논리적 데이터 모델로 객체의 개념을 도입한 객체지향 데이터 모델(object-oriented data model), 그리고 객체 지향 데이터 모델과 관계 데이터 모델의 특성을 모두 수용하는 객체관계 데이터 모델(object-relational data model)이 사용되기도 한다. 하지만 누구나 쉽게 이해할 수 있는 데이터 구조와 데이터 연산을 제공하는 관계 데이터 모델이 꾸준히 인기가 높다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[DB | 3. 데이터베이스 시스템 (part 2)]]></title>
            <link>https://velog.io/@ja_efan/DB-3.-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EC%8B%9C%EC%8A%A4%ED%85%9Cpart-2</link>
            <guid>https://velog.io/@ja_efan/DB-3.-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EC%8B%9C%EC%8A%A4%ED%85%9Cpart-2</guid>
            <pubDate>Thu, 11 Jan 2024 05:27:00 GMT</pubDate>
            <description><![CDATA[<h2 id="03-데이터베이스-사용자">03 데이터베이스 사용자</h2>
<p>사용자(user)는 데이터베이스를 이용하기 위해 접근하는 모든 사람을 의미한다.</p>
<h3 id="1-데이터베이스-관리자">1. 데이터베이스 관리자</h3>
<p>데이터베이스 관리자(DataBase Administrator, <u>DBA</u>)는 데이터베이스 시스템을 운영 및 관리한다.</p>
<p>데이터베이스를 직접 활용하기 보다는 조직 내 사용자를 위해 데이터베이스를 설계 및 구축하고, 제대로 서비스 할 수 있도록 데이터베이스를 제어한다.</p>
<p>&lt;주요 업무&gt;</p>
<ul>
<li>데이터베이스 구성 요소 선정</li>
<li>데이터베이스 스키마 정의</li>
<li>물리적 저장 구조와 접근 방법 결정</li>
<li>무결성 유지를 위한 제약조건 정의</li>
<li>보안 및 접근 권한 정책 결정</li>
<li>백업 및 회복 기법 정의</li>
<li>시스템 데이터베이스 관리</li>
<li>시스템 성능 감시 및 성능 분석</li>
<li>데이터베이스 재구성</li>
</ul>
<h3 id="2-최종-사용자">2. 최종 사용자</h3>
<p>데이터 조작을 위해 데이터베이스에 접근하는 일반 사용자 혹은 최종 사용자(End user)를 말한다.</p>
<p>최종 사용자는 캐주얼 사용자(Casual end user)와 초보 사용자(Naive end user)로 구분할 수 있다. (자세한 내용은 생략)</p>
<h3 id="3-응용-프로그래머">3. 응용 프로그래머</h3>
<p>응용 프로그래머(application programmer)는 프로그래밍 언어로 응용 프로그램을 작성할 때 데이터베이스에 접근하는 데이터 조작어를 삽입하는 사용자이다.</p>
<h2 id="04-데이터-언어">04 데이터 언어</h2>
<p>데이터 언어(data language)는 사용자가 데이터베이스를 구축하고 이에 접근하기 위해 DBMS와 통신하는 수단이다.</p>
<h3 id="1-데이터-정의어">1. 데이터 정의어</h3>
<p>데이터 정의어(Data Definition Language, DDL)는 새로운 데이터베이스를 구축하기 위해 스키마를 정의하거나 기존 스키마의 정의를 수정 또는 삭제하기 위해 사용되는 데이터 언어이다.</p>
<h3 id="2-데이터-조작어">2. 데이터 조작어</h3>
<p>데이터 조작어(Data Manipulation Language, DML)는 사용자가 데이터의 삽입/수정/삭제/검색 등의 연산(처리)를 DBMS에 요구하기 위해 사용되는 데이터 언어이다.</p>
<p>데이터 조작어는 절차적 데이터 조작어(Procedure DML)과 비절차적 데이터 조작어(Nonprocedure DML)로 구분할 수 있다.</p>
<h3 id="3-데이터-제어어">3. 데이터 제어어</h3>
<p>데이터 제어어(Data Contrl Language, DCL)는 데이터베이스에 저장된 데이터의 무결성과 일관성을 유지하면서 여러 사용자가 문제 없이 사용(공유)할 수 있도록 필요한 규칙 등을 정의하는데 사용되는 데이터 언어이다.</p>
<p>데이터 제어어를 사용함으로서 아래 특성을 보장할 수 있다.</p>
<ul>
<li>무결성(Integrity)</li>
<li>보안(Security)</li>
<li>회복(Recovery)</li>
<li>동시성(Concurrency)</li>
</ul>
<h2 id="05-데이터베이스-관리-시스템의-구성">05 데이터베이스 관리 시스템의 구성</h2>
<h3 id="1-질의-처리기">1. 질의 처리기</h3>
<p>질의 처리기(query processor)는 데이터 처리 요구를 해석하여 처리하는 역할을 담당한다.</p>
<p>질의 처리기의 주요 구성요소는 아래와 같다.</p>
<ul>
<li>DDL Compiler</li>
<li>DML Pre-Compiler</li>
<li>DML Compiler</li>
<li>Run-time Database Processor</li>
<li>Transaction Manager</li>
</ul>
<h3 id="2-저장-데이터-관리자">2. 저장 데이터 관리자</h3>
<p>저장 데이터 관리자(stored data manager)는 디스크에 저장된 데이터베이스와 데이터 사전을 관리하고, 여기에 실제로 접근하는 역할을 담당한다.</p>
<blockquote>
<p>reference. 데이터베이스개론 2판, 김연희, 한빛아카데미</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[DB | 3. 데이터베이스 시스템 (part 1)]]></title>
            <link>https://velog.io/@ja_efan/DB-3.-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EC%8B%9C%EC%8A%A4%ED%85%9C-part-1</link>
            <guid>https://velog.io/@ja_efan/DB-3.-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EC%8B%9C%EC%8A%A4%ED%85%9C-part-1</guid>
            <pubDate>Wed, 10 Jan 2024 14:44:12 GMT</pubDate>
            <description><![CDATA[<h2 id="01-데이터베이스-시스템의-정의">01 데이터베이스 시스템의 정의</h2>
<p>데이터베이스 시스템은 데이터베이스에 데이터를 저장하고, 저장된 데이터를 관리하여 조직에 필요한 정보를 생성해주는 시스템을 의미한다. 즉, 데이터베이스와 DBMS를 이용해 조직에 필요한 정보를 제공해주는 시스템이다.</p>
<h2 id="02-데이터베이스-구조">02 데이터베이스 구조</h2>
<h3 id="1-스키마">1. 스키마</h3>
<p>스키마(schema)는 데이터베이스에 저장되는 데이터 구조와 제약 조건을 정의한 것이다.</p>
<p>정의된 스키마에 따라 데이터베이스에 실제로 저장되는 값을 인스턴스(instance)라고 한다.</p>
<h3 id="2-3단계-데이터베이스-구조">2. 3단계 데이터베이스 구조</h3>
<p>실제 데이터베이스의 구조는 복잡하지만 이를 간단하게 3단계로 나누어 볼 수 있다.</p>
<ol>
<li><p><strong>외부 단계(External level)</strong></p>
<p> <u>개별 사용자 관점</u>에서 데이터베이스를 이해하고 표현한다. 
 외부 단계에서는 개별 사용자가 데이터베이스를 어떻게 보는가(논리적)를 표현하므로 사용자마다 생각하는 데이터베이스의 구조가 다르다. 외부 단계에서 사용자에게 필요한 데이터베이스를 정의한 것을 외부 스키마(external schema)라고 하며, 이는 사용자마다 다를 수 있다. 따라서 하나의 데이터베이스에 여러 개의 외부 스키마가 존재할 수 있으며 공유가 가능하다.</p>
</li>
<li><p><strong>개념 단계(Conceptual level)</strong></p>
<p> 데이터베이스를 이용하는 <u>사용자들의 관점을 통합</u>하여, 데이터베이스를 조직 전체의 관점에서 이해하고 표현한다. DBMS나 데이터베이스 관리자 관점에서 모든 사용자에게 필요한 데이터를 통합하여 전체 데이터베이스의 논리적인 구조를 정의하고, 이를 개념 스키마(conceptual schema)라고 한다.</p>
<p> 개념 스키마는 조직 전체의 관점에서 생각하는 데이터베이스의 모습이며, 모든 개별 사용자가 생각하는 데이터베이스의 모습을 하나로 합친 형태이다. 개념 스키마는 전체 데이터베이스에 어떤 데이터가 저장되어 있는지, 데이터들 간 어떤 관계가 존재하고 어떠한 제약 조건이 있는지에 대한 정의 뿐 아니라, 데이터에 대한 보안 정책이나 접근 권한에 대한 정의도 포함한다. 하지만 물리적인 저장방법이나 저장 장치와는 독립적이다.</p>
<p> 하나의 데이터베이스에는 하나의 개념 스키마만 존재하고, 각 사용자는 개념스키마의 일부분을 사용한다.
 즉, 외부 스키마는 개념 스키마를 기초로 하여 만들어진다.</p>
</li>
<li><p><strong>내부 단계(Internal level)</strong></p>
<p> 데이터베이스를 저장하는 <u>저장 장치 관점</u>에서 이해하고 표현한다.
 즉, 내부 단계에서는 전체 데이터베이스가 저장 장치에 실제로 저장되는 방법을 정의하며 이를 내부 스키마(Internal schema)라고 한다.</p>
<p> 데이터베이스는 저장장치에 파일 형태로 저장되는데 내부 스키마는 파일에 데이터를 저장하는 레코드의 구조, 레코드를 구성하는 필드의 크기, 인덱스를 이용한 레코드 접근 경로 등을 정의한다.</p>
<p> 내부 스키마는 데이터베이스의 개념 스키마에 대한 물리적인 저장구조를 표현하므로 하나의 데이터베이스에 하나만 존재한다.</p>
</li>
</ol>
<h3 id="3-데이터-독립성">3. 데이터 독립성</h3>
<p>하나의 데이터베이스에는 세 가지의 스키마가 존재하지만, 각각의 스키마는 데이터베이스를 바라보는 관점만 다를 뿐 모두 같은 데이터베이스를 표현한다. </p>
<p>실제 데이터는 물리적 저장장치에 저장된 데이터베이스에만 존재하므로 외부 스키마를 통해 원하는 데이터를 얻으려면 내부 스키마에 따라 저장된 데이터베이스에 접근해야 한다.
그러므로, 세 가지 스키마 사이에는 <u>유기적인 대응관계</u>가 성립해야 한다.</p>
<p>스키마 사이의 대응 관계를 사상 또는 매핑(mapping)이라고 한다.</p>
<p>데이터베이스를 3단계 구조로 나누고, 단계별로 스키마를 유지하며 스키마 사이의 대응 관계를 정의하는 궁극적인 목적은 <u>데이터 독립성(data independency)</u>을 실현하기 위해서이다.</p>
<p>데이터 독립성은 하위 스키마를 변경하여도 상위 스키마에는 영향을 미치지 않는 특성을 말한다.
3단계 데이터베이스 구조에는 <u>논리적 데이터 독립성</u>과 <u>물리적 데이터 독립성</u>이 있다.
<img src='https://velog.velcdn.com/images/ja_efan/post/5994efe0-0da4-425c-8143-850e33e5e51f/image.jpeg' width="50%" height="50%"></p>
<ol>
<li><p><strong>논리적 데이터 독립성</strong></p>
<p> 논리적 데이터 독립성은 개념 스키마가 변경되더라도 외부 스키마는 영향을 받지 않는 것이다.
 외부/개념 사상(매핑)은 외부 스키마와 개념 스키마의 대응 관계를 정의한 것으로, 응용 인터페이스(application interface)라고도 한다.</p>
<p> 이는 즉, 사용자가 데이터베이스의 논리적 구조가 변경되었다는 것을 알 필요가 없음을 의미한다.</p>
</li>
<li><p><strong>물리적 데이터 독립성</strong></p>
<p> 물리적 데이터 독립성은 내부 스키마가 변경되더라도 개념 스키마는 영향을 받지 않는 것이다.
 이는 결과적으로 외부 스키마에도 영향을 주지 않는다.</p>
<p> 물리적 데이터 독립성이 실현되면 데이터베이스의 저장 구조가 변경되더라도 개념/내부 사상 정보만 적절히 수정해준다면 직접적으로 관련이 없는 데이터베이스의 논리적 구조는 영향을 받지 않는다.</p>
</li>
</ol>
<h3 id="4-데이터-사전">4. 데이터 사전</h3>
<p>데이터베이스를 올바르게 관리하고 운영하기 위해서는 <u>스키마와 사상 정보(mapping information)</u>같은 부가 정보도 함께 저장되어야 한다.</p>
<p>데이터베이스에 저장되는 데이터에 대한 정보를 저장하는 곳을 데이터 사전(data dictionary) 혹은 시스템 카탈로그(system catalog)라고 한다. </p>
<p>데이터베이스에 저장되는 데이터에 대한 정보이므로 데이터에 대한 데이터(data about data)를 의미해 <u>메타데이터(metadata)</u>라고도 한다.</p>
<p>데이터 사전도 데이터를 저장하는 데이터베이스의 일종이므로 시스템 데이터베이스(system database)라고도 한다. 데이터 사전은 주로 DBMS가 생성하고 관리한다.</p>
<p>데이터 사전에 있는 데이터에 실제로 접근하는 데 필요한 위치 정보는 데이터 디렉토리(data directory)라는 곳에서 관리한다.</p>
<blockquote>
<p>reference. 데이터베이스개론, 김연희, 한빛아카데미</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[데이터베이스는 어디에 저장될까?]]></title>
            <link>https://velog.io/@ja_efan/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4%EB%8A%94-%EC%96%B4%EB%94%94%EC%97%90-%EC%A0%80%EC%9E%A5%EB%90%A0%EA%B9%8C</link>
            <guid>https://velog.io/@ja_efan/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4%EB%8A%94-%EC%96%B4%EB%94%94%EC%97%90-%EC%A0%80%EC%9E%A5%EB%90%A0%EA%B9%8C</guid>
            <pubDate>Wed, 10 Jan 2024 12:50:01 GMT</pubDate>
            <description><![CDATA[<p>데이터베이스의 내부 스키마에 대해서 공부하다가 문득 &#39;데이터베이스는 어디에 저장될까?&#39;라는 생각이 들었다.</p>
<p>그래서 내 local에 저장된 데이터베이스를 찾아보기로 했다.</p>
<p>일단 무작정 finder에 들어가서 /opt/homebrew/ 에서 mysql 관련 폴더를 찾기 시작했다.</p>
<p>수 많은 폴더 중 /opt/homebrew/var/mysql/ 에서 내가 사용하는 데이터베이스를 찾을 수 있었다.
<img src='https://velog.velcdn.com/images/ja_efan/post/ce302e49-eb2e-4764-89e7-08c56db0be49/image.png' width=100></p>
위와 같이 데이터베이스 내의 table들이 .idb의 확장자를 가지고 존재하는 것을 확인할 수 있었다.</p>
<p>찾고나니 데이터베이스의 저장위치를 알려주는 코드가 있을 것 같다는 생각에 구글링한 결과,</p>
<blockquote>
</blockquote>
<pre><code class="language-sql">show variables like &#39;datadir&#39;;</code></pre>
<p>위의 코드를 사용하면 데이터베이스 저장위치를 반환해준다고 한다.
<img src ='https://velog.velcdn.com/images/ja_efan/post/8772343a-e0d6-415d-965a-5f0704b5f585/image.png' width=100></p></p>
<p>혹시 나 같은 사람이 있을까봐 올려본다.</p>
]]></description>
        </item>
    </channel>
</rss>