[TIL] SQL , ORM, cookie, session

최하온·2024년 1월 26일
0

TIL

목록 보기
25/71
post-thumbnail

📃What I learned new


SQL 제약조건 정의

: sql 작성 시 컬럼 별로 미리 정해둔 조건
: 테이블 생성 시 정할 수도 있고, ALTER로 수정 변경 가능하지만 웬만하면 생성 시에 확실하게 설계하기!

SQL 제약조건 종류

1. NULL

  • NULL : 값이 없어도 됨
  • NOT NULL : 값이 꼭 존재해야함

2. UNIQUE

: 중복된 키를 허용 하지 않음(유일성 보장)
: null 허용 O
: 한 테이블에 여러개 존재 가능

3. PRIMARY KEY(기본키)

: 각 행을 고유하게 식별할 수 있는 컬럼
: 다른 테이블에서 참조할 수 있음
: unll 허용 X, 테이블에 단 하나.
ex) 주민등록번호나 사원번호

4. FOREIGN KEY(외래키)

: 기본 키를 참조하는 컬럼

그 외 DDFAULT, CHECK 등등 ..

CREATE TABLE Users
(
    userId    INTEGER             NOT NULL AUTO_INCREMENT PRIMARY KEY // (기본키),
    email     VARCHAR(191) 		  UNIQUE NOT NULL, // (중복 허용 x ,빈 값x)
    password  VARCHAR(191)        NOT NULL,
    createdAt DATETIME(3)         NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
    updatedAt DATETIME(3)         NOT NULL DEFAULT CURRENT_TIMESTAMP(3)
);
CREATE TABLE UserInfos
(
    userInfoId   INTEGER        NOT NULL AUTO_INCREMENT PRIMARY KEY,
    userId       INTEGER        UNIQUE NOT NULL, // (Users의 기본키를 참조)
    name         VARCHAR(191)   NOT NULL,
    age          INTEGER        NOT NULL,
    gender       VARCHAR(191)   NOT NULL,
    profileImage VARCHAR(191)   NULL,
    createdAt    DATETIME(3)    NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
    updatedAt    DATETIME(3)    NOT NULL DEFAULT CURRENT_TIMESTAMP(3)
    FOREIGN KEY 1(userId) REFERENCES 2번 Users 3(userId) ON DELETE CASCADE;
    // 1번: UserInfos의 userId를 가지고 테이블 2번 : Users의 3번: userId 를 참조.
);

AUTO_INCREMENT : 데이터가 입력될 때 마다 숫자를 1씩 증가시켜 기본 키의 고유한 값을 유지
CURRENT_TIMESTAMP : 시스템의 현재 타임스탬프를 반환


app.post('/api/tables/', async (req, res, next) => {
  const { tableName } = req.body;

  await connect.promise().query(`
      CREATE TABLE ${tableName}
      (
          id        INT         NOT NULL AUTO_INCREMENT PRIMARY KEY,
          name      VARCHAR(20) NOT NULL,
          createdAt DATETIME    NOT NULL DEFAULT CURRENT_TIMESTAMP
      )`);

  return res.status(201).json({ message: '테이블 생성에 성공하였습니다.' });
});

위 코드처럼 node.js에서 sql문을 사용하는 걸 Row Query라고 하는데 Row Query 사용 시 보안이나 유지보수 등 문제점이 많음. => ORM사용

ORM

:Object Relational Mapping의 줄인말로 객체 테이터 베이스의 관계를 연결해주는 도구.

Prisma

: ORM 중 하나로 여러 RDM에서 많이 쓰임.

출처: https://blog.naver.com/suin2_91

인증 방식

  1. 클라이언트가 서버에 요청을 보냄.
  2. 서버는 요청에 담긴 데이터를 Set-Cookie 헤더에 담아 보내 클라이언트가 쿠키를 저장.
  3. 클라이언트가 쿠키와 함께 요청을 보내면 서버는 정보를 바탕으로 응답을 줌

단점

  1. 쿠키의 값을 그대로 보내고, 새로고침 등에도 쿠키가 유지 되어 보안에 취약.
  2. 용량 제한이 있음.

session

출처: https://www.wisecleaner.com/think-tank

인증 방식

  1. 클라이언트가 서버에 요청을 보냄. 서버는 데이터를 서버에만 저장
  2. Cookie에 세션ID를 담아 응답.
  3. 클라이언트는 세션 ID를 쿠키에 담아 전송.
  4. 서버는 요청 세션 ID와 서버에 있는 세션 ID를 비교 후 인증 수행.

단점

  1. 요청이 많아지면 서버 부하.
  2. 만료기간이 존재.

Token

인증 방식

  1. 클라이언트가 로그인 요청.
  2. 서버는 토근을 발급하여 클라이언트에 전달.
  3. 요청 시 마다 토큰과 함께 요청.
  4. 토근을 검증하고 응답.

단점

  1. 페이로드는 누구나 복호화하여 볼 수 있기 때문에 중요한 정보X

🚨Issue occuring


💦What I tried


나의 접근 방법.

// 숫자들의 약수의 갯수 구하기
// 제곱근이 정수 O : 약수의 개수는 홀수
// 제곱근이 정수 X : 약수의 개수는 짝수
// 약수의 갯수가 짝수면 + 홀수면 -
// 총 값 리턴

// 주어진 두 숫자 사이의 숫자 구하기
function solution(left, right) {
    let btweenNum = [];
    for (i = left; i <= right; i++) {
        btweenNum.push(i); 		// [13,14,15,16,17]
    }
}

반복문으로 주어진 두 숫자의 사이 숫자들을 push로 넣어주기.

function solution(left, right) {
    var answer = 0;
    let btweenNum=[];
    for(i=left; i<=right; i++){
        btweenNum.push(i)
    }
    return btweenNum.map((num)=>Number.isInteger(Math.sqrt()))
}

for문을 돌리자니 배열 하나하나의 약수를 구하는데 벽을 느껴서 구글링을 했다.
=>제곱근의 정수 여부에 따라 약수의 갯수가 정해진다!
바로 JS MDN에서 정수인지 판별하는 메서드와 제곱근을 구하는 메서드인 Math.sqrt()를 사용해보았다.

어딘가.. 잘못되었다🤔
MDN으로 Math.sqrt()를 살펴보니 매개변수를 넣지 않아 제 구실을 못했던 거 같다 num 를 매개변수로 넣어주었다.
true는 약수가 홀수라는 뜻이니 빼고, false는 더하면 된다. 이럴 땐 삼항연산자지!

return
btweenNum.map((num)=>Number.isInteger(Math.sqrt(num))? answer-=num:answer+=num)

마지막 값만 필요하니 pop()!

💡How solve issue


// 주어진 두 숫자 사이의 숫자 구하기
// 숫자들의 약수의 갯수 구하기
// 제곱근이 정수 O : 약수의 개수는 홀수
// 제곱근이 정수 X : 약수의 개수는 짝수
// 약수의 갯수가 짝수면 + 홀수면 -
// 총 값 리턴
function solution(left, right) {
    var answer = 0;
    let btweenNum=[];
    for(i=left; i<=right; i++){
        btweenNum.push(i)
    }
    return btweenNum.map((num)=> Number.isInteger(Math.sqrt(num))? answer-=num:answer+=num).pop()
}

약수를 어떻게 구하는지, 정의가 정확히 무엇인지 지수와 소인수분해 등등 훑어보고 제곱근의 정수 여부로 약수의 개수가 달라지는걸 알았다.

🤔Realization

꾸역꾸역 이어 붙여서 정답은 맞췄지만 뭔가 리턴값이 너무 길다.
다른 사람의 코드를 봐보자


function solution(left, right) {
  let answer = 0;

  for (let i = left; i <= right; i++) {
    let count = 0;
    for (let j = 1; j <= i; j++) {
      if (i % j === 0) count++;
    }
    if (count % 2) answer -= i;
    else answer += i;
  }

  return answer;
}

처음 나의 접근 방법이었고, 내가 생각해내지 못한 방법이다.
1. 주어진 첫 번째 수(13) 부터 두 번째 수(17)까지 배열 돌기
2. 13을 1부터 13까지 나누웠을 때 나누어 떨어지면 count++ (약수의 갯수 구하기)
3. 약수의 갯수를 2로 나누었을 때 나머지가 1이면 참(홀수)이고 0이면 거짓(짝수)이니 더해준다.
if문 조건을 저렇게 주는건 한참보고 이해했다.

아직 갈 길이 먼 거 같다..

0개의 댓글