<프로그래머스 데브코스 풀스택> 2026-01-12 TIL Docker / MariaDB / SQL 기초

데이터베이스(Database; DB)란?

: 데이터를 통합하여 효율적으로 관리하기 위한 데이터 집합체

데이터를 구조화하여 관리함으로써 데이터 중복을 막고, 효율적이고 빠른 데이터 연산을 가능하게 함

 

DBMS(DataBase Managemant System) 

: 데이터베이스를 운영하고 관리

 

종류 : 운영 회사는 다르지만, 데이터베이스에 연산을 요청하기 위해 사용되는 명령어는 동일

 ex) Oracle, MySQL, MariaDB(MySQL의 모체)

 

-> 공통적으로 사용

SQL  (Structured Query Language)

: 데이터베이스에 연산을 요청하기 위해 사용되는 언어로 데이터를 생성, 조회, 수정, 삭제 등과 같은 기능 수행할 수 있음

- INSERT / SELECT / UPDATE / DELETE 

 

 

Docker

Host Operating System = OS 운영체제 (프로그램 돌릴 수 있는 운동장)
모든 시스템(App) 설치할 때에는 OS와 소통을하면서 설치함  -> 모두 자신에게 필요한 환경이 있고, 구축해야함

App을 직접적으로 설치하는 것이 아니라, Docker를 한겹 깔고 설치 

Docker는 컨테이너를 마련해두고, App을 설치할때 컨테이너를 건내줌

우리는 그 컨테이너에서 App을 꺼내서 사용

-> 편리, 무겁지 않게 관리가능 

 

Docker로 MariaDB 설치하기

docker pull mariadb

 

도커 컨테이너 생성

docker run —-name mariadb -d -p 3306:3306 —-restart=always -e MYSQL_ROOT_PASSWORD=root mariadb

--name mariadb : 컨테이너 이름을 'mariadb'로 설정

-d : 백그라운드 실행

-p : 로컬 3306 -> 컨테이너 3306 포트 연결

--restart = always : Docker 재시작 시 자동 실행

-e MYSQL_ROOT_PASSWORD=root : MariaDB root 비밀번호 설정 

 

 👿 Error response from daemon: {"message" : "No such container: mariadb"} 오류
강사님이 올려주신 텍스트 파일을 그대로 활용한 거였는데 오류가 떠서 당황했다...
결론은 -- 가 -으로 잘못 복사돼서 일어난 일이었다. docker run --name이 docker run -name 이렇게! 

 

( Docker desktop 프로그램 실행 상태에서 )

 

1️⃣ mariadb가 있는 컨테이너 접속

docker exec  -it mariadb /bin/bash

mariadb : 컨테이너 중 하나 -> 이 안에 설치관련 구축되어있음

 

2️⃣ mariadb 실행

/* 사용 XX 이전 버전 */
mysql -u root -p

/* 지금 사용 */
mariadb -u root -p

 mysql의 user이름은 root로 접속하고 password는~

 

👿 bash: mysql: command not found 오류 
아니 뭐지?????? mysql가 설치가 안된건가? 뭐 그런게 있나? 이러고 고민하다가 갑자기 스친 슬랙 메시지 하나. 
다른 분이 미리 강의를 수강하고 올려놓으시나 걸 볼 수 있었다

 

너무너무 멋있었암.. 나도 이틀이나 빨리 듣는건데 일주일도 전에 미리 들으시고 이렇게 공유해주신게 .. 그리고 미리 알고계셨던 것같아서 존경심이 들고 멋있었다.. 자 이제 이 자극 가지고 공부다시 가보즈아 

https://hanke-r.tistory.com/entry/MariaDB-%EC%A0%91%EC%86%8D-%EB%AA%85%EB%A0%B9%EC%96%B4-%EB%B3%80%EA%B2%BD-mysql-command-not-found#google_vignette 

 

MariaDB 접속 명령어 변경 (mysql: command not found)

기존에 mariadb 접속할 때, mysql -uroot -p 를 사용해서 접속했었는데, 이번에 설치를 하다보니 mysql: command not found 라는 명령어가 나온다.. 뭔가 설치중 오류인 것으로 판단하고 삭제 후 재설치해도 똑

hanke-r.tistory.com

실행된거 참 싱기.. 

 

SQL

데이터를 저장할 방 만들기

여러가지 사이트를 운영하더라도 , 하나의 데이터베이스에서 방을 나누어 관리할 수 있다. 

 

데이터베이스 확인

SHOW DATABASES;

데이터베이스(Tennis) 만들기

CREATE DATABASE Tennis;

데이터베이스 들어가기

USE Tennis;

 

none : 아직 아무것도 만들어지지 않았다!

 

 

테이블 틀 만들기

CREATE TABLE member(
	id VARCHAR(30),
    name VARCHAR(30),
    pwd VARCHAR(30)
);

 

테이블 데이터 조회

SELECT 컬럼명 FROM 테이블명;

💡 전체 컬럼 조회 시 ` * `(a star; 아 스타) 사용

 

테이블 데이터 삽입 

INSERT INTO 테이블명 (컬럼명1, 컬럼명2, ...) VALUES(컬럼1 데이터, 컬럼2 데이터, ...);
INSERT INTO 테이블명 VALUES (값1, 값2, 값3, ...);

 

특정 데이터 조회

SELECT 컬럼명 FROM 테이블명 WHERE 조건;

 

테이블 데이터 수정

UPDATE 테이블명 SET 컬럼명 = 수정할 값 WHERE 조건;

❗️조건 넣는 거 신경쓰기 : 안넣으면 해당하는 모든 값이 바뀌니까

테이블 데이터 삭제

DELETE FROM 테이블명 WHERE 조건;

❗️조건 넣는 거 신경쓰기 : 안넣으면 해당하는 모든 값이 사라짐!

 

Node.js와 데이터베이스 연동

우선 테이블을 만들어놓고 시작하자!

TennisMarket 

product 테이블

id name description price
1 Red Racket Hot Red! 300000
Blue Racket Cool Blue! 350000
3 Black Racket Chic Black! 500000

 

node.js에서 연동해보기

 

1️⃣ MySQL 설치 

npm install mysql --save

npm : node.js의 명령어 중 하나! 

=> .json 파일, node_modules 등 각종 필요한 파일이 자동으로 다운로드 됨

 

2️⃣ databse > connect > mariadb.js 파일 생성

 

 

[mariadb.js]

1) 우선 모듈을 불러오자.

const mariadb = require('mysql');

모듈은 바꿀 생각이 없으니 const

 

2) 통로를 뚫자.

const conn = mariadb.createConnection(
    {
        host: 'localhost',
        port: '3306', /* docker 초기 설정때 디폴트로 설정함 */
        user: 'root',
        password: 'root',
        database: 'Tennis'
    }
);

3) 모듈로 사용하기 위해 내보내기

module.exports = conn;
🤔 음? 다른 파일에서는 exports.AAA = AAA; 이런 식이었는데 왜 conn만 이런 식이지? 
(exports.start = start; exports.route = route;) == (module.exports.start = start; module.exports.route = route;)
이 친구들의 'module' 이 생략된것 ,
start, route는 여러가지를 내보내지만, conn은 객체 하나만을 export 함!

 

[index.js]

const mariadb = require('./databse/connect/mariadb');
mariadb.connect(); /*연결 완료!*/

 

[requestHandler.js]

    /*main 불러질 때 안에*/
    mariadb.query("SELECT * FROM product", function(err,rows){
        console.log(rows);
    });

Query 던질 수 있고,

err(에러메시지), rows(출력값) 받아들임 => console에 rows 출력!

 

실행하면?

와!! 연결됐다!!!!!!!!!!!! 🥰

 

화면 가져오기 : fs(file sink)

const fs = require('fs');
const main_view = fs.readFileSync('./main.html', 'utf-8');

이렇게만 하면

화면에 이미지가 뜨지않고, console에 pathname으로 사진 경로가 뜸 (url값으로 인식하고 출력하는 것임!)

function redRacket(response){
    fs.readFile('./img/redRacket.png', function(err,data){
        response.writeHead(200, {'Content-Type' : 'text/html'});
        response.write(data);
        response.end();
    })
}

handle['/img/redRacket.png'] = redRacket;

하나씩 손수 가져와줘야함.

HTML을 직접 열었을 때에는 -> 브라우저가 혼자 모든 파일을 열었지만,

Node서버로 열때에는 -> 정의된 경로에 있는 것만 가져오게 되어있음 

🤨.. 이 말이 이해가 안됐다.. 왜 이렇게까지 비효율적으로 사진을 하나하나 들고와야하는가..
⭕️ 기존에는 브라우저가 스스로 파일시스템을 판단할 수 있었는데,
❌ 서버를 킨 뒤로는 [브라우저 ←── HTTP 요청 ──→ Node 서버] 형태가 돼서 브라우저는 요청만 해야하는 것!

 

여기에서 원래 html에서 열면 적용됐던 css가 되지 않았던 이유도 이때문이라고 생각해서

function mainCSS(response) {
    fs.readFile('./main.css', function(err, data) {
        response.writeHead(200, {'Content-Type': 'text/css'});
        response.write(data);
        response.end();
    });
}

handle['/main.css'] = mainCSS;

 직접 이 코드를 추가했더니 바로 적용이 됐다!! 정말 모든 파일을 일일이 가져와야되는구나.. 

 

insert 연동해보자

우선 orderlist 만들자

현재 구동 형태 : url을 넣으면 requestHandler.js가 해당하는 것을 실행해줌

=> 요청을 url로 해줘야겠구만!

 

[requestHandler.js]

function order(response, productId){
        response.writeHead(200, {'Content-Type': 'text/css'});
        
        mariadb.query("INSERT INTO orderlist VALUES (" + productId + ", '"+ new Date().toLocaleDateString() +"');",function(err,rows){
        console.log(rows);
        });
        response.write('order page');
        response.end();
}

우선 누가 어떻게 'productId'를 주는 건지는 모르겠지만, 누군가 주겠지~하며 얘부터 고치고, 

애한테 productId를 주는 파일을 하나하나 따라가면서 추가

 

requestHandler Handle에 router.js가 전달해줌 : route 매개변수에 productId추가

start에서 router에 넘겨주는거니까 server의 start함수 수정

 

[server.js]

let http = require('http');
let url = require('url');

function start(route, handle) {
    function onRequest(request, response){
        let pathname = url.parse(request.url).pathname;
        let queryData = url.parse(request.url, true).query;

        route(pathname, handle, response, queryData.productId);
    }
    http.createServer(onRequest).listen(8888);
}

exports.start = start;

let queryData = url.parse(request.url, true).query; 중요!

 

[main.html]

           <div class ="card">
                <img class="card_img" src="./img/redRacket.png">
                <p class="card_title"> Red Racket </p>
                <input class="card_button" type="button" value="order" onclick="location.href='/order?productId=1'">
            </div>

버튼의 Onclick url 전달값으로 수정

값이 잘들어감!!