백엔드 심화 3-1 ~ 4-3(GUI로 데이터베이스, 디비 연동)

Develop Kim·2024년 9월 13일

programmers

목록 보기
15/40

3 데이터베이스 GUI

3-1 workbench 시작, select

1️⃣ MySql Workbrench

  • 처음 실행하게 되면 아래와 같은 화면이 뜬다

  • 시작에 앞서 docker가 켜져있는지 확인하는 것도 중요함(mysql은 docker위에 설치되어 있기 때문)

  • 여기서 커넥션을 새로 만들면(Database -> connect to database) 다음과 같은 창이 나온다

  • 실행을 하면 다음과 같은 화면이 나옴

  • 내가 만든 보드와 테이블들이 나옴

  • 내가 만든 테이블이 어떤 컬럼의 형태인지도 나옴

  • SELECT를 해보니 오류가 발생함 👉 보드를 더블클릭 후 만들어야 한다는 말

  • 실행을 해보니 테이블을 잘 확인할 수 있음

  • 여기서 테이블 칸을 더블클릭하면 바로 수정이 가능함! 수정이 너무 쉬워짐

2️⃣ 커넥션 메서드에 나오는 항목들은 아래와 같은 의미를 가짐

  • Standard (TCP/IP): 그냥 네트워크나 인터넷을 통해 서버에 연결하는 기본적인 방식임. 네트워크에서 많이 쓰이는 방식이라 딱히 복잡하지 않고, 서버 IP 주소와 포트 번호만 알면 쉽게 연결 가능함.
  • Local Socket/Pipe: 같은 컴퓨터 안에서 프로그램끼리 직접 통신할 때 쓰는 방식임. 네트워크가 필요 없고, 같은 시스템 안에서만 통신하니까 빠르고 간단함. 로컬 환경에서 테스트할 때나 서버와 클라이언트가 같은 컴퓨터에 있을 때 주로 쓰임.
  • Standard TCP/IP over SSH: 이건 TCP/IP 연결을 SSH라는 보안 프로토콜로 감싸서 암호화하는 방식임. 원격 서버에 접속할 때, 중간에 누군가 통신 내용을 볼 수 없게 암호화된 통로(터널)를 만들어서 보안 강화하는 거임. 서버 관리할 때 많이 쓰는 안전한 방법임.
  • LDAP User/Password: LDAP(경량 디렉터리 접근 프로토콜)은 주로 회사에서 직원 정보를 관리할 때 쓰는 시스템인데, 여기서 사용자 이름과 비밀번호로 인증하는 방식임. 쉽게 말해 회사의 로그인 시스템 같은 거라고 보면 됨.
  • LDAP Sasl/Kerberos: 이건 LDAP을 더 안전하게 만들어주는 방식임. SASL과 Kerberos라는 인증 방법을 써서 보안을 더 강화함. 회사나 조직에서 보안이 더 철저한 환경에서 LDAP을 쓸 때 주로 사용함.
  • Native Kerberos: Kerberos는 네트워크에서 안전하게 사용자 인증을 할 수 있게 해주는 시스템임. 특히 기업 환경에서 많이 쓰임. 이 옵션은 Kerberos를 직접 사용하는 방식이라, 보안이 중요한 환경에서는 이걸 쓰면 됨. 신원을 암호화해서 인증해주니까 해킹이나 스푸핑 방지에 좋음.



3-2 유튜브 users 테이블 생성

1️⃣ SQL 에디터의 폰트 크기를 바꿔보자

  • 설정에서 폰트를 바꾸면 됨

2️⃣ 스키마 만들기

  • 왼쪽 스키마 패드에서 우클릭 후 스키마 생성을 하면 다음과 같은 창이 나오고
  • 스키마 제목을 설정한 후 Apply로 스키마를 만들 수 있다.
  • 만들어진 스키마를 확인할 수 있다.

3️⃣ 테이블 만들기

  • 테이블은 스키마 안에 있는 테이블을 우클릭하면 바로 만들 수 있다.

  • 테이블 생성에 들어가면 컬럼을 만들 수 있다.
    데이터 타입도 바로 설정이 가능하며, 기능 설정은 선택하면 된다

    • PK : Primary Key(다른 테이블에서 사용할 고유 키)
    • NN : NOT NULL
    • UQ : Unique(중복 불가)
    • B : Binary
    • UN : Unsigned
    • ZF : ZeroFill
    • AI : Auto Increment(자동 생성)
    • G : Generated
    • Default/Expression(기본값)
  • 테이블 설정을 마치고 Apply를 하게되면 검토할 수 있는 창이 나온다.

    • ASC(어센딩)는 오름차순으로 커진다는 의미, 반대로 DSC는 내림차순



3-3 channels 테이블 생성, FK 오류

1️⃣ channels 테이블을 만들어 보자

  • id는 PK, NN, AI(자동 올림)로 설정해둔다

  • 구독자 수와 비디오 수는 NULL값으로 두는 것 보다는 기본을 0으로 둔다

  • FK의 경우는 아래 Foreign Keys에서 상세하게 설정을 해줄 수 있다.

  • Apply를 클릭하면 리뷰가 나오고

    • user_id로 제한 조건을 걸어두었으며,
    • 제한 조건은 FOREIGN KEY (user_id) 컬럼을 REFERENCES Youtube.users (id)과 엮어서 쓰겠다는 내용
    • ON DELETE NO ACTION // 삭제는 아무 액션이 없음
      ON UPDATE NO ACTION); // 수정도 아무 액션이 없음

2️⃣ 테이블 INSERT를 해보자

  • 테이블의 오른쪽 끝 버튼을 클릭하면 값을 하나씩 넣어줄 수 있음

  • Auto Increment로 인하여 아이디는 자동으로 하나씩 늘어나게 됨
    내가 중간에 아이디를 수정하게 되면 그 값대로 늘어나기 때문에 웬만하면 손대지 않고 AI에 맡기는 것이 좋음

  • 채널 테이블에서 없는 user_id를 넣게 되면 에러가 발생하기도 함
    FK에 데이터를 넣을 때는 주의하자




4 Express-데이터베이스 연동하기

4-1 디비 연동

1️⃣ 워크벤치로 만든 디비를 코드와 연동하기

2️⃣ 데이터베이스 연동을 확인해보자(에러 발생)

// Get the client
import mysql from 'mysql2/promise';

// Create the connection to database
const connection = await mysql.createConnection({
  host: 'localhost',
  user: 'root',
  database: 'test',
});

// A simple SELECT query
try {
  const [results, fields] = await connection.query(
    'SELECT * FROM `table` WHERE `name` = "Page" AND `age` > 45'
  );

  console.log(results); // results contains rows returned by server
  console.log(fields); // fields contains extra meta data about results, if available
} catch (err) {
  console.log(err);
}

// Using placeholders
try {
  const [results] = await connection.query(
    'SELECT * FROM `table` WHERE `name` = ? AND `age` > ?',
    ['Page', 45]
  );

  console.log(results);
} catch (err) {
  console.log(err);
}
  • 위 코드를 실행하니 에러가 발생한다.

    SyntaxError: Cannot use import statement outside a module

  • 에러가 발생하는 이유는 기본적으로 Node.js가 CommonJS 방식의 require 문법을 사용하는데, 여기서 import 문법을 사용하려고 했기 때문이다.

  • 따라서, package.json에 "type": "module"을 추가하거나, import 문법 대신 CommonJS 문법인 require를 사용하면 해결된다.

3️⃣ 정상 작동 확인

  • import 대신 require로 문법을 바꾸면 아래와 같이 코드를 바꿀 수 있고
// Get the client
const mysql = require('mysql2/promise');

// Create the connection to database
async function connectToDatabase() {
  const connection = await mysql.createConnection({
    host: 'localhost',
    user: 'root',
    password: 'root',
    database: 'Youtube', // 유튜브로 수정
  });

  // A simple SELECT query
  try {
    const [results, fields] = await connection.query(
      'SELECT * FROM `users`'
    );

    console.log(results); // results contains rows returned by server
    console.log(fields); // fields contains extra meta data about results, if available
  } catch (err) {
    console.log(err);
  }
}

connectToDatabase();
  • 실행하니 uers 테이블의 데이터를 결과값으로 가져온 것을 확인할 수 있다.



4-2 디비 결과 jason array 비구조화, users created_at 추가

1️⃣ DB에서 데이터를 꺼내써보자

  • 배열에서 json값을 꺼내 쓴다고 생각하면 쉽다. 콘솔로그로 원하는 값을 꺼내서 확인해보자
// Get the client
const mysql = require('mysql2/promise');

// Create the connection to database
async function connectToDatabase() {
  const connection = await mysql.createConnection({
    host: 'localhost',
    user: 'root',
    password: 'root',
    database: 'Youtube', // 데이터베이스 이름을 'Youtube'로 설정
  });

  // A simple SELECT query
  try {
    const [results, fields] = await connection.query( // await를 사용하여 쿼리 결과가 올 때까지 기다립니다. 쿼리의 결과는 results와 fields라는 두 가지 값으로 반환됩니다.
      'SELECT * FROM `users`' // results: 데이터베이스에서 가져온 행들의 배열, fields: 쿼리 결과에 대한 메타데이터
    );

    let arr = [1, 2, 3];
    console.log(arr[0]); // 1을 출력함, 원하는 것을 가져와서 출력할 수 있음
    
    console.log(results[0].id); // 첫번째 배열의 id를 출력함
    
    console.log(results); // 테이블에 저장된 데이터를 모두 가져와 출력
    console.log(fields); // 메타데이터를 가져와 출력하는 것을 확인

  } catch (err) {
    console.log(err);
  }
}

connectToDatabase(); //이 함수는 데이터베이스에 연결하고, 쿼리를 실행한 후 결과를 처리하는 비동기 함수입니다. connectToDatabase()를 호출하여 실제로 이 함수가 실행되도록 합니다.

2️⃣ 비구조화를 이용하면 더 빠르게 값을 가져올 수 있다

  try {
    const [results, fields] = await connection.query( 
      'SELECT * FROM `users`'
    );

    console.log(results[0].id); // 이렇게 가져오는 방식과
    console.log(results[0].email);
    console.log(results[0].name);
    
    let {id, email, name} = results[0] // 비구조화로 가져오는 방식의 반환이 같음
    console.log(id);
    console.log(email);
    console.log(name);


  } catch (err) {
    console.log(err);
  }
}

3️⃣ users테이블에 created_at 추가

  • 그렇다면 date에 대한 값도 잘 가져올 수 있는지 확인해 보기 위해 생성일자 컬럼을 추가해보자

  • users테이블 오른쪽 공구모양을 클릭하면 컬럼을 수정해줄 수 있다.

  • 생성일자 컬럼의 데이터타입은 TIMESTAMP로 하고 기본값을 NOW 또는 CURRENT_TIMESTAMP()를 적어주면 된다.

  • 잘 작동하는 것을 확인 할 수 있다.




4-3 timezone 설정

1️⃣ 지역별 시간대를 설정해보자

  • 시간을 출력하면 기본적으로 UTC기준(SEOUL -9hr)으로 출력되니 지역을 설정해보자
// Get the client
const mysql = require('mysql2/promise');

// Create the connection to database
async function connectToDatabase() {
  const connection = await mysql.createConnection({
    host: 'localhost',
    user: 'root',
    password: '1234',
    timezone: 'Asia/Seoul', // 시간대 지역을 서울로 설정
    database: 'Youtube', // 데이터베이스 이름을 'Youtube'로 설정
  });
  • 엥 안되네? ㅠㅠ

2️⃣ 데이터베이스에서 타임존을 설정해주자

  • 데이터베이스에서 설정해주기 위해 SET GLOBAL time_zone = 'Asia/Seoul'를 명령하고 확인해보면,,, 그래도 변하지 않은 걸 볼 수 있음

  • 그렇다면 콘솔로그에서는? 한국시간으로 잘 출력이 된다!

  • 데이터베이스의 세팅을 확인해보면 글로벌(전체영역)은 한국시간이지만 세션은 그대로인 것을 확인할 수 있었고

  • 세션에 대해서 시간대 적용을 해주니 곧바로 바뀐 것을 확인할 수 있다.

  • 근데 또 코드에서 timezone: 'Asia/Seoul'를 제거하고 실행하면 안된다... 이건 다음에 알아보자

3️⃣ 시간 뒤에 따라오는 소수점을 지우자

  • dateStrings: true를 추가해주면 된다.

  • 데이터베이스에 저장을 하게 되면 string으로 저장되지 않고 날 것의 데이터로 저장되기 때문에 형식을 변경해주어야 한다.




profile
김개발의 개발여정

0개의 댓글