<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>off_the_glass.log</title>
        <link>https://velog.io/</link>
        <description>해줘잉...</description>
        <lastBuildDate>Thu, 20 Feb 2025 03:57:55 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>off_the_glass.log</title>
            <url>https://velog.velcdn.com/images/off_the_glass/profile/7bd3c848-a509-4c53-90a7-3aaa16d0405a/social_profile.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. off_the_glass.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/off_the_glass" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[인라인 뷰와 WITH 구문]]></title>
            <link>https://velog.io/@off_the_glass/%EC%9D%B8%EB%9D%BC%EC%9D%B8-%EC%BF%BC%EB%A6%AC%EC%99%80-WITH-%EA%B5%AC%EB%AC%B8</link>
            <guid>https://velog.io/@off_the_glass/%EC%9D%B8%EB%9D%BC%EC%9D%B8-%EC%BF%BC%EB%A6%AC%EC%99%80-WITH-%EA%B5%AC%EB%AC%B8</guid>
            <pubDate>Thu, 20 Feb 2025 03:57:55 GMT</pubDate>
            <description><![CDATA[<hr>
<h1 id="📌-oracle-인라인-뷰inline-view와-with-구문cte-정리-🚀">📌 Oracle 인라인 뷰(Inline View)와 WITH 구문(CTE) 정리 🚀</h1>
<p>SQL에서 <strong>서브쿼리를 작성해 임시테이블을 활용</strong>방법 중 대표적인 것이 <strong>인라인 뷰(Inline View)와 WITH 구문(CTE, Common Table Expression)</strong>이야.  </p>
<hr>
<h2 id="1️⃣-인라인-뷰inline-view란">1️⃣ 인라인 뷰(Inline View)란?</h2>
<h3 id="🔹-개념">🔹 개념</h3>
<p><strong>인라인 뷰(Inline View)</strong>는 <strong>FROM 절에서 서브쿼리를 사용하여 생성하는 임시 테이블</strong>이야.<br>즉, SQL 문 내에서 <strong>즉석에서 생성된 테이블처럼 동작하는 서브쿼리</strong>라고 생각하면 돼.  </p>
<hr>
<h3 id="✅-인라인-뷰-기본-구조">✅ 인라인 뷰 기본 구조</h3>
<pre><code class="language-sql">SELECT 컬럼명
FROM (서브쿼리) AS 별칭;</code></pre>
<ul>
<li><code>FROM</code> 절에서 <strong>서브쿼리</strong>를 사용하면, 해당 결과가 <strong>임시 테이블</strong>처럼 동작함.  </li>
<li><strong>Oracle에서는 <code>AS</code> 키워드를 생략 가능</strong>하지만, 명확성을 위해 별칭(Alias)은 필수!  </li>
</ul>
<hr>
<h3 id="✅-예제-부서별-it-부서-직원-조회">✅ 예제: 부서별 IT 부서 직원 조회</h3>
<pre><code class="language-sql">SELECT emp_id, name, salary
FROM (SELECT emp_id, name, salary FROM employees WHERE department = &#39;IT&#39;) subquery;</code></pre>
<p><strong>📌 실행 과정:</strong><br>1️⃣ 서브쿼리 <code>(SELECT emp_id, name, salary FROM employees WHERE department = &#39;IT&#39;)</code> 실행<br>2️⃣ 그 결과를 <code>subquery</code>라는 <strong>임시 테이블</strong>로 사용<br>3️⃣ <code>SELECT emp_id, name, salary FROM subquery;</code> 실행  </p>
<p>💡 <strong>즉, 서브쿼리는 마치 테이블처럼 동작하며, 원하는 조건을 추가로 적용할 수 있음!</strong>  </p>
<hr>
<h3 id="✅-예제-인라인-뷰를-활용한-상위-3명의-급여-정보-조회">✅ 예제: 인라인 뷰를 활용한 상위 3명의 급여 정보 조회</h3>
<pre><code class="language-sql">SELECT *
FROM (
    SELECT emp_id, name, salary 
    FROM employees 
    ORDER BY salary DESC
) subquery
WHERE ROWNUM &lt;= 3;</code></pre>
<p><strong>📌 실행 과정:</strong><br>1️⃣ 서브쿼리에서 <code>ORDER BY salary DESC</code>로 급여가 높은 순서대로 정렬<br>2️⃣ <code>ROWNUM &lt;= 3</code>을 적용하여 상위 3명의 직원만 선택  </p>
<p>💡 <strong>인라인 뷰를 사용하면, 복잡한 쿼리를 간결하게 만들 수 있음!</strong>  </p>
<hr>
<h2 id="2️⃣-with-구문cte-common-table-expression이란">2️⃣ WITH 구문(CTE, Common Table Expression)이란?</h2>
<h3 id="🔹-개념-1">🔹 개념</h3>
<p><strong>WITH 구문(CTE, Common Table Expression)</strong>은 <strong>쿼리 실행 중 일시적으로 사용할 수 있는 가상의 테이블을 정의하는 방식</strong>이야.<br>인라인 뷰와 비슷하지만, <strong>가독성과 성능 면에서 더 유리</strong>한 경우가 많아.  </p>
<hr>
<h3 id="✅-with-구문의-기본-구조">✅ WITH 구문의 기본 구조</h3>
<pre><code class="language-sql">WITH 임시테이블명 AS (
    서브쿼리
)
SELECT 컬럼명 FROM 임시테이블명;</code></pre>
<ul>
<li><code>WITH</code> 절에서 서브쿼리를 정의하고, 해당 결과를 <strong>임시 테이블처럼 사용 가능</strong>  </li>
<li>여러 개의 서브쿼리를 정의할 수도 있음!  </li>
</ul>
<hr>
<h3 id="✅-예제-with-구문을-활용한-부서별-평균-급여보다-높은-직원-조회">✅ 예제: WITH 구문을 활용한 부서별 평균 급여보다 높은 직원 조회</h3>
<pre><code class="language-sql">WITH DeptAvg AS (
    SELECT department, AVG(salary) AS avg_salary
    FROM employees
    GROUP BY department
)
SELECT e.emp_id, e.name, e.salary, d.avg_salary
FROM employees e
JOIN DeptAvg d
ON e.department = d.department
WHERE e.salary &gt; d.avg_salary;</code></pre>
<p><strong>📌 실행 과정:</strong><br>1️⃣ <code>WITH DeptAvg AS (...)</code>에서 부서별 평균 급여를 계산하여 임시 테이블 생성<br>2️⃣ <code>DeptAvg</code>를 <code>employees</code> 테이블과 조인<br>3️⃣ 각 직원의 급여가 <strong>부서 평균보다 높은 직원만 필터링</strong>  </p>
<p>💡 <strong>CTE는 동일한 서브쿼리를 여러 번 사용해야 할 때 더 효과적임!</strong>  </p>
<hr>
<h2 id="3️⃣-인라인-뷰-vs-with-구문-비교">3️⃣ 인라인 뷰 vs WITH 구문 비교</h2>
<table>
<thead>
<tr>
<th>비교 항목</th>
<th>인라인 뷰 (Inline View)</th>
<th>WITH 구문 (CTE)</th>
</tr>
</thead>
<tbody><tr>
<td><strong>가독성</strong></td>
<td>복잡한 쿼리가 되면 가독성이 떨어질 수 있음</td>
<td>쿼리를 분리하여 가독성이 뛰어남</td>
</tr>
<tr>
<td><strong>재사용성</strong></td>
<td>동일한 서브쿼리를 여러 번 사용할 경우, 중복 코드 발생</td>
<td><code>WITH</code>에서 정의한 테이블을 여러 번 재사용 가능</td>
</tr>
<tr>
<td><strong>성능 최적화</strong></td>
<td>실행할 때마다 서브쿼리를 다시 계산</td>
<td>최적화 엔진이 CTE를 한 번만 계산할 수도 있음 (SQL 엔진에 따라 다름)</td>
</tr>
<tr>
<td><strong>사용 예시</strong></td>
<td>단순한 서브쿼리, 임시 테이블처럼 활용할 때</td>
<td>복잡한 쿼리, 동일한 서브쿼리를 여러 번 사용할 때</td>
</tr>
</tbody></table>
<p>💡 <strong>즉, 인라인 뷰는 간단한 서브쿼리에 적합하고, WITH 구문(CTE)은 복잡한 쿼리를 깔끔하게 정리하는 데 유용함!</strong>  </p>
<hr>
<h2 id="4️⃣-with-recursive-재귀-cte">4️⃣ WITH RECURSIVE (재귀 CTE)</h2>
<p>🔹 <code>WITH RECURSIVE</code>는 <strong>자기 자신을 참조하여 반복적으로 데이터를 생성할 때</strong> 사용돼!  
🔹 일반적인 계층형 데이터(예: 조직도, 카테고리 트리)에서 활용 가능.  </p>
<p>✅ <strong>예제: 사원 계층 구조 (상사-부하 관계) 조회</strong>  </p>
<pre><code class="language-sql">WITH RECURSIVE EmployeeHierarchy AS (
    SELECT emp_id, name, manager_id, 1 AS level
    FROM employees
    WHERE manager_id IS NULL  -- 최고 관리자 (최상위 노드)

    UNION ALL

    SELECT e.emp_id, e.name, e.manager_id, eh.level + 1
    FROM employees e
    JOIN EmployeeHierarchy eh ON e.manager_id = eh.emp_id
)
SELECT * FROM EmployeeHierarchy;</code></pre>
<p>✔ <code>manager_id IS NULL</code>인 직원부터 시작 (최상위 관리자)<br>✔ <code>UNION ALL</code>을 사용하여 부하 직원들을 재귀적으로 조회<br>✔ <code>level</code> 컬럼을 활용하여 계층 구조 확인 가능  </p>
<hr>
<h1 id="🔥-결론">🔥 결론</h1>
<p>✅ <strong>인라인 뷰(Inline View)</strong></p>
<ul>
<li><code>FROM (서브쿼리)</code> 형태로 사용되며, <strong>임시 테이블처럼 동작</strong>  </li>
<li><strong>단순한 서브쿼리 처리에 적합</strong>하지만, <strong>가독성이 떨어질 수 있음</strong>  </li>
</ul>
<p>✅ <strong>WITH 구문(CTE, Common Table Expression)</strong></p>
<ul>
<li><code>WITH 테이블명 AS (서브쿼리)</code> 형태로 사용되며, <strong>가독성이 좋고, 재사용 가능</strong>  </li>
<li><strong>복잡한 SQL, 동일한 서브쿼리 반복 사용 시 유리</strong>  </li>
</ul>
<p>✅ <strong>WITH RECURSIVE (재귀 CTE)</strong></p>
<ul>
<li><strong>계층 구조(조직도, 카테고리 트리) 데이터를 처리할 때 유용</strong>  </li>
</ul>
<p>📌 <strong>복잡한 SQL을 작성할 때는 가독성과 성능을 고려하여 적절한 방법을 선택하자!</strong> 🚀</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[테이블 3개 JOIN]]></title>
            <link>https://velog.io/@off_the_glass/%ED%85%8C%EC%9D%B4%EB%B8%94-3%EA%B0%9C-JOIN</link>
            <guid>https://velog.io/@off_the_glass/%ED%85%8C%EC%9D%B4%EB%B8%94-3%EA%B0%9C-JOIN</guid>
            <pubDate>Tue, 18 Feb 2025 06:55:42 GMT</pubDate>
            <description><![CDATA[<h3 id="테이블-구조">테이블 구조</h3>
<ol>
<li><p><strong>employees</strong> 테이블: 직원 정보를 저장</p>
<table>
<thead>
<tr>
<th>컬럼명</th>
<th>데이터 타입</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>emp_id</td>
<td>INT</td>
<td>직원 ID</td>
</tr>
<tr>
<td>emp_name</td>
<td>VARCHAR</td>
<td>직원 이름</td>
</tr>
<tr>
<td>dept_id</td>
<td>INT</td>
<td>부서 ID</td>
</tr>
</tbody></table>
</li>
<li><p><strong>departments</strong> 테이블: 부서 정보를 저장</p>
<table>
<thead>
<tr>
<th>컬럼명</th>
<th>데이터 타입</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>dept_id</td>
<td>INT</td>
<td>부서 ID</td>
</tr>
<tr>
<td>dept_name</td>
<td>VARCHAR</td>
<td>부서 이름</td>
</tr>
</tbody></table>
</li>
<li><p><strong>salaries</strong> 테이블: 급여 정보를 저장</p>
<table>
<thead>
<tr>
<th>컬럼명</th>
<th>데이터 타입</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>emp_id</td>
<td>INT</td>
<td>직원 ID</td>
</tr>
<tr>
<td>salary</td>
<td>DECIMAL</td>
<td>급여</td>
</tr>
<tr>
<td>salary_date</td>
<td>DATE</td>
<td>급여 지급일</td>
</tr>
</tbody></table>
</li>
</ol>
<hr>
<h3 id="sql-쿼리-예시">SQL 쿼리 예시</h3>
<pre><code class="language-sql">SELECT 
    e.emp_name,        -- 직원 이름
    d.dept_name,       -- 부서 이름
    s.salary           -- 급여
FROM 
    employees e        -- 직원 테이블
JOIN 
    departments d      -- 부서 테이블
    ON e.dept_id = d.dept_id  -- 부서 ID로 조인
JOIN 
    salaries s         -- 급여 테이블
    ON e.emp_id = s.emp_id  -- 직원 ID로 조인
WHERE 
    s.salary_date = (   -- 가장 최근 급여 정보만 선택
        SELECT MAX(salary_date) 
        FROM salaries 
        WHERE emp_id = e.emp_id
    )
ORDER BY 
    e.emp_name;        -- 직원 이름 기준으로 정렬</code></pre>
<hr>
<h3 id="실행-결과-예시">실행 결과 예시</h3>
<p>쿼리 실행 결과로 예상되는 테이블은 다음과 같습니다:</p>
<table>
<thead>
<tr>
<th>emp_name</th>
<th>dept_name</th>
<th>salary</th>
</tr>
</thead>
<tbody><tr>
<td>Alice</td>
<td>HR</td>
<td>5000</td>
</tr>
<tr>
<td>Bob</td>
<td>IT</td>
<td>6000</td>
</tr>
<tr>
<td>Charlie</td>
<td>IT</td>
<td>5500</td>
</tr>
<tr>
<td>Dave</td>
<td>Marketing</td>
<td>4800</td>
</tr>
</tbody></table>
<h4 id="결과-설명">결과 설명:</h4>
<ol>
<li><strong>emp_name</strong>: 각 직원의 이름</li>
<li><strong>dept_name</strong>: 각 직원이 소속된 부서 이름</li>
<li><strong>salary</strong>: 각 직원의 가장 최근 급여</li>
</ol>
<p>이 예시에서는 <code>employees</code>, <code>departments</code>, <code>salaries</code> 세 테이블을 조인하여 직원 이름, 부서명, 급여 정보를 출력했습니다. 결과는 직원 이름을 기준으로 오름차순으로 정렬되었습니다.</p>
<h4 id="참고-서브쿼리-설명">(참고) 서브쿼리 설명</h4>
<pre><code class="language-sql">WHERE 
    s.salary_date = (   -- 가장 최근 급여 정보만 선택
        SELECT MAX(salary_date) 
        FROM salaries 
        WHERE emp_id = e.emp_id
    )</code></pre>
<p>에선 select가 employee 테이블의  행 개수만큼  실행되고, 한 번에 하나의 행만 반환한다. 
이렇듯 한 번에 하나의 행만 반환하는  서브쿼리를 스칼라 서브쿼리  라고한다. 
따라서 employee의 행이 많으면 성능적으로 부담이 될 수 있어 서 group by와 join을 사용해 아래와 같이 수행하는 것이 더 효과적이다. </p>
<pre><code class="language-sql">SELECT e.emp_id, e.emp_name, d.dept_name, s.salary
FROM employees e
JOIN departments d ON e.dept_id = d.dept_id
JOIN salaries s ON e.emp_id = s.emp_id
JOIN (
    SELECT emp_id, MAX(salary_date) AS max_date
    FROM salaries
    GROUP BY emp_id
) latest_salary ON s.emp_id = latest_salary.emp_id AND s.salary_date = latest_salary.max_date;
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[ROLLUP과 CUBE함수]]></title>
            <link>https://velog.io/@off_the_glass/ROLLUP%EA%B3%BC-CUBE%ED%95%A8%EC%88%98</link>
            <guid>https://velog.io/@off_the_glass/ROLLUP%EA%B3%BC-CUBE%ED%95%A8%EC%88%98</guid>
            <pubDate>Tue, 18 Feb 2025 06:27:29 GMT</pubDate>
            <description><![CDATA[<h2 id="📌-rollup과-cube-함수의-차이와-활용법">📌 ROLLUP과 CUBE 함수의 차이와 활용법</h2>
<p>SQL에서 <code>ROLLUP</code>과 <code>CUBE</code>는 <strong>그룹별로 다양한 수준의 집계 데이터를 생성</strong>할 때 유용한 함수다.<br>둘 다 <code>GROUP BY</code> 절과 함께 사용되며, 계층적인 집계를 만들 수 있다.<br>하지만 두 함수의 동작 방식에는 차이가 있다.  </p>
<p>이번 글에서는 <code>ROLLUP</code>과 <code>CUBE</code>의 개념을 예제와 함께 쉽게 설명해보겠다.  </p>
<hr>
<h2 id="🔹-rollup과-cube의-개념">🔹 <code>ROLLUP</code>과 <code>CUBE</code>의 개념</h2>
<table>
<thead>
<tr>
<th>함수</th>
<th>특징</th>
<th>주 사용처</th>
</tr>
</thead>
<tbody><tr>
<td><strong>ROLLUP</strong></td>
<td>계층적인 집계 (위에서 아래로 단계별)</td>
<td>매출 분석, 분기별 집계</td>
</tr>
<tr>
<td><strong>CUBE</strong></td>
<td>가능한 모든 조합을 집계</td>
<td>다차원 분석 (OLAP)</td>
</tr>
</tbody></table>
<h3 id="✅-rollup이란">✅ <code>ROLLUP</code>이란?</h3>
<ul>
<li><strong>위에서 아래로 계층적인 집계 값을 생성</strong>한다.  </li>
<li><code>GROUP BY</code>에서 지정한 <strong>가장 마지막 컬럼부터 단계적으로 그룹을 제거</strong>하면서 집계를 수행한다.  </li>
</ul>
<h3 id="✅-cube란">✅ <code>CUBE</code>란?</h3>
<ul>
<li><strong>가능한 모든 조합의 그룹을 생성하여 집계를 수행</strong>한다.  </li>
<li><code>ROLLUP</code>보다 더 많은 집계 데이터를 생성한다.  </li>
<li>다차원 분석(OLAP)에서 많이 사용된다.  </li>
</ul>
<hr>
<h2 id="🔹-rollup-예제">🔹 <code>ROLLUP</code> 예제</h2>
<h3 id="📌-예제-데이터-sales-테이블">📌 예제 데이터 (<code>sales</code> 테이블)</h3>
<table>
<thead>
<tr>
<th>region</th>
<th>product</th>
<th>month</th>
<th>sales</th>
</tr>
</thead>
<tbody><tr>
<td>East</td>
<td>A</td>
<td>Jan</td>
<td>100</td>
</tr>
<tr>
<td>East</td>
<td>A</td>
<td>Feb</td>
<td>200</td>
</tr>
<tr>
<td>East</td>
<td>B</td>
<td>Jan</td>
<td>150</td>
</tr>
<tr>
<td>East</td>
<td>B</td>
<td>Feb</td>
<td>250</td>
</tr>
<tr>
<td>West</td>
<td>A</td>
<td>Jan</td>
<td>120</td>
</tr>
<tr>
<td>West</td>
<td>A</td>
<td>Feb</td>
<td>220</td>
</tr>
<tr>
<td>West</td>
<td>B</td>
<td>Jan</td>
<td>170</td>
</tr>
<tr>
<td>West</td>
<td>B</td>
<td>Feb</td>
<td>270</td>
</tr>
</tbody></table>
<p>이제 <code>region</code>, <code>product</code>, <code>month</code>별로 매출을 집계하려고 한다.  </p>
<pre><code class="language-sql">SELECT region, product, month, SUM(sales) AS total_sales
FROM sales
GROUP BY ROLLUP(region, product, month);</code></pre>
<p>🔹 <strong>결과</strong></p>
<table>
<thead>
<tr>
<th>region</th>
<th>product</th>
<th>month</th>
<th>total_sales</th>
</tr>
</thead>
<tbody><tr>
<td>East</td>
<td>A</td>
<td>Jan</td>
<td>100</td>
</tr>
<tr>
<td>East</td>
<td>A</td>
<td>Feb</td>
<td>200</td>
</tr>
<tr>
<td>East</td>
<td>A</td>
<td>NULL</td>
<td>300</td>
</tr>
<tr>
<td>East</td>
<td>B</td>
<td>Jan</td>
<td>150</td>
</tr>
<tr>
<td>East</td>
<td>B</td>
<td>Feb</td>
<td>250</td>
</tr>
<tr>
<td>East</td>
<td>B</td>
<td>NULL</td>
<td>400</td>
</tr>
<tr>
<td>East</td>
<td>NULL</td>
<td>NULL</td>
<td>700</td>
</tr>
<tr>
<td>West</td>
<td>A</td>
<td>Jan</td>
<td>120</td>
</tr>
<tr>
<td>West</td>
<td>A</td>
<td>Feb</td>
<td>220</td>
</tr>
<tr>
<td>West</td>
<td>A</td>
<td>NULL</td>
<td>340</td>
</tr>
<tr>
<td>West</td>
<td>B</td>
<td>Jan</td>
<td>170</td>
</tr>
<tr>
<td>West</td>
<td>B</td>
<td>Feb</td>
<td>270</td>
</tr>
<tr>
<td>West</td>
<td>B</td>
<td>NULL</td>
<td>440</td>
</tr>
<tr>
<td>West</td>
<td>NULL</td>
<td>NULL</td>
<td>780</td>
</tr>
<tr>
<td>NULL</td>
<td>NULL</td>
<td>NULL</td>
<td>1480</td>
</tr>
</tbody></table>
<h3 id="✅-rollupregion-product-month의-동작-방식">✅ <code>ROLLUP(region, product, month)</code>의 동작 방식</h3>
<p>1️⃣ <code>region</code>, <code>product</code>, <code>month</code>별 총 매출<br>2️⃣ <code>region</code>, <code>product</code>별 총 매출 (<code>month</code> 값이 NULL)<br>3️⃣ <code>region</code>별 총 매출 (<code>product</code>와 <code>month</code> 값이 NULL)<br>4️⃣ 전체 총합 (<code>region</code>, <code>product</code>, <code>month</code> 모두 NULL)</p>
<p>✔ <strong>특징:</strong> <code>ROLLUP</code>은 <strong>계층적인 집계를 생성</strong>하며, 마지막 단계에서 전체 합계를 구한다.  </p>
<hr>
<h2 id="🔹-cube-예제">🔹 <code>CUBE</code> 예제</h2>
<p>같은 데이터를 <code>CUBE</code>로 그룹화하면 어떻게 될까?</p>
<pre><code class="language-sql">SELECT region, product, month, SUM(sales) AS total_sales
FROM sales
GROUP BY CUBE(region, product, month);</code></pre>
<p>🔹 <strong>결과</strong></p>
<table>
<thead>
<tr>
<th>region</th>
<th>product</th>
<th>month</th>
<th>total_sales</th>
</tr>
</thead>
<tbody><tr>
<td>East</td>
<td>A</td>
<td>Jan</td>
<td>100</td>
</tr>
<tr>
<td>East</td>
<td>A</td>
<td>Feb</td>
<td>200</td>
</tr>
<tr>
<td>East</td>
<td>A</td>
<td>NULL</td>
<td>300</td>
</tr>
<tr>
<td>East</td>
<td>B</td>
<td>Jan</td>
<td>150</td>
</tr>
<tr>
<td>East</td>
<td>B</td>
<td>Feb</td>
<td>250</td>
</tr>
<tr>
<td>East</td>
<td>B</td>
<td>NULL</td>
<td>400</td>
</tr>
<tr>
<td>East</td>
<td>NULL</td>
<td>NULL</td>
<td>700</td>
</tr>
<tr>
<td>West</td>
<td>A</td>
<td>Jan</td>
<td>120</td>
</tr>
<tr>
<td>West</td>
<td>A</td>
<td>Feb</td>
<td>220</td>
</tr>
<tr>
<td>West</td>
<td>A</td>
<td>NULL</td>
<td>340</td>
</tr>
<tr>
<td>West</td>
<td>B</td>
<td>Jan</td>
<td>170</td>
</tr>
<tr>
<td>West</td>
<td>B</td>
<td>Feb</td>
<td>270</td>
</tr>
<tr>
<td>West</td>
<td>B</td>
<td>NULL</td>
<td>440</td>
</tr>
<tr>
<td>West</td>
<td>NULL</td>
<td>NULL</td>
<td>780</td>
</tr>
<tr>
<td>NULL</td>
<td>A</td>
<td>Jan</td>
<td>220</td>
</tr>
<tr>
<td>NULL</td>
<td>A</td>
<td>Feb</td>
<td>420</td>
</tr>
<tr>
<td>NULL</td>
<td>A</td>
<td>NULL</td>
<td>640</td>
</tr>
<tr>
<td>NULL</td>
<td>B</td>
<td>Jan</td>
<td>320</td>
</tr>
<tr>
<td>NULL</td>
<td>B</td>
<td>Feb</td>
<td>520</td>
</tr>
<tr>
<td>NULL</td>
<td>B</td>
<td>NULL</td>
<td>840</td>
</tr>
<tr>
<td>NULL</td>
<td>NULL</td>
<td>Jan</td>
<td>420</td>
</tr>
<tr>
<td>NULL</td>
<td>NULL</td>
<td>Feb</td>
<td>740</td>
</tr>
<tr>
<td>NULL</td>
<td>NULL</td>
<td>NULL</td>
<td>1480</td>
</tr>
</tbody></table>
<h3 id="✅-cuberegion-product-month의-동작-방식">✅ <code>CUBE(region, product, month)</code>의 동작 방식</h3>
<p>1️⃣ <code>region</code>, <code>product</code>, <code>month</code>별 총 매출<br>2️⃣ <code>region</code>, <code>product</code>별 총 매출<br>3️⃣ <code>region</code>, <code>month</code>별 총 매출<br>4️⃣ <code>product</code>, <code>month</code>별 총 매출<br>5️⃣ <code>region</code>별 총 매출<br>6️⃣ <code>product</code>별 총 매출<br>7️⃣ <code>month</code>별 총 매출<br>8️⃣ 전체 총합  </p>
<p>✔ <strong>특징:</strong> <code>CUBE</code>는 <strong>모든 가능한 조합을 만들어서 집계</strong>한다.  </p>
<hr>
<h2 id="🔹-rollup-vs-cube-차이-비교">🔹 <code>ROLLUP</code> vs <code>CUBE</code> 차이 비교</h2>
<table>
<thead>
<tr>
<th></th>
<th><code>ROLLUP(region, product, month)</code></th>
<th><code>CUBE(region, product, month)</code></th>
</tr>
</thead>
<tbody><tr>
<td><code>region, product, month</code> 그룹화</td>
<td>✅</td>
<td>✅</td>
</tr>
<tr>
<td><code>region, product</code>별 총합</td>
<td>✅</td>
<td>✅</td>
</tr>
<tr>
<td><code>region, month</code>별 총합</td>
<td>✅</td>
<td>✅</td>
</tr>
<tr>
<td><code>product, month</code>별 총합</td>
<td>❌</td>
<td>✅</td>
</tr>
<tr>
<td><code>region</code>별 총합</td>
<td>✅</td>
<td>✅</td>
</tr>
<tr>
<td><code>product</code>별 총합</td>
<td>❌</td>
<td>✅</td>
</tr>
<tr>
<td><code>month</code>별 총합</td>
<td>❌</td>
<td>✅</td>
</tr>
<tr>
<td>전체 총합</td>
<td>✅</td>
<td>✅</td>
</tr>
</tbody></table>
<p>✔ <code>ROLLUP</code>은 <strong>계층적인 집계</strong>만 포함하지만,<br>✔ <code>CUBE</code>는 <strong>모든 조합을 고려한 다차원 집계</strong>를 수행한다.  </p>
<hr>
<h2 id="🔹-언제-사용하면-좋을까">🔹 언제 사용하면 좋을까?</h2>
<p>✅ <strong>ROLLUP을 사용할 때</strong>  </p>
<ul>
<li><strong>계층적 데이터 분석</strong>이 필요할 때  </li>
<li>예) <code>년 → 분기 → 월</code> 단위로 매출 분석할 때  </li>
</ul>
<p>✅ <strong>CUBE를 사용할 때</strong>  </p>
<ul>
<li><strong>다차원 데이터 분석(OLAP)</strong>이 필요할 때  </li>
<li>예) 제품별 / 지역별 / 전체 매출을 한 번에 분석하고 싶을 때  </li>
</ul>
<hr>
<h2 id="🔹-정리">🔹 정리</h2>
<p>✔ <strong>ROLLUP</strong>: 계층적인 집계를 생성 (특정 기준으로 단계적으로 그룹화)<br>✔ <strong>CUBE</strong>: 가능한 모든 조합의 집계를 생성 (더 많은 데이터 제공)<br>✔ <strong>ROLLUP은 한 방향의 그룹화</strong>, <strong>CUBE는 모든 방향의 그룹화</strong>  </p>
<p>데이터 분석 목적에 따라 적절한 함수를 사용하면 더 효과적인 SQL 쿼리를 작성할 수 있다! 🚀  </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[GROUP BY에 명시하지 않은 열은 다중행 함수 없이 SELECT문에 들어갈 수 없다.]]></title>
            <link>https://velog.io/@off_the_glass/GROUP-BY%EC%97%90-%EB%AA%85%EC%8B%9C%ED%95%98%EC%A7%80-%EC%95%8A%EC%9D%80-%EC%97%B4%EC%9D%80-%EB%8B%A4%EC%A4%91%ED%96%89-%ED%95%A8%EC%88%98-%EC%97%86%EC%9D%B4-SELECT%EB%AC%B8%EC%97%90-%EB%93%A4%EC%96%B4%EA%B0%88-%EC%88%98-%EC%97%86%EB%8B%A4</link>
            <guid>https://velog.io/@off_the_glass/GROUP-BY%EC%97%90-%EB%AA%85%EC%8B%9C%ED%95%98%EC%A7%80-%EC%95%8A%EC%9D%80-%EC%97%B4%EC%9D%80-%EB%8B%A4%EC%A4%91%ED%96%89-%ED%95%A8%EC%88%98-%EC%97%86%EC%9D%B4-SELECT%EB%AC%B8%EC%97%90-%EB%93%A4%EC%96%B4%EA%B0%88-%EC%88%98-%EC%97%86%EB%8B%A4</guid>
            <pubDate>Tue, 18 Feb 2025 03:44:39 GMT</pubDate>
            <description><![CDATA[<h2 id="📌-group-by에서-다중행-함수를-사용하지-않은-컬럼을-select에서-사용할-수-없는-이유">📌 GROUP BY에서 다중행 함수를 사용하지 않은 컬럼을 SELECT에서 사용할 수 없는 이유</h2>
<p>SQL에서 <code>GROUP BY</code>를 사용할 때, <strong>집계 함수(다중행 함수)를 사용하지 않은 컬럼은 반드시 <code>GROUP BY</code> 절에 포함해야 한다.</strong><br>그렇지 않으면 오류가 발생한다.  </p>
<p>이 개념을 예제와 함께 쉽게 이해해보자.  </p>
<hr>
<h2 id="🔹-문제-상황">🔹 문제 상황</h2>
<p>다음과 같은 <code>orders</code> 테이블이 있다고 가정하자.  </p>
<table>
<thead>
<tr>
<th>order_id</th>
<th>customer</th>
<th>product</th>
<th>price</th>
</tr>
</thead>
<tbody><tr>
<td>1</td>
<td>A</td>
<td>Apple</td>
<td>100</td>
</tr>
<tr>
<td>2</td>
<td>A</td>
<td>Banana</td>
<td>200</td>
</tr>
<tr>
<td>3</td>
<td>B</td>
<td>Apple</td>
<td>150</td>
</tr>
<tr>
<td>4</td>
<td>B</td>
<td>Banana</td>
<td>250</td>
</tr>
<tr>
<td>5</td>
<td>B</td>
<td>Apple</td>
<td>300</td>
</tr>
</tbody></table>
<p>이제 고객별(<code>customer</code>) 총 주문 금액을 구하는 SQL을 작성해보자.  </p>
<pre><code class="language-sql">SELECT customer, SUM(price)
FROM orders
GROUP BY customer;</code></pre>
<p>✅ <strong>정상 실행 결과</strong>  </p>
<table>
<thead>
<tr>
<th>customer</th>
<th>SUM(price)</th>
</tr>
</thead>
<tbody><tr>
<td>A</td>
<td>300</td>
</tr>
<tr>
<td>B</td>
<td>700</td>
</tr>
</tbody></table>
<hr>
<h2 id="🔹-group-by에-포함되지-않은-컬럼을-사용할-때-발생하는-오류">🔹 GROUP BY에 포함되지 않은 컬럼을 사용할 때 발생하는 오류</h2>
<p>만약 <code>product</code> 컬럼을 추가해서 다음과 같이 조회하려 하면 어떻게 될까?  </p>
<pre><code class="language-sql">SELECT customer, product, SUM(price)
FROM orders
GROUP BY customer;</code></pre>
<p>❌ <strong>오류 발생!</strong>  </p>
<pre><code>ERROR: column &quot;orders.product&quot; must appear in the GROUP BY clause or be used in an aggregate function</code></pre><h3 id="❓-왜-오류가-발생할까">❓ 왜 오류가 발생할까?</h3>
<ul>
<li><code>GROUP BY customer</code>를 했기 때문에 <strong>각 고객별(<code>customer</code>)로 한 줄의 결과만 반환</strong>해야 한다.  </li>
<li>그런데 <code>product</code> 컬럼은 그룹화되지 않았으므로, <strong>어떤 값을 출력해야 할지 모호하기 때문</strong>이다.  </li>
</ul>
<p>예를 들어, 고객 B의 경우 <code>product</code> 컬럼에는 <code>&quot;Apple&quot;</code>과 <code>&quot;Banana&quot;</code>가 포함되어 있는데, 한 줄로 결과를 만들어야 하므로 <strong>어떤 값을 넣어야 할지 알 수 없다.</strong>  </p>
<hr>
<h2 id="🔹-해결-방법">🔹 해결 방법</h2>
<p>이 문제를 해결하는 방법은 크게 <strong>두 가지</strong>가 있다.  </p>
<h3 id="✅-1-group-by-절에-컬럼을-추가">✅ 1) <code>GROUP BY</code> 절에 컬럼을 추가</h3>
<p>모든 <code>product</code>별로 그룹을 만들려면 <code>product</code> 컬럼도 <code>GROUP BY</code>에 포함하면 된다.  </p>
<pre><code class="language-sql">SELECT customer, product, SUM(price)
FROM orders
GROUP BY customer, product;</code></pre>
<p>🔹 <strong>결과</strong>  </p>
<table>
<thead>
<tr>
<th>customer</th>
<th>product</th>
<th>SUM(price)</th>
</tr>
</thead>
<tbody><tr>
<td>A</td>
<td>Apple</td>
<td>100</td>
</tr>
<tr>
<td>A</td>
<td>Banana</td>
<td>200</td>
</tr>
<tr>
<td>B</td>
<td>Apple</td>
<td>450</td>
</tr>
<tr>
<td>B</td>
<td>Banana</td>
<td>250</td>
</tr>
</tbody></table>
<p>이렇게 하면 <strong>고객별 + 상품별로 그룹화</strong>되어 각 조합의 합계를 볼 수 있다.  </p>
<hr>
<h3 id="✅-2-집계-함수aggregate-function-사용">✅ 2) 집계 함수(Aggregate Function) 사용</h3>
<p>만약 특정 값을 하나만 선택하고 싶다면 <code>MIN()</code>, <code>MAX()</code>, <code>STRING_AGG()</code> 같은 <strong>집계 함수</strong>를 사용할 수 있다.  </p>
<h4 id="📌-예시-1-대표적인-상품-하나-선택-최소값-사용">📌 예시 1: 대표적인 상품 하나 선택 (최소값 사용)</h4>
<pre><code class="language-sql">SELECT customer, MIN(product), SUM(price)
FROM orders
GROUP BY customer;</code></pre>
<p>🔹 <strong>결과</strong>  </p>
<table>
<thead>
<tr>
<th>customer</th>
<th>MIN(product)</th>
<th>SUM(price)</th>
</tr>
</thead>
<tbody><tr>
<td>A</td>
<td>Apple</td>
<td>300</td>
</tr>
<tr>
<td>B</td>
<td>Apple</td>
<td>700</td>
</tr>
</tbody></table>
<p>이 방법은 단순히 <strong>알파벳 기준으로 가장 앞에 오는 제품을 선택</strong>하는 방식이다.<br>특정 기준에 따라 제품을 선택하려면 문자열을 묶어서 출력하는 방법을 사용할 수도 있다.  </p>
<h4 id="📌-예시-2-고객이-주문한-모든-상품을-출력">📌 예시 2: 고객이 주문한 모든 상품을 출력</h4>
<pre><code class="language-sql">SELECT customer, STRING_AGG(product, &#39;, &#39;), SUM(price)
FROM orders
GROUP BY customer;</code></pre>
<p>🔹 <strong>결과</strong>  </p>
<table>
<thead>
<tr>
<th>customer</th>
<th>STRING_AGG(product, &#39;, &#39;)</th>
<th>SUM(price)</th>
</tr>
</thead>
<tbody><tr>
<td>A</td>
<td>Apple, Banana</td>
<td>300</td>
</tr>
<tr>
<td>B</td>
<td>Apple, Banana, Apple</td>
<td>700</td>
</tr>
</tbody></table>
<p>이렇게 하면 <strong>각 고객이 주문한 모든 상품을 쉼표로 구분하여 출력</strong>할 수 있다.  </p>
<hr>
<h2 id="🔹-정리">🔹 정리</h2>
<p>✔ <strong>GROUP BY를 사용하면 그룹 단위로 한 줄씩 결과가 반환된다.</strong><br>✔ <strong>GROUP BY에 포함되지 않은 컬럼은 SELECT에서 단독으로 사용할 수 없다.</strong><br>✔ 해결 방법은  </p>
<ul>
<li><code>GROUP BY</code> 절에 컬럼을 추가하기  </li>
<li>집계 함수를 사용하여 대표 값을 선택하기  </li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[조건부자본증권(CoCo본드)와 후순위채권]]></title>
            <link>https://velog.io/@off_the_glass/%EC%A1%B0%EA%B1%B4%EB%B6%80%EC%9E%90%EB%B3%B8%EC%A6%9D%EA%B6%8CCoCo%EB%B3%B8%EB%93%9C%EC%99%80-%ED%9B%84%EC%88%9C%EC%9C%84%EC%B1%84%EA%B6%8C</link>
            <guid>https://velog.io/@off_the_glass/%EC%A1%B0%EA%B1%B4%EB%B6%80%EC%9E%90%EB%B3%B8%EC%A6%9D%EA%B6%8CCoCo%EB%B3%B8%EB%93%9C%EC%99%80-%ED%9B%84%EC%88%9C%EC%9C%84%EC%B1%84%EA%B6%8C</guid>
            <pubDate>Mon, 17 Feb 2025 07:29:46 GMT</pubDate>
            <description><![CDATA[<p>CoCo본드와 후순위채권은 최초 옵션  행사일을 만기일로 본다는 내용을 보고 정리해봤다</p>
<p>📌 최초 옵션 행사일이란?</p>
<blockquote>
<p><strong>최초 옵션 행사일(First Call Date)</strong>은 발행자가 최초로 조기 상환(Call Option)을 행사할 수 있는 날짜를 의미해.
즉, 채권의 원래 만기보다 일찍 발행자가 <strong>&quot;이제 채권을 상환할게!&quot;</strong>라고 선택할 수 있는 최초의 시점이야.</p>
</blockquote>
<p>✅ 왜 최초 옵션 행사일이 중요한가?</p>
<blockquote>
<p>투자자 입장에서 &#39;사실상 만기일&#39;이 될 가능성이 높음
후순위채권이나 조건부자본증권(CoCo 본드)의 공식 만기는 30년, 50년 또는 무기한일 수도 있음
하지만 대부분의 경우, 최초 옵션 행사일(예: 5년 후)에 조기 상환될 확률이 높음
그래서 투자자들은 이 날짜를 사실상 만기일처럼 생각하는 경우가 많아
발행자는 이자 부담을 줄이기 위해 조기 상환할 가능성이 큼</p>
</blockquote>
<blockquote>
<p>후순위채권이나 CoCo 본드는 일반 채권보다 금리가 높음
시간이 지나면 회사의 신용등급이 개선되거나, 시장 금리가 낮아질 수도 있음
이 경우, 발행자는 낮은 금리로 새 채권을 발행하고 기존 채권을 조기 상환할 가능성이 높음
따라서 최초 옵션 행사일에 조기 상환이 이뤄지는 경우가 많음
하지만 반드시 상환된다는 보장은 없음</p>
</blockquote>
<p>발행자의 재정 상황이 악화되거나, 시장 환경이 좋지 않으면 조기 상환을 안 할 수도 있음
이런 경우 투자자는 예상보다 더 오랜 기간 동안 채권을 보유하게 됨</p>
<blockquote>
<p>📌 후순위채권 &amp; CoCo 본드에서 최초 옵션 행사일 예시
💡 예제 1: 후순위채권 (은행 발행)
발행자: K은행
채권 조건:
만기: 30년
최초 옵션 행사일: 5년 후
금리: 연 5.5% (고정금리, 최초 옵션 행사일까지)
가능한 시나리오
5년 후(최초 옵션 행사일)에 K은행이 조기 상환하면, 투자자는 원금과 마지막 이자를 받고 투자 종료
하지만 K은행이 조기 상환을 안 하면, 투자자는 계속해서 채권을 보유하고 이자를 받음
💡 예제 2: CoCo 본드 (조건부자본증권)
발행자: H은행
채권 조건:
만기: 무기한 (Perpetual)
최초 옵션 행사일: 5년 후
금리: 연 6.0% (최초 옵션 행사일까지), 이후 변동금리
가능한 시나리오
5년 후 H은행이 조기 상환하면 투자자는 원금과 이자를 받고 투자 종료
하지만 은행이 조기 상환을 안 하면? 금리가 변동금리로 바뀌고 계속 유지됨
또, 은행이 재무 상태가 악화되면 CoCo 본드가 강제로 상각되거나 주식으로 전환될 위험도 있음
✅ 정리: 최초 옵션 행사일이 사실상 만기일?
✔ 후순위채권과 CoCo 본드는 공식 만기(30년, 50년, 무기한 등)가 있지만,
✔ 대부분의 경우 최초 옵션 행사일(보통 5년 후)에 발행자가 조기 상환하는 경우가 많음
✔ 그래서 투자자들은 이 날을 &quot;사실상의 만기일&quot;로 생각하는 경우가 많음
✔ 하지만 조기 상환이 보장되는 건 아니니 발행자의 재무 상태와 시장 상황을 잘 분석해야 함 🚀</p>
</blockquote>
<p>나의 말:
근데 너가 설명해준 후순위채권과 조건부자본증권에는 옵션 구조가 없었는데 옵션이 낀 후순위채권과 조건부자본증권도 있는거야?
ChatGPT의 말:
✅ 옵션이 포함된 후순위채권과 조건부자본증권도 있음!
네가 지적한 대로, 기본적인 후순위채권과 조건부자본증권(CoCo 본드)에는 옵션이 포함되지 않을 수도 있지만, 실제로는 콜옵션(Call Option), 스텝업(Step-up), 전환옵션(Convertible) 등 다양한 옵션이 포함된 구조도 많아.</p>
<p>1️⃣ 옵션이 포함된 후순위채권
후순위채권 자체는 일반적으로 콜옵션이 없어도 발행될 수 있지만, 발행자가 조기 상환할 수 있도록 콜옵션(Call Option)이 포함된 형태가 일반적이야.</p>
<p>💡 예시: 콜옵션이 있는 후순위채권
발행자: A은행
채권 조건:
만기: 30년
최초 옵션 행사일(First Call Date): 5년 후
금리: 연 5.0% (최초 옵션 행사일까지 고정), 이후 변동금리
콜옵션(Call Option) 포함: 발행자는 5년 후 조기 상환 가능
📌 옵션의 의미
콜옵션(Call Option):</p>
<p>발행자는 5년 후 최초 옵션 행사일에 채권을 조기 상환할 수 있음
만약 금리가 낮아지거나, 은행이 더 유리한 조건으로 자금을 조달할 수 있다면 조기 상환 가능
하지만 은행의 재무 상태가 악화되거나 시장 상황이 안 좋으면 조기 상환을 안 하고 유지
스텝업(Step-up) 조항이 포함될 수도 있음</p>
<p>만약 5년 후 조기 상환을 안 하면 금리가 올라가는 구조
예: 연 5.0% → 5년 후 조기 상환이 안 되면 연 7.0%로 증가
이렇게 하면 발행자는 가급적 5년 후에 조기 상환을 하려는 유인이 생김
2️⃣ 옵션이 포함된 조건부자본증권(CoCo 본드)
조건부자본증권(CoCo 본드)도 다양한 옵션이 추가될 수 있어. 특히, 전환옵션(Convertible Option)과 콜옵션(Call Option)이 주요한 옵션이야.</p>
<p>💡 예시: 콜옵션과 전환옵션이 포함된 CoCo 본드
발행자: B은행
채권 조건:
만기: 무기한 (Perpetual)
최초 옵션 행사일: 5년 후
금리: 연 6.0% (최초 옵션 행사일까지), 이후 변동금리
콜옵션(Call Option) 포함: 발행자는 5년 후 조기 상환 가능
전환옵션(Convertible Option) 포함: 특정 조건 충족 시 채권이 자동으로 주식으로 전환
📌 옵션의 의미
콜옵션(Call Option):</p>
<p>후순위채권과 마찬가지로, 발행자가 5년 후 조기 상환할 수 있는 권리
만약 금리가 낮아지거나 은행의 재무 상태가 좋아지면 조기 상환 가능
전환옵션(Convertible Option):</p>
<p>발행자가 강제 전환(Forced Conversion)할 수 있는 구조도 있음
예를 들어, 은행의 BIS 자기자본비율(BIS Ratio)이 5% 이하로 떨어지면 채권이 주식으로 전환됨
즉, 투자자가 채권을 계속 보유하는 것이 아니라 은행 주식을 받게 되는 구조
💡 정리: 옵션이 포함된 후순위채권 &amp; CoCo 본드의 핵심 포인트
✔ 콜옵션(Call Option): 발행자가 조기 상환할 수 있는 권리
✔ 스텝업(Step-up): 조기 상환을 안 하면 금리가 올라가는 구조
✔ 전환옵션(Convertible Option): 특정 조건 충족 시 채권이 주식으로 자동 전환됨</p>
<p>📌 투자자 입장에서 주의할 점
✅ 발행자의 재무 상태를 확인해야 함</p>
<p>발행자가 조기 상환할 수 있을 것 같아 보이지만, 금융위기나 회사 상황이 악화되면 상환을 안 할 수도 있음
특히 CoCo 본드는 은행이 위기에 빠지면 강제로 원금이 상각되거나 주식으로 전환될 위험이 있음
✅ 최초 옵션 행사일이 &quot;사실상의 만기&quot;일 가능성이 큼</p>
<p>옵션이 포함된 후순위채권과 CoCo 본드는 5년 후 최초 옵션 행사일에 조기 상환될 확률이 높음
하지만 100% 보장되는 것은 아니므로 계약 내용을 잘 확인해야 함
✅ 스텝업 조항이 있으면 조기 상환 가능성이 더 높아짐</p>
<p>금리가 올라가면 발행자는 추가 이자 부담을 줄이기 위해 조기 상환을 할 가능성이 높아짐
🚀 결론
옵션이 없는 후순위채권과 CoCo 본드도 있지만, 대부분의 경우 콜옵션(Call Option)이 포함됨
CoCo 본드는 전환옵션(Convertible Option) 같은 추가적인 옵션이 들어갈 수도 있음
최초 옵션 행사일에 조기 상환이 예상되지만, 반드시 상환된다는 보장은 없으므로 주의해야 함!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[having은 개별행이 아니라 그룹화된 결과에 적용된다.]]></title>
            <link>https://velog.io/@off_the_glass/having%EC%9D%80-%EA%B0%9C%EB%B3%84%ED%96%89%EC%9D%B4-%EC%95%84%EB%8B%88%EB%9D%BC-%EA%B7%B8%EB%A3%B9%ED%99%94%EB%90%9C-%EA%B2%B0%EA%B3%BC%EC%97%90-%EC%A0%81%EC%9A%A9%EB%90%9C%EB%8B%A4</link>
            <guid>https://velog.io/@off_the_glass/having%EC%9D%80-%EA%B0%9C%EB%B3%84%ED%96%89%EC%9D%B4-%EC%95%84%EB%8B%88%EB%9D%BC-%EA%B7%B8%EB%A3%B9%ED%99%94%EB%90%9C-%EA%B2%B0%EA%B3%BC%EC%97%90-%EC%A0%81%EC%9A%A9%EB%90%9C%EB%8B%A4</guid>
            <pubDate>Thu, 13 Feb 2025 01:07:35 GMT</pubDate>
            <description><![CDATA[<h2 id="having의-쓰임">having의 쓰임</h2>
<blockquote>
<p>having은 group by 뒤에 group by에 의해 그룹화된 결과에 대해 적용된다.   where처럼 개별 행에 적용되는 것이 아니다.</p>
</blockquote>
<h4 id="뭔-소리냐">뭔 소리냐..?</h4>
<blockquote>
<p>예시를 보자.</p>
</blockquote>
<p>🎯 부서별 평균 급여가 5000 이상인 부서만 조회하기</p>
<pre><code class="language-sql">SELECT department_id, AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id
HAVING AVG(salary) &gt;= 5000;  -- ✅ 그룹화된 결과 필터링
</code></pre>
<blockquote>
<p>여기서 HAVING은 부서에 의해 그룹화된 각각 부서그룹에 적용됐다. 이와 같이 having은 대부분 사용시 avg,max,min,sum,count등 그룹함수와 함께 사용된다.(꼭 그룹함수를 써야하는 것은 아니다.)</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[sql 실행순서]]></title>
            <link>https://velog.io/@off_the_glass/sql-%EC%8B%A4%ED%96%89%EC%88%9C%EC%84%9C</link>
            <guid>https://velog.io/@off_the_glass/sql-%EC%8B%A4%ED%96%89%EC%88%9C%EC%84%9C</guid>
            <pubDate>Wed, 12 Feb 2025 01:01:24 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><strong>SQL 실행순서</strong> , select문에서 sql의 실행순서</p>
</blockquote>
<p>1.from,join
2.where
3.group by
4.having
5.select
6.order by</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Java에는 call by reference가 없다.]]></title>
            <link>https://velog.io/@off_the_glass/Java%EC%97%90%EB%8A%94-call-by-reference%EA%B0%80-%EC%97%86%EB%8B%A4</link>
            <guid>https://velog.io/@off_the_glass/Java%EC%97%90%EB%8A%94-call-by-reference%EA%B0%80-%EC%97%86%EB%8B%A4</guid>
            <pubDate>Fri, 31 Jan 2025 06:53:03 GMT</pubDate>
            <description><![CDATA[<p>참조: 
<a href="https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EC%9E%90%EB%B0%94%EB%8A%94-Call-by-reference-%EA%B0%9C%EB%85%90%EC%9D%B4-%EC%97%86%EB%8B%A4-%E2%9D%93">https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EC%9E%90%EB%B0%94%EB%8A%94-Call-by-reference-%EA%B0%9C%EB%85%90%EC%9D%B4-%EC%97%86%EB%8B%A4-%E2%9D%93</a>
<a href="https://loosie.tistory.com/486">https://loosie.tistory.com/486</a></p>
<h3 id="call-by-reference--변수가-하나-더-생기는-게-아니라-별칭이-하나-더-생길뿐">call by reference = 변수가 하나 더 생기는 게 아니라 별칭이 하나 더 생길뿐!</h3>
<pre><code class="language-cpp">#include &lt;iostream&gt;
using namespace std;

void modify(int &amp;x) { // x는 a의 참조
    x = 10; // x를 통해 원래 변수의 값을 변경
}

int main() {
    int a = 5;
    modify(a); // a의 주소가 전달됨
    cout &lt;&lt; &quot;a: &quot; &lt;&lt; a &lt;&lt; endl; // a는 이제 10
    return 0;
}</code></pre>
<blockquote>
<p>여기서 modify(a)할 때 x에 a의 <strong>참조가 넘어간다</strong> 
이게 무슨 소리냐?  a라는 변수의 메모리 주소가 0x01이라고 하면, x라는 변수는 0x02이런 식의 메모리를 할당 받아서 그 안에 0x01을 넣는 게 아니라, <strong>x에는 새로운 메모리 할당이 안 된다.</strong>               x는 그냥 a의 <strong>또다른 이름</strong>일 뿐이다. 이게 참조가 넘어간다는 것의 의미다.</p>
</blockquote>
<pre><code class="language-java">class Data {
    int value;
}

class Test {
    static void modifyValue(Data d) {
        d.value = 100; // 객체의 필드값을 변경
    }

    public static void main(String[] args) {
        Data obj = new Data();
        obj.value = 10;

        modifyValue(obj);
        System.out.println(&quot;변경된 값: &quot; + obj.value); // 출력: 변경된 값: 100
    }
}
</code></pre>
<blockquote>
<p>반면 java의 위의 예시코드에서는 d에 <strong>새로운 메모리가 할당</strong>된다.
obj의 주소가 0x01이라고하고 0x01메모리에 저장된 값이 0x02(실제 인스턴스의 주소)라고 하자. 
modifiyValue(obj)에서는 d라는 변수에 0x03이라는 주소의 메모리가 할당되고 0x03의 메모리에는 obj의 값인 0x02가 전달되어 d는 0x02를 값으로 저장한다. 그렇기에 d.value는 obj.value의 값을 수정한다. 
즉, <strong>d는 obj의 또다른 이름이 아닌 것이다.</strong> </p>
</blockquote>
<p>그래서</p>
<pre><code class="language-java">static void modifyValue(Data d) {
        d = new Data();
        d.value = 100; // 객체의 필드값을 변경
    }</code></pre>
<blockquote>
<p>이렇게 코드가 바뀌면 obj.value는 변하지 않는다. 만약 call by reference에 의해 d가 obj의 또다른 이름이었다면 obj의 value는 100으로 바뀌었을 것이다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[JVM의 구조]]></title>
            <link>https://velog.io/@off_the_glass/JVM%EC%9D%98-%EA%B5%AC%EC%A1%B0</link>
            <guid>https://velog.io/@off_the_glass/JVM%EC%9D%98-%EA%B5%AC%EC%A1%B0</guid>
            <pubDate>Thu, 30 Jan 2025 13:01:33 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>JVM(Java Virtual Machine)은 운영체제로부터 메모리를 할당 받는다. 이 할당받은 메모리의 구조에 대한 글이다.</p>
</blockquote>
<h3 id="1heap-영역">1.Heap 영역</h3>
<ul>
<li>실제로 생성된 객체(인스턴스)가 저장되는 영역.</li>
<li>런타임시 동적으로 할당한다.(객체가 생성되면 heap영역에 할당)</li>
<li>가비지 컬렉션의 대상이다.(Stack영역의 변수가 heap영역의 변수를 더이상 참조하지 않으면 가비지 컬렉션의 대상이 된다.)</li>
<li>모든 스레드가 공유한다.</li>
</ul>
<h3 id="2stack-영역">2.Stack 영역</h3>
<ul>
<li>자바 프로그램에서 메소드가 호출될 때 메소드의 스택 프레임이 저장된다.</li>
<li>JVM은 자바 프로그램에서 메소드가 호출되면, 메소드의 호출과 관계되는 <strong>지역 변수와 매개변수</strong>를 스택 영역에 저장한다</li>
<li><strong>객체의 참조값</strong>이 저장됨. 실제 객체는 heap에 저장.</li>
<li>이렇게 스택영역에 저장되는 메소드 호출정보를 스택 프레임이라고 한다.</li>
</ul>
<h3 id="3method영역클래스-영역static영역">3.Method영역(클래스 영역,static영역)</h3>
<ul>
<li>자바 프로그램에서 사용되는 클래스에 대한 정보와 함께 static변수가 저장되는 영역이다.</li>
<li>클래스 구조, static변수, 상수 등의 정보가 저장됨</li>
<li>프로그램 시작 전에 로드되고 프로그램 종료시 소멸된다.</li>
</ul>
<p>참조: <a href="https://www.devkuma.com/docs/jvm/memory-structure/">https://www.devkuma.com/docs/jvm/memory-structure/</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[javac.exe와 java.exe]]></title>
            <link>https://velog.io/@off_the_glass/javac.exe%EC%99%80-java.exe</link>
            <guid>https://velog.io/@off_the_glass/javac.exe%EC%99%80-java.exe</guid>
            <pubDate>Thu, 30 Jan 2025 12:29:01 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>javac.exe는 <strong>컴파일러</strong>로, .java로 끝나는 자바 소스코드파일을 바이트 코드(.Class로 끝나는 파일)로 컴파일한다.
java.exe는 <strong>인터프리터</strong>로, 컴파일된 바이트코드를 해석하고 JVM에서 실행한다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS EFS]]></title>
            <link>https://velog.io/@off_the_glass/AWS-EFS</link>
            <guid>https://velog.io/@off_the_glass/AWS-EFS</guid>
            <pubDate>Tue, 26 Nov 2024 07:08:56 GMT</pubDate>
            <description><![CDATA[<h3 id="efs란">EFS란?</h3>
<blockquote>
<p>Elastic file system의 약자,
EBS와는 다르게 <strong>여러 ec2에 연결가능</strong>하다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/off_the_glass/post/b1faf83b-488c-4a4a-acc9-997c0d102002/image.jpeg" alt=""></p>
<h3 id="efs의-특징">EFS의 특징</h3>
<blockquote>
<p>EFS에 접근하기 위해서는 보안그룹을 거쳐야 한다.
<strong>Linux기반의 AMI만 호환가능</strong>
NFSv4.I 프로토콜 사용
미리 용량을 설정할 필요 없이 쓰는만큼 확장되고 그에 따라 과금된다.</p>
</blockquote>
<h3 id="efs-storage-class">EFS Storage class</h3>
<blockquote>
<p>EFS 저장소의 클래스도 얼마나 자주 사용하는지에 따라 구분된다. 일정기간 동안 사용하지 않으면 하위 저장소로 내려보낸다. 하위 저장소일수록 보관비용은 싸고 접근비용은 비싸다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/off_the_glass/post/2d276b21-bbcf-4afd-bdd5-6b950cdd3a1a/image.jpeg" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS EC2 INSTANCE STORE]]></title>
            <link>https://velog.io/@off_the_glass/AWS-EC2-INSTANCE-STORE</link>
            <guid>https://velog.io/@off_the_glass/AWS-EC2-INSTANCE-STORE</guid>
            <pubDate>Tue, 26 Nov 2024 05:58:51 GMT</pubDate>
            <description><![CDATA[<h3 id="ec2-instance-store란">EC2 instance store란</h3>
<blockquote>
<p>특별한 타입의 ec2 instance로, ec2 instance에 연결된 하드웨어의 IO성능이 매우 좋다. 따라서 버퍼나 캐시 같은 일시적인 스토리지로 좋다.
단, ec2를 stop했을 때 데이터가 날아가기 때문에 장기적인 스토리지로 적합하지 않다. 장기적인 스토리지는 ebs를 사용하자. </p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS AMI]]></title>
            <link>https://velog.io/@off_the_glass/AWS-AMI</link>
            <guid>https://velog.io/@off_the_glass/AWS-AMI</guid>
            <pubDate>Tue, 26 Nov 2024 05:40:00 GMT</pubDate>
            <description><![CDATA[<h3 id="ami란">AMI란</h3>
<blockquote>
<p>Amazon Machine Image의 약자로, EC2를 시작하기 위한 기본 세팅의 모음이다.( EC2를 시작하기 위해 OS, 아키텍쳐 타입, 저장공간 용량등을 세팅해놓은 것)</p>
</blockquote>
<p>참고: <a href="https://velog.io/@ghldjfldj/AWS-AMI%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80">https://velog.io/@ghldjfldj/AWS-AMI%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</a></p>
<h3 id="ami-생성-ami를-이용한-ec2-생성-실습">AMI 생성, AMI를 이용한 EC2 생성 실습</h3>
<p><a href="https://www.udemy.com/course/best-aws-certified-solutions-architect-associate/learn/lecture/39476798#content">https://www.udemy.com/course/best-aws-certified-solutions-architect-associate/learn/lecture/39476798#content</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS EBS 볼륨]]></title>
            <link>https://velog.io/@off_the_glass/AWS-EBS-%EB%B3%BC%EB%A5%A8</link>
            <guid>https://velog.io/@off_the_glass/AWS-EBS-%EB%B3%BC%EB%A5%A8</guid>
            <pubDate>Tue, 26 Nov 2024 03:24:21 GMT</pubDate>
            <description><![CDATA[<h3 id="ebs-볼륨이란">EBS 볼륨이란</h3>
<blockquote>
<p>데이터를 블록단위로 저장하는 스토리지다. (파일 단위가 아니라 블록 단위로 다루서 I/O가 빠르다.), ec2 생성시 자동으로 EBS 볼륨 하나가 ec2에 연결된다.</p>
</blockquote>
<h3 id="ebs-볼륨의-특징">EBS 볼륨의 특징</h3>
<blockquote>
<p>특정 EC2에 연결할 수 있다.
특정 가용영역(avaliability zone)에 종속된다.
원칙적으로 하나의 EBS볼륨이 두 개 이상의 ec2에 연결될 수는 없다.
(io1과 io2 종류의 볼륨에서는 다중 연결 설정을 하면 가능하긴 하고, 최대 16개 인스턴스에 연결할 수 있다.)
EC2 삭제 시 EBS볼륨도 자동삭제되게할 것인지 설정할 수 있다. </p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/off_the_glass/post/7d8146f6-d910-45e9-a2d0-19d7f14c4d47/image.jpeg" alt=""></p>
<h3 id="볼륨-생성ec2에-연결-탈착-삭제">볼륨 생성,ec2에 연결, 탈착, 삭제</h3>
<p><a href="https://www.udemy.com/course/best-aws-certified-solutions-architect-associate/learn/lecture/29388800?start=15#overview">https://www.udemy.com/course/best-aws-certified-solutions-architect-associate/learn/lecture/29388800?start=15#overview</a></p>
<h3 id="ebs-snapshot">EBS snapshot</h3>
<blockquote>
<p>특정 시점에서 EBS 볼륨의 상태를 백업해놓은 것
snapshot 작업 시 ec2에서 분리한 뒤 하는 것이 권장됨.
다른 가용영역으로 스냅샷을 전달하는 것도 가능함.
스냅샷 archive에 스냅샷을 저장하면 75프로 할인 받을 수 있고, 대신
스냅샷을 복구하는데 1일~3일 정도 걸림
<img src="https://velog.velcdn.com/images/off_the_glass/post/16729800-17c0-47c3-b1aa-362b008505a7/image.jpeg" alt=""></p>
</blockquote>
<p>스냅샷 생성, 아키이브 저장, 스냅샷을 이용한 ebs 볼륨 생성 등 실습
<a href="https://www.udemy.com/course/best-aws-certified-solutions-architect-associate/learn/lecture/39476796?start=45#content">https://www.udemy.com/course/best-aws-certified-solutions-architect-associate/learn/lecture/39476796?start=45#content</a></p>
<p>볼륨과 스냅샷에 암호화를 걸어주는 실습
<a href="https://www.udemy.com/course/best-aws-certified-solutions-architect-associate/learn/lecture/29388816#content">https://www.udemy.com/course/best-aws-certified-solutions-architect-associate/learn/lecture/29388816#content</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[데이터베이스의 index]]></title>
            <link>https://velog.io/@off_the_glass/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4%EC%9D%98-index</link>
            <guid>https://velog.io/@off_the_glass/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4%EC%9D%98-index</guid>
            <pubDate>Tue, 26 Nov 2024 02:26:10 GMT</pubDate>
            <description><![CDATA[<h3 id="db의-index란">DB의 index란</h3>
<blockquote>
<p>검색을 빠르게 하기 위한 자료구조, <strong>컬럼의 값을 사용하여 항상 정렬된 상태</strong>를 유지
(예를 들어, employee 테이블이 있다면 department가 index가 될 수 있다.)</p>
</blockquote>
<h3 id="db의-index의-자료구조">DB의 index의 자료구조</h3>
<blockquote>
<p>MYsql innoDB에서는 B+tree같은 변형 B-tree로 이루어져 있다.</p>
</blockquote>
<p>참고: <a href="https://velog.io/@chanyoung1998/B%ED%8A%B8%EB%A6%AC">https://velog.io/@chanyoung1998/B%ED%8A%B8%EB%A6%AC</a> (B트리)</p>
<h3 id="index를-이용한-검색">Index를 이용한 검색</h3>
<blockquote>
<ol>
<li>secondary index를 이용해 데이터의 PK를 찾음</li>
<li>PK를 이용해 row를 찾음</li>
</ol>
</blockquote>
<p>의 구조. </p>
<p>아래는 B+트리를 이용해 
<strong>secondary index</strong>(0<del>7, 사진에서 key = index, 실제 DB에서는 department등 컬럼값)를 통해 
데이터의 PK(A</del>H, 실제 DB에선 ID 등 Primary key)를 찾는 <strong>1번 과정</strong>이다. 
이를 통해 PK를 찾으면 PK를 가지고 다시 한 번 B+트리를 이용해 데이터를 찾는다</p>
<p><img src="https://velog.velcdn.com/images/off_the_glass/post/1f8c39c6-a0eb-41a2-9e64-00ec9fa83abc/image.png" alt=""></p>
<h3 id="index를-이용한-검색의-장점">Index를 이용한 검색의 장점</h3>
<blockquote>
<p>만약 index를 이용하지 않으면 테이블을 처음부터 끝까지 다 뒤져야한다 -&gt; 디스크 IO작업이 훨씬 늘어나 성능저하가 발생</p>
</blockquote>
<h3 id="index를-이용한-검색의-단점">Index를 이용한 검색의 단점</h3>
<blockquote>
<p>인덱스를 관리하기 위해 DB의 약 10%에 해당하는 저장공간이 필요하다.
인덱스를 관리하기 위해 추가 작업이 필요하다.(index 업데이트,삭제 등)
인덱스를 잘못 사용할 경우 오히려 성능이 저하되는 역효과가 발생할 수 있다.
(만약 테이블의 25퍼센트 이상의 데이터 조회시 인덱스를 이용하지 않는 것이
효율적이다.)</p>
</blockquote>
<p>출처: <a href="https://mangkyu.tistory.com/96">https://mangkyu.tistory.com/96</a> [MangKyu&#39;s Diary:티스토리]</p>
<p>참고: <a href="https://mangkyu.tistory.com/96">https://mangkyu.tistory.com/96</a> </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[EC2 hibernate]]></title>
            <link>https://velog.io/@off_the_glass/EC2-hibernate</link>
            <guid>https://velog.io/@off_the_glass/EC2-hibernate</guid>
            <pubDate>Mon, 25 Nov 2024 07:55:27 GMT</pubDate>
            <description><![CDATA[<h3 id="ec2-hibernate란">EC2 hibernate란</h3>
<blockquote>
<p>ec2 인스턴스를 잠자기 모드로 만드는 것. OS를 종료하지 않고 RAM에 있는 데이터를 EBS에 저장해놓는다. 그래서 부팅시 엄청 빠르다. 
(stop, terminate보다 약한 &#39;절전모드&#39;라고 생각하면 된다// ebs는 AWS에서 할당해준 하드디스크라고 생각하면 된다.)</p>
</blockquote>
<p>참고: <a href="https://velog.io/@whddms310/EC2-Hibernate%EB%9E%80">https://velog.io/@whddms310/EC2-Hibernate%EB%9E%80</a> (hibernate)
<a href="https://velog.io/@ghldjfldj/AWS-EBSAMISG">https://velog.io/@ghldjfldj/AWS-EBSAMISG</a> (EBS)</p>
<h3 id="ec2-hibernate-설정">EC2 hibernate 설정</h3>
<blockquote>
<p>EC2 생성 시 고급 세부 정보 - 최대 절전 중지 방식을 활성화 해줘야한다.
그리고 EBS의 암호화를 활성화 시켜줘야하고, RAM의 데이터를 백업할 EBS의 크기가 충분한지 확인해줘야한다.</p>
</blockquote>
<h4 id="1-최대-절전-중지hibernate방식-활성화">1. 최대 절전 중지(hibernate)방식 활성화</h4>
<p><img src="https://velog.velcdn.com/images/off_the_glass/post/f0813668-985d-4b9c-9940-72d7520af5f9/image.jpg" alt=""></p>
<h4 id="2ebs-암호화-활성화">2.EBS 암호화 활성화</h4>
<p><img src="https://velog.velcdn.com/images/off_the_glass/post/6690ff95-ee92-4864-af49-10f3c424f630/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/off_the_glass/post/58a92942-4bee-4b3d-ae0b-09a416d4570d/image.jpg" alt=""></p>
<h4 id="3-ebs-크기-확인">3. EBS 크기 확인</h4>
<blockquote>
<p>위에서 EBS 볼륨이 8기가인데 나는 t2.micro를 사용했고 t2.micro의 ram은 1기가이므로 충분하다.</p>
</blockquote>
<h4 id="4-인스턴스-hibernate-시키기">4. 인스턴스 hibernate 시키기</h4>
<blockquote>
<p>인스턴스 상태 - 인스턴스 최대 절전 모드 클릭 </p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/off_the_glass/post/05f0e8c2-02c2-4f00-8583-9641c55d6b7b/image.jpg" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS ENI]]></title>
            <link>https://velog.io/@off_the_glass/AWS-ENI</link>
            <guid>https://velog.io/@off_the_glass/AWS-ENI</guid>
            <pubDate>Fri, 15 Nov 2024 10:05:05 GMT</pubDate>
            <description><![CDATA[<h3 id="enielastic-network-interface">ENI(elastic network interface</h3>
<blockquote>
<p>ec2에 붙는 가상의 랜카드라고 보면된다. (랜카드: 컴퓨터를 네트워크에 연결하는 역할을 하는 부품), 그래서 ec2를 서브넷에 연결해주는 역할을 한다.
(원래 ec2는 서브넷 안에 있는거 아닌가?란 생각이 들었는데 사실은 ENI가 서브넷 안에 있고 이걸 통해 서브넷에 ec2를 연결해주는 거더라)</p>
</blockquote>
<blockquote>
<p>ENI는 하나의 사설 IP를 가지고 하나의 공용IP도 가질 수 있다.(공용 IP는 선택), ENI는 하나의 가용영역에 바인딩된다.</p>
</blockquote>
<p>참고: <a href="https://jibinary.tistory.com/133">https://jibinary.tistory.com/133</a></p>
<h3 id="이게-왜-필요하냐">이게 왜 필요하냐?</h3>
<blockquote>
<p>** 장애대응<strong>에 좋다. 사실 **IP주소는 EC2가 아니라 ENI가 가지고있다.</strong>
따라서, 100이라는 IP주소에 연결된 서버 EC2 instance에 문제가 생기면 100이란 주소를 갖고있는 ENI를 예비 서버 EC2 instance로 옯기면 네트워크와 IP주소 설정을 변경하지 않아도 클라이언트는 서버에 정상적으로 접근할 수 있다. </p>
</blockquote>
<h3 id="eni-생성과-ec2-instance에-연결">ENI 생성과 EC2 instance에 연결</h3>
<blockquote>
<p>ec2생성시 하나의 ENI는 자동으로 생성되어 ec2에 연결된다. 그리고 이 ENI는 ec2가 삭제되면 같이 삭제된다. 이제는 수동으로 ENI를 하나 만들어서 ec2에 연결하는 방법을 알아보자.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/off_the_glass/post/e86d578e-ba9c-4be9-b314-1dc1bc8695ab/image.jpg" alt=""></p>
<p>EC2에 들어가서 좌측의 사이드바에서 네트워크 및 보안 - 네트워크 인터페이스에 들어가준다.</p>
<p><img src="https://velog.velcdn.com/images/off_the_glass/post/23054ea6-5c47-417a-9a1f-82519a2c0a9e/image.jpg" alt=""></p>
<p>이 화면이 나오면 네트워크 인터페이스 생성을 눌러준다.</p>
<p><img src="https://velog.velcdn.com/images/off_the_glass/post/a7829d3a-4ae1-4e42-bc7a-275d605cf626/image.jpg" alt=""></p>
<p>연결할 ec2가 있는 서브넷을 골라주고 description에 원하는 이름이나 설명을 적고</p>
<p><img src="https://velog.velcdn.com/images/off_the_glass/post/7615894b-aa52-442a-8683-b0e31cb08074/image.jpg" alt=""></p>
<p>보안 그룹은 연결할 ec2가 있는 보안그룹을 골라주고 생성버튼을 눌러준다.</p>
<p>생성이 완료됐으면 우측 상단의 작업-연결을 눌러서
<img src="https://velog.velcdn.com/images/off_the_glass/post/d05e83ac-8a49-412b-ba14-a1e3d68fd611/image.jpg" alt=""></p>
<p>연결할 ec2가 있는 VPC를 눌러주고 연결할 instance를 택하고 연결버튼을 눌러준다.</p>
<p><img src="https://velog.velcdn.com/images/off_the_glass/post/a17f44c8-434d-48b1-9349-5be6d31ec811/image.jpg" alt=""></p>
<h3 id="ec2와-eni를-연결해제하는-방법">EC2와 ENI를 연결해제하는 방법</h3>
<p>네트워크 및 보안 - 네트워크 인터페이스에 들어가서 해당 ENI를 선택 후 우측 상단 작업-분리를 눌러준다.
<img src="https://velog.velcdn.com/images/off_the_glass/post/ddc58d32-da34-49fd-91f3-24ba4ab64267/image.jpg" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS 배치그룹]]></title>
            <link>https://velog.io/@off_the_glass/AWS-%EB%B0%B0%EC%B9%98%EA%B7%B8%EB%A3%B9</link>
            <guid>https://velog.io/@off_the_glass/AWS-%EB%B0%B0%EC%B9%98%EA%B7%B8%EB%A3%B9</guid>
            <pubDate>Fri, 15 Nov 2024 09:36:15 GMT</pubDate>
            <description><![CDATA[<h3 id="aws-배치그룹이란">AWS 배치그룹이란</h3>
<blockquote>
<p>EC2 인스턴스가 어떻게 AWS 인프라에 배치되는지를 제어하는 방식</p>
</blockquote>
<h4 id="1cluster">1.cluster</h4>
<blockquote>
<p>모든 ec2 인스턴스가 동일한 가용영역(availability zone)에 있음
네트워크가 빨라서 계산작업에 유리함, 다만 가용영역에 문제가 생기면 모든 인스턴스가 장애를 겪음</p>
</blockquote>
<h4 id="2분산배치그룹spread">2.분산배치그룹(spread)</h4>
<blockquote>
<p>ec2 인스턴스들이 다른 하드웨어에 분산되어 있는 방식, 따라서 다른 가용영역에 ec2인스턴스들이 존재할 가능성이 높다. (ex, ec2_1은 가용영역1의 1번하드웨어에, ec2_2는 가용영역1의 2번 하드웨어에, ec2_3은 가용영역3의 1번 하드웨어에 배치)
-&gt; 하드웨어 하나에 문제가 생겨도 다른 ec2 인스턴스들은 안전함.
다만, 가용영역당 7개의 인스턴스로 제한됨
따라서, 적당한 크기의 애플리케이션인데 인스턴스의 오류를 격리해야하는 경우에 적합함(하나의 인스턴스에서 오류난다고 서비스가 다운되면 안 되는 경우)</p>
</blockquote>
<h4 id="3분할배치그룹parition">3.분할배치그룹(parition)</h4>
<blockquote>
<p>가용영역당 최대 7개의 파티션이 있을 수 있음, 각 파티션에 여러 개의 ec2 인스턴스 배치, 각 파티션은 AWS의 랙을 나타냄. 최대 수백개의 ec2 인스턴스를 얻을 수 있음. 각 파티션은 다른 파티션의 실패로부터 격리됨</p>
</blockquote>
<p>cf) 랙(rack), 이렇게 수직으로 쌓은 하드웨어를 하나의 랙이라고 한다.</p>
<p><img src="https://velog.velcdn.com/images/off_the_glass/post/e8bd544a-c714-4777-9ad0-d203118a6d47/image.jpg" alt=""></p>
<h3 id="배치그룹-만들기">배치그룹 만들기</h3>
<p><img src="https://velog.velcdn.com/images/off_the_glass/post/09aa72aa-2203-4fd1-b1c5-1317bee2009b/image.jpg" alt=""></p>
<blockquote>
<p>좌측하단의 배치 그룹 선택해서 들어가면 우측 상단에 배치그룹 생성이라고 보인다. 거기서 배치그룹 생성할 수 있고 어떤 방식의 배치그룹 만들건지 결정가능.</p>
</blockquote>
<h3 id="인스턴스-배치그룹에-할당">인스턴스 배치그룹에 할당</h3>
<blockquote>
<p>위의 사진에서 인스턴스 시작 누르고 &#39;고급세부정보&#39; 가며 만들어진 배치그룹 중에서 인스턴스를 할당받을 그룹을 선택할 수 있다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS EC2 요금제 종류]]></title>
            <link>https://velog.io/@off_the_glass/AWS-EC2-%EC%9A%94%EA%B8%88%EC%A0%9C-%EC%A2%85%EB%A5%98</link>
            <guid>https://velog.io/@off_the_glass/AWS-EC2-%EC%9A%94%EA%B8%88%EC%A0%9C-%EC%A2%85%EB%A5%98</guid>
            <pubDate>Tue, 12 Nov 2024 15:44:07 GMT</pubDate>
            <description><![CDATA[<h3 id="on-demand">on-demand</h3>
<blockquote>
<p>쓴만큼 낸다. 그래서 비쌈</p>
</blockquote>
<h3 id="reserved">Reserved</h3>
<blockquote>
<p>기간을 정해 대여받고 할인받는다</p>
</blockquote>
<h3 id="saving-plans">Saving plans</h3>
<blockquote>
<p>&#39;기간을 정해놓고 그 기간동안 시간당 얼마 내겠다&#39; 이런 식으로 가격을 정하고 할인 받는데, 정해진 용량보다 더쓰면 On-demand요금 적용됨</p>
</blockquote>
<h3 id="spot-instance">Spot Instance</h3>
<blockquote>
<p>On-demand에 비해 가격이 가장 저렴함. 최대가격을 정해서 지불하는데 현재 EC2의 가격이 최대가격을 넘으면(이렇게 지불하겠다는 유저가 있으면 이렇게 됨, 일종의 경매임)인스턴스가 손실될 수 있음(AWS가 자원 회수할 수 있음)
그래서 인스턴스가 손실에 대한 회복력이 있으면 사용해볼만함(ex, 배치작업,이미지 프로세싱 등)
DB같이 손실이 나면 안 되는 목적으로는 절대 쓰면 안 됨.</p>
</blockquote>
<h3 id="dedicated-host">Dedicated Host</h3>
<blockquote>
<p>물리적 서버를 대여받음, 어떤 법규를 준수해야하거나 할 떄 많이 사용함, 요금제는 아니고 하나의 옵션인데, 요금제는 On-demand로 할 수도 있고 Reserved로 할 수도 있음</p>
</blockquote>
<h3 id="dedicated-instance">Dedicated Instance</h3>
<blockquote>
<p>전용 하드웨어가 대여되고 그 위에서 돌아가는 인스턴스, 같은 계정 내의 다른 인스턴스와 하드웨어를 공유할 수 있음</p>
</blockquote>
<h3 id="spot-fleet과-spot-instance-aws-시험에-자주-나옴">spot fleet과 spot instance (aws 시험에 자주 나옴)</h3>
<ul>
<li>스팟요청: 인스턴스 수,사양 등을 정해서 aws에 요청</li>
<li>스팟요청에는 ** 일회성 요청 <strong>과 **영구요청</strong>이 있는데, 일회성 요청은 요청의 유효기간이 딱 한 번 요청시에만 유효한거고 영구요청은 유효기간이 영구적인거다.</li>
<li>스팟요청을 취소하는 건 스팟 인스턴스를 종료하지 않는다.</li>
<li>영구 요청으로 스팟요청을 했을 경우, 인스턴스를 종료하기 전에 ** 스팟요청 취소부터 먼저 **해야한다. 안 그러면 인스턴스를 종료하고나서 아직 살아있는 유효한 스팟요청을 aws가 보고 인스턴스를 다시 실행시킬 수 있다. </li>
<li><strong>스팟플릿</strong>: 스팟 인스턴스 세트를 정의하는 방법, set of spot instances + (optional)on demand instances로 구성됨.</li>
<li>스팟플릿은 요금제약하에서 가장 적절한 ** 런치 pool **을 알아서 선택한다. cf) 런치풀: OS,인스턴스 타입, Availiability Zone 등 다양한 옵션</li>
<li>런치 풀이 제약된 요금을 넘거나 용량을 넘으면 instance를 시작하는 것을 종료한다.</li>
</ul>
<h3 id="시험에-가장-자주-나오는-spot-fleet의-인스턴스-할당-전략">시험에 가장 자주 나오는 spot fleet의 인스턴스 할당 전략</h3>
<blockquote>
<ul>
<li>LowestPrice: 가격이 가장 싼 런치풀을 고른다.</li>
</ul>
</blockquote>
<ul>
<li>Diversified: 인스턴스들이 모든 풀에 분산되게 한다.</li>
<li>capacityOptimized: 인스턴스 수에 맞는 최적의 용량을 가진 pool을 선택</li>
<li>priceCapacityOptimzed: 사용가능한 용량이 가장 큰 풀을 먼저 선택하고, 이 풀들에서 가장 가격이 낮은 풀을 선택한다.</li>
</ul>
<p><a href="https://www.udemy.com/course/best-aws-certified-solutions-architect-associate/learn/lecture/29388768#overview">https://www.udemy.com/course/best-aws-certified-solutions-architect-associate/learn/lecture/29388768#overview</a> 강의내용요약</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[EC2에는 IAM 역할을 부여해야한다.]]></title>
            <link>https://velog.io/@off_the_glass/EC2%EC%97%90%EB%8A%94-IAM-%EC%97%AD%ED%95%A0%EC%9D%84-%EB%B6%80%EC%97%AC%ED%95%B4%EC%95%BC%ED%95%9C%EB%8B%A4</link>
            <guid>https://velog.io/@off_the_glass/EC2%EC%97%90%EB%8A%94-IAM-%EC%97%AD%ED%95%A0%EC%9D%84-%EB%B6%80%EC%97%AC%ED%95%B4%EC%95%BC%ED%95%9C%EB%8B%A4</guid>
            <pubDate>Tue, 12 Nov 2024 11:09:17 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>EC2에는 IAM 역할을 부여해야지 Configure에서 Access키, Secret Access키 등 자격증명정보를 부여하면 안된다(보안상 심각한 문제가 생긴다, Access키가 Ec2에 속하면 Ec2에 접속하면 Access키가 탈취될 수 있다. 사실 무슨 말인지 모르겠는데 나중에 알아보자)</p>
</blockquote>
]]></description>
        </item>
    </channel>
</rss>