๐ป Today I Learned Database with MySQL
์ด๋ฒ ์คํ๋ฆฐํธ๋ Chatterbox Server
๊ฐ ์์์ ์ธ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง ์ ์๋๋ก ๋ง๋๋ ๊ฒ์ด๋ค. MySQL
์ ํตํด ๋์ ๋ก์ปฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ฐ์ดํฐ๋ค์ ์ ์ฅํ๊ณ , ์๋ฒ๊ฐ ์ฌ์์ํด๋ ์ ์ฅ๋ ๋ฐ์ดํฐ๊ฐ ์ง์์ง์ง ์๊ฒ ํด์ผํ๋ค.
๋จผ์ Chatterbox Server
์ ํ์ํ ์คํค๋ง๋ฅผ ๋์์ธํ๋ค. server/schema.sql
ํ์ผ์์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ
์ด๋ธ์ ๊ตฌ์กฐ๋ฅผ ์ ์ํ๊ณ MySQL
์๋ฒ์ ๋ก๋ํ CREATE TABLE
๋ฌธ์ ์์ฑํ๋ค. messages
ํ
์ด๋ธ ๊ตฌ์กฐ์๋ username
, text
, date
, roomname
์ด ํฌํจ๋๊ณ , users
ํ
์ด๋ธ ๊ตฌ์กฐ์๋ username
์ด ํฌํจ๋๊ฒ ์์ฑํ๋ค.
DROP DATABASE IF EXISTS chat; // ๋ง์ฝ ์ด๋ฏธ ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ์กด์ฌํ๋ฉด
CREATE DATABASE chat; // ์์ ๊ณ ์๋ก ๋ง๋ ๋ค
USE chat;
// messages ํ
์ด๋ธ
CREATE TABLE messages (
id int not NULL PRIMARY KEY AUTO_INCREMENT,
username varchar(255) not NULL,
text text(1024),
date timestamp not NULL DEFAULT CURRENT_TIMESTAMP,
roomname varchar(255) not NULL
);
// users ํ
์ด๋ธ
CREATE TABLE users (
id int not NULL PRIMARY KEY AUTO_INCREMENT,
username varchar(255) not NULL
);
์๋ ์ฌ์ง์ mysql -u root -p < server/schema.sql
์ ํตํด ๋ด MySQL server
์ ์์ฑํ schema.sql
์ ๋ก๋ํ๊ณ mysql
์์ ํด๋น ๋ด์ฉ์ ํ์ธํ ๋ชจ์ต์ด๋ค.
์, ์ด์ ์๋ฒ๋ฅผ ์์ฑํ๊ณ ์คํํด์ผ ํ๋ค. ๋จผ์ MySQL
๋น๋ฐ๋ฒํธ๋ฅผ ๋ณด์์/ํธ์์ ์ด์ ๋ก ํ๊ฒฝ ๋ณ์๋ก ๋ถ๋ฆฌํด๋์๋ค. ์๋ ํฐ๋ฏธ๋ ๋ช
๋ น์ ํตํด ํ๊ฒฝ ๋ณ์๋ฅผ ์ค์ ํ๊ณ node.js
์์์ process.env.DATABASE_SPRINT_PASSWORD
๋ผ๋ ๋ณ์์์ ์ค์ ํ ๊ฐ์ ์ ๊ทผํ ์ ์๊ฒ ํ๋ค.
$ export DATABASE_SPRINT_PASSWORD='my_value'
๊ทธ๋ฐ๋ฐ ์ด๋ ๊ฒ ํ๊ฒฝ ๋ณ์๋ฅผ ์ค์ ํ๋ฉด ์๋ก ๋ค๋ฅธ ํฐ๋ฏธ๋์์๋ ์ ๊ทผ์ด ์๋๋ ์ ์ด ๋ถํธํ๊ณ , dotenv๋ฅผ ์ฌ์ฉํ๋ฉด .env
ํ์ผ์ ํตํด ์ ๊ทผ ๊ฐ๋ฅํ๊ฒ ํ ์ ์๋ค๋ ๊ฒ์ ๋ฐฐ์ ๋ค.
๋ค์์ผ๋ก๋ ์ฃผ์ด์ง server/app.js
์์ express
ํ๋ ์์ํฌ๋ฅผ ํตํ node.js
์๋ฒ๋ฅผ ์คํ์ํค๊ณ , server/db/index.js
์์ mysql npm module
์ ์ฌ์ฉํ์ฌ ์คํ ์ค์ธ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์๋ฒ์ ์ฐ๊ฒฐํ๋ค.
var express = require('express');
// Middleware
var morgan = require('morgan');
var parser = require('body-parser');
// Router
var router = require('./routes.js');
var app = express();
module.exports.app = app;
// Set what we are listening on.
app.set('port', 3000);
// Logging and parsing
app.use(morgan('dev'));
app.use(parser.json());
// Set up our routes
app.use('/classes', router);
// Serve the client files
app.use(express.static(__dirname + '/../client'));
// If we are being run directly, run the server.
if (!module.parent) {
app.listen(app.get('port'));
console.log('Listening on', app.get('port'));
}
const mysql = require('mysql');
const password = process.env.DATABASE_SPRINT_PASSWORD;
const host = 'localhost';
// user๋ root, ํจ์ค์๋๋ ์ password ๋ณ์
// ์ค์ ๋ก ์ฐ๊ฒฐํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์์น(host)๋ host ๋ณ์
// ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ด๋ฆ(database)์ "chat"
// ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ์ ๋ง๋ค๊ณ , ์ฐ๊ฒฐ ๊ฐ์ฒด export
module.exports = mysql.createConnection({
host,
user: 'root',
password,
database: 'chat',
});
server/models/index.js
์์๋ ๋ฉ์์ง์ ์ฌ์ฉ์ ๋ชจ๋ธ์ ์ ์ํ๋ค. SQL query
๋ฌธ์ ์์ฑํ์ฌ ์ค์ง์ ์ธ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ๊ฐ์ ธ์ controller
์๊ฒ ๋๊ฒจ์ฃผ๋ ์ญํ ์ ๋ด๋นํ๋ค.
๋น๋๊ธฐ ํธ์ถ์ ๊ตฌํํ๊ธฐ ์ํด ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ๋๊ฒจ์ฃผ์๊ณ ์ฝ๋๋ w3schools.com์ Node.js MySQL์ ์ฐธ๊ณ ํ์ฌ ์์ฑํ๋ค.
// ์์์ ์์ฑํ db/index.js์์ ์ฐ๊ฒฐ ๊ฐ์ฒด๋ฅผ ๊ฐ์ ธ์ค๊ณ
var db = require('../db');
// ์ฐ๊ฒฐํ๋ค
db.connect((err) => {
if (err) throw err;
console.log('Connected!');
});
module.exports = {
messages: {
// a function which produces all the messages
get: function () {
return new Promise((resolve, reject) => {
db.query('SELECT * FROM messages', function (err, result) {
if (err) reject(err.message);
resolve(result);
});
});
},
// a function which can be used to insert a message into the database
post: function (data) {
return new Promise((resolve, reject) => {
const sql = 'INSERT INTO messages (username, text, roomname) VALUES ?';
const values = [data.username, data.text, data.roomname];
db.query(sql, [[values]], function (err) {
if (err) reject(err.message);
db.query('SELECT * FROM messages', function (err, result) {
if (err) reject(err.message);
resolve(result);
});
});
});
},
},
// users: {...} ์๋ต
};
server/controllers/index.js
๋ ์๋ฒ ๋ด์์ ํด๋ผ์ด์ธํธ์ ์์ฒญ์ ์๋ง๊ฒ ๋ชจ๋ธ ๊ฐ์ฒด ์์ ํจ์๋ฅผ ํธ์ถํ๊ณ , ๊ฒฐ๊ณผ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ์ญํ ์ ํ๋ค.
// ์์์ ์์ฑํ models/index.js์์ ๋ชจ๋ธ ๊ฐ์ฒด๋ฅผ ๊ฐ์ ธ์จ๋ค
var models = require('../models');
module.exports = {
messages: {
// a function which handles a get request for all messages
get: function (req, res) {
models.messages.get().then((result) => res.send(result));
},
// a function which handles posting a message to the database
post: function (req, res) {
models.messages
.post(req.body)
.then((result) => res.status(201).send(result));
},
},
// users: {...} ์๋ต
};
์ฃผ์ด์ง server/routes.js
๋ ์์ฒญ URL
์ ๋ฐ๋ผ ์๋ฒ ๋ผ์ฐํ
์ญํ ์ ํ๋ค. node.js
์น ์๋ฒ ์ฝ๋ app.js
์์ ์ด ํ์ผ์ require
ํ์ฌ ๋ผ์ฐํฐ๋ก ์ฌ์ฉํ๋ค.
var controller = require('./controllers');
var router = require('express').Router();
//Connect controller methods to their corresponding routes
router.get('/messages', controller.messages.get);
router.post('/messages', controller.messages.post);
router.get('/users', controller.users.get);
router.post('/users', controller.users.post);
module.exports = router;
ํด๋ผ์ด์ธํธ ์ฐ๊ฒฐ์ ๊ธฐ์กด์ ์งํํ๋ Chatterbox client sprint
์ reference
์ฝ๋๋ฅผ ๊ฐ์ ธ์๊ณ , ํ์ฌ ์คํ๋ฆฐํธ์ client
๋๋ ํ ๋ฆฌ๋ฅผ ๋ง๋ค์ด ๊ทธ ์์ ๋ด์๋ค. app.js
์์ server URI
๋ฅผ ๋์ ๋ก์ปฌ MySQL
์๋ฒ๋ก ๋ฐ๊ฟ์ฃผ๊ณ , fetch
ํ๋ ๋ถ๋ถ๊ณผ render
ํ๋ ๋ถ๋ถ๋ง ์ด์ง ์์ ํ๋ค. ๊ฒฐ๊ณผ ํ๋ฉด์ด๋ค.
์๋ฒ๋ฅผ ์คํ์ํค๊ณ , ํด๋ผ์ด์ธํธ ํ์ด์ง๋ฅผ ์๋ก๊ณ ์นจํ์ฌ ๋ฉ์์ง ํ๋๋ฅผ post
์์ฒญํ๋ฉด MySQL
๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅ๋์ด ๋ํ๋๋ ๋ชจ์ต์ด๋ค.
๋ํ, ์๋ฒ๋ฅผ ์ฌ์์ํ์ฌ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋จ์์๋ ๋ฐ์ดํฐ๋ฅผ ์์์ฑ ์๊ฒ ๊ฐ์ ธ์ฌ ์ ์๋ ๋ชจ์ต์ด๋ค.
์ด์ ๋ ํด๋ผ์ด์ธํธ์ HTTP
์์ฒญ์ผ๋ก ์ธํ ๋ฐ์ดํฐ๋ฅผ ์๋ฒ ์ปดํจํฐ์ in-memory
๋ node.js
์ fs
๋ชจ๋์ ํตํ ํ์ผ์ด ์๋๋ผ ์๋ฒ์ ์ฐ๊ฒฐ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅํ ์ ์๋ค. ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ํด ์ดํดํ๊ณ , ์ด๋ป๊ฒ ์ฌ์ฉํ๋์ง์ ๊ทธ ํ์์ฑ์ ์ธ์งํ๊ธด ํ์ง๋ง ์์ง ์คํ๋ฆฐํธ ์ฝ๋์ model
, view
, controller
์ ๋ํด์๋ ์ ๋ชจ๋ฅด๊ฒ ๋ค. ์ด์งธ์ ์ด๋ ๊ฒ ๋๋๋ ๊ฒ์ด๊ณ , ์ ํ์ํ ๊ฒ์ด๊ณ , ์ด๊ฒ์ ์ MVC
๋์์ธ ํจํด์ด๋ผ ๋ถ๋ฅด๋ ๊ฒ์ธ๊ฐ. ๋ค์ ์คํ๋ฆฐํธ์์ ๊ณต๋ถํ๊ฒ ๋ ๋ด์ฉ์ด๋ค. ๊ทธ๋์ ์ด๋ฌํ ํํ์ ์ฝ๋๋ฅผ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์คํ๋ฆฐํธ๋ฅผ ํตํด ๋จผ์ ์ ํ๊ฒ ํ ๊ฒ ๊ฐ๋ค.