<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>sirius2_1.log</title>
        <link>https://velog.io/</link>
        <description>O_O</description>
        <lastBuildDate>Wed, 25 Mar 2026 08:32:19 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>sirius2_1.log</title>
            <url>https://velog.velcdn.com/images/sirius2_1/profile/e3f785eb-7941-4cf6-bf61-a97e4c966aa1/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. sirius2_1.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/sirius2_1" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[JPA 설정 정보]]></title>
            <link>https://velog.io/@sirius2_1/JPA-%EC%84%A4%EC%A0%95-%EC%A0%95%EB%B3%B4</link>
            <guid>https://velog.io/@sirius2_1/JPA-%EC%84%A4%EC%A0%95-%EC%A0%95%EB%B3%B4</guid>
            <pubDate>Wed, 25 Mar 2026 08:32:19 GMT</pubDate>
            <description><![CDATA[<p>JPA는 설정정보 (yml)를 활용한 다양한 옵션을 제공한다.
이 포스트는 jpa의 다양한 설정 옵션을 간략하게 안내한다. </p>
<ul>
<li>jpa.hibernate.ddl-auto</li>
</ul>
<pre><code>| 값 | 의미 |
| --- | --- |
| create | 실행할 때 테이블 생성 |
| create-drop | 종료 시 삭제까지 |
| update | 기존 테이블 유지 + 변경 반영 |
| validate | 구조만 검증 |
| none | 아무것도 안함 |

  * 자주 쓰이는 jpa 구현체인 hibernate의 ddl options</code></pre><ul>
<li>show-sql: true<ul>
<li>jpa가 실행하는 sql을 콘솔에 출력<ul>
<li>defer-datasource-initialization: true</li>
</ul>
</li>
<li>jpa가 테이블 생성 이후에 data.sql실행</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[CI/CD]]></title>
            <link>https://velog.io/@sirius2_1/CICD</link>
            <guid>https://velog.io/@sirius2_1/CICD</guid>
            <pubDate>Fri, 12 Sep 2025 13:49:30 GMT</pubDate>
            <description><![CDATA[<h3 id="cicd-파이프라인-개요">CI/CD 파이프라인 개요</h3>
<ul>
<li><code>git push origin main</code> → GitHub Actions 실행</li>
<li>deploy.yml 기반 자동으로:<ol>
<li>Gradle 빌드 → JAR 생성</li>
<li>Docker 이미지 빌드 → GHCR push</li>
<li>SSH로 EC2 접속 → <code>docker compose pull &amp;&amp; up -d</code></li>
</ol>
</li>
<li>성공하면 EC2에서 바로 최신 컨테이너 실행</li>
</ul>
<h1 id="ec2-배포-요약">EC2 배포 요약</h1>
<h2 id="1️⃣-ec2-인스턴스-생성">1️⃣ EC2 인스턴스 생성</h2>
<ol>
<li>AWS 콘솔 → <strong>EC2</strong> </li>
<li>선택:<ul>
<li><strong>AMI</strong>: Ubuntu</li>
<li><strong>키페어</strong>: 새로 생성 (잘 저장하기)</li>
<li><strong>보안 그룹</strong>:<ul>
<li>22/tcp (SSH)</li>
<li>80/tcp (HTTP)</li>
<li>443/tcp (HTTPS)</li>
<li>8080/사용자 지정  등등</li>
</ul>
</li>
</ul>
</li>
<li>생성 완료 후 퍼블릭 IPv4 주소 확인</li>
</ol>
<h3 id="rds">RDS</h3>
<ol>
<li><p>AWS 콘솔 → <strong>RDS</strong></p>
<ul>
<li><p>엔진: MySQL 8.x LTS</p>
</li>
<li><p>배포 옵션: 단일 인스턴스</p>
</li>
<li><p>스토리지: gp3</p>
</li>
<li><p>퍼블릭 접근: <strong>비활성화</strong></p>
<p>  → EC2와 같은 VPC/Subnet에 두고 <strong>보안 그룹으로만 접근 허용</strong></p>
</li>
</ul>
</li>
<li><p>DB 인스턴스 파라미터</p>
<ul>
<li><strong>타임존</strong>: Asia/Seoul</li>
<li><strong>문자셋</strong>: utf8mb4 / utf8mb4_0900_ai_ci</li>
</ul>
</li>
<li><p>보안 그룹</p>
<ul>
<li>EC2 인스턴스 보안 그룹을 인바운드 소스로 추가 (즉, EC2만 DB 접근 허용)</li>
</ul>
</li>
<li><p>DB 생성 후</p>
<ul>
<li>엔드포인트 주소</li>
<li>사용자명/비밀번호 기록</li>
<li>Flyway/Liquibase로 스키마 관리<ul>
<li>RDS는 수동으로 <code>init.sql</code> 같은 걸 집어넣기 불편하므로,</li>
<li>백엔드 앱에서 <strong>Flyway</strong> 또는 <strong>Liquibase</strong>를 붙여 자동 마이그레이션 → DB 스키마 관리</li>
</ul>
</li>
</ul>
</li>
</ol>
<h2 id="ec2에서-rds로-로컬-db-복원">EC2에서 RDS로 로컬 DB 복원</h2>
<pre><code class="language-bash"># 로컬에서 MYSQLdump 생성
mysqldump -h 127.0.0.1 -u root -p ^
  --databases devmate ^
  --single-transaction --routines --triggers --events ^
  --default-character-set=utf8mb4 --set-gtid-purged=OFF --hex-blob ^
  --result-file=&quot;C:devmate_dump.sql&quot;

# 로컬 -&gt; EC2 업로드
scp -i devmate.pem C:devmate_dump.sql ubuntu@&lt;EC2_IP&gt;:/srv/app/

# EC2에서 복원
sudo apt -y install mysql-client
mysql -h &lt;RDS-ENDPOINT&gt; -P 3306 -u admin -p --default-character-set=utf8mb4 &lt; /srv/app/devmate_dump.sq

# 점검
mysql -h &lt;RDS-ENDPOINT&gt; -u admin -p
</code></pre>
<hr>
<h2 id="2️⃣-ec2-기본-세팅">2️⃣ EC2 기본 세팅</h2>
<pre><code class="language-bash"># 로컬 PC에서
ssh -i &lt;만든키이름&gt;.pem ubuntu@&lt;ec2 IP&gt;

# 서버 접속 후
sudo apt update &amp;&amp; sudo apt -y upgrade

# Docker 권한 부여
sudo usermod -aG docker ubuntu
exit
# 다시 접속해서 적용됨 확인
ssh -i &lt;만든키이름&gt;.pem ubuntu@&lt;ec2 IP&gt;

echo &lt;github PAT&gt; | docker login ghcr.io -u sirius147 --password-stdin
</code></pre>
<h3 id="3️⃣-spring-boot-앱-docker-이미지-준비">3️⃣ Spring Boot 앱 Docker 이미지 준비</h3>
<ul>
<li>Dockerfile(위치는 root바로 아래, build.gradle과 같은 경로)을 통해 앱 이미지 생성 후</li>
<li>컨테이너에 빌드 + 푸시</li>
</ul>
<pre><code class="language-java">GHCR 로그인 (Personal Access Token write:packages 체크):

echo GH_PAT | docker login ghcr.io -u sirius147 --password-stdin

docker build -t ghcr.io/&lt;계정이름&gt;/devmate-backend:latest .
docker push ghcr.io/&lt;계정이름&gt;/devmate-backend:latest</code></pre>
<h2 id="4️⃣-ec2에서-앱-실행">4️⃣ EC2에서 앱 실행</h2>
<h3 id="4-1-배포-디렉토리-생성">4-1. 배포 디렉토리 생성</h3>
<pre><code class="language-bash">mkdir -p ~/app &amp;&amp; cd ~/app
</code></pre>
<h3 id="4-2ec2-srvappenv-env-작성">4-2.(EC2 <code>/srv/app/.env</code>) <code>.env</code> 작성</h3>
<pre><code class="language-bash">DB_URL=jdbc:mysql://devmate-db.....amazonaws.com:3306/devmate?useSSL=false&amp;serverTimezone=Asia/Seoul&amp;characterEncoding=UTF-8
DB_USERNAME=admin
DB_PASSWORD=....
JWT_SECRET=...
SPRING_PROFILES_ACTIVE=prod
...
</code></pre>
<h3 id="4-3-docker-composeyml-작성">4-3. <code>docker-compose.yml</code> 작성</h3>
<pre><code class="language-yaml">services:
  backend:
    image: ghcr.io/&lt;username&gt;/devmate-backend:latest
    container_name: devmate-backend
    restart: always # 서버 재가동
    env_file: .env # env를 사용하는 코
    ports:
      - &quot;18080:8080&quot;   # 포트 포워딩
....
</code></pre>
<h3 id="4-4-실행">4-4. 실행</h3>
<pre><code class="language-bash">docker compose pull   # 이미지 다운로드
docker compose up -d
docker image prune -f # 이전 이미지 삭제

# 상태/로그 확인
docker compose ps
docker compose logs -f backend

.....</code></pre>
<p>→ curl -s -o /dev/null -w &quot;%{http_code}\n&quot; <a href="http://127.0.0.1:18080/actuator/health">http://127.0.0.1:18080/actuator/health</a> 확인</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[JWT 만료 흐름]]></title>
            <link>https://velog.io/@sirius2_1/JWT-%EB%A7%8C%EB%A3%8C-%ED%9D%90%EB%A6%84</link>
            <guid>https://velog.io/@sirius2_1/JWT-%EB%A7%8C%EB%A3%8C-%ED%9D%90%EB%A6%84</guid>
            <pubDate>Fri, 12 Sep 2025 12:50:02 GMT</pubDate>
            <description><![CDATA[<h1 id="access-token-만료-흐름">Access Token 만료 흐름</h1>
<h3 id="a-반응형">A. 반응형</h3>
<ol>
<li><p><strong>프론트</strong>가 보호 API 호출 → <code>Authorization: Bearer &lt;access&gt;</code></p>
</li>
<li><p><strong>리소스 서버(백엔드)</strong>가 access 만료 감지 → <strong>401</strong> 반환</p>
<ul>
<li><p>가능하면 헤더 포함:</p>
<p>  <code>WWW-Authenticate: Bearer error=&quot;invalid_token&quot;, error_description=&quot;expired&quot;</code></p>
</li>
</ul>
</li>
<li><p><strong>프론트</strong>가 401 인터셉트 → <code>POST /auth/refresh</code> 호출</p>
</li>
<li><p><strong>서버</strong>가 refresh 검증 → <strong>새 access(+) 새 refresh(회전 사용 시)</strong> 발급</p>
</li>
<li><p><strong>프론트</strong>가 원래 API <strong>1회 재시도</strong> → 정상 응답</p>
</li>
</ol>
<blockquote>
<p>실패 분기: 3)에서 /auth/refresh가 401/403/400(invalid_grant)이면 로그인 페이지로 리다이렉트</p>
</blockquote>
<h3 id="b-선제-갱신">B. 선제 갱신</h3>
<ul>
<li>프론트가 access의 <code>exp</code>를 디코드해 <strong>만료 30~60초 전</strong> <code>POST /auth/refresh</code> 실행</li>
<li>성공 시 토큰 교체, 실패 시 <strong>즉시 재로그인</strong></li>
</ul>
<hr>
<h1 id="refresh-token-만료-흐름">Refresh Token 만료 흐름</h1>
<h3 id="1-사용자-활동-중-만료무효로그아웃·블랙리스트·재사용탐지-등">1) 사용자 활동 중 만료/무효(로그아웃·블랙리스트·재사용탐지 등)</h3>
<ol>
<li>프론트가 <code>/auth/logout</code> 호출</li>
<li><strong>프론트</strong>: 로컬 access 정리 + 리프레시 쿠키 삭제(서버가 <code>Set-Cookie; Max-Age=0</code>권장) → <strong>재로그인</strong></li>
</ol>
<h3 id="2-오랫동안-미사용하다가-돌아온-경우">2) 오랫동안 미사용하다가 돌아온 경우</h3>
<ul>
<li>첫 API 호출이 <strong>401</strong> → 프론트가 <code>/auth/refresh</code> 시도 → <strong>refresh도 만료</strong>라 실패 → <strong>재로그인</strong></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[개발 짜투리]]></title>
            <link>https://velog.io/@sirius2_1/%EA%B0%9C%EB%B0%9C-%EC%A7%9C%ED%88%AC%EB%A6%AC</link>
            <guid>https://velog.io/@sirius2_1/%EA%B0%9C%EB%B0%9C-%EC%A7%9C%ED%88%AC%EB%A6%AC</guid>
            <pubDate>Fri, 12 Sep 2025 12:48:49 GMT</pubDate>
            <description><![CDATA[<h2 id="mysql-연결">MySql 연결</h2>
<ul>
<li>MySql Command Line Client <strong>(create database devmate)</strong></li>
</ul>
<p><img src="attachment:c4271617-b85f-49d0-8968-407df896011d:image.png" alt="image.png"></p>
<p><img src="attachment:6e42b6bf-e7d7-4452-a2ab-223e45b247fa:image.png" alt="image.png"></p>
<ul>
<li>application.yml을 통해 Springboot와 MySql 서버 연결</li>
</ul>
<p><img src="attachment:6c626ef3-60cc-405e-a8e4-f7424a6fd682:image.png" alt="image.png"></p>
<h3 id="github--intellij-연동">GitHub &amp; Intellij 연동</h3>
<ul>
<li><p>인텔리제이</p>
<ul>
<li><p>VCS → Enable Version Control Integration</p>
</li>
<li><p>터미널 → git remote add origin <a href="https://github.com/USERNAME/REPO.git">https://github.com/USERNAME/REPO.git</a></p>
<ul>
<li><p>git add .</p>
</li>
<li><p>git commit -m &quot;Initial commit: Spring Boot project&quot;</p>
</li>
<li><p>git branch -M main   # 브랜치를 main으로 변경 (GitHub 기본 브랜치와 맞춤)
git push -u origin main</p>
</li>
<li><p>git push origin --delete master</p>
<ul>
<li>main branch에 <a href="http://readme.md">readme.md</a> 파일 등이 만들어져 있다면<ul>
<li>git fetch origin</li>
<li>git pull --rebase origin main</li>
<li>git push -u origin main</li>
</ul>
</li>
<li>CRLF를 LF로 변경<ul>
<li>git config --global core.autocrlf true</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="yaml-파일을-통한-oauth-키-관리-yaml-정리-필요">YAML 파일을 통한 OAuth 키 관리 yaml 정리 필요</h3>
<p><img src="attachment:dc3d6f34-569a-4b97-92d4-b38b451eefef:image.png" alt="image.png"></p>
<ul>
<li>environment setting -local  , mac intellij java env var</li>
<li>annotation processor</li>
<li>docker desktop → run → pull redis image → and run</li>
<li>s3, 배포 url 구축</li>
</ul>
<h3 id="profile">profile</h3>
<p>edit configuration → add Vm Options → </p>
<p><code>-Dspring.profiles.active=local</code> </p>
<h3 id="ec2-ubuntu-접속--rds-mysql-접속">EC2 ubuntu 접속 &amp; RDS MySql 접속</h3>
<p>ssh -i devmate.pem <a href="mailto:ubuntu@13.124.xxx.xxx">ubuntu@</a>&lt;EC2퍼블릭IP&gt;</p>
<p> mysql -h &lt;RDS엔드포인트&gt;(<a href="http://database-devmate.c1smsm2i83cp.ap-northeast-2.rds.amazonaws.com/">http://database-devmate.c1smsm2i83cp.ap-northeast-2.rds.amazonaws.com/</a>) -u admin -p</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[버전관리 소프트웨어 예시]]></title>
            <link>https://velog.io/@sirius2_1/%EB%B2%84%EC%A0%84%EA%B4%80%EB%A6%AC-%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4-%EC%98%88%EC%8B%9C</link>
            <guid>https://velog.io/@sirius2_1/%EB%B2%84%EC%A0%84%EA%B4%80%EB%A6%AC-%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4-%EC%98%88%EC%8B%9C</guid>
            <pubDate>Fri, 12 Sep 2025 12:42:08 GMT</pubDate>
            <description><![CDATA[<h1 id="버전-관리-소프트웨어">버전 관리 소프트웨어</h1>
<p> <br/><br/></p>
<h3 id="소스트리">소스트리</h3>
<ul>
<li>직관적으로 버전 관리 정보를 확인할 수 있는 소프트웨어</li>
</ul>
<p> <br/><br/></p>
<h3 id="버전-관리">버전 관리</h3>
<ul>
<li><p>커밋 내용 취소 (Reset)</p>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/50493a42-bbc2-48a4-a570-30aad8ce042f/image.png" alt=""></p>
<p>*<em>mixed의 경우는 commit을 취소하고, workspace(stage)에 작업내용을 올려둔다. *</em></p>
<p><strong>hard의 경우 commit을 취소하고, 작업내용을 삭제한다</strong></p>
</li>
</ul>
<ul>
<li><p>커밋 되돌리기 (Revert)</p>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/57eb9e95-027f-47aa-893f-5c3369328848/image.png" alt=""></p>
</li>
<li><p><em>버전 변경이 아닌 커밋 이전 상태로 돌리고 이전 상태를 커밋으로 올린다*</em></p>
</li>
</ul>
<ul>
<li><p>폐기와 stash</p>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/373be7ab-71b2-4f69-8dbb-59b47eb7ab8b/image.png" alt=""></p>
</li>
</ul>
<p><strong>폐기의 경우 커밋 직전의 내용을 제거하고 이전 코드로 돌아가게 한다</strong></p>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/a34e5b5c-5cf3-4cde-ad35-c64c4cc20eba/image.png" alt=""></p>
<p> <strong>스태쉬는 작업 내용을 저장하고 불러 올 수 있게한다.</strong></p>
<ul>
<li><p>merge</p>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/14713baf-e099-47ea-be2a-a8c5dd864c83/image.png" alt=""></p>
</li>
</ul>
<br/>

<h3 id="github-desktop">GitHub Desktop</h3>
<ul>
<li>커밋 변경점</li>
</ul>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/25e187a9-0f57-4140-a7f8-5954c651df4c/image.png" alt=""></p>
<p> <strong>history tab에서 커밋 변경 관련 작업을 진행할 수 있다.</strong></p>
<h1 id="커밋과-resetstashrevert-등의-작업을-통해-버전을-관리하고-브랜치를-merge-한-후에-origin에-push-하자">커밋과 reset/stash/revert 등의 작업을 통해 버전을 관리하고 브랜치를 merge 한 후에 origin에 push 하자</h1>
]]></description>
        </item>
        <item>
            <title><![CDATA[데이터베이스 By mariaDB]]></title>
            <link>https://velog.io/@sirius2_1/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-By-mariaDB</link>
            <guid>https://velog.io/@sirius2_1/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-By-mariaDB</guid>
            <pubDate>Fri, 12 Sep 2025 12:36:17 GMT</pubDate>
            <description><![CDATA[<h2 id="brbrbr"> <br/><br/><br/></h2>
<h1 id="maria-db-1">Maria DB (1)</h1>
<hr>
<blockquote>
<ul>
<li>데이터베이스와 dbms, maria DB 간단한 소개</li>
</ul>
</blockquote>
<ul>
<li>maria DB 실습 환경 구축</li>
<li>select, where query 연습</li>
</ul>
<hr>
<hr>
<ul>
<li><p><strong>데이터베이스와 dbms, maria DB 간단한 소개</strong></p>
<br/>
Maria DB는 MySql에서 파생된 RDBMS의 하나로 MySql과 비슷한 문법에 빠른 속도와 경량화를 자랑하는 데이터 베이스이다.
<br/><br/></li>
<li><p><strong>mariaDB 실습 환경 구축</strong></p>
<br/>
1) 먼저 maria DB를 운영체제에 맞게 설치한다.
<br/>
2) db의 bin을 path의 환경변수로 등록한다.
<br/>
![](https://velog.velcdn.com/images/sirius2_1/post/31f27664-7ee9-4b74-9ac8-30dca7abb6e3/image.png)

<p>3) 이후 window 기준 powershell을 통해 mariaDB에 접근 가능하고 heidiSql 콘솔을 통해 GUI로 db를 실행 가능하다.</p>
<br/>
![](https://velog.velcdn.com/images/sirius2_1/post/03c5ee67-9fff-47c9-a11d-c366b2aecf30/image.png)![](https://velog.velcdn.com/images/sirius2_1/post/e8896fb9-9af9-44f4-900c-98dc91a908f0/image.png)

<p> ( 파워쉘을 통해 maria DB를 실행한 모습) </p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/a1b9c4eb-2310-4a6f-82c0-5feb4d59a3d5/image.png" alt=""></p>
<pre><code>(heidiSql에서 세션을 생성하여 DBMS 생성)</code></pre><br/>


<ul>
<li>권한 부여 단계 </li>
</ul>
 <br/>

<p><img src="https://velog.velcdn.com/images/sirius2_1/post/e037a5a0-0259-4aa8-8dfb-4ca548abe7ba/image.png" alt=""></p>
<p><br/><br/></p>
<h3 id="-select--where">** select / where**</h3>
<pre><code>&gt; 특정 열을 또는 열들을 RESULT SET으로써 조회하는 키워드 SELECT
&gt; ALIAS로 열 별칭을 설정할 수 있다.



 SELECT * FROM EMPLOYEE;
 SELECT emp_no, emp_id FROM employee;

 SELECT emp_no AS &#39;no&#39;, emp_id &#39;id&#39;, emp_name `name`,
 job_code jc
 FROM EMPLOYEE;




 &gt; DISTINCT, LIMIT 
 &gt; DISTINCT는 중복행을 제거하는 키워드, 여러 COLS 사용 가능
 &gt; LIMIT은 출력 행을 제한하는 키워드




 SELECT DISTINCT mobile1, mobile2 FROM employee;

 SELECT * FROM employee
 LIMIT 1000;</code></pre><pre><code>&gt; 조회 조건을 지정하는 키워드 WHERE
&gt; 비교 연산자 (=,!=, ..) , 관계 연산자 (&gt;=, ..), 논리연산자 (AND, OR, BETWEEN ~ AND ~ (이상 ,이하)), IN/NOT IN 연산자
  , 문자열에 사용하는 LIKE 연산자, IS NULL/IS NOT NULL (NULL비교는 
  IS/IS NOT과 함께 사용) 등의 연산자를 사용한다.



  -- BETWEEN AND 연산자 사용
  -- usertbl 테이블에서 키가 170 이상 182 이하인 회원의 모든 데이터 조회   

  SELECT *
  FROM usertbl
  -- WHERE height BETWEEN 170 AND 182
  -- WHERE height NOT BETWEEN 170 AND 182
  WHERE NOT height BETWEEN 170 AND 182



  -- IN 연산자 사용
  -- 주소가 경남, 경북, 전남인 회원의 이름, 주소 조회

  SELECT name, addr
  FROM usertbl
  -- WHERE addr = &#39;경남&#39; OR addr = &#39;경북&#39; OR addr = &#39;전남&#39;;
  -- WHERE addr IN (&#39;경남&#39;, &#39;경북&#39;, &#39;전남&#39;);
  -- WHERE NOT addr IN (&#39;경남&#39;, &#39;경북&#39;, &#39;전남&#39;);
  WHERE addr NOT IN (&#39;경남&#39;, &#39;경북&#39;, &#39;전남&#39;);




  -- employee 테이블에서 전화번호 처음 3자리가 010이 아닌 사원의 이름, 전화번호 조회

  SELECT emp_name, IFNULL(phone, &#39;번호없음&#39;)
  FROM employee
  WHERE IFNULL(phone, &#39;번호없음&#39;) NOT LIKE &#39;010%&#39;;



  -- employee 테이블에서 이메일 중 _ 앞 글자가 3자리인 주소를 가진 사원의 사번, 직원명, 이메일 조회 

    -- 예시) sun_di@kh.or.kr
  SELECT emp_id, emp_name, email
  FROM employee
  -- WHERE email LIKE &#39;___\_%&#39;;
  WHERE email LIKE &#39;___$_%&#39; ESCAPE &#39;$&#39;;</code></pre><BR/>

<h3 id="order-by-group-by">ORDER BY/ GROUP BY</h3>
<pre><code> &gt; 행을 정렬하는 키워드 ORDER BY
 &gt; 특정열을 정렬 기준으로 사용 할 수 있고, 후순위 정렬 기준을 지정할 수 있다.
 &gt; 기본이 오름차순이고 ASC/DESC 키워드로 오름차순/내림차순을 명시 할 수 있다.



 -- usertbl 테이블에서 addr으로 오름차순 정렬
 -- 단, addr 일치할 경우 mDate를 가지고 내림차순 정렬

  SELECT userid, NAME, addr, mDate
  FROM usertbl
  -- ORDER BY addr, mDate DESC;
  ORDER BY addr ASC, mDate DESC;



  -- usertbl 테이블에서 아이디, 이름, 가입일 조회(별칭 포함)
  -- 단, 이름으로 내림차순 정렬

  SELECT userid AS &#39;아이디&#39;,
          NAME AS &#39;이름&#39;,
          mDate AS &#39;가입일&#39;
  FROM usertbl
  -- ORDER BY NAME DESC;
  -- ORDER BY 2 DESC; -- 열의 순번 사용
  ORDER BY `이름` DESC; -- 별칭 사용




  &gt; 데이터를 그룹화 하는 키워드 GROUP BY
  &gt; 특정 열의 값을 기준으로 데이터를 그룹화하여 RESULT SET을 제공
  &gt; COUNT(*) 연산자와 자주 사용, HAVING 절로 그룹 조건 설정
  &gt; 마찬가지로 여러 컬럼을 그룹 기준으로 사용할 수 있다 
    (EX) GROUP BY X,Y -&gt; X와 Y의 모든 조합을 그룹으로 사용




  -- employee 테이블에서 부서별 사원의 수, 보너스를 받는 사원의 수, 급여의 합, 평균 급여, 최고 급여, 최저 급여를 조회 (부서별 내림차순)

  SELECT dept_code, 
           COUNT(*), 
           COUNT(bonus),
           SUM(salary),
           FLOOR(AVG(salary)),
           MAX(salary),
           MIN(salary)
  from employee
  GROUP BY dept_code
  ORDER BY dept_code DESC;



  -- HAVING 실습
  -- buytbl 테이블에서 총 구매액이 1000 이상인 회원의 아이디를 조회

  SELECT userid,
          SUM(price * amount) AS &#39;구매액&#39;
  FROM buytbl
  -- 집계 함수의 결과를 WHERE 절에서 조건으로 사용할 수 없다.
  -- WHERE SUM(price * amount) &gt;= 1000
  -- HAVING 절은 반드시 GROUP BY절 다음에 작성해야 한다.
  -- HAVING SUM(price * amount) &gt;= 1000
  GROUP BY userid
  HAVING SUM(price * amount) &gt;= 1000
  ORDER BY &#39;구매액&#39;
</code></pre><h2 id="-조회문에서-키워드-실행-순서">* 조회문에서 키워드 실행 순서</h2>
<p> 1) FROM
 2) WHERE
 3) GROUP BY
 4) HAVING
 5) ORDER BY
 6) SELECT
 7) LIMIT</p>
<br/>
<br/><br/><br/>
<br/><br/><br/>
<br/> 



<hr>
<p> <BR/><BR/><BR/><BR/><BR/></p>
<h1 id="db---데이터-변경">DB - 데이터 변경</h1>
<hr>
<hr>
<blockquote>
<ul>
<li><strong>INSERT</strong></li>
</ul>
</blockquote>
<ul>
<li><strong>UPDATE</strong></li>
<li><strong>DELETE</strong></li>
<li><strong>조건부 데이터 입력, 변경</strong></li>
</ul>
<hr>
<h3 id="insert">INSERT</h3>
<pre><code>
&gt; 기본키 필드, not Nullable 필드는 반드시 insert해야 한다.
&gt; default 제약조건, AUTO_INCREMENT, Nullable 필드는 생략 가능




-- 필드를 인자로 지정해주어 값을 넣어준다.


INSERT INTO usertbl(userid, NAME, birthYear, addr) VALUES (&#39;hong123&#39;, &#39;홍길동&#39;, 2015, &#39;서울&#39;);

INSERT INTO usertbl(NAME, addr, userid, birthyear) VALUES (&#39;유영&#39;, &#39;안산&#39;, &#39;JYY&#39;, 2001);




-- 필드 인자를 명시 하지 않으면, 모든 필드 값을 테이블 열 순서대로 전달해주어야 한다.



INSERT INTO usertbl VALUES(&#39;SIL&#39;, &#39;이성일&#39;, 1998, &#39;서울&#39;); 

INSERT INTO usertbl VALUES(&#39;SIL&#39;,&#39;이성일&#39;, 1998, &#39;서울&#39;, &#39;010&#39;, &#39;12345678&#39;, 179, NULL);




-- 여러 개의 행 삽입



INSERT INTO usertbl(USERID, NAME, BIRTHYEAR, ADDR) VALUES (&#39;OH&#39;, &#39;오혜성&#39;, 1998, &#39;경기&#39;), (&#39;YSW&#39;, &#39;양수우&#39;, 1997, &#39;화정&#39;);

CREATE TABLE usertbl_copy(
    SELECT *
    FROM usertbl
    WHERE 1 = 0
);




-- 다른 테이블로부터 SELECT 한 결과를 테이블에 삽입



INSERT INTO USERTBL_COPY (
    SELECT *
    FROM usertbl
    WHERE ADDR = &#39;강원&#39;
);



-- 열의 순서와 데이터 유형이 맞아야 행이 삽입된다.


INSERT INTO usertbl_copy(userid, name, birthYear, addr) (
    SELECT userid, 
             name, 
             birthYear, 
             addr
    FROM usertbl
    WHERE addr = &#39;강원&#39;
);    


DROP TABLE usertbl_copy;

</code></pre><p><BR/><BR/></p>
<h3 id="update">UPDATE</h3>
<pre><code>&gt; UPDATE &#39;TABLE NAME&#39; SET &#39;FIELD&#39; = &#39;VALUE&#39; WHERE &#39;FIELD&#39; = VALUE 형식
&gt; WHERE 절을 생략 하면 모든 행에 적용

UPDATE usertbl 
SET `name` = &#39;고길동&#39;
WHERE `name` = &#39;홍길동&#39;;

</code></pre><BR/>
<BR/>

<h3 id="delete">DELETE</h3>
<pre><code>&gt; DELETE FROM &#39;TABLE&#39; WHERE ~ LIMIT `No`
&gt; DELETE 또한 WHERE 절을 추가 하지 않으면 모든 행을 삭제 한다.



DELETE FROM usertbl WHERE NAME = &#39;유영&#39;;
DELETE FROM usertbl WHERE MOBILE1 IS NULL LIMIT 2;
</code></pre><h3 id="조건부----데이터-입력-변경과-commitrollback">조건부    데이터 입력, 변경과 COMMIT/ROLLBACK</h3>
<pre><code>&gt; IGNORE -&gt; 기본 키가 중복된 데이터 삽입 시 경고를 출력한다. 
&gt; INSERT INTO `TABLE` VALUES ~ ON DUPLICATE KEY UPDATE ~ -&gt; 데이터 없으면 INSERT, 있으면 UPDATE



INSERT IGNORE INTO usertbl(userid, NAME, birthYear, addr)
VALUES (&#39;BBK&#39;, &#39;바보킴&#39;, 1999, &#39;인천&#39;);




-- usertbl 테이블에 userid가 BBK인 회원이 없으면 INSERT를 수행하고
-- userid가 BBK인 회원이 있으면 UPDATE를 수행한다.


INSERT INTO usertbl(userid, NAME, birthYear, addr)
VALUES (&#39;BBK&#39;, &#39;바보킴&#39;, 1999, &#39;인천&#39;)
ON DUPLICATE KEY UPDATE NAME = &#39;바비킴&#39;, addr = &#39;인천&#39;;






&gt; AUTOCOMMIT은 사용자가 COMMIT 명령을 실행하지 않아도 자동으로 모든 명령이 COMMIT 되어 즉시 반영되는 것을 말한다.


SELECT @@AUTOCOMMIT;

SET autocommit = 1; -- 활성화
SET autocommit = 0; -- 비활성화

-- autocommit이 활성화된 경우 ROLLBACK으로 실행이 취소되지 않는다.
DELETE FROM usertbl WHERE userid = &#39;HONG&#39;;

SELECT * FROM usertbl;

ROLLBACK;

-- autocommit이 비활성화된 경우 ROLLBACK으로 실행이 취소된다.
DELETE FROM usertbl WHERE userid = &#39;sung123&#39;;

SELECT * FROM usertbl;

ROLLBACK;

-- autocommit이 비활성화된 경우에 변경 사항을 확정하려면 COMMIT을 실행해야 한다.
DELETE FROM usertbl WHERE userid = &#39;sung123&#39;;

SELECT * FROM usertbl;

COMMIT;
ROLLBACK;    
</code></pre><p><BR/><BR/><BR/><BR/><BR/><BR/><BR/><BR/><BR/></p>
<hr>
<p> <br/><br/><br/></p>
<p> <br/><br/><br/></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[STOMP 기반 채팅 요약]]></title>
            <link>https://velog.io/@sirius2_1/STOMP-%EA%B8%B0%EB%B0%98-%EC%B1%84%ED%8C%85-%EC%9A%94%EC%95%BD</link>
            <guid>https://velog.io/@sirius2_1/STOMP-%EA%B8%B0%EB%B0%98-%EC%B1%84%ED%8C%85-%EC%9A%94%EC%95%BD</guid>
            <pubDate>Fri, 12 Sep 2025 12:32:10 GMT</pubDate>
            <description><![CDATA[<h1 id="채팅">채팅</h1>
<h3 id="1-소켓-연결">1) 소켓 연결</h3>
<ul>
<li>WebSocket(SockJS)로 <strong><code>/ws-chat</code></strong> 에 연결</li>
<li>연결 시 JWT 전달(쿼리 <code>?token=...</code> 혹은 STOMP header)</li>
</ul>
<h1 id="stomp-기반-채팅-동작-구조">STOMP 기반 채팅 동작 구조</h1>
<h2 id="1-기본-개념">1. 기본 개념</h2>
<ul>
<li><p><strong>STOMP</strong> = “Simple Text Oriented Messaging Protocol”</p>
<p>  → WebSocket 위에서 동작하는 <strong>채팅 전용 규약</strong></p>
</li>
<li><p>핵심동작:</p>
<ol>
<li><strong>CONNECT</strong> → 서버와 인증된 연결 맺기</li>
<li><strong>SUBSCRIBE</strong> → 내가 듣고 싶은 채널 구독</li>
<li><strong>SEND</strong> → 특정 채널에 메시지 발송하기</li>
</ol>
</li>
<li><p>서버는 클라이언트에게 직접 보내지 않고, 브로커(/topic, /queue)를 통해 라우팅</p>
</li>
</ul>
<hr>
<h2 id="2-전체-흐름-채팅-1건-전송-예시">2. 전체 흐름 (채팅 1건 전송 예시)</h2>
<h3 id="🟢-1-클라이언트-→-서버-연결">🟢 (1) 클라이언트 → 서버: 연결</h3>
<ol>
<li>클라이언트는 <strong>WebSocket</strong>으로 <code>/ws-chat</code> 엔드포인트에 연결</li>
<li>연결 시 <strong>JWT 토큰</strong>을 같이 보냄 (<code>?token=</code> 또는 header)</li>
<li>서버는 토큰을 검증하고, <code>Principal(userId)</code>를 세션에 심어둠</li>
</ol>
<hr>
<h3 id="🟢-2-클라이언트-→-서버-구독">🟢 (2) 클라이언트 → 서버: 구독</h3>
<ul>
<li>클라이언트가 특정 채널 메시지를 받으려면 <strong>SUBSCRIBE</strong> 해야 함</li>
<li>예: <code>SUBSCRIBE /topic/channels.1</code></li>
<li><strong>서버 → 클라이언트 방향</strong> 메시지가 도착</li>
</ul>
<hr>
<h3 id="🟢-3-클라이언트-→-서버-메시지-전송">🟢 (3) 클라이언트 → 서버: 메시지 전송</h3>
<ul>
<li>유저가 메시지를 보낼 때는 <strong>SEND</strong> 프레임으로 서버에 요청</li>
<li>목적지: <code>/app/chat.channels.1.send</code></li>
<li>payload: <code>{&quot;content&quot;:&quot;안녕&quot;,&quot;attachments&quot;:[]}</code></li>
<li>서버는:<ol>
<li>DB에 메시지 저장</li>
<li>해당 채널 모든 구독자에게 <code>/topic/channels.1</code>으로 브로드캐스트</li>
</ol>
</li>
</ul>
<hr>
<h3 id="🟢-4-서버-→-클라이언트-메시지-전달">🟢 (4) 서버 → 클라이언트: 메시지 전달</h3>
<ul>
<li><code>/topic/channels.1</code>을 구독한 모든 사용자가 <strong>실시간으로 메시지 수신</strong></li>
<li>따라서 REST API로 polling 할 필요 없이, 채팅창에 바로 메시지가 뜸</li>
</ul>
<hr>
<h3 id="🟢-5-클라이언트-→-서버-읽음-처리">🟢 (5) 클라이언트 → 서버: 읽음 처리</h3>
<ul>
<li><p>채팅방에 있는 유저가 마지막 메시지를 읽으면:</p>
<ul>
<li><code>SEND /app/chat.channels.1.read</code></li>
<li>payload: <code>{&quot;lastReadMessageId&quot;: 123}</code></li>
</ul>
</li>
<li><p>서버는 DB의 <code>lastReadChatMessageId</code>를 갱신하고,</p>
<p>  <code>/topic/channels.1</code>으로 <strong>“누가 어디까지 읽었는지”</strong> 이벤트를 브로드캐스트</p>
</li>
</ul>
<hr>
<h3 id="🟢-6-서버-→-클라이언트-읽음-표시-전달">🟢 (6) 서버 → 클라이언트: 읽음 표시 전달</h3>
<ul>
<li>다른 유저들 화면에 “님이 읽음” 같은 표시가 즉시 뜸</li>
</ul>
<h1 id="✅-한-줄-정리">✅ 한 줄 정리</h1>
<blockquote>
<p>STOMP 기반 채팅은 WebSocket으로 연결 → 채널 구독 → 메시지 SEND → 서버가 브로드캐스트 → 모든 구독자가 실시간 수신 구조다.</p>
</blockquote>
</BR>


<h3 id="커넥트-테스트-by-postman">커넥트 테스트 BY POSTMAN</h3>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/9b69496f-4ec4-4b14-a6af-27ffa6d52915/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로젝트 초기 설계]]></title>
            <link>https://velog.io/@sirius2_1/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%B4%88%EA%B8%B0-%EC%84%A4%EA%B3%84</link>
            <guid>https://velog.io/@sirius2_1/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%B4%88%EA%B8%B0-%EC%84%A4%EA%B3%84</guid>
            <pubDate>Thu, 09 Jan 2025 01:07:45 GMT</pubDate>
            <description><![CDATA[<h1 id="프로젝트">프로젝트</h1>
<br/>

<ol>
<li><p>주제 회의</p>
</li>
<li><p>세부 기능 정의</p>
</li>
<li><p>요구사항 명세서 / api 명세서와 WBS <em>(Work Breakdown Structure)</em></p>
<ul>
<li>테이블 명세서, DB 구축 -&gt; 테스트 케이스</li>
</ul>
</li>
<li><p>IA, 디자인, ERD 설계 및 협업 방식 및 개발 환경 및 MSA 구성</p>
<ol start="5">
<li>환경 설정 및 엔티티 설계</li>
</ol>
</li>
<li><p>백엔드 구축 &amp; 프론트엔드 구축</p>
</li>
<li><p>배포 환경 설계 (CI/CD)</p>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[DB +@]]></title>
            <link>https://velog.io/@sirius2_1/DB</link>
            <guid>https://velog.io/@sirius2_1/DB</guid>
            <pubDate>Fri, 27 Dec 2024 08:11:29 GMT</pubDate>
            <description><![CDATA[<h1 id="db---프로시저와-트리거">DB - 프로시저와 트리거</h1>
<hr>
<hr>
<blockquote>
<ul>
<li><strong>프로시저</strong></li>
</ul>
</blockquote>
<ul>
<li><strong>트리거</strong></li>
</ul>
<hr>
<BR/>
<BR/>

<h3 id="스토어드-프로시저">스토어드 프로시저</h3>
<ul>
<li><p><em>DELIMITER는 구문문자 정의의 기능을 한다. EX) DELIMIETER $$ -&gt; $$를 C언어에서 ; 처럼 사용하겠다는 선언</em></p>
<pre><code>  &gt; DELIMITER로 PROCEDURE 정의 문자 선언을 안하면, 내부 구문과 프로시저 구문의 구분이 어렵다.

  &gt; 마지막에 DELIMITER ;를 한 이유도 마찬가지로 다시 구문문자 정의를 ;로 바꾸기 위함이다.</code></pre></li>
<li><p><em>@는 세션이 끝나기 전까지 변수를 유지해주는 역할을 한다. 이는 프로시저가 끝나고도 변수의 값을 유지한다</em></p>
</li>
</ul>
<pre><code>
&gt; 매개변수 활용 프로시저
DELIMITER $$
CREATE OR REPLACE PROCEDURE getName(
    IN `name` CHAR(10),
    OUT userName CHAR(15)
)
BEGIN
    SELECT uname
    INTO userName
    FROM usertbl
    WHERE uname = `name`;
END$$
DELIMITER ;

CALL getName(&#39;이승기&#39;, @namie);

SELECT @namie;


&gt; if then문 활용
DELIMITER $$
CREATE OR REPLACE PROCEDURE empProc(
    IN id CHAR(3)
)
BEGIN 
    DECLARE `year` INT;

    SELECT YEAR(hire_date)
    INTO `year`
    FROM employee
    WHERE emp_id = id;

    if `year` &gt;= 2010 then
        SELECT &#39;10년대 입사&#39;;
    ELSEIF `year` &gt;=2000 then
        SELECT &#39;00년대 입사&#39;;
    ELSE SELECT &#39;입싸&#39;;
    END if;
END $$
DELIMITER ;

CALL empProc(&#39;209&#39;);

&gt; case when then문 활용
DELIMITER $$
CREATE OR REPLACE PROCEDURE gradeProc(
    IN score TINYINT
)
BEGIN 
    DECLARE grade CHAR(2);

    case 
        when score &gt;= 90 then SET grade = &#39;A&#39;;
        when score &gt;= 80 then SET grade = &#39;B&#39;;
        when score &gt;= 70 then SET grade = &#39;C&#39;;
        ELSE SET grade = &#39;F&#39;;
    END case;

    SELECT grade;
END$$
delimiter ;

CALL gradeProc(90);


&gt; while do 문 활용
DELIMITER $$
CREATE OR REPLACE PROCEDURE sumProc()
BEGIN 
    DECLARE i INT;
    DECLARE SUM INT;

    SET i = 1;
    SET SUM = 0;

    while i &lt;= 10 do
        SET SUM = SUM + i;
        SET i = i + 1;
    END while;

    SELECT CONCAT(&#39;1부터 10까지의 합:&#39;, SUM);

END$$
DELIMITER ;

CALL sumProc();

&gt; sql error handler
&gt; DECLARE CONTINUE/EXIT/UNDO HANDLER FOR NOT FOUND/SQLEXCEPTION ...
DELIMITER $$
CREATE OR REPLACE PROCEDURE handleProc()
BEGIN
    DECLARE CONTINUE handler FOR SQLEXCEPTION    
        SELECT &#39;error emerge&#39;;
    SELECT &#39;안녕&#39;;
END$$
DELIMITER ;

CALL handleProc();

DROP PROCEDURE handleProc;
</code></pre><h3 id="트리거">트리거</h3>
<ul>
<li>테이블에 삽입, 수정, 삭제 등의 작업이 일어날 때, 자동으로 작동되는 객체</li>
<li>DML 문에 발생하는 이벤트</li>
<li>임의 실행 불가, 이벤트 발생 시에 자동 수행</li>
<li>매개변수 사용 불가, view에 사용 불가</li>
<li>BEFORE/AFTER TRIGGER가 있다</li>
</ul>
<pre><code>DELIMITER $$
CREATE OR REPLACE TRIGGER inserTrigger
AFTER insert ON employee
FOR EACH row
BEGIN
    --
END$$
DELIMITER ;
</code></pre><p><BR/><BR/><BR/><BR/><BR/><BR/><BR/><BR/><BR/></p>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[DB 공부]]></title>
            <link>https://velog.io/@sirius2_1/DB-%EA%B3%B5%EB%B6%80</link>
            <guid>https://velog.io/@sirius2_1/DB-%EA%B3%B5%EB%B6%80</guid>
            <pubDate>Mon, 23 Dec 2024 08:50:14 GMT</pubDate>
            <description><![CDATA[<h1 id="db---데이터-형식과-내장-함수">DB - 데이터 형식과 내장 함수</h1>
<hr>
<hr>
<blockquote>
<ul>
<li><strong>DATA TYPE 정리</strong></li>
</ul>
</blockquote>
<ul>
<li><strong>형변환함수</strong></li>
<li><strong>제어함수</strong></li>
<li><strong>문자열함수</strong></li>
<li><strong>수학함수</strong></li>
<li><strong>날짜-시간함수</strong></li>
<li><strong>순위-분석함수</strong></li>
</ul>
<hr>
<h3 id="data-types">DATA TYPES</h3>
<p> <img src="https://velog.velcdn.com/images/sirius2_1/post/2f558b41-e035-43a5-9f2a-fefd1f9d2ee4/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/a0afee45-9b99-4fc7-ac3b-59d654145aa3/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/f44e0920-4278-412f-8d37-4f150ae5c459/image.png" alt=""></p>
<h3 id="형변환함수">형변환함수</h3>
<pre><code>&gt; 기본 사용법
SELECT CONVERT(123456789, CHAR);
SELECT CAST(123456789 AS CHAR);

&gt; REPLACE 함수와의 활용
SELECT CONVERT(REPLACE(&#39;10,000,000&#39;,&#39;,&#39;,&#39;&#39;), INT);


&gt; usertbl 테이블에서 mobile1의 데이터를 숫자 데이터로 형 변환 후 조회
SELECT NAME, convert(mobile1, INT), mobile1
FROM usertbl;

&gt; maria db에서 convert나 cast는 매우 유용하지만 모든 데이터타입 변환이 가능한 것은 
아니다. 
select CONVERT(2024,smallint);

&gt; LITERAL 연산
SELECT &#39;100&#39; + &#39;200&#39;; -- 정수로 변환되어 연산된다.
SELECT CONCAT(&#39;100&#39;,&#39;200&#39;); -- 문자와 문자를 연결한다.
SELECT CONCAT(100,&#39;200&#39;); -- 정수가 문자로 변환되어 연결된다.
SELECT 1 &gt; &#39;2mega&#39;; -- 산술 연산 -&gt; &#39;2mega&#39; -&gt; 2
SELECT 0 = &#39;mega&#39;;  -- &#39;mega&#39; 변환 -&gt; 문자로만 구성 -&gt; 0으로 변환;</code></pre><h3 id="제어-흐름함수">제어-흐름함수</h3>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/03627cea-5dd2-4703-bcf8-82b9f22d39d0/image.png" alt=""></p>
<pre><code>
&gt; ifnull과 NVL 함수
SELECT IFNULL(NULL,&#39;값이 없음&#39;), IFNULL(100, &#39;값이 없음&#39;);
SELECT nvl(NULL, &#39;값이 없음&#39;), nvl(100,&#39;값이 없음&#39;);

&gt; NVL2 함수  -&gt; NVL2(&#39;EXP&#39;, IF TRUE, IF FALSE);
SELECT nvl2(NULL, 100, 200), nvl2(300,100,200);


&gt; case 연산자
SELECT case 10
            when 1 then &#39;일&#39;
            when 5 then &#39;오&#39;
            when 10 then &#39;십&#39;
            ELSE &#39;모름&#39;
         END AS &#39;결과&#39;;


SELECT case 
            when 10 &gt; 20 then &#39;10 &gt; 20&#39;
            when 10 = 20 then &#39;10 = 20&#39;
            ELSE &#39;모름&#39;
         END AS &#39;결과&#39;;
</code></pre><h3 id="문자열함수">문자열함수</h3>
<pre><code>
&gt; concat, concat_ws 함수
SELECT CONCAT(&#39;2024&#39;, &#39;12&#39;, &#39;16&#39;),
            CONCAT_ws(&#39;/&#39;,&#39;2024&#39;, &#39;12&#39;, &#39;16&#39;);

&gt; elt, field, find_in_set, instr, locate 함수
SELECT ELT(5,&#39;하나&#39;, &#39;둘&#39;, &#39;셋&#39;, &#39;넷&#39;,&#39;다섯&#39;);  // n번째 문자열을 출력한다.

SELECT FIELD(&#39;하나&#39;, &#39;하나&#39;, &#39;둘&#39;, &#39;셋&#39;); // 문자열들에서 해당 문자열의 위치를 출력

SELECT FIND_IN_SET(&#39;둘&#39;, &#39;하나,둘,셋&#39;); // 문자열에서 문자열의 위치를 출력

SELECT INSTR(&#39;하나둘셋&#39;, &#39;하나&#39;); // 문자열에서 문자열의 위치를 확인

SELECT LOCATE(&#39;구옥&#39;, &#39;주악구옥주희&#39;); // 문자열의 위치를 문자열에서 확인


&gt; format 함수
SELECT FORMAT(1234567.89, 1); // 자릿수 표시와 함께 소숫점 반올림까지

&gt; insert,left,right 함수
SELECT INSERT(&#39;abcdefghi&#39;, 3, 4, &#39;####&#39;); -&gt; ab####ghi

SELECT LEFT(&#39;naver&#39;, 5); -&gt; naver
SELECT RIGHT(&#39;baemin&#39;, 6); -&gt; baemin

&gt; lpad, rpad  함수
SELECT LPAD(&#39;hello&#39;,10); SELECT RPAD(&#39;hello&#39;,10,&#39;#&#39;);

&gt; ltrim, rtrim, trim, substring

SELECT LTRIM(&#39;        hello      &#39;);
SELECT RTRIM(&#39;        hello       &#39;);
SELECT TRIM(&#39;          hello        &#39;);

SELECT SUBSTRING(&#39;대한민국만세&#39;, 3 ,3);
SELECT SUBSTRING(&#39;대한민국만세&#39; FROM 3);
SELECT SUBSTRING(&#39;대한민국만세&#39; FROM 3 FOR 2);
SELECT SUBSTRING(&#39;대한밈ㄴ국만세&#39; FROM -2 FOR 2);

&gt; SUBSTRING_INDEX 함수
SELECT SUBSTRING_INDEX(&#39;cafe.naver.com&#39;, &#39;.&#39;, 2),
         SUBSTRING_INDEX(&#39;cafe.naver.com&#39;, &#39;.&#39;, -2);
</code></pre><h3 id="수학함수">수학함수</h3>
<pre><code>&gt; ceilng, floor 함수
SELECT CEILING(4.3), FLOOR(4.7), ROUND(4.4), ROUND(4.5), ROUND(4.355, 2);

SELECT TRUNCATE(123.456, 2), TRUNCATE(123.45,-1); -&gt; 123.45, 120

</code></pre><h3 id="날짜-및-시간-함수">날짜 및 시간 함수</h3>
<pre><code>SELECT ADDDATE(&#39;2025-01-01&#39;, INTERVAL 10 DAY), ADDDATE(&#39;2025-01-01&#39;, INTERVAL 1 MONTH); -&gt; &#39;2025-01-11&#39;, &#39;2025-02-01&#39;

SELECT DATEDIFF(CURDATE(), &#39;2024-05-25&#39;),
            TIMEDIFF(CURTIME(), &#39;09:00:00&#39;);

&gt; dayofweek, monthname, dayofyear, last_day 함수
SELECT DAYOFWEEK(CURDATE()),
MONTHNAME(&#39;2024-05-25&#39;),
DAYOFYEAR(CURDATE()),
LAST_DAY(CURDATE());

&gt; makedate, maketime, period_add, period_diff 함수
SELECT MAKEDATE(2025,100),
        MAKETIME(22,58,59),
        PERIOD_ADD(202402,12),
        PERIOD_DIFF(202405,202505),
        PERIOD_DIFF(&#39;2025-05&#39;, &#39;2024-05&#39;);            </code></pre><BR/>

<h3 id="순위-분석윈도우함수">순위-분석(윈도우)함수</h3>
<pre><code>
&gt; 순위 관련 함수
&gt; order by height desc key로 내림차순 정렬 한 후에 row_number() 함수로 순번을 매긴다.
SELECT ROW_NUMBER() OVER(ORDER BY height DESC) AS &#39;num&#39;, NAME, addr, height
FROM usertbl
ORDER BY height DESC;

&gt; 지역 별로 순위를 매겨서 주소, 순위, 이름, 키를 조회
SELECT addr, ROW_NUMBER() OVER(partition by addr order by height DESC) AS &#39;num&#39;, NAME, height
FROM usertbl;

&gt; 동순위 발생 시 다음 등 수 생략
SELECT RANK() over(order by height DESC), NAME, height
FROM usertbl;

&gt; 동순위 발생하여도 다음 등 수 이어감
SELECT dense_RANK() over(order by height DESC), NAME, height
FROM usertbl;

&gt; 전체 인원을 키 순서로 세운 후에 4개의 그룹으로 분할
SELECT NTILE(4) OVER(ORDER BY height DESC) &#39;num&#39;, NAME, height
FROM usertbl;

&gt; 분석 윈도우 함수
&gt; usertbl 테이블에서 키 순서대로 정렬 후 다음 사람과 키 차이를 조회
SELECT NAME, addr, height,
height -  LEAD(height, 1) OVER(ORDER BY height DESC) AS &#39;lead&#39; 
FROM usertbl
ORDER BY height DESC;




&gt; usertbl 테이블에서 키 순서를 정렬 후 이전 사람과 키 차이를 조회
SELECT NAME, addr, height,LAG(height,1) OVER(ORDER BY height DESC)  - height AS  &#39;키차이&#39;
FROM usertbl; 


&gt; usertbl 지역별로 가장 키 큰 사람과 차이를 조회

SELECT addr, NAME, height, FIRST_VALUE(height) OVER(partition by addr ORDER BY height DESC) - height
FROM usertbl;
</code></pre><p><BR/><BR/><BR/><BR/><BR/><BR/><BR/><BR/><BR/><BR/></p>
<hr>
<p> <br/><br/><br/></p>
<h1 id="db---조인">DB - 조인</h1>
<hr>
<hr>
<blockquote>
<ul>
<li><strong>INNER JOIN</strong></li>
</ul>
</blockquote>
<ul>
<li><strong>OUTER-JOIN</strong></li>
<li><strong>CROSS-JOIN/SELF-JOIN</strong></li>
<li><strong>UNION-ALL</strong></li>
</ul>
<hr>
<h3 id="inner-join">INNER JOIN</h3>
<pre><code>&gt; 특정 조건을 만족하는 행들 끼리 하나의 행을 만든다.
&gt; 23개의 employees -&gt; 21개의 join (employee에서 dept_code 가 null인 행)
SELECT * FROM employee e INNER JOIN department d ON e.dept_code = d.dept_id;

&gt; NATURAL JOIN: 동일한 이름의 열이 더 있을 때 -&gt; join 조건이 이상해지고 원하지 않는 결과가 나올 수 있다.
SELECT emp_id, emp_name, job_code, job_name
FROM employee
NATURAL JOIN job;

&gt; INNER JOIN에 WHERE 절 사용
SELECT emp_no, emp_name, bonus, d.dept_title
FROM employee e
INNER JOIN department d ON e.dept_code = d.dept_id
WHERE bonus IS not NULL;</code></pre><h3 id="outer-join">OUTER JOIN</h3>
<pre><code>&gt; outer join 실습
&gt; 1) left outer join (왼쪽의 테이블은 모두 포함)
SELECT * FROM employee e
LEFT /*OUTER*/ JOIN department d ON e.dept_code = d.dept_id
ORDER BY e.dept_code;

&gt; 2) right outer join (부서에 속해있는 사원이 없어도 부서에 대한 정보가 출력된다.)
SELECT e.emp_name, d.dept_id, d.dept_title, e.salary FROM employee e
right /*OUTER*/ JOIN department d ON e.dept_code = d.dept_id
ORDER BY e.dept_code;
</code></pre><h3 id="crossself-join">CROSS/SELF JOIN</h3>
<pre><code>&gt; cross join 23rows * 9rows -&gt; 207rows
SELECT * FROM employee
CROSS JOIN department;

&gt; self join -&gt; inner join을 자기 자신( 하나의 테이블)로 진행
SELECT e.emp_id, e.emp_name, e.dept_code, m.emp_id &#39;사수id&#39;, m.emp_name &#39;사수 이름&#39;
 FROM employee e

&gt; none equal join (비등가 조인)
&gt; sal_grade에서 조건에 맞는 행이 mapping 된다.
SELECT employee.emp_id AS &#39;id&#39;, employee.emp_name AS &#39;name&#39;, sal_grade.sal_level AS &#39;salary_level&#39;
FROM employee
INNER JOIN sal_grade ON employee.salary BETWEEN sal_grade.min_sal AND sal_grade.max_sal;
</code></pre><h3 id="실습-with-union">실습 with UNION</h3>
<pre><code>&gt; 실습문제

-- 테이블을 다중 JOIN 하여 사번, 직원명, 부서명, 지역명, 국가명 조회
SELECT e.emp_id,
         e.emp_name,
         d.dept_title,
         l.local_name,
         n.national_name
FROM employee e
LEFT OUTER JOIN department d ON e.dept_code = d.dept_id
LEFT OUTER JOIN location l ON d.location_id = l.local_code
LEFT OUTER JOIN national n ON l.national_code = n.national_code;

-- 한국과 일본에서 근무하는 직원들의 직원명, 부서명, 지역명, 근무 국가를 조회하세요.
SELECT e.emp_name,
         d.dept_title,
         l.local_name,
         n.national_name
FROM employee e
INNER JOIN department d ON e.dept_code = d.dept_id
INNER JOIN location l ON d.location_id = l.local_code
INNER JOIN national n ON l.national_code = n.national_code
WHERE n.national_name IN (&#39;한국&#39;, &#39;일본&#39;);

-- 1) UNION 연산자
SELECT emp_id, 
         emp_name, 
         dept_code, 
         salary
FROM employee
WHERE dept_code = &#39;D5&#39;

UNION

SELECT emp_id, 
         emp_name, 
         dept_code,
         salary
FROM employee
WHERE salary &gt; 3000000;

-- 위 쿼리문 대신에 WHERE 절에 OR 연산자를 사용해서 처리가 가능하다.
SELECT emp_id, 
         emp_name, 
         dept_code,
         salary
FROM employee
WHERE dept_code = &#39;D5&#39; OR salary &gt; 3000000;

-- 2) UNION ALL 연산자
SELECT emp_id, 
         emp_name, 
         dept_code, 
         salary
FROM employee
WHERE dept_code = &#39;D5&#39;

UNION ALL

SELECT emp_id, 
         emp_name, 
         dept_code,
         salary
FROM employee
WHERE salary &gt; 3000000;</code></pre><BR/>

<BR/>

<BR/>

<p><BR/><BR/><BR/><BR/><BR/><BR/><BR/><BR/><BR/><BR/></p>
<hr>
<p> <br/><br/><br/></p>
<h1 id="db---서브쿼리">DB - 서브쿼리</h1>
<hr>
<hr>
<blockquote>
<ul>
<li><strong>SUB QUERY</strong></li>
</ul>
</blockquote>
<ul>
<li><strong>단일행 서브쿼리</strong></li>
<li><strong>다중행 서브쿼리</strong></li>
<li><strong>다중열 서브쿼리</strong></li>
<li><strong>다중행 다중열 서브쿼리</strong></li>
<li><strong>인라인 뷰</strong></li>
</ul>
<hr>
<BR/>

<h3 id="subquery">SUBQUERY</h3>
<pre><code>&gt; 서브 쿼리 실습
-- 하나의 sql 문 안에 또 다른 sql 문을 서브 쿼리라 한다.

-- 서브 쿼리 예시
-- 노웅철 사원과 같은 부서원들을 조회
-- 1) 노웅철 사원의 부서 코드를 조회
SELECT emp_name, dept_code
FROM employee
WHERE emp_name = &#39;노옹철&#39;;
-- 2) 부서코드가 노옹철 사원의 부서 코드와 동일한 사원들을 조회

SELECT emp_name, dept_code
FROM employee
WHERE dept_code = &#39;D9&#39;;


SELECT emp_name, dept_code
FROM employee
WHERE dept_code = (
SELECT dept_code
FROM employee
WHERE emp_name = &#39;노옹철&#39;);


</code></pre><BR/>

<h3 id="단일행-서브쿼리">단일행 서브쿼리</h3>
<pre><code>
-- 1) 단일행 서브 쿼리 서브쿼리 조회 결과 값의 개수가 1일 떄
-- 전 직원의 평균 급여 보다 더 많은 급여를 받고 있는 직원들의 사번, 직원명, 직급 코드, 급여를 조회

SELECT AVG(salary)
FROM employee;

SELECT emp_id, emp_name, job_code, salary
FROM employee
WHERE salary &gt;= (SELECT AVG(salary) FROM employee);
</code></pre><h3 id="다중행-서브쿼리">다중행 서브쿼리</h3>
<pre><code>
-- 2) 다중행 서브 쿼리 서브 쿼리 조회 결과 값의 개수가 여러 행 일 떄

-- 각 부서별 최고 급여를 받는 직원의 이름, 직급 코드, 부서 코드, 급여 조회
-- 부서별 최고 급여 조회
SELECT max(salary), dept_code FROM employee
GROUP BY dept_code;

SELECT emp_name, job_code, dept_code, salary
FROM employee
WHERE salary IN (SELECT MAX(salary) FROM employee GROUP BY dept_code)
ORDER BY salary desc;


-- 직원들의 사번, 직원명, 부서 코드, 구분(사원/사수) 조회
SELECT DISTINCT manager_id
FROM employee
WHERE manager_id IS NOT NULL;

SELECT emp_id, emp_name, dept_code
        , case
            when emp_id IN (SELECT DISTINCT manager_id
                                FROM employee
                                WHERE manager_id IS NOT NULL) then &#39;사수&#39;
            ELSE &#39;사원&#39;
        END AS 구분
FROM employee;


-- 대리 직급에도 과장 직급들의 최소 급여보다 많이 받는 
-- 직원의 사번, 이름, 직급 코드, 급여 조회

SELECT salary
FROM employee
WHERE job_code = &#39;J5&#39;;

SELECT min(salary)
FROM employee e
INNER JOIN job j ON e.job_code = j.job_code
WHERE j.job_name = &#39;과장&#39;;

-- any는 서브 쿼리의 결과 값의 목록 중 하나라도 조건을 만족하면 참이 된다. (ALL은 모든 조건이 만족되어야 한다)

SELECT emp_id, emp_name, job_code, salary
FROM employee
WHERE job_code = &#39;J6&#39; AND salary &gt; ANY(
    SELECT min(salary)
    FROM employee e
    INNER JOIN job j ON e.job_code = j.job_code
    WHERE j.job_name = &#39;과장&#39;);</code></pre><h3 id="다중열-서브쿼리">다중열 서브쿼리</h3>
<pre><code>-- 3) 다중열 서브 쿼리 서브 쿼리 조회 결과 1행에 여러 개의 열의 값일 때
-- 부서 코드가 D5이면서 직급 코드가 j5인 사원들을 조회    
SELECT emp_name, dept_code, job_code
FROM employee
WHERE (dept_code, job_code) = (
    SELECT dept_code, job_code
    FROM employee
    WHERE emp_name = &#39;하이유&#39;    
);    


</code></pre><BR/>

<h3 id="다중행-다중열-서브쿼리">다중행 다중열 서브쿼리</h3>
<pre><code>-- 4) 다중행 다중열 서브 쿼리 서브 쿼리 조회 결과 여러 행 여러 열의 값이 조회 될 때

-- 각 부서별 최고 급여를 받는 직원의 사번, 직원명, 부서 코드, 급여 조회
-- 부서별 최고 급여 조회
SELECT dept_code, MAX(salary)
FROM employee
GROUP BY dept_code;



SELECT emp_no, emp_name, IFNULL(dept_code,&#39;부서없음&#39;), salary
FROM employee
WHERE (IFNULL(dept_code, &#39;부서없음&#39;), salary) IN (
    SELECT IFNULL(dept_code, &#39;부서없음&#39;), MAX(salary)
    FROM employee
    GROUP BY dept_code
)
ORDER BY dept_code desc;

</code></pre><BR/>

<h3 id="인라인-뷰">인라인 뷰</h3>
<pre><code>
-- 인라인 뷰
-- from 절에 서브 쿼리 작성 및 서브 쿼리 수행 결과를 마치 테이블 처럼 사용
SELECT e.*
FROM (
    SELECT emp_id AS &#39;사번&#39;,
        emp_name AS &#39;이름&#39;,
        salary AS &#39;급여&#39;,
        salary*12 AS &#39;연봉&#39;
    FROM employee
) e;

-- employee 테이블에서 급여로 순위를 매겨서 출력
SELECT e.* 
FROM (
    SELECT ROW_NUMBER() OVER(ORDER BY salary DESC) AS &#39;num&#39;,
        emp_name,
        salary
    FROM employee
) e
WHERE e.num BETWEEN 6 AND 10;
</code></pre><p><BR/><BR/><BR/><BR/><BR/><BR/><BR/></p>
<hr>
<p> <br/><br/><br/></p>
<h1 id="db---모델링">DB - 모델링</h1>
<hr>
<hr>
<blockquote>
<ul>
<li><strong>DB모델링</strong></li>
</ul>
</blockquote>
<ul>
<li><strong>개념적모델링</strong></li>
<li><strong>논리적모델링</strong></li>
<li><strong>물리적모델링</strong></li>
</ul>
<hr>
<BR/>
<BR/>

<h3 id="db-모델링">DB 모델링</h3>
<ul>
<li>개념적 모델링: 개념적 모델링은 ENTITY 간의 관계를 정의하여 ERD를 제작하는 과정을 의미한다.</li>
<li>논리적 모델링: ERD를 사용하려는 DBMS 맞게 사상(MAPPING)하여 관계 스키마 모델을 만드는 과정</li>
<li>물리적 모델링: 작성된 논리적 모델을 실제 저장장치에 저장하기 위한 물리적 구조를 정의하는 과정</li>
</ul>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/cd549ad9-89eb-4838-b1cb-ca4943cb582e/image.png" alt=""></p>
<BR/>

<h3 id="개념적-모델링">개념적 모델링</h3>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/b562eb99-73ce-4c4b-afb7-94c319a7c7ac/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/2ebadb64-7e60-41be-b44b-c5cd54815203/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/2c20b0b1-e08a-436e-893f-4842108cf4ab/image.png" alt=""></p>
<h3 id="논리적-모델링">논리적 모델링</h3>
<h4 id="keys">Keys</h4>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/64850aa2-7a32-41aa-a2bc-94480c4e33f9/image.png" alt=""></p>
<ul>
<li>슈퍼키 ( 유일성 o, 최소성 X)</li>
<li>후보키 ( 유일성 O, 최소성 O)</li>
<li>기본키 ( 후보키 중 하나 , 가장 단순한 속성 집합이어야 좋음)</li>
<li>복합키 ( 결정자적 컬럼 두 개 이상으로 구성 된 기본키)</li>
<li>외래키 ( 속성 참조를 위해 필요한 다른 테이블의 기본키 -&gt; 해당 테이블 데이터 수정 시 무결성을 유지 시켜준다.)</li>
<li>대체키 ( 후보키 집합 중 기본키를 제외한 나머지 키)</li>
</ul>
<h4 id="이상현상anomaly--테이블에서-공유하는-데이터-임에도-각-튜플에-독립적으로-존재하기-때문에-나타나는-현상">이상현상(anomaly) : 테이블에서 공유하는 데이터 임에도 각 튜플에 독립적으로 존재하기 때문에 나타나는 현상</h4>
<ul>
<li>삽입이상 
<img src="https://velog.velcdn.com/images/sirius2_1/post/43517116-b844-4cf7-9761-a5092feebd4f/image.png" alt=""></li>
</ul>
<ul>
<li>삭제이상</li>
</ul>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/ff0f2214-d79d-4cbc-89a6-4b7a9df686a8/image.png" alt=""></p>
<ul>
<li>수정이상</li>
</ul>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/0024ba17-a96a-4775-857a-d117d9aa311b/image.png" alt=""></p>
<BR/>

<h4 id="함수-종속성">함수 종속성</h4>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/6c9a8bb2-5662-488b-8a62-48c87703f663/image.png" alt=""></p>
<ul>
<li>다이어그램</li>
</ul>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/e970247e-92df-4a81-a0b3-feed7f9c6726/image.png" alt=""></p>
<BR/>

<h4 id="정규화">정규화</h4>
<p>** 1. 기본키는 릴레이션의 다른 모든 속성을 결정할 수 있어야 한다. **
** 2. 기본키가 아닌 속성이 결정자일 때, 이상현상이 발생한다. **</p>
<p>** 정규화는 이상현상이 있는 릴레이션을 분해하여 이상현상을 없애는 과정이다. **</p>
<BR/>

<blockquote>
<ul>
<li><h4 id="제1정규형">제1정규형</h4>
릴레이션의 모든 속성값을 원자값으로 한다.</li>
</ul>
</blockquote>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/06d28ac3-df39-4a37-97dd-5202643d33f6/image.png" alt=""></p>
<blockquote>
<ul>
<li><h4 id="제2정규형">제2정규형</h4>
제 1정규형을 만족하고, 릴레이션의 모든 속성이 기본키에 완전 함수 종속이 되게 한다.</li>
</ul>
</blockquote>
<ul>
<li>이때 기본키의 부분집합이 결정자 <strong>(부분 함수 종속)</strong> 가 되어서는 안된다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/f2888b39-9bd2-47a0-b0a2-484842e0b12c/image.png" alt=""></p>
<blockquote>
<ul>
<li><h4 id="제3정규형">제3정규형</h4>
제 2정규형을 만족하고, 릴레이션 내 속성 간 이행적 종속을 제거하고 분해하여 참조하도록 한다.</li>
</ul>
</blockquote>
<ul>
<li>기본키가 아닌 속성은 기본키에만 종속하도록 한다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/f677ad8b-c409-46be-99e0-6602c3bb9d27/image.png" alt=""></p>
<blockquote>
<ul>
<li><h4 id="bcnf정규형">BCNF정규형</h4>
제 3정규형을 만족하고, 모든 결정자는 후보키여야 한다.</li>
</ul>
</blockquote>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/dea4fa77-0fd5-4022-8184-d75a66361c92/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/f435ba6e-8f65-4dca-9b00-a2286422edbb/image.png" alt=""></p>
<p><BR/><BR/></p>
<h3 id="물리적모델링">물리적모델링</h3>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/ed9a59fe-2815-4346-8928-5959407ef084/image.png" alt=""></p>
<p><BR/><BR/><BR/></p>
<hr>
<h1 id="db---데이터-변경">DB - 데이터 변경</h1>
<hr>
<hr>
<blockquote>
<ul>
<li><strong>테이블생성과 제약조건</strong></li>
</ul>
</blockquote>
<ul>
<li><strong>테이블수정/삭제</strong></li>
<li><strong>뷰</strong></li>
<li><strong>인덱스</strong></li>
</ul>
<hr>
<BR/>

<h3 id="테이블-생성">테이블 생성</h3>
<pre><code>&gt; DROP TABLE &lt;-&gt; CREATE TABLE
&gt; DEFAULT KEYWORD를 통해 DEFAULT 값을 지정해 줄 수 있다
DROP TABLE `tb_member`;

CREATE TABLE `tb_member` (
    `mem_no` INT NOT NULL,
    `mem_id` VARCHAR(20) NOT NULL,
    `mem_pass` VARCHAR(20) NOT NULL,
    `mem_name` VARCHAR(15) NOT NULL,
    `enroll_date` DATE DEFAULT CURDATE()
);

</code></pre><h3 id="제약조건">제약조건</h3>
<blockquote>
<ul>
<li>NOT NULL : NULL 값을 입력 받지 않는다</li>
</ul>
</blockquote>
<ul>
<li>PRIMARY KEY: 유일성 + NOT NULL (UNIQUE + NOT NULL)</li>
<li>UNIQUE: 유일성 (중복값 입력불가)</li>
<li>CHECK: 입력 값 범위 또는 조건 지정</li>
<li>REFERENCES: FOREIGN KEY 제약
<img src="https://velog.velcdn.com/images/sirius2_1/post/27186822-4854-4d2e-8d88-b0dd5f9bdb41/image.png" alt=""></li>
</ul>
<h4 id="컬럼-제약조건">컬럼 제약조건</h4>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/7926da1e-f555-456a-906f-1c188ca50399/image.png" alt=""></p>
<h4 id="테이블-제약조건-not-null은-테이블제약조건으로-설정할-수-없다">테이블 제약조건 (NOT NULL은 테이블제약조건으로 설정할 수 없다)</h4>
<blockquote>
<ul>
<li>제약조건에 이름을 설정할 수 있다. (컬럼 제약조건도 내부적으로는 ALIAS 참조 가능)</li>
</ul>
</blockquote>
<ul>
<li>CONSTRAINT <code>CON_NAME</code> UNIQUE(<code>FIELD_NAME</code>);</li>
</ul>
<pre><code>&gt; PRIMARY KEY 제약 조건의 경우 여러 개의 열을 묶어서 하나의 기본 키를 생성할 수 있다. 이 때, 한 열의 중복값은 허용된다.

&gt; UNIQUE 제약 조건도 여러 개의 열을 묶어서 하나의 제약 조건으로 생성할 수 있다. 

CREATE TABLE `tb_member` (
    `mem_no` INT AUTO_INCREMENT, --&gt; INT AUTO_INCREMENT 를 하나의 데이터타입처럼 사용
    `mem_id` VARCHAR(20) NOT NULL,
    `mem_pass` VARCHAR(20) NOT NULL,
    `mem_name` VARCHAR(15) NOT NULL,
    `enroll_date` DATE DEFAULT CURDATE(),
    /* CONSTRAINT */ PRIMARY KEY(mem_no),
    -- PRIMARY KEY(mem_no, mem_id),
    CONSTRAINT uq_tb_member_mem_id UNIQUE(mem_id)
      -- UNIQUE(mem_id, mem_id)
);
</code></pre><h3 id="테이블-수정삭제">테이블 수정/삭제</h3>
<pre><code>
&gt; ALTER TABLE : 열 또는 제약조건의 추가, 수정, 삭제, 이름 변경의 작업 진행
&gt; DROP TABLE: TABLE을 삭제

-- usertbl 테이블에 gender 열을 추가 (단, 기본값을 남자로 지정)
ALTER TABLE usertbl ADD gender CHAR(10) DEFAULT &#39;male&#39; NOT NULL;
-- usertbl 테이블에 age 열을 추가 (단, 기본값은 0으로, birthYear 뒤에 생성, 맨 앞은 first  keyword)
ALTER TABLE usertbl ADD age TINYINT DEFAULT 0 AFTER birthyear;

-- usertbl 테이블에서 name 열의 데이터 유형을 CHAR(15)로 변경
ALTER TABLE usertbl MODIFY NAME CHAR(15) NULL;
-- 열의 이름을 변경
ALTER TABLE usertbl RENAME COLUMN `NAME` TO uname;

-- 위 내용을 한 번에 변경
ALTER TABLE usertbl CHANGE COLUMN NAME uname VARCHAR(20) DEFAULT &#39;없음&#39; NOT NULL; 


ALTER TABLE usertbl DROP column age;



ALTER TABLE usertbl ADD CONSTRAINT `CONS_NAME` PRIMARY KEY(&#39;FIELD_NAME&#39;);

ALTER TABLE usertbl ADD CONSTRAINT &#39;CONS_NAME&#39; FOREIGN KEY(&#39;FIELD NAME&#39;) REFERENCES &#39;TABLE_NAME&#39;(&#39;FIELD_`NAME`&#39;);

ALTER TABLE tb_member ADD CONSTRAINT CHECK(gender = &#39;남자&#39; OR gender = &#39;여자&#39;);

ALTER TABLE usertbl DROP CONSTRAINT PRIMARY KEY;

ALTER TABLE usertbl DROP CONSTRAINT `CONS_NAME`;


</code></pre><pre><code>-- 테이블 삭제
DROP TABLE tb_member;
DROP TABLE tb_member_grade;
DROP TABLE tb_member, tb_member_grade;

-- 테이블 이름 변경
RENAME TABLE salary_grade TO sal_grade;
</code></pre><p><BR/><BR/></p>
<h3 id="뷰">뷰</h3>
<br/>

<ul>
<li>가상의 테이블, 읽기전용, 뷰 안에서 데이터 수정 가능</li>
<li>직접 테이블을 전해주기보다는 필요한 형태로 정보를 가공하고 권한을 제한해서 보여줄 수 있는 장점이 있다.</li>
<li>조인 연산이나 서브쿼리 사용 등 복잡한 쿼리 자주 사용해야한다면 해당 쿼리를 매번 작성하기 보다는 뷰를 생성하여 필요할 때마다 간단하게 조회
<BR/><BR/></li>
</ul>
<pre><code>CREATE VIEW v1
AS SELECT emp_name, phone, d.dept_title FROM employee
    LEFT OUTER JOIN department d ON employee.dept_code = d.dept_id;

SELECT * FROM v1;

&gt; SELECT 절에 함수나 산술 연산이 기술되어 있는 경우 별칭을 지정해야 한다.
CREATE OR REPLACE VIEW v_employee
AS SELECT emp_id,
              emp_name,
              IF(SUBSTRING(emp_no, 8, 1) = &#39;1&#39;, &#39;남자&#39;, &#39;여자&#39;) AS &#39;gender&#39;,
              salary
    FROM employee;


&gt; 뷰를 이용해서 DML(INSERT, UPDATE, DELETE) 사용
CREATE VIEW v_job
AS SELECT *
    FROM job;

SELECT job_code, job_name FROM v_job;

INSERT INTO v_job VALUES (&#39;J8&#39;, &#39;알바&#39;);

UPDATE v_job
SET job_name = &#39;인턴&#39;
WHERE job_code = &#39;J8&#39;;

DELETE 
FROM v_job
WHERE job_code = &#39;J8&#39;;

&gt; 산술 연산이 정의된 뷰의 데이터 수정 작업은 실행 되지 않는다.
CREATE VIEW v_emp_salary
AS SELECT emp_id,
             emp_name,
             emp_no,
             salary * 12 AS &#39;salary&#39;
    FROM employee;

INSERT INTO v_emp_salary
VALUES (&#39;300&#39;, &#39;홍길동&#39;, &#39;950525-1234567&#39;, 30000000);

UPDATE v_emp_salary
SET salary = 30000000
WHERE emp_id = &#39;200&#39;;

SELECT * FROM v_emp_salary;


DROP VIEW v1;
</code></pre><h3 id="인덱스">인덱스</h3>
<ul>
<li><p>추가적인 쓰기 작업과 저장공간을 활용하여 검색속도를 향상시키는 자료구조</p>
</li>
<li><p>인덱스를 사용하지 않는 컬럼은 조회 시 full scan을 진행한다.</p>
</li>
<li><p>인덱스를 사용하면 select 외에도 update,delete 작업에서 속도가 향상한다(조회가 포함되기 때문에)</p>
</li>
<li><p>또한 insert 작업 시, 새로운 데이터에 인덱스 추가, delete 시, 해당 데이터의 인덱스 사용하지 않음, update 시, 기존 인덱스 사용하지 않음/ 새로운 인덱스 사용과 같은 작업으로 부하가 추가 될 수 있다.</p>
</li>
<li><p>PRIMARY KEY에 CLUSTERD INDEX 하나가 기본으로 생성, 이외에는 보조 인덱스 (UNIQUE 제약 조건 하에는 보조 인덱스가 기본으로 생성)</p>
</li>
</ul>
<blockquote>
</blockquote>
<p><strong>인덱스의 장점</strong></p>
<ul>
<li>조회 속도로부터 성능 향샹</li>
<li>시스템의 부하를 줄여줌<br/></li>
<li><em>인덱스의 단점*</em></li>
<li>db 전체 저장공간의 10% 가량을 사용</li>
<li>인덱스 관리를 위한 추가적이 작업이 필요</li>
<li>잘못 사용 시, 오히려 성능이 저하<br/></li>
<li>CREATE, DELETE, UPDATE가 빈번한 테이블의 경우에는 인덱스 사용이 부적합하다, 이러한 쿼리가 잦아질 경우 인덱스가 비대해져 데이터보다 많은 공간을 차지 하게 될 수 있다.<BR/></li>
<li><em>인덱스를 사용하면 좋은 경우*</em></li>
<li>규모가 큰 테이블</li>
<li>JOJN/WHERE/ORDERBY 절이 잦은 경우</li>
<li>INSERT/UPDATE/DELETE 절이 적은 테이블</li>
<li>컬럼 내 중복 데이터가 적은 경우(B+TREE의 KEY/VALUE 구조 탐색이기 때문)</li>
</ul>
<p><strong>인덱스설계</strong></p>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/3e18e729-a15f-4ee4-8af5-f35ba10ee6a9/image.png" alt="">
<img src="https://velog.velcdn.com/images/sirius2_1/post/fe1aa88e-84ab-4eb9-99b6-6be78bec7afc/image.png" alt=""></p>
<pre><code>

CREATE OR REPLACE INDEX idx_firstname ON employees(first_name);
CREATE OR REPLACE INDEX idx_lastname ON employees(last_name);

ANALYZE TABLE employees;


SELECT * FROM employees WHERE first_name = &#39;moon&#39;;
EXPLAIN SELECT * FROM employees WHERE first_name = &#39;moon&#39;;
&gt; index 를 사용했을 때, 조회하는 행의 개수가 대폭 줄어든다.


CREATE OR REPLACE INDEX idx_firstlast ON employees(first_name, last_name);
&gt; 두 개 이상의 컬럼을 인덱스로써 활용할 수 있다.

EXPLAIN SELECT * FROM employees WHERE emp_no = 100000;
EXPLAIN SELECT * FROM employees WHERE emp_no * 1 = 100000;
&gt; emp_no = 100000으로 조회 했을 때, 한 개 행을 조회한 반면, emp_no * 1과 같이 where 절에 이항 연산자를 사용했을 때, 모든 행을 조회하였다.</code></pre><p><BR/><BR/><BR/><BR/><BR/><BR/></p>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[리눅스 정리]]></title>
            <link>https://velog.io/@sirius2_1/BEYOND-SW-CAMP-13-1%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@sirius2_1/BEYOND-SW-CAMP-13-1%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Tue, 10 Dec 2024 07:59:42 GMT</pubDate>
            <description><![CDATA[<hr>
<hr>
<h1 id="리눅스-기초">리눅스 기초</h1>
<hr>
<hr>
<blockquote>
<ul>
<li>우분투 리눅스에 관한 간단한 소개</li>
</ul>
</blockquote>
<ul>
<li>쉘과 터미널 커널에 대한 간단한 소개</li>
<li>가상 머신을 이용하여 ssh(secure shell) 설정 </li>
<li>기본적인 리눅스 커맨드 숙지</li>
</ul>
<hr>
<br/>

<p><br/><br/><br/></p>
<ul>
<li><strong>쉘과 터미널의 개념</strong>
<img src="https://velog.velcdn.com/images/sirius2_1/post/831b3267-85f8-4331-8d02-e6430d69f2e8/image.png" alt=""></li>
</ul>
<p><em>터미널은 컴퓨터의 입출력을 담당하는 전용 하드웨어이다 (리눅스에선 소프트웨어 터미널을 사용). 쉘과 혼동 하면 안된다</em></p>
<br/>
<br/>



<ul>
<li><strong>ssh의 개념과 설정 과정</strong>
<img src="https://velog.velcdn.com/images/sirius2_1/post/3929e641-1099-4bdf-9e16-10f433b7bdb5/image.png" alt=""></li>
</ul>
<br/>

<p><em>putty가 아닌 <strong>movaxterm</strong>이라는 프로그램으로 클라이언트와 서버를 연결했다. GUI가 훨씬 사용하기 편하였다.</em></p>
<br/>

<p><img src="https://velog.velcdn.com/images/sirius2_1/post/dd08025c-98be-49ac-8a5c-6faf7582511c/image.png" alt=""></p>
<p><br/><br/></p>
<ul>
<li>** ssh 설정 과정**</li>
</ul>
<br/>

<p><img src="https://velog.velcdn.com/images/sirius2_1/post/1f9fc2f7-2229-4551-ae1f-46feaf4dbc0b/image.png" alt=""></p>
<p><em>먼저 server에 오픈 라이브러리를 설치한다.</em></p>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/e651fd74-f105-4133-9efd-3358510e7106/image.png" alt=""></p>
<p>_server(가상머신)에 포트포워딩 설정을 해준다. (루프백 IP로 30021포트로 접속 시 가상 머신의 IP와 포트로 포워딩을 한다.) _</p>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/fb89d6a8-774d-47b9-a68d-c57ef1ce5f12/image.png" alt=""></p>
<p>movaxterm 설정을 통해 클라이언트에도 remote  host 설정을 해준다. (loop back IP와 포트 번호)</p>
<br/>

<p><img src="https://velog.velcdn.com/images/sirius2_1/post/e60f7f04-68db-4607-9cdc-3336a64d8e05/image.png" alt=""></p>
<p>이제 movaxterm에서 ssh rsa 암호화 키를 생성한다.</p>
<br/>

<p><img src="https://velog.velcdn.com/images/sirius2_1/post/7c6723c7-653b-4302-81a1-cfcbb5d84e5d/image.png" alt=""></p>
<p>공개키와 비공개키가 서버에 생성되었다.</p>
<br/>

<p><img src="https://velog.velcdn.com/images/sirius2_1/post/f5216282-d0a7-4aab-a5c1-e99325c24a01/image.png" alt=""></p>
<p>ssh-keygen 설정에 따라 비공개키 이름을 &#39;authorized_keys&#39;로 변경해준다.</p>
<br/>

<p><img src="https://velog.velcdn.com/images/sirius2_1/post/9ad928a9-ad52-4272-be40-484c1f6f338a/image.png" alt=""></p>
<p>movaxterm에서 비공개키를 SFTP(Secure File Transport Protocol)을 이용해 클라이언트에 원격으로 다운로드 한다.</p>
<br/>

<p><img src="https://velog.velcdn.com/images/sirius2_1/post/f16b722e-50ab-40a6-89e9-0afeddfdc2c9/image.png" alt=""></p>
<p>advanced SSH settings에서 비공개키 경로를 지정해 설정을 완료한다. (이제 암호화를 통해 쉽게 서버에 접근할 수 있다.)</p>
<p><br/><br/></p>
<ul>
<li><strong>잊고 있던 또는 새로 알게 된 리눅스 커맨드</strong></li>
</ul>
<br/>
<br/>

<p><img src="https://velog.velcdn.com/images/sirius2_1/post/c67f8f85-be14-41ca-b5c2-787daaf0d93a/image.png" alt=""></p>
<br/>

<p><img src="https://velog.velcdn.com/images/sirius2_1/post/3ad2ebb7-76e6-4187-aefe-af6643ae7c18/image.png" alt=""></p>
<br/>

<p><img src="https://velog.velcdn.com/images/sirius2_1/post/a6b62270-4944-46aa-84cb-432dbf531542/image.png" alt=""></p>
<br/>

<p><img src="https://velog.velcdn.com/images/sirius2_1/post/2e16e15e-596a-40a1-a554-4b2a62bcbe0b/image.png" alt=""></p>
<br/>

<p><img src="https://velog.velcdn.com/images/sirius2_1/post/6f052b7b-e82a-4400-b551-6a6a9a106169/image.png" alt=""></p>
<br/>

<p><img src="https://velog.velcdn.com/images/sirius2_1/post/3e13abe6-f48c-4e5b-909a-eeeb6375c895/image.png" alt=""></p>
<br/>

<p><img src="https://velog.velcdn.com/images/sirius2_1/post/e8f8e8f0-17af-4956-9479-e4e7255b29dd/image.png" alt=""></p>
<p><br/><br/><br/></p>
<hr>
<p><br/><br/></p>
<hr>
<hr>
<h1 id="리눅스-기초2">리눅스 기초2</h1>
<hr>
<hr>
<ul>
<li>vim 사용법</li>
<li>텍스트 처리</li>
<li>파일 관리</li>
</ul>
<hr>
<ul>
<li><p><strong>cp, mv, ln, find 명령어 복습</strong></p>
<p><br/><br/></p>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/b79de2f2-7875-453c-a821-2a7ea27e49f1/image.png" alt=""></p>
<p><br/><br/></p>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/ead5733b-d22e-48d5-a2e6-98a56791857e/image.png" alt=""></p>
</li>
</ul>
<p><br/><br/></p>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/79ee5c92-bf88-4ba2-803e-f7c9569823ba/image.png" alt=""></p>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[MatplotIib 기본 사용]]></title>
            <link>https://velog.io/@sirius2_1/MatplotIib</link>
            <guid>https://velog.io/@sirius2_1/MatplotIib</guid>
            <pubDate>Sun, 04 Feb 2024 06:40:10 GMT</pubDate>
            <description><![CDATA[<hr>
<h2 id="matplotlib">Matplotlib</h2>
<blockquote>
<p>파이썬의 대표적인 시각화 라이브러리, 다양한 형태의 그래프로 데이터를 시각화 할 수 있다.
터미널에서 pip install matplotlib 커맨드로 설치하여 사용할 수 있다.</p>
</blockquote>
<hr>
<h2 id="pyplot">Pyplot</h2>
<blockquote>
<p>matplotlib의 대부분의 기능이 pyplot이라는 submodule을 기초로 한다.
주로 plt라는 alias로 import를 수행한다.</p>
<blockquote>
<pre><code>import matplotlib.pyplot as plt</code></pre></blockquote>
</blockquote>
<pre><code>
-----
## plot &amp; show

&gt; plot 함수는 기본적으로 figure상에 점들을 그리는 함수로 기본적으로 좌표와 좌표 사이에 line을 그려준다.

&gt; parameters로 x좌표의 집합 array, y좌표 집합의 array를 전달받는다.
&gt;&gt; 예를 들어, (0,0),(6,250)이라는 두좌표를 잇는 선을 그리고 싶다면 인자로 [0,6],[0,250]을 전달하면 된다.

**예시를 통해 확인해보자**
</code></pre><p>&#39;&#39;&#39; simple example&#39;&#39;&#39;
import matplotlib.pyplot as plt 
import numpy as np</p>
<p>x_points = np.array([0,6])
y_points = np.array([0,250])</p>
<p>plt.plot(x_points,y_points)
plt.show()</p>
<h1 id="점들을-잇는-line-대신-marker로만-plot을-표현하고-싶다면">점들을 잇는 line 대신 marker로만 plot을 표현하고 싶다면</h1>
<h1 id="3번째-인자로-ring을-의미하는-o를-전달해주면-된다">3번째 인자로 ring을 의미하는 &#39;o&#39;를 전달해주면 된다.</h1>
<p>plt.plot(x_points,y_points,&#39;o&#39;)
plt.show()</p>
<pre><code>

**실행결과**

![](https://velog.velcdn.com/images/sirius2_1/post/c5c0cd3f-80f2-4fa9-8af1-228bbf8efca0/image.png)![](https://velog.velcdn.com/images/sirius2_1/post/6a121460-98b5-4dbb-957a-279902b5ca20/image.png)


&gt; x좌표와 y좌표의 개수를 맞추어 줘야하는데, y좌표 array만 전달한다면 default로 y좌표 array의 길이에 맞추어 x좌표들이 생성된다. (ex) 0,1,2..
</code></pre><p>plt.plot(y_points)
plt.show()</p>
<pre><code>
![](https://velog.velcdn.com/images/sirius2_1/post/a441f849-56a6-412e-b5ce-13e024f1d1e6/image.png)


-----------

## marker and line

&gt; 시각화의 대표적인 방법이 marker로 그리기와 line으로 그리기 이다. 그 안에서도 다양한 표현방식이 있는데 먼저 marker부터 알아보자.

&gt; plot함수에는 format string인자를 전달할 수 있는데, 앞서 &#39;o&#39; 도 그의 일종이다. 기본적 형식은 &#39;marker|line|color&quot; 로 &#39;o&#39;,&#39;*&#39;과 같은 marker의 모양, &#39;:&#39;(점선),&#39;--&#39; (실선), &#39;-&#39; (선) 등 선의 모양, &#39;r&#39;,&#39;g&#39;,&#39;b&#39;,&#39;y&#39;,&#39;c&#39;,&#39;m&#39;,&#39;k&#39;,&#39;w&#39; (red,green,blue,yellow,cyan,magenta,black,white)와 같은 색깔 약어를 전달할 수 있다. 
&gt;&gt; 예를 들어 &#39;*:m&#39;의 경우는  *모양 marker를 사용하고 점간에 점선으로 연결하며 색상은 margenta 색인 plot을 그린다.

&gt; 이 외에도 다양한 인자를 전달 할 수 있다. 
markersize를 의미하는 ms, markerEdgeColor를 의미하는 mec, markerFaceColor를 의미하는 mfc인자에 적절한 값을 전달하여 원하는 표현을 할 수 있다.
&gt;&gt; color인자들의 전달값으로는 &#39;#4CAF50&#39;같은 hexaDecimal Notation을 전달할 수도 있고, &#39;hotpink&#39;와 같은 color name을 전달할 수도 있다.
</code></pre><p>y_points = np.array([1,3,8,9])</p>
<p>plt.plot(y_points, &quot;*:b&quot;,ms = 15, mec = &#39;y&#39;, mfc = &#39;c&#39;)
plt.show()</p>
<pre><code>![](https://velog.velcdn.com/images/sirius2_1/post/cf9cff65-eadc-48d3-bb4f-d2103971d6b7/image.png)


&gt; line을 그리는 경우도 다양한 인자를 전달할 수 있는데 linestyle을 의미하는 ls, linewidth를 의미하는 lw, color를 의미하는 c인자에 적절한 값을 전달할 수 있다.
</code></pre><p>y_points = [1,3,8,7]
plt.plot(y_points,ls=&#39;:&#39;,c=&#39;hotpink&#39;)
plt.show()</p>
<p>plt.plot(y_points,lw=15.2)
plt.show()</p>
<pre><code>
![](https://velog.velcdn.com/images/sirius2_1/post/d45f071d-a07c-4048-bf15-899fecb0841e/image.png)
![](https://velog.velcdn.com/images/sirius2_1/post/ce5010f1-28d2-411d-8c1d-9ca9cf251392/image.png)

&gt; 하나의 plot에 두 개 이상의 line을 그리기 위해서는 각기 다른 좌표집합을 가진 plot 함수를 두번 실행 후 show하는 방법이 있고, 하나의 plot함수에 각기다른 좌표집합 배열을 전부 전달하는 방법이 있다.
</code></pre><p>x1 = np.array([0,1,2,3])
y1 = np.array([1,3,8,6])
x2 = np.array([0,1,2,3])
y2 = np.array([3,2,8,9])
plt.plot(x1,y1)
plt.plot(x2,y2)
plt.show()</p>
<p>plt.plot(x1,y1,x2,y2)
plt.show()</p>
<pre><code>
![](https://velog.velcdn.com/images/sirius2_1/post/c0da6d40-c673-49ee-937a-eca2054aa7fb/image.png)

--------

## label &amp; grid

&gt; plot의 x축과 y축별로 label을 표현할 수 있고, grid를 추가해줄 수도 있다.
&gt;&gt; xlabel함수와 ylabel함수, title함수를 통해 설정할 수 있고, 각 함수들은 fontdict라는 인자에 적절한 값을 전달해주어 label들의 형태를 지정할 수 있다. title함수의 경우 loc 인자에 &#39;center&#39;등의 값을 전달하여 포지션을 정할 수 있다.

&gt; grid 함수를 통해 격자표현을 figure상에 추가할 수 있고, axis 인자에 &#39;x&#39;또는 &#39;y&#39;를 입력해 줄 수 있다. default는 모든 축이다. 또한 line을 표현하는 인자 처럼, color, linewidth, linestyle등의 인자를 사용하여 꾸며줄 수 있다.
</code></pre><p>x_points = np.array([1,2,3,5,4,2])
y_points = np.array([3,9,11,3,9,1])</p>
<p>fonts = {&#39;family&#39;:&#39;serif&#39;,&#39;color&#39;:&#39;k&#39;,&#39;size&#39;:15}
plt.xlabel(&quot;x axis&quot;,fontdict = fonts)
plt.ylabel(&quot;y axis&quot;,fontdict = fonts)
plt.title(&quot;Title&quot;,loc = &#39;center&#39;,fontdict=fonts)
plt.plot(x_points,y_points)
plt.grid(axis = &#39;y&#39;, color =&#39;m&#39;, linestyle = &#39;--&#39;, linewidth = 0.5)
plt.show()</p>
<pre><code>
![](https://velog.velcdn.com/images/sirius2_1/post/6525a060-0003-4e21-861d-7dc9d0865f5c/image.png)


--------

## subplot

&gt; subplot함수를 통해 여러개의 그래프를 그려줄 수 있다.

&gt; 3개의 인자를 기본으로 받는데 처음 두 인자는 행,열의 정보 즉, subplot의 사이즈에 관련된 인자를 받고, 마지막 인자는 current plot 즉 현재 그리고자하는 plot의 index를 인자로 받는다. index는 1부터 시작한다.
&gt;&gt; 각 plot별로 title을 그려줄 수 있고, suptitle함수를 통해 전체 제목을 명시할 수 있다.
</code></pre><p>x1 = np.array([1,2,3,7])
y1 = np.arange(10,50,10)
fonts = {&#39;family&#39;:&#39;serif&#39;,&#39;color&#39;:&#39;b&#39;,&#39;size&#39;:10}</p>
<p>plt.subplot(2,2,1)
plt.plot(x1,y1)
plt.title(&quot;plot 1&quot;,loc = &#39;center&#39;,fontdict=fonts)</p>
<p>x2 = np.array([6,7,8,9])
y2 = np.array([1,2,3,4])</p>
<p>plt.subplot(2,2,2)
plt.plot(x2,y2)
plt.title(&quot;plot 2&quot;,loc= &#39;center&#39;,fontdict=fonts)</p>
<p>x3 = np.array([12,4,24,1])
y3 = np.array([10,39,29,19])</p>
<p>plt.subplot(2,2,3)
plt.plot(x3,y3)
plt.title(&quot;plot 3&quot;,loc= &#39;center&#39;,fontdict=fonts)</p>
<p>x4 = np.array([10,20,30,40])
y4 = np.array([1,2,7,9])</p>
<p>plt.subplot(2,2,4)
plt.plot(x4,y4)
plt.title(&quot;plot 4&quot;,loc= &#39;center&#39;,fontdict=fonts)</p>
<p>plt.suptitle(&quot;subplots&quot;)
plt.show()</p>
<pre><code>
![](https://velog.velcdn.com/images/sirius2_1/post/145104e8-f64a-4b04-9778-d8e1653e309b/image.png)


--------
## scatter plot &amp; bar plot

&gt; 선과 marker표현 이외에도 다양한 그래프 표현이 가능하다.

&gt; scatter plot과 bar plot또한 기본적으로 x scale과 y scale관련 인자를 전달 받는데 , bar plot의 경우 주로 x-scale의 경우 categorized 변수를 전달받는다.

&gt; 먼저 scatter plot의 경우 여러 개의 scatter 실행 시 default로 각기 다른 색이 주어지나 color인자에 색상값을 전달 할 수 있다. 점 별로 다른 색을 원할 경우, c 인자에 점 개수와 맞춘 색상 array를 전달하여 할 수 있다. 또한 s 인자에 sizes 배열을 전달하여 점 별 크기를 달리 할 수 있다. 추가적으로 alpha인자에 0~1사이의 값을 전달하여 투명도를 조절할 수 있다.
&gt;&gt; c 값에 전달할 array로 다양한 값을 전달할 수 있지만 color에 숫자를 부여한 colormap을 사용하여 숫자값을 전달 할 수 있는데 이 때, scatter의 인자로 cmap에 사용할 colormap(nipy_spectral,viridis 등)을 전달해 주어야 한다.
</code></pre><p>x1 = np.random.randint(100,size=(100))
y1 = np.random.randint(100,size=(100))</p>
<p>colors = np.random.randint(100,size=(100))
sizes = 10 * colors</p>
<p>plt.scatter(x1,y1,c= colors, s = sizes, alpha =0.5,cmap= &#39;nipy_spectral&#39;)
plt.colorbar()
plt.show()</p>
<pre><code>![](https://velog.velcdn.com/images/sirius2_1/post/6822c17a-7e8b-449f-a527-bda329ef410d/image.png)

&gt; bar plot의 경우에는 color, width등의 인자를 전달 받아 plot을 그리는데
barh 함수를 사용하면 vertical이 아닌 horizontal bar를 구성할 수 있다.
&gt;&gt; 이 때 barh함수는 width 대신 height인자를 사용한다.
</code></pre><p>x = [&#39;A&#39;, &#39;B&#39;, &#39;C&#39;]
y =np.array([1,2,3])</p>
<p>plt.bar(x,y,color=&#39;Blue&#39;,width = 0.5)
plt.show()  </p>
<pre><code>
![](https://velog.velcdn.com/images/sirius2_1/post/bfd75312-ca6d-4a4d-a642-8a53c437aa65/image.png)


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

## histogram &amp; pie chart

&gt; 기존의 plot들과 다르게 hist함수와 pie함수는 인자로 하나의 scale array만 전달 받는다. 

&gt; hist함수의 경우 전달받은 array의 분포에 따른 histogram을 그려준다.
</code></pre><p>x = np.random.normal(174,5,1000)</p>
<p>plt.hist(x)
plt.show()</p>
<pre><code>
![](https://velog.velcdn.com/images/sirius2_1/post/addfc944-ff04-434a-af10-4cfa14d39d4f/image.png)

&gt; pie 함수의 경우 전달받은 인자 배열에서 각 성분이 차지 하는 비율을 pie chart로 그려준다.
&gt;&gt; labels array와 colors array를 전달하여 각 pie별 속성을 정할 수 있다. 이외에도 pie 별 중심으로부터 멀어진 정도를 나타내는 배열인 explode 인자, pie의 그림자 여부를 나타내는 shadow인자, 반시계 방향으로 향하는 pie startangle을 의미하는 startangle인자를 통해 다양한 표현을 할 수 있다.

&gt; legend함수를 통해 범례(label)정보를 요약할 수 있고, title인자를 주어 legend의 제목을 설정할 수 있다.
</code></pre><p>p = np.array([3,12,19,7])
colors = [&#39;y&#39;,&#39;b&#39;,&#39;k&#39;,&#39;r&#39;]
explode = np.array([0.2,0,0,0])
labels = [&#39;att A&#39;,&#39;att B&#39;,&#39;att C&#39;,&#39;att D&#39;]</p>
<p>plt.pie(p,colors=colors,labels = labels, explode= explode,shadow=True,startangle=90)
plt.legend(title = &quot;Atts&quot;)
plt.show()  </p>
<p>```</p>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/70d74b94-b101-48f7-8cec-f08912aef7ee/image.png" alt=""></p>
<blockquote>
<p><strong>References</strong></p>
<blockquote>
<p><a href="https://www.w3schools.com/python/matplotlib_pyplot.asp">https://www.w3schools.com/python/matplotlib_pyplot.asp</a></p>
</blockquote>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[Numpy (2)]]></title>
            <link>https://velog.io/@sirius2_1/Numpy-2</link>
            <guid>https://velog.io/@sirius2_1/Numpy-2</guid>
            <pubDate>Sat, 27 Jan 2024 13:06:57 GMT</pubDate>
            <description><![CDATA[<h2 id="numpy-2">Numpy (2)</h2>
<blockquote>
<p>전편에 이어서 이번 편에는 다양한 numpy 함수들에 대해 알아보자.</p>
</blockquote>
<blockquote>
<p>기본적인 함수와 동작 원리에 대해 알고 싶다면 전편을 보고오는 것을 추천한다.
링크 -&gt; <a href="https://velog.io/@sirius2_1/Numpy">Numpy(1)</a></p>
</blockquote>
<hr>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/040801b2-5f5d-4601-bd66-c5ba0474c6f6/image.png" alt=""></p>
<hr>
<h2 id="범용함수">범용함수</h2>
<blockquote>
<p>numpy는 다양한 범용함수들이 있고 다음 함수들은 성분별 연산을 한 ndarray를 return한다.</p>
</blockquote>
<hr>
<pre><code>print(np.sqrt(a)) #-&gt; square root (제곱근)
print(np.exp(a)) # -&gt; 성분별 지수표현
print(np.maximum(a,b)) # 두 배열의 성분별 가장 큰 성분 ndarray return
# 범용함수는 out 이라는 인자에 원본이 수정되길 원하는 ndarray를 주어 원본을 수정할 수 있다.
# 이 외에 sign, mod등의 함수등이 있다.</code></pre><hr>
<p><strong>출력</strong></p>
<pre><code>[[1.         1.41421356 1.73205081]
 [2.         2.23606798 2.44948974]]
[[  2.71828183   7.3890561   20.08553692]
 [ 54.59815003 148.4131591  403.42879349]]
[[2 5 4]
 [4 5 6]]</code></pre><hr>
<h2 id="meshgrid-함수">meshgrid 함수</h2>
<blockquote>
<p>meshgrid 함수는 2차원 격자점을 생성하는 함수로 x축 좌표범위를 포함하는 1차원 배열과 y축 좌표범위를 나타내는 1차원 배열을 입력하면 격자점을 의미하는 2차원 배열을 2개 return한다. </p>
</blockquote>
<hr>
<pre><code># meshgrid
# x_scale (x좌표 범위) 1차원배열, y_scale (y좌표 범위) 1차원 배열을 전달받아
# 2차원 격자점을 구성하는 x범위 * y범위의 2차원 배열(x범위의 원소 하나당 y범위 원소 개수 만큼의 원소가 필요) 과, y범위 * x범위의 2차원 배열을 튜플로 return한다.
arr1 = np.linspace(1,10,10)
arr2 = np.linspace(-10,-1,10)
x,y = np.meshgrid(arr1,arr2)
print(x,y,sep =&#39;\n&#39;)</code></pre><hr>
<p>**출력</p>
<pre><code>[[ 1.  2.  3.  4.  5.  6.  7.  8.  9. 10.]
 [ 1.  2.  3.  4.  5.  6.  7.  8.  9. 10.]
 [ 1.  2.  3.  4.  5.  6.  7.  8.  9. 10.]
 [ 1.  2.  3.  4.  5.  6.  7.  8.  9. 10.]
 [ 1.  2.  3.  4.  5.  6.  7.  8.  9. 10.]
 [ 1.  2.  3.  4.  5.  6.  7.  8.  9. 10.]
 [ 1.  2.  3.  4.  5.  6.  7.  8.  9. 10.]
 [ 1.  2.  3.  4.  5.  6.  7.  8.  9. 10.]
 [ 1.  2.  3.  4.  5.  6.  7.  8.  9. 10.]
 [ 1.  2.  3.  4.  5.  6.  7.  8.  9. 10.]]
[[-10. -10. -10. -10. -10. -10. -10. -10. -10. -10.]
 [ -9.  -9.  -9.  -9.  -9.  -9.  -9.  -9.  -9.  -9.]
 [ -8.  -8.  -8.  -8.  -8.  -8.  -8.  -8.  -8.  -8.]
 [ -7.  -7.  -7.  -7.  -7.  -7.  -7.  -7.  -7.  -7.]
 [ -6.  -6.  -6.  -6.  -6.  -6.  -6.  -6.  -6.  -6.]
 [ -5.  -5.  -5.  -5.  -5.  -5.  -5.  -5.  -5.  -5.]
 [ -4.  -4.  -4.  -4.  -4.  -4.  -4.  -4.  -4.  -4.]
 [ -3.  -3.  -3.  -3.  -3.  -3.  -3.  -3.  -3.  -3.]
 [ -2.  -2.  -2.  -2.  -2.  -2.  -2.  -2.  -2.  -2.]
 [ -1.  -1.  -1.  -1.  -1.  -1.  -1.  -1.  -1.  -1.]]</code></pre><hr>
<h2 id="3항-함수-where">3항 함수 where</h2>
<blockquote>
<p>3항 연산을 해주는 함수로 예시를 통해 알아보자.</p>
</blockquote>
<hr>
<pre><code>arr = np.random.randn(10)
np.where(arr&gt;0,1,0) # 인자별로 condition, true expression, false expression이다</code></pre><hr>
<p><strong>출력</strong></p>
<pre><code>array([1, 1, 1, 1, 0, 0, 0, 1, 1, 1])</code></pre><hr>
<h2 id="수학통계논리정렬-methods">수학,통계,논리,정렬 methods</h2>
<hr>
<blockquote>
<p>고속 연산 및 행렬 연산에 특화된 numpy의 수학 함수들이다.</p>
</blockquote>
<hr>
<pre><code>#수학 통계 논리 정렬 method
arr = np.random.normal(10,1,(5,4))
print(arr,end=&#39;\n\n&#39;)

print(f&quot;평균:{arr.mean()},표준편차:{arr.std()},분산:{arr.var()},합:{arr.sum()},최댓값:{arr.max()},최솟값:{arr.min()}&quot;,end=&#39;\n\n&#39;)

print(arr.cumsum(),arr.cumprod(),sep=&#39;\n&#39;,end=&#39;\n\n&#39;) #각각 누적합이 표현된 배열과 누적곱이 표현된 배열 return
# 이외에도 argmax,argmin함수 -&gt; index별 최대,최소 return

#논리 연산 활용
arr = np.array([ True,  True,  True,  True,  True, False, False,  True, False,
        True])

print((arr&gt;0).sum(),any(arr&gt;0),all(arr&gt;0),end=&#39;\n\n&#39;)

#정렬 method
arr = np.random.randn(2,3)
print(arr,end=&#39;\n\n&#39;)

arr.sort()
print(arr) #axis = default(0)이어서 행별로 정렬된 모습</code></pre><hr>
<p><strong>출력</strong></p>
<pre><code>[[10.03343893 10.68056724  8.43650331  9.43330238]
 [ 9.75785049 11.51439128  9.6669426  10.04736482]
 [11.46274045 11.53502913 10.56644004 10.14926509]
 [ 8.921722   11.39547227 11.78748405  9.43048274]
 [10.17538653  9.53749446  8.9141994  10.63973599]]

평균:10.204290659802984,표준편차:0.9529397491647639,분산:0.9080941655382031,합:204.0858131960597,최댓값:11.787484045563003,최솟값:8.436503309900058

[ 10.03343893  20.71400617  29.15050948  38.58381186  48.34166235
  59.85605363  69.52299623  79.57036105  91.0331015  102.56813062
 113.13457066 123.28383575 132.20555775 143.60103002 155.38851407
 164.8189968  174.99438334 184.5318778  193.4460772  204.0858132 ]
[1.00334389e+01 1.07162819e+02 9.04079479e+02 8.52845510e+03
 8.32193897e+04 9.58220616e+05 9.26306369e+06 9.30693802e+07
 1.06683015e+09 1.23059168e+10 1.30029732e+11 1.31970622e+12
 1.17740520e+13 1.34170884e+14 1.58153715e+15 1.49146588e+16
 1.51762418e+17 1.44743322e+18 1.29027084e+19 1.37281411e+20]

7 True False

[[-0.38586334 -0.77576235  0.99571135]
 [-1.93320478  0.24853063 -0.03124534]]

[[-0.77576235 -0.38586334  0.99571135]
 [-1.93320478 -0.03124534  0.24853063]]</code></pre><hr>
<h2 id="선형대수-함수">선형대수 함수</h2>
<blockquote>
<p>선형대수의 행렬식, 행렬곱, 역행렬구하기, 행렬분해등의 복잡한 수식을 numpy.linalg 라이브러리를 import하여 사용할 수 있다.</p>
</blockquote>
<hr>
<pre><code># 선형대수 함수
# 행렬곱 연산 dot 함수 (python 3.5 이상 부터는 @라는 연산자로 dot 대체가능 ex)a @ b)
a = np.random.randn(3,4)
b= np.random.randn(4,3)
print(a.dot(b),np.dot(a,b),sep=&#39;\n&#39;,end=&#39;\n\n&#39;)

# numpy.linalg -&gt; 역행렬, 행렬식, 분해 함수 등 포함

from numpy.linalg import inv, det

X = np.random.randn(3, 3)
print(det(X),end=&#39;\n\n&#39;) # 행렬식 return
print(inv(X),end=&#39;\n\n&#39;) # 역행렬 return</code></pre><hr>
<p><strong>출력</strong></p>
<pre><code>[[ 1.71361706 -1.39846694  1.44384403]
 [-0.2764774  -0.23821622 -1.096304  ]
 [-3.18230161  2.8214342   1.39753731]]
[[ 1.71361706 -1.39846694  1.44384403]
 [-0.2764774  -0.23821622 -1.096304  ]
 [-3.18230161  2.8214342   1.39753731]]

-0.5407583180361959

[[ 3.56730319 -0.38978817 -0.17305708]
 [-0.18910906  0.3522893  -0.50529179]
 [-0.77080427 -0.77348985 -0.19517602]]</code></pre><hr>
<h2 id="numpyrandom">numpy.random</h2>
<blockquote>
<p>numpy의 random 모듈은 특히나 자주 쓰이는 모듈로서, 관련함수들을 잘 알아두는 것이 좋다. 1편에서 다뤘던, normal함수, randn함수도 numpy.random 모듈 안의 함수이다.</p>
</blockquote>
<hr>
<pre><code>#numpy.random
np.random.seed(0)
# 난수 생성 -&gt; 이후 항상 같은 난수 사용
#np.random.RandomState(123) 국소적 난수 생성

# shuffle과 permutation
# shuffle은 원본 배열의 순서를 변경, permutation은 수정된 객체 반환
arr = np.linspace(1,10,10)
print(np.random.permutation(arr))
np.random.shuffle(arr)
print(arr)

# rand와 randint
print(np.random.rand(3,2),np.random.randint(5),sep=&#39;\n&#39;) # rand는 0~1의 uniform dist에서 인자 사이즈의 배열 return, randint는 0~4의 uniform 정수 dist에서 정수 한개 return
# binomial, gamma,uniform
print(np.random.binomial(n=1,p=0.5,size=10)) #n-&gt;trial, p-&gt;probability</code></pre><hr>
<p><strong>출력</strong></p>
<pre><code>[ 3.  9.  5. 10.  2.  7.  8.  4.  1.  6.]
[ 4.  6.  2.  3. 10.  9.  1.  7.  8.  5.]
[[0.81216873 0.47997717]
 [0.3927848  0.83607876]
 [0.33739616 0.64817187]]
0
[1 1 1 1 1 0 1 0 1 0]</code></pre><hr>
<h2 id="배열-파일-저장">배열 파일 저장</h2>
<blockquote>
<p>numpy의 배열은 바이너리 파일로 원하는 경로에 저장할 수 있고, 단일 배열의 경우 .npy라는 확장자, 복수 배열 저장의 경우 .npz라는 확장자를 가진다.
save,savez 함수를 통해 저장하고, load함수를 통해 불러온다.
예시를 통해 자세히 알아보자.</p>
</blockquote>
<hr>
<pre><code># numpy array file
 arr = np.arange(10)
 np.save(&#39;./f1&#39;,arr) #경로에 배열을 바이너리 파일로 저장 .npy확장자
 arr1 = np.load(&#39;./f1.npy&#39;) #load
# 여러 배열 저장
 np.savez(&#39;./f2&#39;,a =arr, b = arr1) 
 #a와 b라는 key지정 가능, npz라는 확장자로 저장

 arr2 = np.load(&#39;./f2.npz&#39;)
 arr[&#39;a&#39;] # key로 호출</code></pre><hr>
<h3 id="지금까지-12편에-걸쳐서-numpy라는-행렬연산-모듈에-대해-알아보았다-numpy의-고속연산이라는-장점은-데이터-분석-머신러닝-등-다양한-분야에서-사용되고있다-numpy모듈을-공부하여-효율적인-코딩을-기획해보자">지금까지 1,2편에 걸쳐서 Numpy라는 행렬연산 모듈에 대해 알아보았다. numpy의 고속연산이라는 장점은 데이터 분석, 머신러닝 등 다양한 분야에서 사용되고있다. numpy모듈을 공부하여 효율적인 코딩을 기획해보자.</h3>
<hr>
<blockquote>
<p><strong>References</strong></p>
<blockquote>
<p><a href="https://compmath.korea.ac.kr/appmath/NumpyBasics.html">https://compmath.korea.ac.kr/appmath/NumpyBasics.html</a>
<a href="https://velog.io/@euisuk-chung/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EC%8B%9C%EA%B0%81%ED%99%94-%EB%A7%88%EC%8A%A4%ED%84%B0%ED%95%98%EA%B8%B0-Numpy">https://velog.io/@euisuk-chung/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EC%8B%9C%EA%B0%81%ED%99%94-%EB%A7%88%EC%8A%A4%ED%84%B0%ED%95%98%EA%B8%B0-Numpy</a></p>
</blockquote>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[Numpy (1)]]></title>
            <link>https://velog.io/@sirius2_1/Numpy</link>
            <guid>https://velog.io/@sirius2_1/Numpy</guid>
            <pubDate>Sat, 27 Jan 2024 12:43:59 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/sirius2_1/post/e2032a17-6363-4c31-869a-153d026cb145/image.png" alt=""></p>
<hr>
<h2 id="numpy란">numpy란</h2>
<pre><code># pip install numpy
import numpy as np
</code></pre><blockquote>
<p>numpy는 numeric python의 약자로,
    n차원 배열 (ndarray)을 이용한 행렬 연산(성분별 연산)을 통해 고속 연산을 제공하는 라이브러리이다.
    ndarray 배열은 ndim, shape, dtype이라는 속성을 가진다.
 다음은 ndarray를 생성하고, 속성을 확인하는 코드이다.</p>
</blockquote>
<pre><code>  # array함수를 통해 ndarray 생성 (인자로 sequence 전달)
arr = np.array([1,2,3])

# ndarray의 속성값
print(arr.ndim,arr.dtype,arr.shape)

# astype함수를 통해 type을 변경한 ndarray를 생성할 수 있다. =&gt; 이를 통해 정수로 이루어진 문자열 ndarray또한 type을 바꿀 수 있다.

arr1 = arr.astype(np.float64)
</code></pre><p><strong>출력</strong></p>
<pre><code>1 int32 (3,)</code></pre><blockquote>
<p>다음은 다차원 배열 출력 예시이다.</p>
</blockquote>
<pre><code>#2차원 ndarray 생성
arr= np.array([[1,2,3],[4,5,6]])
arr.shape
</code></pre><p><strong>출력</strong></p>
<pre><code>(2, 3)</code></pre><hr>
<h2 id="배열-생성-기본-methods">배열 생성 기본 methods</h2>
<blockquote>
<p>numpy는 다양한 형태의 배열을 생성할 수 있다. zeros, ones 같은 함수는 각각 0,1로 구성된 배열을 return하고 linspace, randn, normal함수는 각각 균등분포, 정규분포에서 원소를 추출하여 배열을 생성한다.</p>
<blockquote>
<p>다음 예시코드에서 부터 함수 사용법과 인자 구분등을 주석으로 확인할 수 있다.</p>
</blockquote>
</blockquote>
<pre><code># zeros, ones, arange ( arange는 python의 range객체와 같이 사용)
a = np.zeros((2,3))
b = np.ones((1,5))
c = np.arange(1,6,2)
d = np.zeros_like(c) # 인자로 받은 array와 동일한 shape과 dtype의 zeros 배열 생성

# np.linspace(a,b,num) a&lt;= 원소 &lt;=b 인 원소 num개를 균등한 간격으로 가진 배열 생성
a = np.linspace(0,1,10)

# np.random.random((shape)) -&gt; 0~1사이의 균등분포에서 원소를 추출하여 shape를 가진 배열 생성, 인자 shape은 tuple형태로 전달
a = np.random.random((2,4))

#np.random.randn(shape) mean = 0, std = 1인 정규분포에서 shape size의 난수를 원소로하는 배열을 생성, shape는 &#39;()&#39;없이 전달 --&gt; (randn, reshape, transpose는 shape을 &#39;()&#39;기호 없이 인자로 전달한다.
a = np.random.randn(2,4)

# np.random.normal(loc,scale,(shape))의 경우 평균과 표준편차를 지정할 수 있음</code></pre><hr>
<h2 id="numpy-ndarray의-특징">numpy ndarray의 특징</h2>
<blockquote>
<ul>
<li>배열과 배열 사이 또는 배열과 scalar 사이에 element wise한 연산이 가능하다.</li>
</ul>
</blockquote>
<hr>
<pre><code>na = np.array([1,2,3])
nb = np.array([4,5,6])
print(na + nb, na * nb, na *2, sep = &#39; &#39;)</code></pre><hr>
<p>**
출력**</p>
<pre><code>[5 7 9] [ 4 10 18] [2 4 6]
6 2.0 3 1</code></pre><hr>
<blockquote>
<ul>
<li>numpy indexing &amp; slicing</li>
</ul>
</blockquote>
<blockquote>
<blockquote>
<p>numpy의 1차원배열의 경우 파이썬 내장 리스트의 indexing과 slicing 기법을 동일하게 적용할 수 있다. 
다만 slicing을 할 때, shallow copy이므로 deep copy 객체를 생성하려면.copy()함수를 사용한다.</p>
</blockquote>
</blockquote>
<blockquote>
<blockquote>
<p>다차원 배열의 경우에는 python 내장 리스트와 같이 indexing과 slicing을 할 수 있으나 comma를 통해서도 indexing과 slicing을 할 수 있다.</p>
</blockquote>
</blockquote>
<blockquote>
<p>예시를 통해 확인해 보자.</p>
</blockquote>
<hr>
<pre><code>aa = np.array([1,2,3,4,5])
print(aa[0],aa[:3],end=&#39;\n\n&#39;)

bb = np.array([[1,2,3,4,5], [6,7,8,9,10]])
print(bb[1,0],bb[:2,:2],bb[1,:],bb[:,0],bb[:,:2],sep =&#39;\n&#39;)</code></pre><hr>
<p><strong>출력</strong></p>
<pre><code>1 [1 2 3]

6
[[1 2]
 [6 7]]
[ 6  7  8  9 10]
[1 6]
[[1 2]
 [6 7]] </code></pre><hr>
<h2 id="논리-인덱싱과-추가적인-정수-인덱싱">논리 인덱싱과 추가적인 정수 인덱싱</h2>
<blockquote>
<p>앞서 알아본 방식으로도 배열을 인덱싱할 수 있지만, numpy ndarray는 논리 인덱싱도 가능하다. 예시를 통해 자세히 알아보자.</p>
</blockquote>
<hr>
<pre><code># 논리 인덱싱
names = np.array([&#39;Bob&#39;, &#39;Joe&#39;, &#39;Will&#39;, &#39;Bob&#39;, &#39;Will&#39;, &#39;Joe&#39;, &#39;Joe&#39;])

np.random.seed(0)

data = np.random.randn(7, 4)
data</code></pre><p><strong>출력</strong></p>
<pre><code>array([[ 1.76405235,  0.40015721,  0.97873798,  2.2408932 ],
       [ 1.86755799, -0.97727788,  0.95008842, -0.15135721],
       [-0.10321885,  0.4105985 ,  0.14404357,  1.45427351],
       [ 0.76103773,  0.12167502,  0.44386323,  0.33367433],
       [ 1.49407907, -0.20515826,  0.3130677 , -0.85409574],
       [-2.55298982,  0.6536186 ,  0.8644362 , -0.74216502],
       [ 2.26975462, -1.45436567,  0.04575852, -0.18718385]])</code></pre><hr>
<pre><code>arr = data[names == &quot;Bob&quot;,:2] 
# names에서 0, 3을 논리 연산자로 가져와 data에서 indexing한다.
print(arr) #이 때 arr는 deep copy 객체

mask = (names == &#39;Bob&#39;) | (names == &#39;Will&#39;) 
# 여러 행 정보를 masking하여 indexing에 활용한다.
# numpy 논리 연산자로 and or등을 사용할 수 없고 반드시 &amp;,|를 사용해야된다.

arr_m = data[mask]
# 논리 인덱싱으로 원본 데이터 수정

# 다른 방식의 논리 인덱싱
data[data &lt; 0] = 0
print(data)</code></pre><hr>
<p><strong>출력</strong></p>
<pre><code>[[1.76405235 0.40015721]
 [0.76103773 0.12167502]]

[[1.76405235 0.40015721 0.97873798 2.2408932 ]
 [1.86755799 0.         0.95008842 0.        ]
 [0.         0.4105985  0.14404357 1.45427351]
 [0.76103773 0.12167502 0.44386323 0.33367433]
 [1.49407907 0.         0.3130677  0.        ]
 [0.         0.6536186  0.8644362  0.        ]
 [2.26975462 0.         0.04575852 0.        ]]</code></pre><hr>
<blockquote>
<p>다음은 추가적인 정수 예시이다. 정수 인덱싱을 통해 다양한 방식으로 array를 indexing할 수 있다.</p>
</blockquote>
<hr>
<pre><code># 정수 인덱싱
arr = np.empty((8, 4))

for i in range(8):
    arr[i] = i
print(arr, end =&#39;\n\n&#39;)


# 음수를 포함한 행 인덱스 배열을 ndarray의 index로 주어 특정 행만 뽑을 수 있다.
print(arr[[-4, -5, 0, 6]], &#39;\n\n&#39;)
# 음수 인덱스 -1은 마지막행인 7행을 의미하고  -2행은 그 전 행인 6행을 의미한다.


#  2개의 인덱스 배열을 인자로 주면 인덱스 배열들의 대응하는 원소별 튜플에 해당하는 원소들로 구성된 1차원 ndarray가 반환된다.  
print(arr[[-4, -5, 0, 6],[0,2,3,1]])
# 예를들어 (-4,0), (-5,2), ...의 원소들로 구성된 ndarray가 반환된다.</code></pre><hr>
<p><strong>출력</strong></p>
<pre><code>[[0. 0. 0. 0.]
 [1. 1. 1. 1.]
 [2. 2. 2. 2.]
 [3. 3. 3. 3.]
 [4. 4. 4. 4.]
 [5. 5. 5. 5.]
 [6. 6. 6. 6.]
 [7. 7. 7. 7.]]

[[4. 4. 4. 4.]
 [3. 3. 3. 3.]
 [0. 0. 0. 0.]
 [6. 6. 6. 6.]] 


[4. 3. 0. 6.]</code></pre><hr>
<h2 id="행렬의-변환-전치">행렬의 변환 (전치)</h2>
<blockquote>
<p>행렬의 전치 연산을 할 수 있다.
역시 예시를 통해 알아보자.</p>
</blockquote>
<hr>
<pre><code># 행렬의 전치
arr = np.arange(0,20).reshape(4,5)
# reshape함수는 함수의 shape을 인자와 같이 바꿔준다. ex) 4*5 size행렬

arr = arr.dot(arr.T) # arr.T -&gt; 전치 행렬
print(arr)


arr_3 = np.arange(2*3*4).reshape(2,3,4) # reshape에 인자로 -1을 넣으면 예시의 2*3*4의 값을 맞추는 인자가 -1대신 채워진다. ex) 2,3,-1 -&gt; -1대신 4가 채워짐
print(arr_3)

arr_3 = arr_3.transpose(2,0,1) # axis 0 -&gt; 면, 1 -&gt; 행, 2-&gt; 열을 의미하는데, transpose함수를 통해 기존의 2 * 3 * 4 의 고차원 행렬도 4*2*3 행렬로 전치할 수 있다. 
arr3
# 같은 열 기준으로 새로운 4개의 면이 구성, 각 면별로 새로운 2행(기존에 면으로 구분되던 원소들이 행으로 구분), 3열 (기존에 행으로 구분되던 원소들이 열로 구분) 로 전환된다.
# 비슷한 함수 arr.swapaxes(0,2) -&gt; 면과 열의 축 전치==&gt;arr.transpose(2,1,0)와 같은 효과</code></pre><hr>
<p><strong>출력</strong></p>
<pre><code>[[  30   80  130  180]
 [  80  255  430  605]
 [ 130  430  730 1030]
 [ 180  605 1030 1455]]

[[[ 0  1  2  3]
  [ 4  5  6  7]
  [ 8  9 10 11]]

 [[12 13 14 15]
  [16 17 18 19]
  [20 21 22 23]]]

  array([[[ 0,  4,  8],
        [12, 16, 20]],

       [[ 1,  5,  9],
        [13, 17, 21]],

       [[ 2,  6, 10],
        [14, 18, 22]],

       [[ 3,  7, 11],
        [15, 19, 23]]])</code></pre><hr>
<p><strong>여기까지 numpy library의 기본적인 성질과 함수들을 알아보았다.
다음 포스트에서 수학함수, 선형대수함수, random module 등 다양한 활용법에대해 알아보자.</strong></p>
<p>numpy(2) 링크-&gt; <a href="https://velog.io/@sirius2_1/Numpy-2">Numpy(2)</a></p>
<hr>
<blockquote>
<p><strong>References</strong></p>
<blockquote>
<p><a href="https://compmath.korea.ac.kr/appmath/NumpyBasics.html">https://compmath.korea.ac.kr/appmath/NumpyBasics.html</a>
<a href="https://velog.io/@euisuk-chung/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EC%8B%9C%EA%B0%81%ED%99%94-%EB%A7%88%EC%8A%A4%ED%84%B0%ED%95%98%EA%B8%B0-Numpy">https://velog.io/@euisuk-chung/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EC%8B%9C%EA%B0%81%ED%99%94-%EB%A7%88%EC%8A%A4%ED%84%B0%ED%95%98%EA%B8%B0-Numpy</a></p>
</blockquote>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[Ubuntu Linux Command]]></title>
            <link>https://velog.io/@sirius2_1/Ubuntu-Linux-Command</link>
            <guid>https://velog.io/@sirius2_1/Ubuntu-Linux-Command</guid>
            <pubDate>Thu, 25 Jan 2024 11:40:56 GMT</pubDate>
            <description><![CDATA[<hr>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/0ae1bca1-cc8f-4087-8a59-891c2ea25329/image.png" alt=""></p>
<hr>
<h2 id="기타-명령어">기타 명령어</h2>
<pre><code># web browser
~$ firefox
# 윈도우의 msoffice
~$ libreoffice
# 윈도우의 메모장
~$ gedit </code></pre><hr>
<h2 id="도움되는-단축키">도움되는 단축키</h2>
<ul>
<li><p>화면 캡처</p>
<blockquote>
<p>PrtScreen(전체창), Alt+PrtScreen (현재창), shift+PrtScreen (원하는 장면 캡처)</p>
</blockquote>
</li>
<li><p>녹화</p>
<blockquote>
<p>cntl+shift+alt+R (한번 더 누르면 녹화종료)</p>
</blockquote>
</li>
</ul>
<hr>
<h2 id="시작과-종료">시작과 종료</h2>
<ul>
<li>종료</li>
</ul>
<pre><code>    ~$ poweroff
    ~$ halt -p
    ~$ shutdown -p now</code></pre><ul>
<li><p>재시작</p>
<pre><code>  ~$ reboot
  ~$ shutdown -r now</code></pre></li>
</ul>
<ul>
<li>로그아웃(터미널 또는 콘솔에서 로그아웃 명령)</li>
</ul>
<pre><code>    $ logout
    $ exit</code></pre><hr>
<h2 id="기본-명령어-1">기본 명령어 (1)</h2>
<ul>
<li>ls <blockquote>
<p>list의 약자, window의 dir 역할, 디렉터리 파일 목록 나열</p>
<blockquote>
<pre><code>    ex) ls /etc/system</code></pre><p>경로 제일 앞 &#39;/&#39;는 root를 나타냄 (절대경로) &lt;-&gt; 상대경로는 &#39;.&#39;를 통해 나타냄, &#39;.&#39; -&gt; (현재 dir),   &#39;..&#39; -&gt; (부모dir)</p>
</blockquote>
</blockquote>
</li>
</ul>
<blockquote>
<blockquote>
<p>option으로 -a(숨김파일까지 포함하여), -l(목록을 자세히 보여줌), ls *.txt(확장자가 txt인 파일을 보여줌), ls -l /etc/b* (b로 시작하는 파일을 모두 보여줌)등이 있다.</p>
</blockquote>
</blockquote>
<ul>
<li>pwd</li>
</ul>
<blockquote>
<p>print working directory의 약자로 현재 dir의 절대경로를 나타냄</p>
</blockquote>
<ul>
<li><p>cd</p>
<blockquote>
<p>change directory의 약자로, 뒤 인자에 오는 경로로 이동</p>
<blockquote>
<pre><code>ex) cd /etc/system</code></pre></blockquote>
</blockquote>
</li>
<li><p>rm </p>
<blockquote>
<p>remove의 약자, <strong>파일</strong>또는 <strong>디렉터리</strong>를 삭제</p>
<blockquote>
<pre><code>    ex) rm -rf abc</code></pre><p>리눅스는 별도의 hidden file이라는 속성이 존재 x, 파일명이나 디렉터리 제일 앞 글자를 &#39;.&#39;으로 하면 자동으로 숨김파일이 된다.</p>
</blockquote>
</blockquote>
</li>
<li><p>cp</p>
<blockquote>
<p>copy의 약자, <strong>파일 또는 디렉터리를</strong> 복사</p>
<blockquote>
<pre><code>    ex) cp abc.txt 123.txt</code></pre></blockquote>
</blockquote>
</li>
<li><p>touch</p>
<blockquote>
<p>크기가 0인 파일을 생성, 이미 존재한다면 해당 파일의 최종수정시간을 변경</p>
<blockquote>
<pre><code>    ex) touch abc.txt</code></pre></blockquote>
</blockquote>
</li>
<li><p>mv</p>
<blockquote>
<blockquote>
<p><strong>파일 또는 디렉터리의</strong> 이름을 변경하거나 위치를 변경</p>
<pre><code>    ex) mv abc.txt 123.txt
  ex) mv a b c d (/d로 파일 a,b,c를 이동)
  ex) mv abc.txt /etc/systemd/</code></pre></blockquote>
</blockquote>
</li>
<li><p>mkdir</p>
<blockquote>
<p>make directory의 약자로 새로운 디렉터리 생성, 해당 디렉터리는 명령을 실행한 사용자의 소유가 된다.</p>
<blockquote>
<pre><code>    ex) mkdir abc
  ex) mkdir -p /def/ghi (/def/ghi를 생성하는데 def(parent dir)가 없다면 생성한다.)</code></pre></blockquote>
</blockquote>
</li>
<li><p>rmdir  </p>
<blockquote>
<p>디렉터리를 삭제, <strong>삭제권한이 있어야하고</strong>, <strong>디렉터리가 비어있어야 한다.</strong> 파일이 들어있는 디렉터리를 제거하려면 -r 옵션을 넣어준다.</p>
<blockquote>
<pre><code>    ex) rmdir -r abc</code></pre></blockquote>
</blockquote>
</li>
<li><p>cat</p>
<blockquote>
<p>concatenate 의 약자로, 파일내용을 화면에 보여준다. 여러 인자를 사용하면 여러파일을 연결하여 보여준다.</p>
<blockquote>
<pre><code>    ex) cat abc.txt def.txt</code></pre></blockquote>
</blockquote>
</li>
<li><p>head, tail</p>
<blockquote>
<p>텍스트형식의 파일의 앞 10행 또는 뒤 10행을 출력한다.</p>
<blockquote>
<pre><code>    ex) head /etc/sytemd/user.conf
    ex) tail -3 /etc ... (뒤에서 3행만 출력)</code></pre></blockquote>
</blockquote>
</li>
<li><p>more , less</p>
<blockquote>
<p>텍스트 형식의 파일을 페이지 단위로 출력 space bar로 이동, b를 누르면 이전페이지, q를 누르면 종료, less는 기능이 더 확장되어 화살표 및 pageUp/Down 키도 사용가능</p>
</blockquote>
</li>
</ul>
<blockquote>
<pre><code>    ex) more /etc/...
    ex) less +10 /etc/... (10행부터 출력)</code></pre></blockquote>
<ul>
<li><p>file</p>
<blockquote>
<p>해당 파일의 타입을 출력</p>
<blockquote>
<pre><code>    ex) file abc.txt</code></pre></blockquote>
</blockquote>
</li>
<li><p>chmod</p>
<blockquote>
<p>change mode의 약자, 파일의 권한 변경 명령어 </p>
<blockquote>
<pre><code>    ex)chmod 777 sample.txt</code></pre></blockquote>
</blockquote>
</li>
</ul>
<blockquote>
<p>여기서 777은 Read|Write|eXecute 3bit로 구성된 0~7의 값을 갖는 숫자 3개로 높은 자리순으로 소유자, 그룹, 그외 사용자의 권한을 나타낸다.</p>
</blockquote>
<ul>
<li>clear<blockquote>
<p>현재 터미널을 깔끔하게 지워준다.</p>
<blockquote>
<pre><code>    ex) clear</code></pre></blockquote>
</blockquote>
</li>
</ul>
<hr>
<h2 id="기본-명령어-2">기본 명령어 (2)</h2>
<ul>
<li>grep<blockquote>
<p>파일에서 특정 문자열을 찾기 위한 명령어</p>
<blockquote>
<p>grep [option] [pattern] [file]</p>
</blockquote>
</blockquote>
</li>
</ul>
<blockquote>
<blockquote>
<pre><code>    ex) grep &quot;str&quot; *.txt</code></pre></blockquote>
</blockquote>
<ul>
<li><p>ifconfig</p>
<blockquote>
<p>장치 ip정보 출력</p>
<blockquote>
<pre><code>    ex) ifconfig [장치이름]</code></pre></blockquote>
</blockquote>
</li>
<li><p>tar, gzip, xz</p>
<blockquote>
<p>파일 압축명령어</p>
</blockquote>
</li>
</ul>
<blockquote>
<p>xz는 확장명 xz로 압축하거나 풀어준다</p>
<blockquote>
<pre><code>    ex) xz [filename] (xz파일 생성, 기존 파일 제거)
    xz -d [filename.xz] (decompress)</code></pre></blockquote>
</blockquote>
<blockquote>
<p>gz는 확장명 gz로 압축하거나 풀어준다.</p>
</blockquote>
<blockquote>
<pre><code>ex) gzip [filename] (file을 filename.gz로 만들어줌) 
ex) gzip -d filename.gz (gunzip filename.gz) (압축을 풀어 file을 만듦)</code></pre></blockquote>
<blockquote>
<p>tar는 파일압축과 파일 묶기를 동시에 제공할 수 있는 명령어</p>
<blockquote>
<p>Actions) c -&gt; 새로운 묶음 만듦, x -&gt; 묶인 파일을 풀어줌, t-&gt; 묶음을 풀기전에 묶인 경로를 보여줌, C -&gt; 묶음을 풀 때, 지정 디렉터리에 압출을 풀어줌
Options) f -&gt; 묶음 파일 이름 지정, v -&gt; 묶거나 푸는 과정을 보여줌, J -&gt; tar + xz, z -&gt; tar + gzip</p>
</blockquote>
</blockquote>
<blockquote>
<pre><code>ex)tar cvfJ my.tar.xz /etc/.. 
tar Cxvf mydir my.tar (mydir에 tar풀기)
tar xfJ my.tar.xz (xz 압축 해제, tar풀기)</code></pre></blockquote>
<hr>
<h2 id="vi-단축키">vi 단축키</h2>
<hr>
<ul>
<li>명령모드</li>
</ul>
<blockquote>
<p>h,l,j,k 순으로 좌,우,하,상 방향으로 커서 한칸 이동</p>
</blockquote>
<blockquote>
<ul>
<li>dd : 현재 커서의 행 삭제 (앞에 숫자를 넣으면 현재커서 부터 숫자의 행만큼 삭제)</li>
</ul>
</blockquote>
<ul>
<li><p>yy :현재 커서가 있는 행 복사 (똑같이 앞에 숫자 옵션 가능)</p>
</li>
<li><p>x : 현재 커서가 위치한 글자 삭제</p>
</li>
<li><p>X : 현재 커서가 위치한 앞 글자 삭제 (backspace)</p>
</li>
<li><p>입력모드</p>
</li>
</ul>
<blockquote>
<ul>
<li>i: 현재 커서 위치부터 입력</li>
</ul>
</blockquote>
<ul>
<li>I: 현재 커서 줄의 맨 앞부터 입력</li>
<li>a: 현재 커서 다음 칸 부터 입력</li>
<li>A: 현재 커서 줄 맨 마지막 부터 입력</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Git]]></title>
            <link>https://velog.io/@sirius2_1/Git</link>
            <guid>https://velog.io/@sirius2_1/Git</guid>
            <pubDate>Wed, 24 Jan 2024 12:20:22 GMT</pubDate>
            <description><![CDATA[<h2 id="git">Git</h2>
<hr>
<blockquote>
<p>git은 분산형 버전 관리 소프트웨어로, 소스 버전 관리를 협업자들의 각기 다른 (분산된) local repositary에 업데이트 하고, github라는 remote repositary(Github)에서 공유하여 협업을 하게 업데이트 해주는 소프트웨어이다. </p>
</blockquote>
<hr>
<h2 id="git-command">git command</h2>
<hr>
<blockquote>
<p>기본적으로 명령 프롬프트 상에서 명령어 기반으로 원하는 작업을 진행할 수 있다.</p>
<blockquote>
<p><strong>workspace - stage - local repositary - remote repositary 사이에서의 동작을 진행</strong>
 <a href="https://git-scm.com/docs">명령어 관련 공식 reference</a></p>
</blockquote>
</blockquote>
<hr>
<h3 id="git-init---git-clone-url">git init &amp;  git clone &quot;url&quot;</h3>
<p>init -&gt; 해당 디렉터리 상에 git 저장소 생성, .git 폴더가 만들어짐</p>
<p>clone -&gt; workspace에 url(원격저장소, 로컬저장소)의 모든 내용을 복제, 디렉터리 상 기존 존재하던 파일은 제거</p>
<hr>
<h3 id="git-pull--fetch--remote--merge">git pull &amp; fetch &amp; remote &amp; merge</h3>
<ul>
<li><em><strong>git remote -v 명령어로 원격저장소 이름을 확인하고 git branch 명령어로 브랜치 이름을 확인한다.</strong></em></li>
</ul>
<p>pull -&gt; 원경저장소의 변경사항을 workspace에 불러오기 (pull없이는 push를 할 수 없음, workspace에서 작업하던 내용은 유지)</p>
<pre><code>git pull --all
git pull [원격저장소명] [브랜치]</code></pre><p>fetch -&gt; 원격저장소의 변경사항을 local repositary에 불러와 확인하기 (pull or merge 할 지 말지 정할 수 있음)</p>
<pre><code>git fetch -- all
git fetch origin</code></pre><p>remote -&gt; 원격저장소 관리<br>    # local 저장소에 연결된 원격저장소 확인
    git remote
    # 원격저장소를 local저장소에 추가
    git remote add [별칭] [원격저장소주소]
    # 원격저장소 삭제
    git remote rm [원격저장소 이름]
merge -&gt; 현재 브랜치를 특정브랜치와 병합</p>
<pre><code>#master branch를 현재브랜치로 merge
# &#39;master&#39;: 최초 repository 생성 후 commit하면 자동으로 생기는 branch
git merge master</code></pre><hr>
<h3 id="git-status">git status</h3>
<p>현재 local repositary의 상태</p>
<h3 id="git-add--rm">git add &amp; rm</h3>
<p>변경점 또는 변경사항을  workspace에서 stage에 추가 -&gt; add
파일을 삭제 또는 stage에서 제거 -&gt; rm</p>
<pre><code># 모든 변경점 추가
git add -A
# 현 디렉터리 상 모든 파일에 변경점 추가
git add .
# 특정 파일만 추가
git add sample.txt

# 파일을 제거
git rm sample.txt
# 파일을 stage에서 제거
git rm -cached sample.txt</code></pre><hr>
<h3 id="git-commit--log--reset--revert">git commit &amp; log &amp; reset &amp; revert</h3>
<p>commit -&gt; 변경점을 저장 (stage에서 local로)</p>
<pre><code># message와 함께 저장
git commit -m &quot;msg&quot;
# 모든 변경점 저장
git commit -a </code></pre><p>log -&gt; commit 내용 확인</p>
<pre><code>git log --all</code></pre><p> reset -&gt; commit 취소</p>
<pre><code># soft -&gt; stage로, HEAD^ -&gt; 최신 COMMIT
 git reset --soft HEAD^
 # mixed -&gt; unstaged로, local 변경사항은 유지
 git reset --mixed HEAD^
 # hard -&gt; unstaged, local 변경점도 제거
 git reset --hard HEAD^</code></pre><p> revert -&gt; 지정한 commit으로 되돌리고 commit</p>
<pre><code>git revert &quot;commit hash 또는 태그명&quot;</code></pre><h3 id="git-restore--clean">git restore &amp; clean</h3>
<p>restore -&gt; unstaged 된 또는 staged 된 변경점을 복구</p>
<pre><code>git restore &quot;filename&quot;
git restore staged &quot;filename&quot;</code></pre><p>clean -&gt; untracked된 파일을 제거
    # 파일만 제거
    git clean -f
    # 디렉터리도 제거
    git clean -f -d
    # gitignore 설정 파일도 제거
    git clean -f -d -x</p>
<hr>
<h3 id="git-push--branch">git push &amp; branch</h3>
<pre><code># 원격저장소에 특정브랜치 적용
git push [원격저장소명] [브랜치명]

# 전체 브랜치 확인
git branch
# 새로운 브랜치 생성
git branch &quot;name&quot;
# 해당 브랜치로 이동
git checkout [브랜치이름]
# 해당 브랜치 삭제
git branch -d [브랜치이름]</code></pre><hr>
<h2 id="references">References</h2>
<p><a href="https://urbanbase.github.io/dev/2021/01/15/GitCommand.html">https://urbanbase.github.io/dev/2021/01/15/GitCommand.html</a>
<a href="https://velog.io/@jameskoo0503/Github-basics">https://velog.io/@jameskoo0503/Github-basics</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[MarkDown 기본문법]]></title>
            <link>https://velog.io/@sirius2_1/MarkDown-%EA%B8%B0%EB%B3%B8%EB%AC%B8%EB%B2%95</link>
            <guid>https://velog.io/@sirius2_1/MarkDown-%EA%B8%B0%EB%B3%B8%EB%AC%B8%EB%B2%95</guid>
            <pubDate>Tue, 23 Jan 2024 09:21:10 GMT</pubDate>
            <description><![CDATA[<hr>
<h3 id="markdown언어란">MarkDown언어란?</h3>
<hr>
<p>mark 별로 다른 의미의 tag를 통해 구조화된 text 표현 language인 MarkUp에서 파생된 언어로 간결한 표현과 쉬운 tag등의 장점으로 쉽게 쓰기 읽히는 장점으로 github 등에서 프로젝트에 대한 간략한 설명 등을 위한 언어로 쓰임</p>
<hr>
<h3 id="기본-문법">기본 문법</h3>
<hr>
<ul>
<li><strong>제목과 구분선</strong></li>
</ul>
<blockquote>
<p>작성하려는 제목 문구 앞에 &#39;#&#39;을 붙여주어 제목 문구의 크기를 조절</p>
<blockquote>
<p>#의 개수를 6개까지 조절하며 크기를 조절할 수 있고, 개수가 작을수록 크기가 크다</p>
</blockquote>
</blockquote>
<blockquote>
<p>단락을 구분하기 위한 시각적 구분선을 만들기 위해선 &#39;-&#39; 또는 &#39;*&#39;을 3회 이상 입력해주면 된다. </p>
<blockquote>
<p>&#39;---&#39; 또는 &#39;***&#39; 와 같이</p>
</blockquote>
</blockquote>
<ul>
<li><strong>줄바꿈</strong></li>
</ul>
<blockquote>
<p>Enter 한번으로는 줄바꿈이 되지 않고 Enter를 진행하는 문구 뒤에 두 번 입력해주어야 다음줄로 진행이 된다. </p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/sirius2_1/post/a55af317-dc21-499a-865c-8f993a036d91/image.png" alt=""></p>
</blockquote>
</blockquote>
<ul>
<li><strong>불릿(bullet)</strong></li>
</ul>
<blockquote>
<p>불릿은 주의를 끌기 위해 텍스트 앞에 붙이는 기호로 <em>,+,- 중에 아무거나 텍스트 앞에 입력해주면 된다, 이 때 tab + &#39;</em>&#39; 와 같이 입력해주면 속이 비어있는 불릿이 출력된다.</p>
</blockquote>
<ul>
<li>예시</li>
<li>예시</li>
<li>예시<ul>
<li>예시</li>
</ul>
</li>
</ul>
<ul>
<li><strong>인용구</strong></li>
</ul>
<blockquote>
<p>인용구의 경우 &#39;&gt;&#39;를 입력하여 표현할 수 있고 &#39;&gt;&#39;의 개수를 늘릴 수록 인용의 인용을 추가할 수 있다.</p>
<blockquote>
<p>이를 단계적 표현의 시각화로 활용할 수도 있다. </p>
</blockquote>
</blockquote>
<ul>
<li><strong>강조표현</strong></li>
</ul>
<blockquote>
<p>_또는 *로 텍스트의 앞뒤를 *example* 와 같이 감싸면 <em>example</em> 과 같이 italic체로 작성 할 수 있고, __ 또는 ** 로 텍스트의 앞뒤를 감싸면 <strong>example</strong> 과 같이 bold체로 쓸 수가 있다. </p>
</blockquote>
<blockquote>
<p>~<del>로 text 앞뒤를 감싸면 ~</del>text~~와 같이 지움 표시를 넣을 수 있다.</p>
</blockquote>
<ul>
<li><strong>코드 표현</strong></li>
</ul>
<blockquote>
<p>tab 또는 역따옴표 3개 사이공간에 (``` ```) 코드표현을 입력할 수 있다.  </p>
</blockquote>
<blockquote>
<pre><code>tab을 입력한 뒤 문자를 입력</code></pre></blockquote>
<pre><code>코드를 입력하세요</code></pre><ul>
<li>** 하이퍼링크 ** </li>
</ul>
<blockquote>
<p>하이퍼링크 삽입을 위해서 &lt;&gt;사이에 링크를 넣어주면 된다.</p>
<blockquote>
<p><a href="https://velog.io/@sirius2_1/posts">https://velog.io/@sirius2_1/posts</a></p>
</blockquote>
</blockquote>
<blockquote>
<p>[링크의 이름](주소,&quot;디스크립션&quot;) 포맷으로 링크의 이름과 캡션을 넣어줄 수도 있다.</p>
<blockquote>
<p><a href="https://velog.io/@sirius2_1/posts,%22Sirius%22">밝은 별</a></p>
</blockquote>
</blockquote>
<hr>
<ul>
<li>References
<a href="https://velog.io/@gmlstjq123/Readme.md-%ED%8C%8C%EC%9D%BC-%EC%9E%91%EC%84%B1%EB%B2%95">https://velog.io/@gmlstjq123/Readme.md-%ED%8C%8C%EC%9D%BC-%EC%9E%91%EC%84%B1%EB%B2%95</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[python 전역 변수 ]]></title>
            <link>https://velog.io/@sirius2_1/python-%EC%A0%84%EC%97%AD-%EB%B3%80%EC%88%98</link>
            <guid>https://velog.io/@sirius2_1/python-%EC%A0%84%EC%97%AD-%EB%B3%80%EC%88%98</guid>
            <pubDate>Tue, 12 Sep 2023 10:49:47 GMT</pubDate>
            <description><![CDATA[<h3 id="local-variable">Local variable</h3>
<br>

<h4 id="파이썬-함수에서-선언되어-사용되는-변수는-parameter-포함-함수-내부에서만-쓸-수-있다">파이썬 함수에서 선언되어 사용되는 변수는 (parameter 포함) 함수 내부에서만 쓸 수 있다.</h4>
<br>




<pre><code>def func(x:int):
    x+=1
    y=&quot;local&quot;
    return

 x=1
 print(x)
 func(x)
 print(x)</code></pre><blockquote>
<p>1
1</p>
</blockquote>
<p>위 코드에서 x값의 변화가 없듯이, 함수의 parameter 포함, 내부에서 선언된 변수는 함수실행 이후 유효범위에서 벗어난다.  </p>
<br>
<br>

<p>python의 pass by assignment에 따라 mutable 한 객체 (list,dict 등)은 함수 내부에서 local 변수로 복사 없이 사용 가능하지만 immutable한 객체(int,str,tuple 등)은 어떻게 해야될까?
<br>
<br></p>
<h3 id="global-variable">Global variable</h3>
<p>이를 해결하기 위한 방법 중 하나가 함수 내부에서 전역변수임을 나타내는 키워드, &#39;global&#39;을 사용하는 것이다.
<br></p>
<pre><code>def func(a:int):
    a+=10
    global x
    x+=1
    return

x=10
print(x)
func(x)
print(x)</code></pre><blockquote>
<p>10
11</p>
</blockquote>
<br>

<p>주의 할 점으로 전역변수 선언과 동시에 할당은 할 수 없다는 것이다.</p>
<pre><code>global var</code></pre><p>와 같이 선언 후에 값을 수정할 수 있다.
또 전역변수 선언 여부와 관계없이 매개변수로 전역변수를 인자로 주어도 매개변수가 받은 값은 복사된 값이므로 원본 데이터에 영향을 주지 않는다.</p>
]]></description>
        </item>
    </channel>
</rss>