티스토리 뷰

DB

[SQL/DB기초] 1주차 / 2주차 정리

uijin-j 2023. 7. 30. 18:52

백준 장학금 챌린지 목표 중 하나인 SQL/DB 강의 수강을 위해 수강한 내용을 블로그에 정리하기로 했다!

 

 

📌 관계 데이터 모델과 관계 연산자

✔️ 관계 데이터 구조

▪️ 기본 개념

 - 모든 데이터를 테이블로 표현하여 저장

 

▪️ 릴레이션(relation)

 - 테이블릴레이션이라 함

 - 릴레이션은 속성(attribute)으로 구성 (원자값 or NULL값)

 - 다중값 속성(리스트) 허용X

 

▪️ 관계 데이터베이스 (Relational Database, RDB)

 ▫️ 스키마

  - 관계 스키마 = { 릴레이션 스키마 } = { 테이블 } (ex. '대학' 관계 스키마 = { 학생, 과목, 등록 })

▫️ 데이터

  - 관계 데이터베이스 = { 릴레이션 인스턴스 } = { 튜플 }

 

✔️ 관계 제약

 ▫️ 건전한 상태

  - 데이터베이스(테이블의 집합)에 저장된 데이터가 정확하고 데이터 간의 불일치가 없음

 

 ▫️ 데이터베이스의 건전성 유지

  - 데이터베이스는 어느 시점에도 항상 건전한 상태를 유지해야 함

  - 이를 위해 관계 제약(무결성 제약)매커니즘이 백그라운드에서 실행됨

 

 ▫️ 기본키(PK)

  - 테이블에서 튜플을 유일(unique)하게 식별할 수 있는 속성의 집합

 

 ▫️ 외래키(FK)

  - 어떤 테이블의 기본키(PK)에 있는 값만을 갖는 속성의 집합

  - 외래키는 기본키가 아님 but 기본키이면서 동시에 외래키인 경우도 있음(PK/FK)

 

 ▫️ 부모-자식 테이블

  - 자식 테이블 : FK가 정의된 테이블 (FK를 통해 PK를 참조)

  - 부모 테이블 : FK가 참조하는 PK가 정의된 테이블

 

▪️ 무결성 제약

 ▫️ 개체 무결성

  : 기본키(PK)값은 유일하며, 널 값을 가질 수 없음(NOT NULL)

 ▫️ 참조 무결성

  : 외래키(FK)값은 부모 테이블의 기본키(PK)값과 같거나 NULL 값을 가짐

 

✔️ 관계 대수

  - 릴레이션 조작(ex. 검색 갱신)을 위한 대수 연산자

  - 관계 대수에서 피연산자는 릴레이션이고, 연산의 결과도 릴레이션

 

 ▫️ 폐쇄 성질

  - 피연산자와 연산 결과가 모두 같은 데이터 타입(테이블)이어야함

  - 중첩된 수식의 표현이 가능

 

1️⃣ 집합 연산자

  ▪️ 합집합 ∪

  ▪️ 교집합 ∩

  ▪️ 차집합 -

  ▪️ 카티션 프로덕트 ×

    : 두 릴레이션에 속한 모든 튜플을 각각 접속(concatination)시킨 튜플로 이루어진 릴레이션

 

✔️ ∪, ∩, -연산의 피연산자들은 (1) 차수(속성의 갯수)가 같아야 함 (2) 대응하는 속성 별로 도메인이 같아야 함

✔️ ∪, ∩, × 연산은 결합적(결합 법칙O) + 교환적(교환 법칙O)

 

❕ 릴레이션(R)의 수학적 표현

  - R(A1, A2, A3, ..., An) (Ai는 속성이며 대응하는 도메인 Di가 있음)

 

2️⃣ 순수 관계 연산자

  ▪️ 셀렉트 - 조건에 만족하는 튜플을 반환

    : SQL 검색문의 WHERE 절!

  

▪️ 프로젝트 - 타겟 속성리스트를 반환 

  :  SQL 검색문의 SELECT 절!

❕ 결과에 중복된 튜플은 제거

 

  ▪️ 조인 - 카티션 프로덕트에 기반한 연산

  :  SQL 검색문의 FROM 절!

 ▫️ 세타조인

 ▫️ 등가조인

 ▫️ 자연조인 (일반적으로 조인은 자연조인을 의미)

 

3️⃣ 확장된 관계 연산자

  ▪️ 외부 조인

    : 조인할 양쪽 릴레이션에서, 조인 결과에 포함되지 않는 튜플도 대응하는 튜플 속성 값을 모두 NULL값으로 만들어서 결과에 포함

    : left (outer) join, right (outer) join, full (outer) join

 

  ▪️ 그룹 연산과 집계 연산

   ▫️ 그룹 연산

    : 기준 속성 값이 같은 튜플끼리 그룹핑 (ex. Group학년(학생))

    : 집계 연산을 위한 전처리로 많이 사용!

 

   ▫️ 집계 연산

    : 기준 속성 값에 대해 통계치(COUNT, AVG, MIN, MAX, STDDEV, VARIAN)를 계산

    ❕ 기준 속성에 NULL값이 들어있는 튜플은 계산에서 제외

    ❕ 기준 속성에 중복값이 있는 튜플도 계산에 포함 

 

 ▪️ 작명 연산

  : 중각 결과 릴레이션에 이름을 붙이고, 그것의 속성 명칭을 변경하는 기능

 

📌 다양한 ERD 표기법

✔️ ERD에서 표현하는 내용

  - 테이블의 구조

  - 테이블 간의 관계 (by PK/FK 컬럼)

 

✔️ 관계의 특성 (인스턴스 레벨)

 ▪️ 매핑 정보

  : 일대일(1:1), 일대다(1:n), 다대다(n:m)

다대다 매핑두 개의 일대다 매핑으로  표현(중간 테이블 도입)

 

 ▪️ 참여 정보

  : 부분 참여, 전체 참여

 

✔️ 관계의 종류

 ▪️ 비식별 관계

  : FK값을 PK값으로 가지지 않는 관계 (점선으로 표현)

 ▪️ 식별 관계

  : FK값을 PK값으로 가지는 관계 (실선으로 표현)

  : (1) 존재 종속 관계이거나 (2) 다대다 매핑일 경우 식별 관계를 형성

🙋🏻‍♀️ 존재 종속 관계?

💡 어떤 튜플(b)의 존재가 다른 튜블(a)의 존재에 달려있음! a는 주 튜플, b는 종속 튜플이라고 함!

     종속 테이블은 관계에 항상 전체 참여함!

 

✔️ ERD 표기법

1️⃣ IE 표기법 (ex. MySQL Workbench)

2️⃣ IDEF1X 표기법

    : 부모 테이블의 참여 형태는 표현 X

 

📌 스키마와 테이블 정의

✔️ SQL 표준

 : SQL 표준은 기능을 명세. 따라서 벤터별(ex. MySQL, MariaDB, SQL Server 등)로 표준과 다른 용어를 쓰는 것이 허용

 : 제조사는 SQL 표준의 기능을 선택적으로 구현

 : 일반적으로 벤터별로 SQL 문법의 차이는 적어지고 있으나, 데이터 타입과 내장 함수에서는 여전히 차이가 많음!

❕ DBMS의 교체가 항상 가능하도록, 이식성이 보장된 응용 프로그램을 작성! (특정 제품 고유의 기능보다는, 가능하면 표준 기능만을 사용!)

 

✔️ SQL 데이터 타입

 ▪️ 숫자형

   - 정수형: INTEGER, SMALLINT, ...

   - 실수형: DECIMAL(p,s), FLOAT, REAL, DOUBLE (p: 전체 자릿수, s: 소수점 이하 자릿수)

▪️ 문자형

   - 고정길이 문자열: CHAR(n)

   - 가변 길이 문자열: VARCHAR(n)

▪️ 날짜형

   - DATE

   - TIME

   - TIMESTAMP: DATE & TIME

   - INTERVAL

 

🔎 MySQL의 데이터 타입 🔎

 ▪️ 숫자형

   ▫️ 정수형

    - TINYINT: 1 byte

    - SMALLINT: 2 bytes

    - MEDIUMINT: 3 bytes

    - INT: 4 bytes

    - BIGINT: 8 bytes

   ▫️ 실수형

    - DECIMAL(p,s)

❕ 컬럼의 디폴트 부호 특성은 SIGNED

 

▪️ 문자형

   ▫️ 고정길이 문자열

    - CHAR(n): data (최대 255문자, n은 문자 갯수)

 

   ▫️ 가변길이 문자열

    - VARCHAR(n): 1 or 2 byte prefix + data (최대 65,535 문자, prefix는 n값을 기록)

 

💁🏻‍♀️ CHAR(n)와 VARCHAR(n)의 차이가 정확하게 뭐죠?

👩🏻‍🏫 CHAR(n)을 쓰면 데이터를 저장할 때 우측의 남는 공간을 공백 문자로 채움! 검색 시 결과값에서 공백을 제거(MySQL)

     VARCHAR가 CHAR에 비해 작은 공간을 사용하지만 CHAR에 비해 접근 속도가 약간 느려질 수 있음!

❕ CHAR()나 VARCHAR(n)에서 입력 데이터가 n보다 클 경우, 넘치는 부분은 truncate됨!

 

   ▫️ TEXT 문자열: VARCHAR(n)과 동일 but n은 미리 할당된 값을 사용

    - TINYTEXT: 1 byte prefix + data (최대 255 문자)

    - TEXT: 2 byte prefix  + data (최대 65,535 문자)

    - MEDIUMTEXT: 3 byte prefix  + data (최대 16,777,215 문자)

    - LONGTEXT: 4 byte prefix  + data (최대 4,294,967,295 문자)

 

   ▫️ ENUM(a, b, c, ...): 나열형 (enumeration)

    - 나열된 문자열 중 단 하나의 문자열만 갖는 타입

 

   ▫️ SET(a, b, c, ...): 나열형 다중값

    - NULL을 포함하여 1개 이상의 문자열을 갖는 타입. 값들을 ","로 구분

❕ PK나 FK에는 ENUM과 SET 타입을 사용할 수 없음

 

▪️ 이진 문자형

   ▫️ 고정길이 이진 문자열

    - BINARY(n): data (최대 255 바이트)

 

   ▫️ 가변길이 이진 문자열

    - VARBINARY(n): 1 or 2 byte prefix + data (최대 65,535 바이트)

 

 ▫️ BLOB (binary large object)이진 문자열: VARBINARY(n)과 동일 but n은 미리 할당된 값을 사용

    - TINYBLOB: 1 byte prefix + data (최대 255 바이트)

    - BLOB: 2 byte prefix  + data (최대 65,535 바이트)

    - MEDIUMBLOB: 3 byte prefix  + data (최대 16,777,215 바이트)

    - LONGBLOB: 4 byte prefix  + data (최대 4,294,967,295 바이트)

 

▪️ 날짜형

   ▫️ YEAR (yyyy)

   ▫️ DATE (yyyy-mm-dd)

   ▫️ TIME, TIME(fsp) (hh:mm:ss[.fraction])

   ▫️ DATETIME, DATETIME(fsp) (yyyy-mm-dd hh:mm:ss[.fraction])

   ▫️ TIMESTAMP, TIMESTAMP(fsp) (yyyy-mm-dd hh:mm:ss[.fraction])

      - 디스플레이 형식은 DATETIME과 동일

      - 실제로는 unix epoch 부터의 초의 갯수(카운터)

      - DATETIME에 비해 저장 공간을 줄일 수 있음(5바이트 → 4바이트)

 

❕ SQL 표준에서의 용어

: 릴레이션(relation) → 테이블(table)

: 속성(attribute) → 컬럼, 열(column)

: 튜플(tuple) → 행(row)

 

❗ SQL 명령문의 종류?

▪️ 데이터 정의문(DDL)

  : CREATE, DROP, ALTER

▪️ 데이터 조작문(DML)

  : INSERT, DELETE, UPDATE, SELECT

▪️ 데이터 제어문(DCL)

  : GRANT, REVOKE

▪️ 트랜젝션 제어문(TCL)

  : COMMIT, ROLLBACK, SAVEPOINT

 

✔️ SQL DDL 명령어

▪️ 스키마 관련

  1️⃣ CREATE SCHEMA

CREATE SCHEMA wtwt;
CREATE DATABASE wtwt;

  2️⃣ DROP SCHEMA

 

▪️ 테이블 관련

  3️⃣ CREATE TABLE

    : 테이블의 구조와 컬럼의 제약조건을 명세

 

❗ 컬럼 제약 조건

- NOT NULL

- UNIQUE [KEY]: 고유한 값을 갖거나 NULL (내부적으로 저장장치에 인덱스를 생성하라는 명령)

- PRIMARY KEY: UNIQUE and NOT NULL

- FOREIGN KEY: 부모 테이블의 PK값 or NULL

- CHECK: 입력/수정 가능한 값의 범위를 제한하는 논리식

❕컬럼 제약조건의 서술 위치에 따라 (1) 컬럼 레벨 정의 방식, (2) 테이블 레벨 정의 방식으로 나뉨!

 

💁🏻‍♀️ 테이블 레벨 정의방식?

💡 NOT NULL을 제외한 모든 제약조건(UNIQUE, PRIMARY KEY, FOREIGN KEY, CHECK)을 정의

💡 조건명을 사용할 수 있음 → 제약 조건의 삭제/추가 가능! (수정은 불가능!)

💡 일반적으로 NOT NULL을 제외한 모든 컬럼 제약조건에 권장!

CREATE TABLE users
(
    user_id       BIGINT NOTNULL,
    nickname      VARCHAR(10) NOTNULL,
    password      VARCHAR(255) NOTNULL,
    gender        ENUM(MALE, FEMALE, NONE),
    birthday      DATE,
    profile_image BIGINT NOTNULL,
    
    CONSTRAINT pk_user
        PRIMARY KEY (user_id),
    CONSTRAINT fk_user_image
        FOREING KEY (profile_image) REFERENCES images(image_id),
    CONSTRAINT chk_birthday
        CHECK (birthday >= '1900-01-01')
);

❕하나의 컬럼에만 적용되는 CHECK 제약조건은 column constraint로 서술 가능 (여러 컬럼에 적용되는 조건은 table constraint로!)

birthday    DATE    CHECK (birthday >= '1900-01-01')

 

❕제약조건 명칭의 Namespace

  - 표준 SQL : NOT NULL을 제외한 모든 제약조건이 같은 namespace에 속함

  - MySQL : 제약조건 별로 namespace가 존재

 

❕생성된 테이블의 구조 확인

DESCRIBE users;

 

❕SELECT 문을 이용한 테이블 생성 + 데이터 삽입 (MySQL, Oracle)

CREATE TABLE users_temp AS
SELECT *
FROM   users;

: 새로운 테이블을 생성하고, SELECT 문의 결과를 새로운 테이블에 삽입

: 기본 제약조건 중 NOT NULL 제약조건만 생성되는 테이블에 적용 (PRIMARY KEY, FOREIGN KEY, UNIQUE, CHECK 제약조건은 모두 사라짐)

 

❕SELECT 문을 이용한 테이블 생성 + 데이터 삽입 (SQL Server)

SELECT *
INTO   users_temp
FROM   users;

 

  4️⃣ DROP TABLE

  : 테이블 정의와 테이블 데이터를 모두 삭제

  : 참조 무결성을 위해 RESTRICT(거부) | CASECADE(함께 삭제) 옵션 제공 (부모 테이블을 삭제할 때 실행하는 제약 조건)

 

🔎 MySQL

: RESTRICT | CASECADE 옵션과 관계없이, 자식 테이블이 한 개라도 있으면, 테이블(부모 테이블)에 대한 삭제 거부

DROP TABLE users;

 

  5️⃣ ALTER TABLE

  : 컬럼의 추가/삭제/수정 or 제약조건의 추가/삭제

ALTER TABLE users
ADD COLUM name VARCHAR(10);

: FIRST/AFTER 절이 없으면, 디폴트는 'AFTER 마지막_컬럼명'

❕ 컬럼을 수정하는 것은 기존 데이터를 고려해야 하므로 제한적! (수정 후에도 기존 데이터는 영향을 받지 않아야 함)

  - 기존 데이터가 있으면, 컬럼의 크기를 늘릴 수는 있지만 줄이지는 못함

  - 컬럼이 NULL 값만 가지고 있거나 테이블에 아무 행도 없으면 컬럼의 크기를 줄일 수 있음

  - 컬럼이 NULL 값만을 가지고 있으면, 데이터 타입을 변경할 수 있음

  - 컬럼의 DEFAULT 값을 바꾸면, 변경 작업 이후 발생하는 행 삽입에만 영향을 미침

  - 컬럼에 NULL 값이 없을 경우에만, NOT NULL 제약조건을 추가할 수 있음

ALTER TABLE users
MODIFY COLUMN profile_image BIGINT NOT NULL DEFAULT '0';
ALTER TABLE users
ADD CONSTRAINT chk_nickname
    CHECK (chk_nickname LIKE 'nickname_%')

 

  6️⃣ RENAME TABLE - MySQL, Oracle 등 일부 DBMS에서만 제공

RENAME TABLE users TO user;

 

  7️⃣ TRUNCATE TABLE

  : 테이블 정의는 그대로 두고, 테이블 데이터를 모두 삭제

  : 내부적으로는 DROP TABLE문 실행 후, CREATE TABLE 문을 통해 테이블을 다시 생성

TRUNCATE TABLE users; /* 자식이 있으면 실행 거부! */

 

💁🏻‍♀️ DDL과 DML의 차이?

 ▪️ DDL의 테이블/튜플 삭제 명령어

  - 트랜젝션 로그에 실행 기록을 남기지 않음 (시스템 부하↓)

  - DDL 명령이 실행되는 즉시, 해당 작업이 완료됨 (AUTO COMMIT)

  - Rollback을 통한 데이터 복구 불가

 ▪️ DML의 튜플 삭제 명령어

  - 테이블 정의는 유지, 데이터(튜플)만 삭제

  - 트랜젝션 로그에 실행 기록을 남기므로, 시스템 부하↑

  - COMMIT 명령을 실행하여, 로그에 기록된 명령을 하드디스크의 테이블에 실제로 반영

  - Rollback을 통한 데이터 복구 가능

 

📌 단일 테이블 검색문1

✔️ SELECT 문

SELECT     [ALL|DISTINCT] {{컬럼 [AS] 컬럼+별칭}* | *} /* project, 집계 연산자 */
FROM       테이블_리스트    /* join 연산자 */
[WHERE     튜플_조건식]    /* select 연산자 */
[GROUP BY  컬럼명 [HAVING 그룹_조건식]] /* group 연산자 */
[ORDER BY  {컬럼명|컬럼_별칭|컬럼_위치 [ASC|DESC],}+] 
[LIMIT     [offset,] row_count]

: MySQL, SQL Server의 경우 FROM절도 생략OK

: 실행 순서는 (1) FROM절 → (2) WHERE 절 → (3) GROUP BY 절 → (4) HAVING 절 → (5) SELECT 절 → (6) ORDER BY 절 → (7) LIMIT 절

 

SELECT *
FROM users;
SELECT user_id, nickname 닉네임
FROM users
WHERE gender = 'FEMALE';

❕ 출력 테이블의 형태에 따른 분류

  - 다중행 질의(table query) : 실행 결과가 n-tuple의 집합

  - 다중값 질의(column query) : 실행 결과가 scalar value(1-tuple)의 집합

  - 단일값 질의(scalar query) : 실행 결과가 1개의 값(scalar value = 1-tuple 1개로 이루어진 집합)

 

 ▪️ SELECT 문의 SELECT절

  : 검색 결과 출력할 컬럼들(컬럼 리스트)를 명세

  : 관계 대수의 project 연산자

 

SELECT [ALL|DISTINCT] {{컬럼 [[AS] 컬럼_별칭],}+ | *}
FROM 테이블_리스트

 - ALL : 중복된 튜플을 모두 포함(Default)

 - DISTINCT : 중복된 튜플은 하나만 남겨두고 모두 제거

 - 컬럼 별칭 : 컬럼에 출력용 별칭을 부여할 수 있음, 컬럼명 대신 컬럼 표현식이 사용될 때 유용 (컬럼 별칭에 공백이 필요하면 따옴표를 사용!)

❕ 표준 SQL에서, 컬럼 별칭은 WHERE절, GROUP BY 절에 사용X (SELECT절, ORDER BY 절에는 사용O)

❕ MySQL에서는 GROUP BY(HAVING)절에서 허용! (WHERE절에서는 사용X)

SELECT quantity * priceEach 주문액
FROM orderDetails
WHERE quantity * priceEach >= 2000; /* 주문액 >= 2000 불가! */

 

WITH절을 이용해 임시 테이블을 만들고, 두 검색문을 연결할 수 있음!

 : 주 검색문의 실행이 완료되면, 임시 테이블은 삭제됨

 : 관계 대수의 rename 연산자 (중간 결과 저장)

WITH temp AS
(
    SELECT quantity * priceEach 주문액
    FROM orderDetails
)
SELECT 주문액
FROM temp
WHERE 주문액 >= 2000;

 

❕컬럼 별칭의 용도

1️⃣ 기존 컬럼의 출력용 명칭을 정의 (ex. 영문 컬럼명을 한글 컬럼명으로 대체)

2️⃣ 산술 표현 식을 사용한 컬럼 생성 (quantity * priceEach 주문액) 

3️⃣ 문자열 연결을 이용한 컬럼 생성 (CONCAT(firstName, ' ', lastName) 이름)

4️⃣ CASE 표현식을 사용한 컬럼 생성

 

💁🏻‍♀️ CASE 표현식?

 : SELECT 절에서 IF-THEN-ELSE 논리와 유사한 기능 제공 (중첩OK)

 : 기존 컬럼의 값을 변경하거나, 새로운 컬럼을 생성하는데 사용

SELECT user_id, nickname,
       CASE gender
           WHEN 'FEMALE' THEN '여자'
           WHEN 'MALE' THEN '남자'
           ELSE '알수없음'
       END AS gender
FROM users;

 

 ▪️ 검색문의 WHERE절

 : 테이블에서 튜플 조건식이 true인 튜플만 선택(조건에 맞는 튜플만 필터링)

 : 관계 대수의 select 연산자

 

❗ 조건식에 들어가는 연산자의 종류

1️⃣ 비교 연산자

  : >, >=, <, <=, =, <> (!=)

2️⃣ SQL 연산자

  - SQL 문장을 프로그래밍 언어가 아니라, 일반 영어 문장과 비슷하게 보이도록 함

  - SQL 문장을 짧게 만들어주며, 성능 측면에서도 장점O

  : BETWEEN a AND b / NOT BETWEEN a AND b

SELECT *
FROM users
WHERE rate BETWEEN 3 AND 5;

  : IN (list), NOT IN (list)

SELECT  *
FROM users
WHERE nickname in ('uijin._.j', 'seyeoonny');

  : LIKE str / NOT LIKE str

SELECT *
FROM posts
WHERE text LIKE '%검색어%' OR 
      title LIKE '%검색어%';

  : IS NULL / IS NOT NULL

💁🏻‍♀️ NULL 값?

 : 값이 존재하지 않는 것을 표현할 때 사용 (ASCII 코드 00: NULL)

 : 어떤 값과도 계산(결과는 NULL)하거나 비교(결과는 FALSE)할 수 없음

SELECT *
FROM users
WHERE profile_image IS NULL;

 

3️⃣ 논리 연산자

  : (), NOT,AND, OR (이 순서대로 먼저 처리)

 

❕비교 연산자 및 SQL 연산자가 논리 연산자보다 우선 처리!

 

 

 

'DB' 카테고리의 다른 글

[DB/SQL기초] 내일배움코스 후기  (0) 2023.08.29
[MySQL] 설치 + 간단한 명령어  (0) 2023.08.16
[SQL/DB기초] 5주차 정리  (0) 2023.08.15
[SQL/DB기초] 4주차 정리  (0) 2023.08.13
[SQL/DB기초] 3주차 정리  (0) 2023.08.06
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
글 보관함