[데이터베이스] 관계형 데이터베이스 - Learn SQL Part.3

윤후·2022년 3월 7일
0

Section 3

목록 보기
22/41

Sprint 풀이


유어클래스에 있는 내용을 중심으로 문제를 풀어보자.

첫 번째로 해야할 일

sprint를 받아보면 폴더내에 .env.exmple 이라는 파일이 있다. 이 파일을 살펴보면 DARABASE에 관한 USERNAME, PASSWORD, NAME이 있는 것을 볼 수 있다.

const dotenv = require('dotenv');
const mysql = require('mysql');

dotenv.config();

class SingletonBase {
  static instance;
  constructor() {
    if (!SingletonBase.instance) {
      SingletonBase.instance = this;
    } else {
      console.log('    already has instance.');
      console.log('    return existing instance.');
    }

    return SingletonBase.instance;
  }
}

module.exports = class DatabaseConnector extends SingletonBase {
  constructor() {
    super();
    this.config = {
      host: 'localhost',
      user: process.env.DATABASE_USERNAME || 'root',
      password: process.env.DATABASE_PASSWORD || '',
      database: process.env.DATABASE_NAME || 'learnmysql'
    };

    return this;
  }

  init() {
    this.connection = mysql.createConnection({
      ...this.config,
      multipleStatements: true
    });

    return new Promise((resolve, reject) => {
      this.connection.connect((err) => {
        if (err) {
          reject(err.message);
        }
        resolve('ok');
      });
    });
  }

  terminate() {
    if (!this.connection || this.connection.state === 'disconnected') {
      console.log('        cannot terminate connection of disconnected state.');
      return;
    }
    return new Promise((resolve, reject) => {
      this.connection.end((err) => {
        if (err) {
          reject(err.message);
        }

        // delete conneciton object
        delete this.connection;
        resolve('ok');
      });
    });
  }

  query(sql) {
    return new Promise((resolve) => {
      this.connection.query(sql, function (error, results) {
        if (error) throw error;

        resolve(results);
      });
    });
  }
};

앞서 환경변수의 설정을 위해 dotenv 모듈을 사용한다고 했던 적이 있다. lib/common/mysql의 경로로 들어가보면 dotenv 모듈과 mysql모듈이 require되어 있는 것을 볼 수 있다. 간단하게 말해서 이 파일에서 환경변수를 확인하고 MySQL의 learnmysql이라는 데이터베이스에 접속할 수 있는 셋팅이 되는 것이다.

.env파일은 이러한 환경변수를 저장하기 위한 파일이다. .evn.exmple을해당 빈칸에 사용자 접근을 위해 USERNAME, PASSWORD, NAME을 설정해주고, 해당 파일을 .env으로 바꿔준다.

두 번째로 해야할 일

.env 파일의 셋팅을 완료했다면 learnmysql이라는 데이터베이스를 만들어야 한다.MySQL에 들어가기 위해서 터미널에 아래와 같은 명령어를 실행한다.

mysql -u root -p

위의 명령어를 실행하면 터미널에서 MySQL에 접근할 수 있게 된다. u는 user를 나타내며 root라는 user의 MySQL로 들어간다고 생각하면 되겠다. -p는 Password를 입력하면 되며,위의 명령어를 실행하면 자동적으로 비밀번호를 입력하는 입력창이 뜰 것이다.

비밀번호를 입력하면 MySQL안으로 들어오게 된다. 현재 root인 user가 가지고 있는 Database가 무엇이 있는지 살펴보자.

SHOW DATABASES;

Database를 보기 위해서는 SHOW라는 명령어를 사용하지만, 여러개의 Database가 있으니 복수형인 SHOW Databases로 써주어야 함.

이전에 만들어 두었던 Database들이 있는 것을 볼 수 있다. 미리 만들어 두었던 learnmysql이 있기 때문에 삭제하고 다시한번 만들어보자.

DROP DATABASE learnmysql;

위의 명령어를 실행하면 learnmysql이라는 데이터베이스가 삭제된걸 볼 수 있다. 이제 다시 한번 learnmysql을 생성해보자.

CREATE DATABASE learnmysql;

위의 명령어로 다시 learnmysql이라는 데이터베이스를 만들 수 있다.

세 번째로 해야할 일

learnmysql이라는 데이터베이스를 만들었으므로, 해당 데이터베이스에 어떤 테이블이 들어갈지 만들어주어야 한다. 그렇다면 이전에 배웠던 schema를 활용하면 되겠다.

schema는 위와 같은 관계로, user의 id와 content의 userId가 연결되어 있는 것을 볼 수 있다. user와 content는 1:N의 관계로 있는데 이는 Primary Key와 Foreign key로 연결될 수 있겠다.

두 관계중 content는 N이라는 여러개의 정보가 엮여 있기 때문에 user의 Foreign key를 참조하고 있는 것이다.

이제, migrations/schema.sql로 들어가 해당 코드를 봐보자.

CREATE TABLE `user` (
  `id` int PRIMARY KEY AUTO_INCREMENT,
  `name` varchar(255) not NULL,
  `email` varchar(255) not NULL
);

CREATE TABLE `content` (
  `id` int PRIMARY KEY AUTO_INCREMENT,
  `title`varchar(255),
  `body`varchar(255),
  `created_at` timestamp not NULL DEFAULT CURRENT_TIMESTAMP,
  `userId` int,
  FOREIGN KEY (`userId`) REFERENCES `user` (`id`)
);

schema에서 봤던 관계대로 테이블을 만드려고 한다. .sql파일로 되어 있으니 테이블을 생성하기 위해 CREATE TABLE을 사용하는 것을 볼 수 있겠다.

CREATE TABLE user

user라는 테이블에는 id, name, email이 들어간다. 여기서 id는 user가 가지고 있는 고유한 값, 즉 Primary Key가 되겠다. 이는 테이블이 추가 되면 자동으로 추가되어야 하기 때문에 아래와 같은 명령어로 id 값이 자동 생성될 수 있도록 한다.

`id` int PRIMARY KEY AUTO_INCREMENT

user의 name과 email은 문자열로 저장이 될 것이기 때문에 varchar(255)로 지정해둔 것이다.

 `name` varchar(255) not NULL,
 `email` varchar(255) not NULL

자, 이제 content의 테이블을 봐보자. user와 비슷하게 고윳갑인 Primary Key가 존재하는 것을 볼 수 있다. 위의 user의 Primary Key와 같이 int로 정수형을 선언하고 테이블의 값이 추가되면 자동으로 추가될 수 있도록 아래와 같은 코드를 써준다.

`id` int PRIMARY KEY AUTO_INCREMENT

content의 title과 body는 문자열로 저장이 될 것이기 때문에 varchar(255)로 지정해 둔다.

  `title`varchar(255),
  `body`varchar(255),

content의 데이터의 생성일을 알기 위한 created_at을 timestamp로 선언을 한다. timestamp는 현재의 시간, 일, 월, 년도의 표시를 알려주기 위한 방법의 선언이다.

`created_at` timestamp not NULL DEFAULT CURRENT_TIMESTAMP

참조
TIMESTAMP

위에서 user와 content의 관계는 1:N이라고 하였고, user의 Foreign Key는 content 테이블에서 가지고 있어야 한다. 해당 값을 설정해주기 위하여 아래와 같은 명령어로 userid를 설정해준다.

`userId` int,
  FOREIGN KEY (`userId`) REFERENCES `user` (`id`)

네 번째로 해야할 일

schema.sql 파일에 user와 content 테이블을 만들었다. 그럼 이제 데이터베이스를 선택해보고, 테이블이 어떻게 들어가 있는지 확인해보자.

use learnmysql;

위의 명령어를 사용하면 내가 지정한 database를 사용하게 되는 것이다.

database가 changed되었다고 알려주고 있다.
해당 데이터베이스에 어떤 테이블이 있는지 알아보기 위해 아래의 코드를 써보자.

SHOW TABLES;


위와 같이 learnmysql이라는 데이터베이스에는 content와 user라는 테이블이 만들어져 있는 것을 볼 수 있다.

그렇다면, 여기서 user테이블의 아래와 같은 구조를 보기 위해 어떤 명령어를 사용해야 할까?

## user 테이블

| Field | Type    | Null | Key | Default | Extra          |
| ----- | ------- | ---- | --- | ------- | -------------- |
| id    | int     | No   | PK  | null    | auto_increment |
| name  | varchar | No   |     | null    |                |
| email | varchar | No   |     | null    |                |

이전에 배웠던 SELECT를 사용하면 될까?

SELECT * FROM USER

위와 같은 명령어를 사용하면 Empty set이라는 결과가 출력된다. 이는 생각해보면 당연한 것이, 해당 테이블에 대한 값을 보여주게끔 하는 명령어이기 때문이다.

아래와 같은 명령어로 user의 테이블이 어떻게 만들어져 있는지 확인할 수 있겠다.

DESC user;


마찬가지로 content의 테이블이 어떻게 만들어져 있는지 확인해보자.

DESC content;

profile
궁금한걸 찾아보고 공부해 정리해두는 블로그입니다.

0개의 댓글

관련 채용 정보