본문 바로가기
DATABASE/DBMS

251103 | DBMS ( 스키마 , 테이블)

by codechu 2025. 11. 3.

DBMS

개념 

  • DBMS( Database Management System) 는 웹 개발 뿐만 아니라 서버( 혹은 서비스, 제공자 등) 가 클라이언트 ( 혹은 일반적인 사용자, 고객군) 에게 제공하는데 있어, 소실되면 안 되고 유지, 기억해야하는 내용들을 SQL(언어)을 통해 쉽게 처리하기 위해 사용하는 체계이다.
  • SQL(Structured Query Language)은 DBMS가 가지는 구조 및 데이터를 통제하기 위해 사용하는 언어이다. 

규칙

  • SQL 키워드는 대문자로 작성하는 것이 권장되나, 소문자로 작성하여도 무방하다. 단, 섞어서 사용하지 않도록 유의한다.
  • 모든 구성요소( 스키마, 테이블, 열, 사용자 이름 등)의 이름은 소문자 스네이크 케이스로 명명한다. ->(user_name)
  • 모든 구성요소의 이름을 언급할 때에는 백틱(`) 으로 감싼다.
  • 문자열 리터럴은 홑따옴표(') 로 감싼다.
  • 하나의 쿼리가 끝나는 경우 쿼리의 끝에 세미콜론(;)을 작성한다. 세미콜론은 작성하기 전까지는 개행이 이루어져도 하나의 쿼리인 것으로 간주한다.

주석

  • 주석(comment)은 쿼리 실행에 영향을 미치지 않고 간단한 메모를 남기기 위해 사용한다.
  • 한 줄 주석: 한 줄 주석은(샾 #) 및 대쉬 두 개( -- )를 작성해 사용할 수 있다.
  • 여러 줄 주석 : */로 시작하며 */로 끝낸다.

스키마

  • 스키마(schema)는 서로 관련 있는 테이블을 묶어내기 위해 사용한다.
  • 주로 하나의 서비스( 플랫폼 ) 에 대한 데이터를 가지는 테이블들을 묶어내기 위해 하나의 스키마를 만들어서 사용한다.
  • schema 라는 키워드는 DABABESE 라는 키워드와 치환하여 사용하여도 된다.
SHOW SCHEMA 
= 
SHOW DATABASE
  • 실제 데이터를 직접 가지지 않는 단순한 껍데기이다.
  • 명명법: 소문자 스네이크 케이스, 단수

 

생성하기

  • 스키마를 생성하기 위해 아래 쿼리를 실행한다
CREATE SCHEMA `이름`;
이미 존재하는 스키마의 이름을 사용할 수 없음에 유의한다

 

조회하기

  • 존재하는 스키마의 목록을 조회하기 위해 아래 쿼리를 실행한다.
SHOW SCHEMA;

 

수정하기

  • 스키마의 이름을 변경하는 것은 불가능하다.
  • 결과적으로 동일한 결론에 도달하기 위해, 새로운 이름을 가지는 스키마를 생성하고 이전 스마키에 있는 모든 테이블들을 새로운 스키마로 옮긴 뒤, 이전 스키마를 삭제하는 방식으로 진행하여야 한다. ( 스키마 이름을 1-> 2로 기존껄 수정은 불가능 그냥 새로  만들고 스키마 1에 있는 내용들을 옮기는 방식은 가능)

삭제하기

  • 존재하는 스키마를 삭제하기 위해 아래 쿼리를 실행한다.
  • 스키마를 삭제하면 이가 가지고 있는 테이블 및 테이블의 레코드가 모두 삭제되고 되돌릴 수 없음으로 유의한다.
DROP SCHEMA `이름`;

 

 

테이블

  • 테이블(table)은 실제 데이터(레코드)를 담기위해 존재한다.
  • 테이블은 독립적으로 존재할 수  없고 반드시 스키마에 소속되어 있어야 한다.
  • 영문법: 소문자 스네이크 메이스, 복수형

 

생성하기

  • 테이블을 생성하기 위해 아래 쿼리를  실행한다. ( 스키마를 엑셀 파일을 만드는걸로 예를 들면 테이블은 엑셀 파일 안에 시트를 생성하는 것과 비슷하다.)
CREATE TABLE `소속 스키마 이름`.`테이블 이름`
(
[열 구조...];
[제약 조건 구조,...]
);

 

기본키 제약 조건(Primary key constraint)

  • 기본키가 되는 한 개 이상의 열(들)은 해당 테이블의 기준이 되는 열(들)을 의미한다.
  • 기본키로 기정된 열(들)이 가지는 값에 대해서 다른 레코드는 중복디는 값을 가질 수 없다.
  • 하나의 테이블은 기본키를 가지지 않거나 하나의 기본키만 가질수 있다.
  • 기본키의 대상이 되는 열은 null 일 수 없음으로, 해당 열은  not null 이어야 한다.
  • 기본키를 선언하려면 아래와 같이 제약 조건 구조를 작성한다.
CONSTRAINT PRIMERY KEY(['열 이름',...]) -> 여기안에 여러개 기본키 넣을 수 있음
대신 둘 중 하나만 같아도 상관없고, 둘 다 같으면 안 된다는 것

CREATE TABLE employees (
    employee_id INT,
    name VARCHAR(100),
    hire_date DATE,
    CONSTRAINT PRIMARY KEY (employee_id)
);

 

유니크 제약 조건(Unique key constraint)

  • 유니크로 지정된 열이 가지는 값은 중복될 수 없다.
  • 값이 중복될 수 없다는 부분은 기본키와 같으나, 유니크는 테이블에서 대표성을 띄지 않거나, 그 의미가 약하다는 점이 다르다. 추가로 하나의 테이블이 여러개의 유니크를 가질수 있다는 점 또한 다르다.
  • 기본키는 null 값을 허용하지 않지만, 유니크는 null 값을 허용한다. 단, null 값에 대해서는 중복 검사를 실시하지 않는다.
  • 유니크 제약 조건을 선언하려면 아래와 같이 제약 조건 구조를 작성한다.

외래키 제약 조건(Foreign key constraint)

  • 외래키 제야 조건이 적용되는 열이 가지는 레코드의 값을 참조 대상인 (referencing)테이블의 열이 가지는 레코드의 값으로 제한하기 위해 사용하는 제약 조건이다.
  • 참조 대상이 되는 열은 기본키이거나 유니크이어야한다.
  • 외래키를 적용하고 있는 열과 참조 대상인 열의 데이터 타입은 호환되어야 한다.(같아야 한다)
  • 외래키를 적용하고 있는 열은 null일 수  있고, 참조 대상인 열이 null을 가지고 있는가의 여부는 확인 하지않는다.
  • 외래키를 선언하려면 아래와 같이 제약 조건 구조를 작성한다.
CONSTRAINT FOREIGN KEY ([`적용하는 열`,...]) REFERENCES ([ `참조 대상 스키마`.`참조 대상 테이블`
.`참조 대상 열`,..])

EX)

부모 테이블
CREATE TABLE departments (
    `dept_id` INT PRIMARY KEY,
    `dept_name` VARCHAR(100)
);
자식 테이블
CREATE TABLE employees (
    `emp_id` INT PRIMARY KEY,
    `emp_name` VARCHAR(100),
    `dept_id` INT,
    CONSTRAINT fk_dept FOREIGN KEY (`dept_id`)
    REFERENCES `departments`(`dept_id`)
);

이렇게 상속,참조를 걸어놓으면 부모 참조 데이터는 삭제, 수정 불가능하다.
이런 경우를 위해 "ON DELETE CASCADE, ON UPDATE CASCADE"는 외래 키 제약 조건(Foreign Key Constraint) 에서 
부모 테이블의 행이 삭제될 때, 그 행을 참조하고 있는 자식 테이블의 행들도 자동으로 함께 삭제되게 하는 옵션" 
을 사용한다.

CREATE TABLE employees (
    emp_id INT PRIMARY KEY,
    emp_name VARCHAR(100),
    dept_id INT,
    CONSTRAINT fk_dept
        FOREIGN KEY (dept_id)
        REFERENCES departments(dept_id)
        ON DELETE CASCADE
        ON UPDATE CASCADE
);

ON DELETE [CASCADE] [SET NULL]
ON UPDATE [CASCADE] [SET NULL]

- RESTRICT : 기본 값으로 , 행위(삭제 및 수정) 을 제한한다. NO ACTION과 동이하게 작동한다.
- CASCADE : 행위에 따라, 같이 삭제 되거나 수정되도록 지정한다.
- SET DEFAULT : 해당 열이 가져야 하는 기본 값으로 지정한다. 단, 해당 기본 값 또한
                외래키 제약 조건에 구속된다.
 -SET NULL : 해당 열의 값을 NULL 로 지정한다. 단, 해당 열이 NULL을 허용하여야만 한다.

체크 제약 조건(Check constraint)

  • 체크 제약 조건은 주어진 논리 조건을 만족할 때에만 레코드를 삽입, 수정 할 수 있게하기 위해 사용한다.
  • 다른 제약 조건과 달리 반드시 어떠한 열에 의존적일 필요는 없다.
  • 체크 제약 조건을 선언하려면 아래와같이 제약 조건을 작성한다.
CONSTRAINT CHECK ([조건])

 

 

 

 

 

 

 

 

실제 예시

CREATE TABLE testdb.employees (
    id INT AUTO_INCREMENT,
    name VARCHAR(50) NOT NULL,
    age INT,
    PRIMARY KEY (id)
);

 

조회하기

  • 특정 스키마에 소속되어있는 테이블의 목록을 조회하기 위해 아래 쿼리를 실행한다.
show table in `소속 스키마 이름`;
  •  특정 테이블이 가지고 있는 열의 구조를 조회하기 위해 아래 쿼리를 실행한다.
DESC `스키마 이름`.`테이블 이름`;
DESCRIBE `스키마 이름`.`테이블 이름`;

 

수정하기

  • 이름 및 소속 스키마 변경하기
    • 존재하는 테이블의 이름을 변경하거나, 소속 스키마를 변경하고자 할 때 아래 쿼리를 실행한다.
      • 소속 스키마만 변경하는 경우
      • 테이블만 변경하는 경우
      • 둘 다 변경하는 경우 
ALTER TABLE `기존 스키마 이름`.`기존 테이블 이름` RENAME `새로운 스키마 이름`.`새로운 테이블 이름`;
  • 열 추가하기
    • 존재하는 테이블에 열을 추가하기 위해 아래 쿼리를 실행한다.
ALTER TABLE `스키마 이름`.`테이블 이름` ADD COLUMN [열 구조]
ex)
ALTER TABLE `study1103`.`people` ADD COLUMN `age` INT;
 * 별도의 명시가 없다면 추가되는 열은 테이블의 가장 마지막 자리에 추가딘다.
 * 추가하려는 열을 특정 열 뒤에 추가하려면 아래 와 같이 AFTER 키워드를 활용한다
 
 ALTER TABLE `study1103`.`people` ADD COLUMN `age` INT AFTER `DATE`;
 
 *AFTER의 반대되는 개념인 BEFORE 키워드는 존재하지 않으며 가장 앞자리에 열을 추가하기 위해
 FIRST 키워드를 활용한다.
 
  ALTER TABLE `study1103`.`people` ADD COLUMN `age` INT FIRST;
  • 열 이름 변경하기
    • 존재하는 열의 이름을 변경하기 위해 아래 쿼리를 실행한다.
ALTER TABLE `스키마 이름`.`테이블 이름` RENAME COLUMN `기존 열 이름` TO `새로운 열 이름`;
  • 열 구조 수정하기
    • 존재하는 열의 구조를 수정하기 위해 아래 쿼리를 실행한다.
ALTER TABLE `스키마 이름`.`테이블 이름` MODIFY COLUMN [열 구조];

*열 구조 수정과 동시에 AFTER 및 FIRST 키워드를 사용해 위치 또한 옮길 수 있다. 
 + 기존 속성 값들을 바꾸지 않아도 명시해줘야 함.
 
 위치만 변경 (그래도 전체 정의 명시해야 함)
ALTER TABLE `study1103`.`people`
MODIFY COLUMN `birth_date` DATE NULL AFTER `gender`;
  • 열 삭제하기
    • 존재하는 열을 삭제하기 위해 아래 쿼리를 실행한다. 열을 삭제하면 이에 해당하는 로케드들이 가지고 있는 데이터가 삭제되고 되돌릴 수 없음으로 유의한다.
ALTER TABLE `스키마 이름`.`테이블 이름` DROP COLUMN [열 이름];

 

삭제하기

  • 테이블을 삭제하기 위해 아래 쿼리를 실행한다. 테이블을 삭제하면 이가 가지고 있는 레코드가 모두 삭제되고 되돌릴 수 없음으로 유의한다.
DROP TABLE `스키마 이름`.`테이블 이름`;

 

수정 예문

create table `study1104`.`countries`(
    `code_a2` varchar(5) not null,
    `code_a3` varchar(5) null,
    `name_en` varchar(100) null,
    `name_ko` varchar(100) null,
    `name_na` varchar(100) null,
    `population` int unsigned null,
    `gdp` int unsigned null,
    `updated_at` date null
);

alter table `study1104`.`countries`
    modify column `code_a2` varchar(2) not null,
    modify column `code_a3` varchar(3) not null,
    drop column `name_ko`,
    rename column `name_na` to  `name_native` ,
    modify column `population` bigint unsigned not null default 0,
    modify column  `gdp` double unsigned null,
    modify column  `updated_at` datetime null;
    
    
    -> 삭제랑 이름 변경만 할 때는 속성 안 적음
    
    RENAME COLUMN 과 MODIFY COLUMN 을 합쳐놓은게 CHACNGE COLUMN

 


  • 열(COLUMN)은 테이블에 존재하는 레코드가 가지는 데이터의 타입을 정하기 위해 사용한다.
  • 명명법: 소문자 스네이크 케 이스, 단수형
  • 열 구조는 아래와 같다.
`열 이름`[데이터 타입] [NULL] [NOT NULL]? -> 널 값을 허용할 거냐 안 할거냐
EX
`NAME` VACHAR(50)
  • NULL : 해당 열의 값이 비어있을 수 있다는 의미이다. 생략시 기본 값
  • NOT NULL : 해당 열의 값이 비어있을 수 없다는 의미이다.
  • DEFAULT x : 레코드 삽입시 해당 열의 값을 명시하지 않을 경우  사용할 기본 값을 x 로 설정한다. 생략시 x는  null이다.
  • AUTO_INCREMENT : 데이터 타입이 숫자인(인덱싱 되는) 열에 사용할 수 있고, 1부터 시작해 레코드가 삽입 될 때 마다 1씩 증가하기위해 사용한다. 단, 모종의 사유로 레코드 삽입이 실패하거단 레코드가 삭제되어도 테이블의 메타 데이터에서 카운팅되는 값을 기준으로 함으로, 이 값이 재정렬 되거나 감소하지는 않느다. 이에 해당값을 절대로 해당 테이블이 가지고 있는 레코드의 개수로 인식되어서는 안 된다.

 

데이터 타입

  • 모든 정수형과 DEMICAL 을 제외한 실수형 타입 뒤에 UNSIGNED 키워드를 붙여 음수부 크기 만큼 양수를 추가적으로 사용할 수 있다. 가령 TINYINT UNSIGNED 타입의 범위는 0 부터 255가지이다.

정수형

  • TINYINT : (1Byte) -127 -127 까지의 정수
 age TINYINT UNSIGNED,
  • SMALLINT : (2byte) -32,768 - 32,767 까지의 정수
  • MEDIEUMINT : (3byte) -8,388,608 - 8,388,607 까지의 정수
  • INT :(4bytes) -2,147,483,648 - 2,147,483,647 까지의 정수
  • BIGINT : (8bytes) -9,223,372,036,854,775,808 - 9,223,372,036,854,775,807 까지의 정수

실수형 

  • FLOAT : (4BYTES ) -3.402823466E + 38 부터 3.402823466E + 38 까지의 부동 소수. 값을 저장하는 방식 때문에 오류(오차)가 발생할 수 있어 유의해야 한다. ( 정수 길이에 따라 최대 소수점 7번째 자리까지 정확성 보장.)
  • DOUBLE :(8BYTES) -1.797693134862315157E + 308 부터 1.797693134862315157E + 308 까지의 부동 소수 . 값을 저장하는 방식 때문에 오류(오차)가 발생할 수 있어 유의해야 한다. ( 정수 길이에 따라 최대 소수점 15번째 자리까지 정확성 보장.)
  • DECIMAL(t,p) : (가변 용량,  t bytes) 전체 길이가 t 소수부 길이가 p인 고정 소수. 차지하는 용량이 큰 대신 값이 유실되지 않는다. 정수부와 소수부는 할당된 길이를 초과할 수 없고 남는 공간을 다른 부분에 빌려줄 수 없다.
⚠️ 주의할 점

FLOAT과 DOUBLE은 근사값(approximate value) 이라서, 정확한 소수 계산에는 부적합합니다. 예를 들어 금융(금액) 계산에는 오차가 날 수 있어요. 정확한 소수 연산이 필요한 경우 → DECIMAL 타입을 사용하세요.

price DECIMAL(10, 2) -- 총 10자리, 소수점 아래 2자리 (예: 12345678.90)

 

문자형

id int
writer varchar(50)
title varchar(1000)
content varchar(65000)

하나의 테이블이 가지는 열 구조 중에, 
데이터 타입이 인라인(in-row)인 데이터 타입의 길이의 합이 65,535를 초과할 수 없음.

위 내용 varchar = 66,050 > 65,535 // 테이블이 만들어지지 않음


“인라인 데이터”란 행 내부에 직접 저장되는 데이터 타입을 의미합니다.
→ 예: INT, VARCHAR, CHAR, TEXT, DATE 등 일부 데이터 타입.

 

  • VARCHAR(n) :(4n Bytes,n은 최대 65,535) 문자를 담기 위해 사용한다. 최대 n 개의 문자를 담을 수 있다.
  • VARCHAR의 저장 방식과 문자셋(Byte 크기)
    • VARCHCAR(1) - 1Byte ~ 4 Byte
    • 0~9 a-z(라틴) 일부 특수 문자(기본) : 1바이트
    • 일부 확장 라틴 (é, ü 등) : 2바이트
    • CJK 등 : 3바이트
    • 이모지 : 4바이트
  • TINYTEXT(n) :(4n Bytes,n은 최대 255) 문자를 담기 위해 사용한다. 최대 n 개의 문자를 담을 수 있다.
  • TEXT(n) :(4n Bytes,n은 최대 65,535) 문자를 담기 위해 사용한다. 최대 n 개의 문자를 담을 수 있다.
  • MEDIUMTEXT(n) :(4n Bytes,n은 최대 16,777,215) 문자를 담기 위해 사용한다. 최대 n 개의 문자를 담을 수 있다. 
  • LONGTEXT(n) :(4n Bytes,n은 최대 4,294,967,295) 문자를 담기 위해 사용한다. 최대 n 개의 문자를 담을 수 있다.

 

논리형

 

  • BOOLEAN : (1Byte) 참(true)과 거짓(false)을 가질 수 있다. 실제로는 TINYINT (1) 타입이고, 참은 1로 거짓은 0으로 처리한다.

날짜 및 시간

  • DATE : 날짜(년,월,일) 을 가질 수 있다.
  • TIME(n) : 시간(시,분,초)을 가질 수 있다. n은 마이크로초의 길이를 의미하며, 생략시 0이고 최대 길이는 6이다.
  • DATETIME(n) : 날짜와 시간을 가질 수 있다. n은 마이크로초의 길이를 의미하며, 생략이 0이고 최대 길이는 6이다.

기타( 첨부파일 )

  • TIMEBLOB(n) :( Bytes, n은 최대 255) 이진 데이터를 담기 위해 사용한다.
  • BLOB(n) : (Bytes, n은 최대 65,535) 이진 데이터를 담기 위해 사용한다.
  • MEDIUMBLOB(n) : ( Bytes, n은 최대 16,772,215) 이진 데이터를 담기 위해 사용한다.
  • LONGBLOL(n) : ( Bytes, n은 4,294,967,295) 이진 데이터를 담기 위해 사용한다.

'DATABASE > DBMS' 카테고리의 다른 글

231105 | DBMS -JOIN  (0) 2025.11.05
251104-251105 | DBMS ( 레코드 )  (0) 2025.11.04