데이터 베이스

데이터를 저장하는 구조/자료의 모음

데이터의 집합소

중복이 없어야 한다.

 

데이터 베이스 이전에는 파일시스템(ex 엑셀)을 사용했다.

이러한 파일시스템을 사용하다가 데이터베이스로 변경된 이유는 무엇일까?

> 데이터의 중복 문제

> 데이터의 불일치(개개인의 업데이트가 다름)

 

DBMS

DataBase Managemant System

파일 시스템이 가진 문제를 해결하기 위해 만들어진 것

데이터베이스에 접근하고 이를 관리하기 위해 존재한다

 

관계형 데이터베이스 > RDBMS

 

우리는 My SQL을 사용한다.

오라클이 My SQL을 오라클이 인수하면서 유료화가 됐고,

유료화에 불만을 가진 사람들이 나와서 무료로 만든것이 mariaDB를 만들었다.

 

용어

열(Column, Attribute, 속성)

행(Record, Tuple, 튜플)

테이블(Table, Relation)

key : 데이터베이스에서 튜플을 착거나 순서대로 정렬할 때 구분하고 정렬의 기준이 되는 속성

기본키(Primary Key) : 특정 튜플을 유일하게 구별할 수 있는 속성/ Null값과 중복이 불가능하다.

외래키(Foreign Key) : 기본키를 참조하는 속성

 

 

MySQL

가장 널리 사용되고 있는 관계형 데이터베이스 관리 시스템 ( RDBMS )
오픈 소스
윈도우, Mac, 리눅스 다양한 운영체제에서 사용 가능

 

설치 과정

mysql을 구글에 검색한 후 다운로드로 가서 아래에 있는 위를 클리한다.

여기서 MySQL Community Server를 클리하여 들어간다.

최신 버전 아래의 버전을 다운받는다 안전하게

go to 다운로드 페이지로 넘어가면 두가지가 있다

위에 있는 것은 웹이랑 연결해서 설치 파일을 다운로드 하는 것이고, 아래는 설치파일까지 함께 다운로드 받아 인터넷 연결이 없는 상황에서도 설치가 가능하다.

노땡스를 누르고 설치를 진행한다. 그 후 설치파일 실행하면 된다.

 

구조분해할당

배열이나 객체의 속성을 해체해 그 값을 개별 변수에 담는 것

- 배열 구조 분해

- 객체 구조 분해

 

배열 구조 분해

const[변수] = 배열;

//배열 구조 분해
        let lists = ['apple','grape'];
        //기존 방식
        console.log(lists[0],lists[1]);
        //구조 분해
        [item1, item2] = lists;
        console.log(item1, item2);
        //교환 많이 사용하는 편은 아니다.
        let x = 1, y = 2;
        [x, y] = [y, x];
        console.log(x, y);

const로 배열을 선언했을때 배열 자체는 바꿀 수 없지만 내부 원소의 값은 수정이 가능하다.

 

객체란?

{} 안에 키 : 값을 넣어서 선언하는 것

        //객체
        const Person = {
            //key:value
            name: 'dj',
            age: 222,
            gender: 'm',
            friends: ['alex','json'],
            hello : function(){
                console.log('hello');
            },
            'j-1':'Korea'
        };
        //객체 호출 방법과 수정 방법
        console.log(Person.name);
        Person.age = 234;
        console.log(Person.age);
        console.log(Person.friends[0]);
        console.log(Person['name']);
        console.log(Person['j-1']);//문자열 형태로 객체 내에서 선언된 키를 불러올 때 사용한다.
        Person.city = 'Seoul';//city 키 추가
        console.log(Person);

객체 구조 분해

//예시
        const Persons = [{},{},{}];

        //객체 구조 분해
        const {name, city, gender, key1 = 'Hi'} = Person;
        console.log(name, city, gender, key1);

연산자

...

spread 연산자

// spread 사용
const spread = [...b, ...a];

console.log(con);
console.log(spread);

//객체도 가능
const person = {
    name : "dj",
    age : 28,
}

console.log({...person});
const c = 'Hello';
console.log({...c});

간단히 생각하면 ...을 사용해서 해당 선언된 변수나 객체를 쪼개준다고 생각하면 된다.

마지막의 console.log(...c)로 하면 어떻게 될까?

원래 중괄호 안에서 분해되던 Hello가 나뉘어져서 하나씩 출려된다. 여기서 주의할 점은 객체에 spread 연산자를 쓸때는 중괄호를 무조건 붙여줘야한다.

 

rest 연산자

호출할때 지정을 해준 것을 제외한 나머지를 배열로 출력해준다.

function get(z,q,...rest){
    console.log(z);
    console.log(q);
    console.log(rest);
}
get(10,20,30,40,50);

순서로 지정해준 z와 q에는 각각 10과 20이 순서대로 들어가고 나머지인 30 40 50을 배열로 출력해준다.

 

spread vs rest

• spread 파라미터는 호출하는 함수의 파라미터에 사용

• rest 파라미터는 호출받는 함수의 파라미터에 사용. 호출하는 함수 의 파라미터 순서에 맟춰 값 설정 후 남은 파라미터 값을 배열로 설정


클래스

클래스 안에서는 function과 키워드를 쓸 수 없다

그리고 생성자가 있는데 생성자는 

new 연산자를 통해 객체를 생성할 때 반드시 호출이 되고 제일 먼저 실행되는 일종의 메서드라고 생각하면 편하다.(메서드와 비슷하지 그 의미가 같은 것은 아니다) 생성자는 멤버 변수를 초기화하는 역할을 한다.

js에서는 많이 사용하는 편은 아니다 함수나 객체를 더 많이 사용한다.

 



body-parser

postman

포스트맨에 들어가서 가입 후 나의 작업공간에서 주소 입력해서 정보를 주고 받을 수 있다. >> 더 찾아서 공부해보자

 

일단 사용 순서를 간단히 정리해보자

const express = require('express');
const app = express();
const PORT = 8080;

app.use(express.urlencoded({extended:true}));
app.use(express.json()); // 위 포함 두줄이 body parser이다. 이를 통해서 post 정보를 전송할때 요청의 req.body로 받을 수 있게 해준다.

app.get('/',(req,res) => {
    res.send('Hello');
});

app.post('/',(req,res) => {
    console.log(req.body);
});

app.listen(PORT, ()=>{
    console.log(`http://http://localhost:${PORT}`);
});

이렇게 해서 서버를 키고

포스트맨에서 앞은 post로 바꾸고 body에서 json 파일 형식으로 어떤 내용을 보내면 서버에서 정보를 받을 수 있다.

이러한 과정을 확인할 수 있도록 도움을 주는 것이 포스트맨이다.

대략적으로 말하면 포스트맨으로 프론트엔드에서 정보를 보내는 상황을 만들 수 있다.

 

form 전송

입력된 데이터를 한 번에 서버로 전송하기 위해 사용 

폼 자체적으로 정보를 전송하는 것은 아니다.

클라이언트가 서버에게 정보를 보낼 때 사용한다.

• 속성 : action, name, target, method

• 폼 요소 : <input>, <select>, <textarea>, <button> 등등

 

보내는 방식은 get 방식과 post 방식이 있다 둘의 차이는 다음과 같다

회원가입시에 get 방식을 하면 개인정보가 url에 모두 표시가 되기 때문에 회원가입 같은 경우는 post 방식을 사용해야한다.

쿼리는 url 창에 있는 정보를 가져오는 것이고 바디는 서버의 내용(?)을 가져오는 방식이다 (다시 찾아보고 정리할때 제대로 작성해야겠다.)


form validation (유효성 검사)

정보가 올바르게 입력됐는지 검사하는 것이다.

ex) 비밀번호: 8자리 이상, 특수문자 및 대문자 1개 이상 포함

ex) 이메일: @ 기호 반드시 포함

입력 정보가 바로 데이터베이스에 들어가기 때문에 유효성 검사는 상당히 중요하다.

 

• required : 필수 값

• minlength / maxlength : 최소/최대 문자수

• min / max : 최소/최대 값

• type : 입력받는 정보 타입

• pattern : 정규식으로 검사

 

정규식이란?

정규 표현식 - JavaScript | MDN (mozilla.org)

 

정규 표현식 - JavaScript | MDN

정규 표현식, 또는 정규식은 문자열에서 특정 문자 조합을 찾기 위한 패턴입니다. JavaScript에서는 정규 표현식도 객체로서, RegExp의 exec()와 test() 메서드를 사용할 수 있습니다. String의 match(), matchA

developer.mozilla.org

사용 예시는 위와 같다 외워서 사용하기는 힘들기 때문에 찾아보고 사용하면서 개인적으로 익혀보자

 

nodemon

코드가 바뀔때 마다 자동으로 node를 재실행 해주는 역할이다.

[오늘 할 일]

html css 정리 블로깅

오늘 진도 복습(조퇴 때문에 못들은 부분 받아서 익히기) : 못한 form 실습 해보기

자취방 짐 정리

운동 1시간 이상

7월달은 약속이나 일정이 많아서 추가적인 공부를 할 시간이 좀 부족하다.. 8월달은 그 시간을 확보하고 바로 포트폴리오도 준비하면서 공부할 것이다. 일단은 피그마도 연습해보고, 포트폴리오 틀 잡아서 내용 채운 다음에 사이트로도 제작해 보고자 한다. 내일 자취방 이사도 있어서 시간이 많을지는 모르겠지만 그래도 해봐야지 허허

 

비동기 처리(동시에 처리하는 것)

seTimeout(코드,delay) 를 사용하여 처리할 수 있다.

특정 코드의 연산이 끝날때까지 코드의 실행을 멈추지 않고 다음코드를 먼저 실행하는 자바스크립트의 특성이다.

 

pay가 먼저 실행되기 때문에 전역변수안에 값이 들어가지 않는다.

 

콜백 함수

자바스크립트는 함수를 인자로 받고 다른 함수를 통해 반환될 수 있는데, 인자로 대입되는 함수를 콜백함수라고 한다.

즉, 다른 함수가 실행된 후에 실해되는 함수이다.

함수를 선언할때는 파라미터로 함수를 받아서 쓸 수 있다.

이를 사용하는 이유는 비동기 방식으로 작성된 함수를 동기 처리하기 위해 사용된다.

콜백 지옥

비동기 프로그래밍 시 발생하는 문제이다. 콜백함수가 반복될수록 단계가 깊어지기 때문에 코드의 가독성이 떨어지고, 코드 수정 난이도가 엄청나게 커질수가 있다.

이러한 문제를 해결하기 위해 나온것이 promise 객체이다


promise 객체

비동기 함수를 동기 처리하기 위해 만들어진 객체

성공과 실패를 분리하여 반환

비동기 작업이 완료된 이후에 다음작업을 연결시켜 진행할 수 있는 기능을 가짐

 

• Pending(대기) : Promise를 수행 중인 상태

• Fulfilled(이행) : Promise가 Resolve 된 상태 (성공)

• Rejected(거부) : Promise가 지켜지지 못한 상태. Reject 된 상태 (실패)

• Settled : fulfilled 혹은 rejected로 결론이 난 상태

 

위와 같은 상태를 가진다.

 

Promise는 두가지 콜백 함수를 가진다.

resolve(value) : 작업이 성공한 경우 그 결과를 value와 함께 호출 > then 메소드 활용

reject(error) : 에러 발생 시 에러 객체를 나타내는 error와 함께 호출 > catch 메소드 활용

finally > 성공 실패와 상관없이 호출

then, catch를 사용하면 결과값만 가져온다.

 

Promise 체이닝

then으로 연결하기 때문에 콜백 지옥에 빠지지 않을 수 있고, 순차적으로 작업을 할 수 있다.

예외 처리도 마지막에 catch로 지정할 수 있어서 편하다.

//체이닝을 사용 안 한 경우
//(4+3)*2-1

function add(n1, n2, callback){
    setTimeout(function(){
        let result = n1 + n2;
        callback(result);
    },1000);
}

function mul(n, callback){
    setTimeout(function(){
        let result = n *2;
        callback(result);
    },700);
}

function sub(n, callback){
    setTimeout(function(){
        let result = n -1;
        callback(result);
    },500);
}

//add
add(4, 3, function(x){
    console.log("1 : ", x)
    mul(x, function(y){
        console.log("2 :", y);
        sub(y, function(z){
            console.log("3 :", z);
        })
    })
})

 

//Promise 체이닝
//장점 : tnen 메서드를 연속해서 쓸 수 있다. > 순차적인 작업이 가능하다.
//예외처리도 마지막에 catch로 지정하면 되기 때문에 간편하다.

function add(n1, n2){
    return new Promise(function(resolve,reject){
        setTimeout(function(result) {
            result = n1 + n2;
            resolve(result);
            // callback(result);
        },1000);
    });

}

function mul(n){
    return new Promise(function(resolve,reject){
        setTimeout(function(result) {
            result = n *2;
            resolve(result);
            // callback(result);
        },700);        
    });

}

function sub(n){
    return new Promise(function(resolve,reject){
        setTimeout(function(result) {
            result = n -1;
            // resolve(result);
            // callback(result);
            reject(new Error("에러처리"));// 에러 객체 만들어서 에러 처리하기
            // PS C:\Users\82103\Documents\KDT-8-Web\230729_비동기처리> node 230729_promise.js
            // 1 :  7
            // 2 :  14
            // Error: 에러처리
            //     at Timeout._onTimeout (C:\Users\82103\Documents\KDT-8-Web\230729_비동기처리\230729_promise.js:140:20)
            //     at listOnTimeout (node:internal/timers:569:17)
            //     at process.processTimers (node:internal/timers:512:7)
        },500);        
    });

}

//add
add(4, 3).then(function(result){
    console.log("1 : ", result);
    //then을 연속적으로 쓸려면 여기서 값을 반환해줘야한다.
    return mul(result);    
}).then(function(result){
    console.log("2 : ", result);
    //then을 연속적으로 쓸려면 여기서 값을 반환해줘야한다.
    return sub(result);    
}).then(function(result){
    console.log("3 : ", result);    
}).catch(function(err){
    console.log(err);
});

두 코드를 비교해보면 체이닝을 한 것이 가독성도 높고 예외 처리 다루기가 훨씬 쉽다. (사실 체이닝 안할때의 예외 처리는 솔직히 잘 모른다..)


async/await

프로미스 기반 코드를 좀 더 쓰기 쉽고, 읽기 쉽게 하기 위해 등장했다.

• async

• 함수 앞에 붙여 Promise를 반환한다.

• 프로미스가 아닌 값을 반환해도 프로미스로 감싸서 반환한다.

• await

• ‘기다리다’ 라는 뜻을 가진 영단어

• 프로미스 앞에 붙여 프로미스가 다 처리될 때까지 기다리는 역할을 하며 결과는 그 후에 반환한다.

 

//async와 await은 항상 같이 사용한다.

let product;
let price;
exec();

function goMart(){
    console.log("마트에 와서 어떤 음료를 마실까");
}

function pickDrink() {
    return new Promise(function(resolve, reject){
        setTimeout(function(){
            console.log("고민 끝!!");
            product = "사이다";
            price = 2000;
            let mymoney = 2000;
            if(price <= mymoney){
                resolve();
            }else{
                reject("돈이 부족해요");
            }
        }, 3000);
    })
}

function pay(){
    console.log(`상품명 : ${product}, 가격 : ${price}`);
}

이 상태에서 아래와 같이 사용한다.

async function exec() {
    goMart(); // 먼저 실행 1번
    await pickDrink(); // 2번
    pay();// 3번 pay가 pickDrink의 실행이 끝날때까지 기다려야 함으로 pickDrink 앞에 await을 붙여준다.

}

 

http는 사실 거의 사용하지 않는다. > 가독성과 확장성이 떨어지기 때문이다.

express가 노드js의 거의 90%정도를 차지한다.

 

Express

설치를 위해서는 

npm init -y

npm install express

를 입력해 설치한 후에

 

.gitignore 파일을 만들어서 /node_modules를 하여 용량이 큰 모듈 파일이 깃으로 올라가지 못하게 막는다.

 

.gitignore?

• Git 버전 관리에서 제외할 파일 목록을 지정하는 파일

• Git 관리에서 특정 파일을 제외하기 위해서는 git에 올리기 전에 .gitignore에 파일 목록을 미리 추가해야 한다.

 

*.txt → 확장자가 txt로 끝나는 파일 모두 무시

!test.txt → test.txt는 무시되지 않음.

test/ → test 폴더 내부의 모든 파일을 무시 ( b.exe와 a.exe 모두 무시 )

/test → (현재 폴더) 내에 존재하는 폴더 내부의 모든 파일 무시 ( b.exe무시 )

 

보통 모듈 이름을 변수로 지정하는 것이 관례이다.

 

express를 불러오는 방법에는 두가지가 있다

1. const express = require("express");

2. import express from "express";

2번째 방법이 최신 버전이기 때문에 두 가지 방법을 다 사용하되 최신 버전을 더 많이 사용해보자

 

app.get("/",(req, res) => {

})

순서가 request와 responce를 결정한다. 즉 어떤 변수를 넣어도 처음이 req 다음이 res이다.

 

백엔드를 보통 포트 8000번대에서 다루기(?) 때문에 8000번대를 많이 사용한다.

 

const express = require("express");

const app = express();
const PORT = 8080

app.get("/",(req, res) => {
    res.send("Hello express");
})

app.listen(PORT,() => {
    console.log(`http://localhost:${PORT}`);
})

//import express from "express";는 최신 버전
console.log(express);

실행시키려면 터미널 창에서 node index.js를 입력하면 된다.

 

get

get 방식으로 열리는 도메인이며 get의 "/"에 쓴 이름이 포트 뒤에 이름으로 간다.

만약에 "/app"을 적으면 http://localhost:8080/app이 주소가 된다.

 

app.get("/",(req, res) => {
    // res.send("Hello express");
    res.send({result: true, code : 1000, mesage : "회원가입 성공!" });
})

get 안에 객체로도 만들 수 있다. 그리고 객체 안에 객체를 또 넣을 수 있다.

listen

서버를 열어주는 역할을 한다. 

console.log는 터미널 창에서 뜨고 윈도우에서 뜨지 않는다.

 

Node.js가 어려운 이유

모듈을 하나하나씩 늘려가면서 정말 많아지기 때문에 번거롭고 어렵다 느껴지는 것이다.

npm에서 검색해서 필요한 모듈을 찾고 사용할 수 있다.

 

MIT 라이선스가 무료로 사용 가능하다.

 


그리고 계속 add 할때 오류가 나서 찾아봤는데

https://cocoon1787.tistory.com/728

 

[Git] "LF will be replaced by CRLF in..." 에러 해결 방법

warning: LF will be replaced by CRLF in app.js. The file will have its original line endings in your working directory The file will have its original line endings in your working directory 🚀 git add를 할 때 위와 같은 에러들이 자주 발생

cocoon1787.tistory.com

이유가 이 때문이었다. 이에 대한 해결 방법은 터미널에 git config --globa core.autocrlf true를 쓰면 해결된다.

 


템플릿 엔진

뷰를 보여주기 위한것 실무에서는 많이 사용하지 않는다. 노드 js 자체적으로 웹을 보여주기 위해 사용하는 것이기 때문에 회사 내부적으로 테스트용 웹페이지를 확인하기 위해 사용하는 정도라 많이 사용하지 않는다. 리액트를 들어가게 된다면 거의 사용하지 않을 것이다.

 

EJS 템플릿

• 템플릿 엔진 : 문법과 설정에 따라 파일을 html 형식으로 변환시키는 모듈

• ejs

• Embedded Javascript 의 약자로, 자바스크립트가 내장되어 있는 html 파일

• 확장자는 .ejs

 

<%

%> 

위와 같은 방식으로 쓰고 한줄에 하나씩 사용한다.

값만 표현할 때는  <% =I %> 이와같이 사용한다.

 

npm install ejs로 설치

 

app.set view 엔진을 불러올때 사용

app.use 미들웨어 서버가 처음부터 끝까지 코드가 있을때 중간에 실행 시키는 놈

 

res.render(이름,데이터)// 데이터도 보낼 수 있다.

 

그리고 이상태에서 컨트롤+c를 누르면 서버가 꺼지는 거라서 누르지 않고 실행을 해야 들어갈 수 있다.

 

미들웨어

• 요청이 들어옴에 따라 응답까지의 중간 과정을 함수로 분리한 것

• 서버와 클라이언트를 이어주는 중간 작업

• use() 를 이용해 등록할 수 있다.

 

이론 수업이 끝난 후에 기존에 우리가 했던 실습을 Node.js를 이용해서 ejs로 바꾸는 실습을 진행했다. 그래서 7월7일에 만들었던 애벌레 실습을 옮기는데 이미지를 불러오는 과정에서 어려움을 겪었다..그래서 이를 정리해서 올린다.

app.use(express.static("public"));// 앞에 아무것도 없으면 바로 연결되는 것이기 때문에 바로 이미지로 들어갈 수 있다.
app.use("/static",express.static("public"));// 앞에서 사용하는 /static은 웹 페이지에서 사용할 가상 경로를 설정해주는것이다.
app.use("/static",express.static(path.join(__dirname,"public")));
// __dirnamedms public을 문자열로 가지고 오고 path.join 을 통해 절대 경로로 가져오는 것이다.

따라서 /static은 웹에서 사용되는 가상 주소이고 이를 이미지 경로에 지정을 해줘야한다 위에서 순서대로 1,2,3이라고 하고 이미지를 웹에 띄울려면 아래와 같이 적어야한다.

1. <img src="pngwing.png" alt="">

2. <img src="static/pngwing.png" alt=""> 

3. <img src="static/pngwing.png" alt="">

/static을 적는 부분에 아무것도 적지 않는다면 그냥 이미지 파일 이름만 적어도 적용이 된다.

+ Recent posts