[7장] MySQL

2022. 5. 7. 16:25책/Node.js 교과서

지금까진 모든 데이터를 변수에, 즉 컴퓨터 메모리에 저장해왔다. 이 말은 서버 종료시 메모리가 정리되면서 저장했던 데이터도 날아간다는 뜻이다. 이를 방지하기 위해선 데이터베이스를 사용해야 한다. 물론 이 책이 데이터베이스를 깊게 다루는 책은 아니므로 '적당히' 필요한 정도로만 알아보자.

1. 데이터베이스(DB)

컴퓨터 시스템에 전자적으로 저장되는 구조화된 정보 또는 데이터의 조직화된 모음. 이러한 데이터 베이스를 관리하는 시스템을 DBMS; DataBase Management System 라고 부른다.

보통 서버의 하드디스크나 SSD 등의 저장 매체에 데이터를 저장한다. DBMS 중에서 RDBMS라 부르는 관계형 DBMS가 많이 사용되는데, 대표적인 예로 Oracle, MySQL, MSSQL등이 있다. 이들 모두 SQL이란 언어를 사용하는데, 세부적으로 약간의 차이는 있는 편.

2. 데이터베이스 및 테이블 생성

2.1 DB 생성

mysql> CREATE SCHEMA `nodejs` DEFAULT CHARACTER SET utf8;
Query OK, 1 row affected, 1 warning (0.01 sec)

mysql> use nodejs;
Database changed

# CREATE SCHEMA : 스키마를 생성합니다

# `nodejs` : 스키마 이름. 백틱으로 감싸줘야함

# 세미콜론(;) : SQL 구문은 마지막에 세미콜론을 붙여야 실행됨
# 예약어 : CREATE SCHEMA 같이 MySQL이 기본적으로 알고 있는 구문. 보통 대문자로 작성한다(소문자를 쓴다고 안돌아가는건 아니지만)

 

2.2 테이블 생성

테이블이란 데이터가 들어갈 수 있는 틀을 말한다. 넣고싶은 데이터가 있다면 테이블을 만들어줘야 하며, 당연히 만들어준 테이블의 형식에 맞는 데이터만 들어갈 수 있다. 아래처럼 생긴 테이블을 만들어보자.

 

# CREATE TABLE [DB명.테이블명] : 지정한 DB 안에 테이블을 생성한다

# DROP TABLE [테이블명] : 테이블을 제거

# 콤마( , ) : 컬럼 구분자

 

1) users 테이블 만들기

id name age marred comment created_at
1 aaaa 20 false    
2 bbbb 24 true    
3 cccc 28 ture    
4 dddd 31 false    
mysql> CREATE TABLE nodejs.users(
    -> id INT NOT NULL AUTO_INCREMENT,
    -> name VARCHAR(20) NOT NULL,
    -> age INT UNSIGNED NOT NULL,
    -> married TINYINT NOT NULL,
    -> comment TEXT NULL,
    -> created_at DATETIME NOT NULL DEFAULT now(),
    -> PRIMARY KEY(id),
    -> UNIQUE INDEX name_UNIQUE (name ASC))
    -> COMMENT = '사용자 정보'
    -> DEFAULT CHARACTER SET = utf8
    -> ENGINE = InnoDB;
    
    
테이블의 생김새와 정보가 궁금하다면?

mysql> DESC users;
+------------+--------------+------+-----+-------------------+-------------------+
| Field      | Type         | Null | Key | Default           | Extra             |
+------------+--------------+------+-----+-------------------+-------------------+
| id         | int          | NO   | PRI | NULL              | auto_increment    |
| name       | varchar(20)  | NO   | UNI | NULL              |                   |
| age        | int unsigned | NO   |     | NULL              |                   |
| married    | tinyint      | NO   |     | NULL              |                   |
| comment    | text         | YES  |     | NULL              |                   |
| created_at | datetime     | NO   |     | CURRENT_TIMESTAMP | DEFAULT_GENERATED |
+------------+--------------+------+-----+-------------------+-------------------+
6 rows in set (0.02 sec)

mysql> SHOW TABLES;
+------------------+
| Tables_in_nodejs |
+------------------+
| users            |
+------------------+
1 row in set (0.00 sec)

2) comments 테이블 만들기

mysql> CREATE TABLE nodejs.comments(
    -> id INT NOT NULL AUTO_INCREMENT,
    -> commenter INT NOT NULL,
    -> comment VARCHAR(100) NOT NULL,
    -> created_at DATETIME NOT NULL DEFAULT now(),
    -> PRIMARY KEY(id),
    -> INDEX commenter_idx (commenter ASC),
    -> CONSTRAINT commenter
    -> FOREIGN KEY (commenter)
    -> REFERENCES nodejs.users (id)
    -> ON DELETE CASCADE
    -> ON UPDATE CASCADE)
    -> COMMENT = '댓글'
    -> DEFAULT CHARSET=utf8mb4
    -> ENGINE=InnoDB;
    
    
mysql> SHOW TABLES;
+------------------+
| Tables_in_nodejs |
+------------------+
| comments         |
| users            |
+------------------+
2 rows in set (0.00 sec)


mysql> DESC comments;
+------------+--------------+------+-----+-------------------+-------------------+
| Field      | Type         | Null | Key | Default           | Extra             |
+------------+--------------+------+-----+-------------------+-------------------+
| id         | int          | NO   | PRI | NULL              | auto_increment    |
| commenter  | int          | NO   | MUL | NULL              |                   |
| comment    | varchar(100) | NO   |     | NULL              |                   |
| created_at | datetime     | NO   |     | CURRENT_TIMESTAMP | DEFAULT_GENERATED |
+------------+--------------+------+-----+-------------------+-------------------+
4 rows in set (0.00 sec)

 

3) 자료형 및 옵션

더보기

 

1) 자료형

INT 정수. 소수도 필요하면 FLOAT나 DOUBLE 자료형 사용하면 된다
VARCHAR( n ) 길이가 0~n인 가변문자열
CHAR( n ) 길이가 n인 고정길이 문자열
TEXT 수백 자 이상의 긴 글을 저장
TINYINT -128 ~ 127까지의 정수
BOOLEAN 1 or 0
DATETIME 날짜와 시간에 대한 정보를 담고 있다. 날짜만 필요하면 DATE, 시간만 필요하면 TIME 자료형

 

2) 컬럼 옵션

NULL / NOT NULL 빈 칸 허용 여부
AUTO_INCREMENT 숫자를 자동으로 +1씩 추가함
UNSIGNED 음수 사용 금지. FLOAT, DOUBLE 자료형엔 적용 불가하며 '나이', '점수'같은 컬럼에 써먹기 좋음
ZEROFILL 숫자의 자리수가 고정돼있는 경우에만 사용 가능한데, 비어있는 자리를 0으로 채운다는 뜻
EX) INT(4) 인데 숫자 1을 넣었다면 0001로 저장
CURRENT_TIMESTAMP
= now( ) 
현재 시간을 저장
PRIMARY KEY ROW(레코드)를 식별자로써, 각 행을 구별하는 용도로 써먹기 가장 좋은 컬럼을 기본키로 지정한다. 기본키는 데이터베이스가 별도로 컬럼을 관리하므로 조회 시 속도가 빨라진다.
UNIQUE INDEX 해당 값이 고유해야 하는지에 대한 옵션. 
FOREIGN KEY 다른 테이블의 기본 키를 저장하는 컬럼.
CONSTRAINT [제약조건명] FOREIGN KEY [컬럼명] REFERENCES [참고하는 컬럼명] 으로 지정한다.

...
-> CONSTRAINT commenter
-> FOREIGN KEY (commenter)
-> REFERENCES nodejs.users (id)

 

3) 테이블 옵션 

COMMNET 테이블에 대한 보충 설명을 달아준다. 필수는 아님.
DEFAULT CHARACTER SET 한글 허용을 위한 utf8
ENGINE Storage Engine을 뜻하며, 물리적 저장장치에서 데이터를 어떤 식으로 구성하고 읽어올지를 결정하는 역할을 한다. 

너무 자세한 얘기는 이 책의 범위를 벗어나므로 MyISAM, InnoDB, Archive가 제일 많이 사용된다는 것만 알고가자

 

3. CRUD 작업

3.1 Create(생성)

DB와 Table을 다 만들었으니 실제로 데이터를 생성해서 집어넣어보자.

 

# INSERT INTO [테이블명] ( [컬럼1], [컬럼2], ... ) VALUES ( [값1], [값2], ... );

#nodejs.users 테이블
INSERT INTO nodejs.users (name, age, married, comment) VALUES ('zero', 24, 0, '자기소개 1');
INSERT INTO nodejs.users (name, age, married, comment) VALUES ('nero', 32, 1, '자시소개 2');

#nodejs.comments 테이블
INSERT INTO nodejs.comments (commenter, comment) VALUES (1, '안녕하세요. zero의 댓글입니다');

 

3.2 Read(조회)

1) 기본

# SELECT * FROM nodejs.users;

# SELECT [컬럼1], [컬럼2] FROM [테이블명];

더보기
mysql> SELECT * FROM nodejs.users;
+----+------+-----+---------+------------+---------------------+
| id | name | age | married | comment    | created_at          |
+----+------+-----+---------+------------+---------------------+
|  1 | zero |  24 |       0 | 자기소개 1 | 2022-05-07 22:28:15 |
|  2 | nero |  32 |       1 | 자시소개 2 | 2022-05-07 22:29:16 |
+----+------+-----+---------+------------+---------------------+
2 rows in set (0.12 sec)

mysql> SELECT name, age FROM nodejs.users;
+------+-----+
| name | age |
+------+-----+
| zero |  24 |
| nero |  32 |
+------+-----+
2 rows in set (0.00 sec)

 

2) 조건문(WHERE, AND, OR)

# SELECT name, age FROM nodejs.users WHERE married = 1 AND age > 30;

# SELECT id, age FROM nodejs.users WHERE married = 0 OR age > 30;

더보기
mysql> SELECT name, age FROM nodejs.users WHERE married = 1 AND age > 30;
+------+-----+
| name | age |
+------+-----+
| nero |  32 |
+------+-----+
1 row in set (0.00 sec)

mysql> SELECT id, age FROM nodejs.users WHERE married = 0 OR age > 30;
+----+-----+
| id | age |
+----+-----+
|  1 |  24 |
|  2 |  32 |
+----+-----+
2 rows in set (0.00 sec)

 

# 정렬 : ORDER BY [컬럼명] [ASC | DESC]

# ROW 개수 : LIMIT [숫자]

# ROW 건너뛰기 : OFFSET [건너뛸 숫자]

더보기
mysql> SELECT * FROM nodejs.users ORDER BY age DESC;
+----+------+-----+---------+------------+---------------------+
| id | name | age | married | comment    | created_at          |
+----+------+-----+---------+------------+---------------------+
|  2 | nero |  32 |       1 | 자시소개 2 | 2022-05-07 22:29:16 |
|  1 | zero |  24 |       0 | 자기소개 1 | 2022-05-07 22:28:15 |
+----+------+-----+---------+------------+---------------------+
2 rows in set (0.00 sec)


mysql> SELECT id, name FROM nodejs.users LIMIT 1;
+----+------+
| id | name |
+----+------+
|  2 | nero |
+----+------+
1 row in set (0.04 sec)


# OFFSET이 20이라고 치면
# ROW를 1~20개, 21~40개 가져오는 방식
# 페이지 구현할 때 좋음!
mysql> SELECT id, name FROM nodejs.users ORDER BY age DESC LIMIT 1 OFFSET 1;
+----+------+
| id | name |
+----+------+
|  1 | zero |
+----+------+
1 row in set (0.00 sec)

 

3.3 Update(수정)

# UPDATE [테이블명] SET [컬럼명 = 바꿀내용] WHERE [조건]

더보기
mysql> UPDATE nodejs.users SET comment = '수정내용' WHERE id = 2;

 

3.4 Delete(삭제)

# DELETE FROM [테이블명] WHERE [조건]

더보기
mysql > DELETE FROM nodejs.users WHERE id = 2;

 

' > Node.js 교과서' 카테고리의 다른 글

[7장] MySQL/ORM 관계설정  (0) 2022.05.22
[7장] MySQL/ORM  (0) 2022.05.08
[6장] Express / Router  (0) 2022.05.07
[6장] Express/multer  (0) 2022.05.06
[6장] Express  (0) 2022.05.05