관계형 데이터베이스를 사용하기 위해서 먼저 데이터베이스를 설치한다.
apt 혹은 apt-get 패키지 매니저를 사용해서 MySQL 데이터베이스를 간단하게 설치할 수 있다.
sudo apt update
sudo apt install mysql-server
이제부터 root user 라는 개념이 계속 나올 것이다.
root 사용자는 관계형 데이터베이스에서 master 사용자를 뜻한다.
관리자 사용자이므로 해당 데이터베이스 시스템의 모든 권한을 가지고 있다.
리눅스의 root 사용자와 동일한 개념이라고 생각하면 된다.
아래 명령어를 실행한다.
mysql_secure_installation
여기서부터 ㄹㅇ 중요하다.
설치 과정 중에 root 사용자의 비밀번호를 설정하라고 나오면 설정하도록 하는데 아마 그런 말은 안나올 것이고 필자의 경우는 현재 root 비밀번호를 입력하라고 해서 입력했더니
ERROR 1045 (28000): Access denied for user 'root'@'localhost'
위 에러만 계속 떴었다.
아래에서 원인을 해결해 보자.
현재 글을 쓰는 시점에서는 mysql 버전이 8.0.20 이다. 대부분 이 과정을 따라가야 할 것이다.
mysql -u root
명령어로 MySQL 데이터베이스에 접속한다.
위 명령어는 최고권리(root)를 가진 사용자(-u)로 mysql을 실행하라는 의미이다.
sudo mysql
과 같은 의미이다.
Are you root?
라는
- 위 사진처럼 MySQL에 접속했으면 다음 SQL 구문을 실행하여 어떤 인증 모드가 사용되고 있는지 확인한다.
SELECT user, plugin, host FROM mysql.user;
위 구문을 입력하면 user가 여러명 뜰텐데 root 사용자만 보면 된다.
아래 처럼 나오면 root 사용자는 auth_socket 인증 모드를 사용하고 있는 것이다.
+-----------+-----------------------+-----------+
| user | plugin | host |
+-----------+-----------------------+-----------+
| root | auth_socket | localhost |
+-----------+-----------------------+-----------+
- 다음 SQL 명령어를 사용하여 root 사용자의 비밀번호를 사용해서 인증 모드로 변경하도록 하자.
따옴표 안의 password 부분은 원하는 비밀번호를 사용하면 된다.
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_passwrod BY 'password';
대문자는 SQL 구문과 값을 구분하기 위해 사용한 것이므로 소문자로 써도 무방하다.
- 다음 SQL 구문을 실행하여 변경된 설정이 곧바로 반영되도록 하자.
FLUSH PRIVILEGES
- root 사용자의 인증 모드를 확인하여 변경사항이 잘 반영되었는지 확인하자.
SELECT user, authentication_string, plugin, host FROM mysql.user;
+-----------+-----------------------+-----------+
| user | plugin | host |
+-----------+-----------------------+-----------+
| root | mysql_native_password | localhost |
+-----------+-----------------------+-----------+
위와 같이 root 사용자의 plugin 칼럼 값이 mysql_native_password로 바뀌었다면
이제 root 사용자의 비밀번호를 사용하여 MySQL 데이터베이스에 접속할 수 있을 것이다.
mysql -u root
명령어를 쓰면 에러가 뜨고mysql -u root -p
이제부터 API에 MySQL 데이터베이스 시스템을 연결하여 데이터를 저장하도록 한다.
앞서 말한 것처럼 관계형 데이터베이스 시스템은 데이터를 저장하기 전에 미리 테이블 구조와 관계를 구현해 놓아야 한다.
그러므로 먼저 미니터 API를 위한 테이블 구조와 관계, 즉 스키마(schema)를 구현하도록 한다.
그 구조는 다음과 같다.
이제 다음 명령어를 통해 MySQL 데이터베이스에 접속한다.
mysql -u root -p
그리고 'miniter'라는 이름의 데이터베이스를 생성한다.
CREATE DATABASE miniter;
📌️ MySQL은 데이터베이스 시스템이다. 데이터베이스 시스템 안에는 여러 데이터베이스가 존재할 수 있다. 그리고 각 데이터베이스에는 여러 테이블이 존재하는 구조가 된다.
데이터베이스를 생성했다면 해당 데이터베이스를 사용하겠다고 use 명령어를 사용해서 MySQL 데이터베이스 시스템에 알려 줘야 한다.
알려주지 않으면 MySQL은 어떠한 데이터베이스를 선택해야 할지 모르므로 오류가 난다.
USE miniter
miniter 데이터베이스를 선택했으면 이제 miniter 데이터베이스에 테이블들을 생성하도록 하자.
SQL에서 테이블 생성은 CREATE TABLE 구문을 사용해서 생성할 수 있다.
CREATE TABLE 구문의 기본적인 문법은 아래와 같다.
CREATE TABLE users(
column 1 data_type,
column2 data_type,
...
PRIMARY KEY (column1),
CONSTRAIT 1,
CONSTRAIT 2
)
위에 있는 미니터 API 데이터베이스 스키마에 있는 테이블들을 생성하려면 다음의 CREATE TABLE 구문들을 사용하면 된다.
CREATE TABLE users(
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL,
hashed_password VARCHAR(255) NOT NULL,
profile VARCHAR(2000) NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY email (email)
);
CREATE TABLE users_follow_list(
user_id INT NOT NULL,
follow_user_id INT NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (user_id, follow_user_id),
CONSTRAINT users_follow_list_user_id_fkey FOREIGN KEY (user_id)
REFERENCES users(id),
CONSTRAINT users_follow_list_follow_user_id_fkey FOREIGN KEY (follow_user_id)
REFERENCES users(id)
);
CREATE TABLE tweets(
id INT NOT NULL AUTO_INCREMENT,
user_id INT NOT NULL,
tweet VARCHAR(300) NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id),
CONSTRAINT tweets_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id)
);
id INT NOT NULL AUTO_INCREMENT,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY email (email)
CONSTRAINT users_follow_list_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id),
테이블들을 생성했다면 마지막으로 SHOW TABLES 명령어로 테이블들이 생성되었는지 확인해 보자.
그리고 EXPLAIN table_name 명령어로 테이블들의 칼럼과 칼럼 타입 등을 확인할 수 있다.
올바르게 입력하고 생성했다면 터미널 창에서 다음과 같은 결과를 확인할 수 있다.
(api) ssm@asusumin ~/Projects/api mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 15
Server version: 8.0.20-0ubuntu0.20.04.1 (Ubuntu)
Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> CREATE DATABASE miniter;
Query OK, 1 row affected (0.01 sec)
mysql> USE miniter;
Database changed
mysql>
mysql> CREATE TABLE users(
-> id INT NOT NULL AUTO_INCREMENT,
-> name VARCHAR(255) NOT NULL,
-> email VARCHAR(255) NOT NULL,
-> hashed_password VARCHAR(255) NOT NULL,
-> profile VARCHAR(2000) NOT NULL,
-> created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
-> updated_at TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
-> PRIMARY KEY (id),
-> UNIQUE KEY email (email)
-> );
Query OK, 0 rows affected (0.02 sec)
mysql> CREATE TABLE users_follow_list(
-> user_id INT NOT NULL,
-> follow_user_id INT NOT NULL,
-> created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
-> PRIMARY KEY (user_id, follow_user_id),
-> CONSTRAINT users_follow_list_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id),
-> CONSTRAINT users_follow_list_follow_user_id_fkey FOREIGN KEY (follow_user_id) REFERENCES users(id)
-> );
Query OK, 0 rows affected (0.02 sec)
mysql> CREATE TABLE tweets(
-> id INT NOT NULL AUTO_INCREMENT,
-> user_id INT NOT NULL,
-> tweet VARCHAR(300) NOT NULL,
-> created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id),
-> CONSTRAINT tweets_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id)
-> );
Query OK, 0 rows affected (0.02 sec)
mysql> show tables;
+-------------------+
| Tables_in_miniter |
+-------------------+
| tweets |
| users |
| users_follow_list |
+-------------------+
3 rows in set (0.00 sec)
mysql> explain users;
+-----------------+---------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+---------------+------+-----+-------------------+-----------------------------+
| id | int | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | | NULL | |
| email | varchar(255) | NO | UNI | NULL | |
| hashed_password | varchar(255) | NO | | NULL | |
| profile | varchar(2000) | NO | | NULL | |
| created_at | timestamp | NO | | CURRENT_TIMESTAMP | DEFAULT_GENERATED |
| updated_at | timestamp | YES | | NULL | on update CURRENT_TIMESTAMP |
+-----------------+---------------+------+-----+-------------------+-----------------------------+
7 rows in set (0.00 sec)
mysql> explain users_follow_list;
+----------------+-----------+------+-----+-------------------+-------------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+-----------+------+-----+-------------------+-------------------+
| user_id | int | NO | PRI | NULL | |
| follow_user_id | int | NO | PRI | NULL | |
| created_at | timestamp | NO | | CURRENT_TIMESTAMP | DEFAULT_GENERATED |
+----------------+-----------+------+-----+-------------------+-------------------+
3 rows in set (0.00 sec)
mysql> explain tweets;
+------------+--------------+------+-----+-------------------+-------------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+-------------------+-------------------+
| id | int | NO | PRI | NULL | auto_increment |
| user_id | int | NO | MUL | NULL | |
| tweet | varchar(300) | NO | | NULL | |
| created_at | timestamp | NO | | CURRENT_TIMESTAMP | DEFAULT_GENERATED |
+------------+--------------+------+-----+-------------------+-------------------+
4 rows in set (0.00 sec)
mysql> exit
exit
명령어를 통해 MySQL 데이터베이스 시스템 접속을 종료할 수 있다.
이제 미니터 API에 데이터베이스를 연결시킬 것이다.