Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions DataBase/jecheol/SQL Injection 스크랩.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

[링크](https://noirstar.tistory.com/264)
109 changes: 109 additions & 0 deletions DataBase/minhyeok/ERD_정규화과정.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# ERD (Entity Relationship Diagram)

## 개념
개체-관계 모델. 테이블간의 관계를 설명해주는 다이어그램이라고 볼 수 있으며, 이를 통해 프로젝트에서 사용되는 DB의 구조를 한눈에 파악할 수 있습니다.
즉, API를 효율적으로 뽑아내기 위한 모델 구조도라고 생각하면 됩니다.

<img src="https://velog.velcdn.com/images%2Fash3767%2Fpost%2Fdfb466b9-a200-45eb-8517-d41418a7f16c%2Fimage.png" width="800" height="400">


## 중요성

ERD는 복잡한 데이터 구조와 관계를 시각적으로 표현함으로써, 데이터베이스 설계를 명확하고 이해하기 쉽게 만들어줍니다. 또한, ERD를 통해 데이터의 무결성과 일관성을 보장할 수 있습니다.

<br>

# 정규화 과정

## 개념

정규화는 데이터베이스에서 중복을 최소화하고, 데이터를 구조적으로 표현하기 위해 사용하는 과정입니다. 이를 통해 데이터의 무결성과 효율성을 높일 수 있습니다.

## 원칙

정규화는 중복된 데이터를 제거하고, 데이터를 논리적으로 구조화하는 것을 목표로 합니다. 이를 위해 여러 단계의 정규형을 거치게 됩니다.

## 특징

- 데이터 조회시 조인 증가 => 필요에 따라 반정규화 진행

- 업무 변경시에도 모델의 유연성 향상

- 엔터티 의미 해석 명확

- 테이블 수 증가

- 모델의 독립성 향상

<img src="https://camo.githubusercontent.com/5e277c100800b192212c08221028d66da5b21d4a69c93567a805e0d83c2bc081/68747470733a2f2f76656c6f672e76656c63646e2e636f6d2f696d616765732f6c696272613330332f706f73742f62633636313565622d303933342d343066392d396566362d3063313735373866623266322f696d6167652e706e67" width="800" height="600">

## 제 1 정규화

- 모든 속성값이 원자값으로만 되어 있음

## 제 2 정규화

- 모든 속성은 기본키에 완전 함수 종속 만족
- 부분적 함수 종속성 제거
- 그러나 기본키가 속성 하나로만 구성되어있으면 Pass

<img src="https://camo.githubusercontent.com/b77e37d0178e29ef9e1c4ae19b98fa43fa92dc640d67361c48e032f57bc07968/68747470733a2f2f76656c6f672e76656c63646e2e636f6d2f696d616765732f6c696272613330332f706f73742f66636430306566642d383266302d343632372d613866642d6462306130633633366234302f696d6167652e6a7067" width="800" height="400">

- 학생번호와 강좌이름 속성으로 구성된 기본키

- 하지만 강좌명에 따라 강의실이 결정되는 부분 함수 종속이 존재

- 따라서, 강좌명을 기본키로하는 테이블을 생성하여 수강 테이블, 강의실 테이블로 분리하여 제 2정규화 조건 충족

## 제 3 정규화

- 이행함수 종속성 제거

- 이행적 종속이란 A -> B, B -> C 이면 A -> C 라는 것을 의미한다.

<img src="https://camo.githubusercontent.com/98506e21b37405a1645a6501f73e424319a3bdee6ab72c65474e84a07856a5f4/68747470733a2f2f76656c6f672e76656c63646e2e636f6d2f696d616765732f6c696272613330332f706f73742f62323631373434352d303564622d346238322d393132382d3235313730646332373934322f696d6167652e706e67" width="800" height="400">

<br>

- 학생번호에 따라 수강료가 결정되는 이상한 상황이 발생함.

- 또한, 강좌가 2만원이라는 것이 중복된다.

- 수강료는 강좌에 따라 결정되야 하므로 이행함수 종속성을 제거한다.

- 다음과 같이 계절수강 테이블, 수강료 테이블을 나누었다.

<br>

<img src="https://camo.githubusercontent.com/d1364ae4e1f7421db2db0cb4c4655373a7b1cad20d7d20069b160fccd0622501/68747470733a2f2f76656c6f672e76656c63646e2e636f6d2f696d616765732f6c696272613330332f706f73742f63623038336232652d323434322d346437322d396163612d3462666332613437303337352f696d6167652e706e67" width="800" height="400">

## BCNF 정규화

- 모든 결정자가 후보키인 정규형을 뜻한다.
- 제 3 정규화까지 진행한 테이블의 모든 결정자가 후보키가 되도록 테이블을 분리시킨다.

- 결정자란?

한 속성의 값이 다른 속성의 값을 결정짓는다면, 그 속성을 '결정자'라고 한다.

<img src="https://camo.githubusercontent.com/618de0dd83018e0d979195f34ceb9b37f1c51e2ed81ca8ca25b77e2136f7d5a6/68747470733a2f2f76656c6f672e76656c63646e2e636f6d2f696d61676573253246797573656f676930323138253246706f737425324661333964386237662d343330662d343764312d386463332d393831346432376566613933253246696d6167652e706e67" width="800" height="400">

<br>

- 이 테이블에서 각 튜플을 구분할 수 있는 학생번호와 특강이름이 기본키이다.

- 따라서 학생번호와 특강이름으로 해당 교수를 알 수 있다.

- 그런데 마찬가지로 교수를 알면 특강 이름을 알 수 있다.

- 교수는 특강이름을 알 수 있는 결정자인데 후보키가 아닌 상황이 발생함.

- 모든 결정자가 후보키이어야한다는 BCNF 정규화 조건을 충족시키지 못함.

<br>

<img src="https://camo.githubusercontent.com/7e94a0a34d64ad6dbfee1021e11f30959efe82f06142ec048500480741984783/68747470733a2f2f76656c6f672e76656c63646e2e636f6d2f696d61676573253246797573656f676930323138253246706f737425324631363961326665352d326434652d343662632d393034372d333264356132353333656162253246696d6167652e706e67" width="800" height="400">

<br>

- 그래서 다음과 같이 특강신청 테이블, 특강 교수 테이블로 나누어 문제를 해결.
148 changes: 148 additions & 0 deletions DataBase/minhyeok/JOIN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
# 조인이란?

두 개 이상의 테이블에서 필요한 데이터를 가져와서 하나의 결과 집합으로 결합하는 연산입니다. 조인을 사용하면 여러 테이블에 분산된 데이터를 효율적으로 조회할 수 있습니다.

## 종류

<img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FluYd1%2FbtrbUXM4iJJ%2FqLt17TKyK9is4xdS1pK0ok%2Fimg.png" width="800" height="700">

<br>

### Inner Join(내부 조인)

두 테이블의 교집합을 반환합니다. 즉, 조인 조건에 맞는 행만 결과로 반환하며, 조건에 맞지 않는 행은 제외됩니다.

<img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJp2Vf%2FbtqE33quGjY%2F9kvKNZGxK6Z1eDT3VHYAek%2Fimg.png" width="800" height="300">

<br>

<img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdfAaJp%2FbtqE2tpEeo9%2FhAVVa3o3FP790ZzBiO5pCK%2Fimg.png" width="400" height="300">


### Left Outer Join(왼쪽 외부 조인)

왼쪽 테이블의 모든 행과 오른쪽 테이블에서 조인 조건에 맞는 행을 반환합니다. 오른쪽 테이블에 매칭되는 행이 없는 경우에는 NULL 값을 반환합니다.

SELECT A.ID, B.ID, A.NAME, B.NAME
FROM Table A, Table B
WHERE A.ID = B.ID(+);

<img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Feb6dKq%2FbtqE42qPl9E%2FHmM4YZlkk2C8HO730kUzHK%2Fimg.png" width="400" height="300">


### Right Outer Join(오른쪽 외부 조인)

오른쪽 테이블의 모든 행과 왼쪽 테이블에서 조인 조건에 맞는 행을 반환합니다. 왼쪽 테이블에 매칭되는 행이 없는 경우에는 NULL 값을 반환합니다.

SELECT A.ID, B.ID, A.NAME, B.NAME
FROM Table A, Table B
WHERE A.ID(+) = B.ID;

<img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbj8SA2%2FbtqE4Csupbr%2FNVJUoxUKuTMVMgqm8pDonk%2Fimg.png" width="800" height="300">

<br>

<img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPuHTd%2FbtqE13ymgOR%2FOtNiJ9rF9ZWhwKAanVKyEK%2Fimg.png
" width="400" height="300">

### Full Outer Join(전체 외부 조인)

왼쪽 테이블과 오른쪽 테이블의 합집합을 반환합니다. 양쪽 테이블에서 조인 조건에 맞는 행을 반환하며, 매칭되는 행이 없는 경우에는 NULL 값을 반환합니다.


### Inner Join VS Outer Join

댓글이 있는 게시물만 보여줘라 VS 댓글이 없는 게시물도 보여줘라


<br>

# Nested Loop Join(중첩 조인)

두 테이블을 조인하는 가장 기본적인 방법으로 하나의 테이블을 기준으로 기준 테이블의 행 마다 다른 테이블의 모든 행을 검색하는 방식. => 이중 for문과 유사

## 사용 케이스

- 작은 테이블 간의 조인이나, 인덱스가 적용된 테이블에 효과적

## 작동 방식

<img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyPw0M%2FbtrbYtjXJCQ%2FurK6VRtm1T0c9cygsQIOfK%2Fimg.png" width="800" height="400">

- Table A가 Outer Table(선행 테이블), Driving Table(구동 테이블)

- Table B가 Inner Table(후행 테이블), Driven Table

1. 외부 테이블의 첫 번째 행을 가져옵니다.

2. 내부 테이블의 모든 행을 검색하면서, 조인 조건에 맞는 행을 찾습니다.

3. 조건에 맞는 모든 행을 찾았다면, 외부 테이블의 다음 행으로 이동하고, 내부 테이블의 검색을 다시 시작합니다.

4. 외부 테이블의 모든 행을 검사할 때까지 이 과정을 반복합니다.

### 그런데, 후행 테이블을 Index화 한다면 모든 테이블을 검색하지도 않아도 되어 속도를 빠르게 할 수 있다.

- index는 도서관의 도서 분류라고 보면 됨 => 모든 자료를 검색하지 않아도 된다.

<img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAcmKI%2Fbtrb2bCzmEg%2FxL8X1rtMECBnM7dww7WRB1%2Fimg.png" width="800" height="400">

- Drivng Table의 범위가 작을수록 수행속도가 빨라진다. 따라서 Driving Table을 어떤 테이블로 설정하는지가 중요하다.

<br>

# Sort Merge Join

각 테이블을 조인 키에 따라 정렬한 후, 두 테이블을 병합하면서 조인을 수행하는 방식

## 사용 케이스

- 두 테이블이 이미 정렬된 상태거나, 정렬된 인덱스가 존재할 때 효과적

- 출력해야 할 결과 값이 많을 때

<img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99F16B4E5BC6F1CA16" width="800" height="400">

## 작동 방식

1. 선행 테이블에서 조건을 만족하는 행을 찾고 조인 키를 기준으로 정렬

2. 후행 테이블에서도 같은 작업

3. Join 수행

## Hash Join

해싱 기법을 이용하여 조인을 수행하는 기법이다.

<img src="https://mblogthumb-phinf.pstatic.net/MjAyMTAzMTJfNzMg/MDAxNjE1NTEzOTU2MjE5.84G3mzMzZVqYw41YO646oub5jZ8RhxAfI4j5Gn3Ox1kg.OdFsFijkhoRW99bOew1jsIBaECy9kp2Vr_o_Y723pFMg.PNG.dnjswls23/s1111sff.png?type=w800" width="800" height="400">

## 작동 방식

1. 선행 테이블에서 조건을 만족하는 행을 찾는다.

2. 선행 테이블의 조인 키로 해시함수를 적용하여 테이블을 생성한다. 이때, 조인 컬럼과 select 절에서 필요로 하는 컬럼도 함께 저장한다.

3. 1,2를 반복 수행한다.

4. 후행 테이블에서 조건을 만족하는 행을 찾는다.

5. 후행 테이블의 조인 키로 해시 함수를 적용하여 해당하는 버킷을 찾는다. => 조인 키를 이용하여 실제 조인된 데이터를 찾는다.

6. 조인 성공시 추출버퍼에 넣는다.

## 사용 케이스

- 조인 컬럼에 인덱스를 사용하지 않는다. 따라서, 조인 컬럼 인덱스가 없는 경우에도 사용가능하다.

- 해시 함수를 이용하여 조인을 하기 때문에 동등 연산 조인에서 사용한다. => 해시 함수가 적용될 때 동일한 값은 항상 같은 값으로 해싱 되기 때문.

## 특징

- 조인 시 해시 테이블을 메모리에 생성해야 한다.

- 생성된 해시 테이블의 크기가 메모리 적재 크기보다 커지면 임시 영역(디스크)에 저장한다. 이 과정은 추가적인 작업이 필요.

- 따라서, 결과 행의 수가 적은 것을 선행 테이블로 사용하는 것이 좋다.

- 해시 테이블을 만든 선행 테이블을 빌드 테이블이라고 하며, 후행 테이블을 프로브 테이블이라고 한다.
89 changes: 89 additions & 0 deletions DataBase/minhyeok/SQL Injection.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# SQL Injection 이란?

악의적인 사용자가 보안상 취약점을 이용하여 이득을 얻기 위해 SQL 쿼리문을 조작하여 DB가 비정상적인 동작을 하도록 유도하는 행위이다. 공격이 비교적 쉬우나, 큰 피해를 입힐 수 있어 많은 주의가 필요하다.

# 종류

<img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F9958373C5C8890FA03" width="800" height="400">

<br>

- 입력값에 대한 검증이 없을 때 발생

- 특정 SQL 구문을 주입하여 WHERE 절을 참으로 만들고, 뒤의 구문을 주석 처리하여 모든 정보를 조회

- 이로 인해 가장 먼저 만들어진 계정으로 로그인에 성공할수도 있다. (관리자 계정) => 추가적인 피해


## Union based SQL Injection

<img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99BD4C3C5C8890FA0A" width="800" height="400">

<br>

- Union 키워드를 사용하여 정상적인 쿼리문에 추가적인 쿼리문을 주입

- 이를 통해 원하는 쿼리문을 실행할 수 있게 된다.

- 두가지 조건이 필요 하나는 Union 하는 두 테이블의 컬럼 수가 같아야 하고, 데이터 형이 같아야 한다.

## Blind SQL Injection

<img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99525F3C5C8890F90E" width="800" height="400">

<br>

- 데이터베이스로부터 특정한 값이나 데이터를 전달받지 않고, 단순히 참과 거짓의 정보만 알 수 있을 때 사용

- Boolean based는 로그인 성공과 실패 메시지를 이용하여 DB의 테이블 정보 등을 추출해 낼 수 있다.

## Time based

<img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99CAFB395C88914513" width="800" height="400">

<br>

- 서버의 응답 시간을 이용하여 데이터베이스의 정보를 유추하는 기법.

## Stored Procedure SQL Injection

- 저장 프로시저를 이용하여 SQL Injection을 수행하는 방법

- 특히 MS-SQL의 xp_cmdshell과 같은 특정 저장 프로시저를 이용하여 윈도우 명령어를 사용할 수 있다.

## Mass SQL Injection

- 한 번의 공격으로 다량의 데이터베이스를 조작하여 큰 피해를 입히는 방법

- 주로 MS-SQL을 사용하는 ASP 기반 웹 애플리케이션에서 많이 사용되며, 쿼리문은 HEX 인코딩 방식으로 인코딩하여 공격

<br>

# 대응방법

## 입력 값에 대한 검증

- 사용자로부터 입력 받은 값에 대한 검증은 필수

- 이때 화이트리스트 기반의 검증이 필요하며, 블랙리스트 기반의 검증은 빠진 항목 하나로 인해 공격에 성공할 위험

- 공격 키워드와는 의미 없는 단어로 치환

## Prepared Statement 구문 사용

- 사용자의 입력 값을 문자열로 인식하게 하여 전체 쿼리문이 공격자의 의도대로 작동하지 않도록 하는 방법

- DBMS가 미리 컴파일하여 실행하지 않고 대기하며, 사용자의 입력은 이미 의미 없는 단순 문자열로 인식

## Error Message 노출 금지

- 데이터베이스 에러 발생 시, 에러가 발생한 쿼리문과 함께 에러에 관한 내용을 반환하면, 이를 통해 테이블명 및 컬럼명 그리고 쿼리문이 노출될 수 있다.

- 따라서, 사용자에게 보여줄 수 있는 페이지를 제작하거나 메시지박스를 띄우는 등의 방법으로 에러 메시지의 노출을 막아야 한다.

## 웹 방화벽 사용

- 웹 공격 방어에 특화된 웹 방화벽의 사용은 효과적인 보안 방법 중 하나

- 웹 방화벽은 소프트웨어 형, 하드웨어 형, 프록시 형 등의 종류가 있으며, 각각의 방법은 서버에 직접 설치하거나, 네트워크 상에서 서버 앞 단에 하드웨어 장비로 구성하거나, DNS 서버 주소를 웹 방화벽으로 바꾸는 등의 방식으로 운용된다.

Loading