KDT/TIL

10/14 TIL : MySQL ์ ์šฉ

ebulsok 2022. 10. 17. 13:48

๐Ÿ”Ž SQL(Structured Query Language)

  • ๊ด€๊ณ„ํ˜•, Relational DBMS(RDBMS)
  • ํ‚ค์™€ ๊ฐ’์˜ ๊ด€๊ณ„๋ฅผ ํ…Œ์ด๋ธ”ํ™” ์‹œํ‚จ ์›์น™์„ ํ† ๋Œ€๋กœ DB๋ฅผ ๊ตฌ์„ฑ
  • ์žฅ์ : ๊ตฌ์กฐํ™”๊ฐ€ ๋ช…ํ™•ํ•˜์—ฌ ์˜ˆ์™ธ๊ฐ€ ์—†์Œ, ๋ฐ์ดํ„ฐ ์ž…์ถœ๋ ฅ ์†๋„๊ฐ€ ๋งค์šฐ ๋น ๋ฆ„, ์‹ ๋ขฐ์„ฑ์ด ๋†’์Œ
  • ๋‹จ์ : DB ๊ตฌ์กฐ ๋ณ€๊ฒฝ์ด ๋งค์šฐ ์–ด๋ ต๊ธฐ ๋•Œ๋ฌธ์— ๋น…๋ฐ์ดํ„ฐ ๋“ฑ ์ƒˆ๋กœ์šด ํ‚ค๊ฐ€ ์ถ”๊ฐ€๋  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์—๋Š” ์‚ฌ์šฉ์ด ์–ด๋ ค์›€
  • ๊ตฌ๋ฌธ ์—ฐ์Šต: https://www.w3schools.com/sql/trysql.asp?filename=trysql_select_all 

 

๐Ÿšฉ DB์—์„œ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ

SELECT * FROM ์ด๋ฆ„;

SELECT * FROM Customers;

 

๐Ÿšฉ ์›ํ•˜๋Š” ์ปฌ๋Ÿผ์˜ ๊ฐ’๋งŒ ๊ฐ€์ ธ์˜ค๊ธฐ

SELECT ์ปฌ๋Ÿผ๋ช… FROM table;

SELECT City, Country FROM Customers;

 

๐Ÿšฉ DB์—๋Š” ์˜ํ–ฅ์—†์ด ์›ํ•˜๋Š” ๋ฐ์ดํ„ฐ ์ถ”๊ฐ€ํ•ด์„œ ๊ฐ€์ ธ์˜ค๊ธฐ

SELECT ์ปฌ๋Ÿผ๋ช…, ์›ํ•˜๋Š” ๋ฐ์ดํ„ฐ FROM table;

SELECT City, 1, 'test', NULL FROM Customers

 

๐Ÿšฉ ์›ํ•˜๋Š” ์กฐ๊ฑด์„ ์ถฉ์กฑํ•˜๋Š” Row๋งŒ ๊ฐ€์ ธ์˜ค๊ธฐ

SELECT * FROM table WHERE ์กฐ๊ฑด

SELECT * FROM OrderDetails WHERE Quantity>5;

 

๐Ÿšฉ Row๋ฅผ ์ •๋ ฌํ•ด์„œ ๊ฐ€์ ธ์˜ค๊ธฐ

ORDER BY

SELECT * FROM Customers ORDER BY ContactName;

SELECT * FROM Customers ORDER BY ContactName DESC;

SELECT * FROM Customers ORDER BY CustomerName ASC, ContactName DESC

 

๐Ÿšฉ Row์˜ ๊ฐœ์ˆ˜ ์ง€์ •ํ•˜๊ธฐ

LIMIT ์›ํ•˜๋Š” Row ์ˆœ๋ฒˆ, ์ž๋ฅด๋Š” ๊ฐœ์ˆ˜

SELECT * FROM Customers LIMIT 10;

SELECT * FROM Customers LIMIT 30 10;

 

๐Ÿšฉ Column ๋ช…์„ ๋ณ€๊ฒฝํ•ด์„œ ๊ฐ€์ ธ์˜ค๊ธฐ

AS

SELECT CustomerId AS id, CustomerName AS name FROM Customers;

 

๐Ÿšฉ ํ…Œ์ด๋ธ” ํ•ฉ์น˜๊ธฐ

JOIN ON

SELECT * FROM Products P JOIN Categories C ON P.CategoryID = P.CategoryID;

 

๐Ÿ”Ž Local์— mysql DB ๊ตฌ์ถ•ํ•˜๊ธฐ

  • [ํ„ฐ๋ฏธ๋„] mysql -u root -p
  • [ํ„ฐ๋ฏธ๋„] show databases;
  • [ํ„ฐ๋ฏธ๋„] use sakila;
  • [ํ„ฐ๋ฏธ๋„] show tables;

 

๐Ÿšฉ MySQL workbench

DB ์ƒ์„ฑ: create schema `MyDB` default character set utf8mb4 collate utf8mb4_general_ci;

TABLE ์ƒ์„ฑ: create table visitor ( id int primary key, counts int );

DATA ์‚ฝ์ž…ํ•˜๊ธฐinsert into visitor ( id, counts ) values ( 1, 0 );

DATA ์‚ญ์ œdelete from visitor where id = 2;

DATA ์ˆ˜์ •: update visitor set counts = counts + 1 where id = 1;

TABLE ์ˆ˜์ • ๋ฐ ์‚ญ์ œ

 

๐Ÿ”Ž DB ํ†ต์‹ ์šฉ ์„œ๋ฒ„ ๊ตฌ์ถ•ํ•˜๊ธฐ

  • ๋ฆฌ์•กํŠธ ํ”„๋กœ์ ํŠธ ์ตœ์ƒ๋‹จ์— data-server ํด๋” ๋งŒ๋“ค๊ธฐ
  • [ํ„ฐ๋ฏธ๋„] npm i express cors mysql

 

๐Ÿšฉ express ์„œ๋ฒ„ ์ฝ”๋“œ ์ž‘์„ฑ

// data-server/server.js
const express = require('express');
const cors = require('cors');
const PORT = 4000;

const app = express();

app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cors());

const dataRouter = require('./routes/data');
app.use('/data', dataRouter);

app.listen(PORT, () => {
  console.log(`๋ฐ์ดํ„ฐ ํ†ต์‹  ์„œ๋ฒ„๊ฐ€ ${PORT}์—์„œ ์ž‘๋™ ์ค‘`);
});

 

๐Ÿšฉ MySQL ์„œ๋ฒ„ ํ†ต์‹ ์šฉ ๋ชจ๋“ˆ ์ž‘์„ฑ

// data-server/dbConnect.js
const mysql = require('mysql');

const connection = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: ' ',
  port: '3306',
  database: 'MyDB',
});

connection.connect();

module.exports = connection;

 

๐Ÿšฉ DB ํ†ต์‹ ์šฉ ์ปจํŠธ๋กค๋Ÿฌ ์ž‘์„ฑ

// data-server/controllers/dataController.js
const connection = require('../dbConnect');

const db = {
  getCounts: (cb) => {
    connection.query('SELECT counts FROM MyDB.visitor;', (err, data) => {
      if (err) throw err;
      cb(data);
    });
  },
  incCounts: (cb) => {
    connection.query('UPDATE visitor SET counts = counts + 1 WHERE id = 1;', (err) => {
      if (err) throw err;
      cb(JSON.stringify('์—…๋ฐ์ดํŠธ ์„ฑ๊ณต'));
    });
  },
};

module.exports = db;

 

๐Ÿšฉ ์ฃผ์†Œ๋ณ„ routing ์ฒ˜๋ฆฌ

// data-server/routes/data.js
const express = require('express');
const router = express.Router();

const db = require('../controllers/dataController');

router.get('/count', (req, res) => {
  db.getCounts((data) => {
    res.send(data);
  });
});

router.post('/inccount', (req, res) => {
  db.incCounts((msg) => {
    res.send(msg);
  });
});

module.exports = router;

 

๐Ÿšฉ React ์•ฑ์—์„œ ๋ฐ์ดํ„ฐ ์š”์ฒญ

import { useDispatch } from 'react-redux';
import styled from 'styled-components';
import OrangeButton from './OrangeButton';
import { next } from '../store/modules/mbti';
import { useEffect, useState } from 'react';

export default function Start() {
  const [counts, setCounts] = useState(0);
  const dispatch = useDispatch();

  useEffect(() => {
    async function fetchData() {
      const resCount = await fetch('http://localhost:4000/data/count');
      if (resCount.status === 200) {
        const num = await resCount.json();
        if (num[0].counts !== 0) setCounts(num[0].counts);
      } else throw new Error('ํ†ต์‹  ์ด์ƒ');
    }
    fetchData();
  }, [counts]);

  return (
    <>
      <Header>๊ฐœ๋ฐœ์ž MBTI ์กฐ์‚ฌ</Header>
      <MainImg src="/images/main.jpg" alt="๋ฉ”์ธ ์ด๋ฏธ์ง€" />
      <SubHeader>
        ๊ฐœ๋ฐœ์ž๊ฐ€ ํ”ํžˆ ์ ‘ํ•˜๋Š” ์ƒํ™ฉ์— ๋”ฐ๋ผ์„œ MBTI๋ฅผ ์•Œ์•„๋ด…์‹œ๋‹ค! ์ง€๊ธˆ๊นŒ์ง€{'\n\n'}
        {counts} ๋ช…์ด ์ฐธ์—ฌํ•ด์ฃผ์…จ์Šต๋‹ˆ๋‹ค.
      </SubHeader>
      <OrangeButton text="ํ…Œ์ŠคํŠธ ์‹œ์ž‘" clickEvent={() => dispatch(next())} />
    </>
  );
}

const MainImg = styled.img`
  width: inherit;
`;

const Header = styled.p`
  font-size: 3em;
`;

const SubHeader = styled.p`
  font-size: 1.5em;
  color: #777;
`;

 

* ํ†ต์‹ ์—๋Ÿฌ ์‹œ ๋Œ€์ฒ˜

alter user 'root'@'localhost' identified with mysql_native_password BY ' ๋น„๋ฐ€๋ฒˆํ˜ธ ';

 

๐Ÿšฉ ๋งˆ์ง€๋ง‰ ํŽ˜์ด์ง€์—์„œ count + 1 ์š”์ฒญ

// src/components/Show.js
export default function Show() {
  const result = useSelector((state) => state.mbti.mbtiResult);
  const explanation = useSelector((state) => state.mbti.explanation[result]);
  const dispatch = useDispatch();

  const incCount = async () => {
    const resInc = await fetch('http://localhost:4000/data/inccount', {
      method: 'POST',
    });
    if (resInc.status === 200) console.log(await resInc.json());
    else throw new Error('ํ†ต์‹  ์ด์ƒ');
  };

  return (
    <>
      <Header>๋‹น์‹ ์˜ ๊ฐœ๋ฐœ์ž MBTI ๊ฒฐ๊ณผ๋Š”?</Header>
      <Explanation>{explanation.text}</Explanation>
      <Result>{result}</Result>
      <Additional>์ด๊ฑด ์žฌ๋ฏธ๋กœ ์ฝ์–ด ๋ณด์„ธ์š”!</Additional>
      <AdditionalImg src={explanation.img} alt="ํŒฉํญ" />
      <OrangeButton
        text="๋‹ค์‹œ ๊ฒ€์‚ฌํ•˜๊ธฐ"
        clickEvent={() => {
          incCount();
          dispatch(reset());
        }}
      />
    </>
  );
}