12週目コードセグメント-データベース関係データベース/データベースORM/データベースNoSQL


これは勉強を始めた1週間です.コードを記述することによって、データベースからどのようにデータを受信し、加工するか、CLIを使用して直接データベーステーブルを作成し、関係を確立するか、プロセスがどのように処理されるか、どのデータフォーマットがあなたに適しているかを理解します.始める前は難しいと思っていたので怖かったのですが、理解できてよかったので面白かったです.まだスタート段階なのですが、表面的には形が見えないので気がふさいでいるのかわかりませんが、その部分で意外と大きな魅力を感じました.魔法をかけたような感じがします.😲
今回の勉強で公式文書をたくさん読んだようです.正直に言うと、正式なファイル作成コードを読んで理解するよりも、正式なファイル以外の内容を整理することでもっと勉強しました.しかしやはり常に接触しなければならなくて、後でやっと便利に使うことができて、少し近く置くべきです🤤 今週トイ問題を解いた時、怒りすぎてうまくいかなかったのでProgrammer問題を解き始めました.第一段階から解こうと思っていたのですが、以前あまり使わなかった高次関数やもっと簡潔に自然に解ける姿を見て、自分がずいぶん成長した気がして、気持ちが良かったです.その後、他の人が書いた解答を見たとき、私が書いたコードが悪くないことを確認して、とても喜んでいました.これからは焦らないで、私のレベルで順番に進んでください.気が短いとかえって食べ物がたまる私は自分がよくやったと思うので、警戒心を緩めないでください.プロジェクトの前の残りの時間の中で、あなたの顔の表情をよく調整して、よく勉強しなければなりません.🦾

12週間勉強した内容の中で整理したい内容


[データベース]リレーショナル・データベース

  • SQL Advanced
  • Case사용 (if문과 같은 기능)
    SELECT CASE
    WHEN CustomerId <= 25 THEN 'GROUP1'
    WHEN CustomerId <= 50 THEN 'GROUP2'
    ELSE 'GROUP3'
    END
    FROM customers
    
    
    
    SUBQUERY (쿼리 중첩)
    SELECT CustomerId, CustomerId = (SELECT CustomerId FROM customers WHERE CustomerId = 2)
    FROM customers
    WHERE CustomerId < 6
    
    
    
    EXISTS (존재여부 확인)
    SELECT EmployeeId
    FROM employees WHERE EXISTS (
      SELECT 
      FROM c.supportRepId = e.EmployeeId
      )
    ORDER BY EmployeeId
    
    
    
    FROM (서브 쿼리 사용 가능)
    SELECT *
    FROM (
      SELECT CustomerId
      FROM customers
      WHERE CustomerId < 10
    )
    
    <쿼리문을 이용하여 데이터베이스 접근>
      
      
    const db = require('../db');
    
    module.exports = {
      orders: {
        get: (userId, callback) => {	//해당유저가 작성한 모든 주문 가져오기
          // const sql = `SELECT orders.id, orders.total_price, orders.created_at, order_items.order_quantity, items.name, items.price, items.image
          // FROM orders 
          // INNER JOIN users ON (orders.user_id = users.id)
          // INNER JOIN order_items ON (orders.id = order_items.order_id)
          // INNER JOIN items ON (order_items.item_id = items.id)
          // WHERE (users.id =${userId})`;
    
          // db.query(sql, (err, result) => {
          //   callback(err, result);
          // });
          
          const queryString = `SELECT orders.id, orders.created_at, orders.total_price, items.name, items.price, items.image, order_items.order_quantity FROM items
          INNER JOIN order_items ON (order_items.item_id = items.id)
          INNER JOIN orders ON (orders.id = order_items.order_id)
          WHERE (orders.user_id = ?)`;
    
          const params = [userId];
    
          db.query(queryString, params, (error, result) => {
            callback(error, result);
          });
        },
    
        
        post: (userId, orders, totalPrice, callback) => {	//해당 유저의 주문요청을 데이터베이스에 생성
          
          // orders: [{ quantity: 1, itemId: 2 },{ quantity: 1, itemId: 4 }]
    
          const sql1 = `INSERT INTO orders (user_id, total_price) VALUES (${userId}, ${totalPrice})`;
          db.query(sql1, (err, result) => { 
            const sql2 = `INSERT INTO order_items (order_id, item_id, order_quantity) VALUES ?`;
            const values = orders.map((el) => [
              result.insertId,
              el.itemId,
              el.quantity,
            ]);
    
            db.query(sql2, [values], (err, result) => {
              callback(err, result);
            });
          });
        },
      },
    
      
      items: {
        get: (callback) => {	//모든 상품 데이터를 가져오기
          const query = "SELECT * FROM items";
          db.query(query, (err, result) => {
            callback(err, result);
          });
        },
      },
    };

    [データベース]ORM

  • MCV:モデル、ビュー、コントローラは設計モードの弱い部分である.1つのアプリケーションとプロジェクトで、コンポーネントを3つのロールに分割するモード

    コントローラを操作すると、コントローラはモデルを介してデータをインポートし、情報に基づいてビューをユーザーに表示するように制御します.
  • 용어
  • Model:データ・情報を指し、情報を加工する部品.編集するすべてのデータが必要です.
  • View:データベースのユーザ可視画面、ユーザインタフェース要素
  • Controller:データとユーザインタフェース要素をつなぐ架け橋
  • sequlize를 이용하여 MVC패턴 적용
  • sequelize, sequelize-cli 설치 후 ORM 설정
    
      1. config.json에 database 설정 이름을 mysql에서 database생성
      2. Model 생성 
    "npx sequelize-cli model:generate --name User --attributes firstName:string,lastName:string,email:string"
    
      3. migrations을 통해 테이블 생성 
    "npx sequelize-cli db:migrate"
    
    
    
    
    Associations을 이용한 join table 구현
    
      1. 새 테이블의 모델 파일과 마이그레이션 생성
      2. migrations을 통해 테이블 생성
      3. 새로운 마이그레이션 파일을 생성
    "sequelize migration:create --name 파일명"
    
      4. 만든 파이그레이션 파일에 FK만들기
      5. 모델 파일 Association을 belongsTo, hasMany로 정의
      6. 생성하기
    "sequelize db:migrate"
    
                 
    
                 
                 
    [4]
    
      'use strict';
    
    module.exports = {
      up: async (queryInterface, Sequelize) => {	=> sequelize db:migrate
      
        await queryInterface.addColumn('urls', 'userId', Sequelize.INTEGER);
    
        await queryInterface.addConstraint('urls', {
          fields: ['userId'],
          type: 'foreign key',
          name: 'custom_fkey_constraint_name',
          references: {
            table: 'users',
            field: 'id'
          },
          onDelete: 'cascade',
          onUpdate: 'cascade'
        })
      },
    
      down: async (queryInterface, Sequelize) => {	  => sequelize db:migrate:undo
      
        await queryInterface.removeConstraint('urls', 'custom_fkey_constraint_name')
        await queryInterface.removeColumn('urls', 'userId')
    
        // await removeColumn('urls', 'userId')
       // FK먼저 지우고 column지움
      }
    };
    
    
    
    
    [5]
    
    url.js
        static associate(models) {
          url.belongsTo(models.user, {
            foreignKey: "userId"
          })
        }
    
    
    
    user.js
        static associate(models) {
          user.hasMany(models.url)
        }
    
    
    
    
    또는 models/index.js에서 한번에 처리
    
    const { url, user } = sequelize.models;
    url.belongsTo(user);
    user.hasMany(url);
    
    
    
    
    
    *만약에 sequelize에 오류가 발생한다면?*
      
      sudo npm install -g sequelize
      sudo npm i -g sequelize-cli 재설치
    
    
      node_modules/.bin/sequelize db:migrate로 실행

    [データベース]NoSQL

  • NoSQL기반의 비관계형 데이터베이스 사용 경우 => [MongoDB 도큐먼트 이용]
  • 非構造大容量データの格納
  • クラウドコンピューティングとストレージスペースを活用した場合[SQL:垂直拡張、NoSQL:水平拡張]
  • サービスの迅速な導入とデータ構造の頻繁な更新
  • JSON形式は読みやすく使いやすい形式です.
    ただし、テキスト形式であるため読み取りは容易であるが、スライス速度が遅く、メモリの使用は非効率な基本データ型のみをサポートするため、BSON形式で問題解決=>
    Export
    
    BSON: mongodump --uri "<Atlas Cluster URI>"
    
    JSON: mongoexport --uri "<Atlas Cluster URI>"
    		  --collection=<collection name>
      		  --out=<filename>.json
      
      
    Import
    
    BSON: mongorestore --uri "<Atlas Cluster URI>"
    		   --drop dump
    
    JSON: mongoimport --uri "<Atlas Cluster URI>"
    		  --drop=<filename>.json	==> drop은 선택적 사용
              
              
        
             
    - mongodump: BSON형식의 데이터를 내보내기
    - mongorestore: mongodump가 생성한 BSON형식 데이터 가져오기
    
    
    - mongoexport: JSON형식의 데이터를 아틀라스 클러스터에서 내보낼 때., 내보낼때 아틀라스 클러스터에 컬렉션을 더하는 대신 외부에 데이터 복사본 만듬
    - mongoimport: 데이터베이스를 아틀라스 클러스터로 가져오기. JSON일수도 있고, 다른 데이터 형식일 수도 있음
  • MongoDB CRUD
  • -CREATE
    
    
    _id는 필수. but, 작성하지 않아도 자동 생성(ObjectId로 생성) => 같은 내용이여도 다른 아이디 값인 경우 다르다고 인식
    insert를 이용(객체 담아서), 다수의 도큐먼트 삽입시 배열안에 작성
    
    db.test.insert([{"_id":"1", "test":"1"}, {"_id":"1", "test":"2"}, {"_id":"3", "test":"3"}], {"ordered":false})
    
    _id값이 중복인 부분은 삽입하지 않음. 인덱스 순서 삽입이 진행
    {"ordered":false} 작성시 앞에서 오류가 발생하면 오류부분을 제외하고 진행
    
    
    
    
    
    -READ
    
    
    find를 이용하여 원하는 데이터를 찾음
    show dbs => use databasename => db.names.find({"content":"hi"})
    
    전체를 보고 싶은 경우 db.names.find().pretty()  *pretty를 작성시 객체로 보기 편하게 나옴*
    갯수를 알고 싶은 경우 db.names.find().count()
    조건에 부합한 한개 만 db.names.findOne({"_id": 12513513})
    
    
    
    
    
    -UPDATE
    
    
    $inc: 다양한 필드 값을 동시에 업데이트 가능
    $set: 주어진 필드 지정된 값을 업데이트. 존재하지 않는 필드명 작성시 새롭게 추가됨
    $push: 값이 배열로 이뤄져있을 때 요소 추가
    
    db.names.updateMany({"key":"1"}, {"$inc": {"pop":10}})  *한 번에 여러 데이터 추가 시*
    db.names.update({})	*한 번에 하나 데이터 추가 시*
    
    
    
    
    
    -DELETE
    
    
    db.name.deleteMany({"content":"hi"})
    db.name.deleteOne({"content":"hi"})
    
    컬렉션을 삭제하기 위해서 drop을 사용
    db.collection_name.drop()
    
    
    
    
    
    -비교 연산자
    
    
    $eq =   $ne ≠   $gt >   $lt <   $gte >=   $lte <=
    db.names.fin({"during": {"$lte":70}, "content":{"$ne":"hi"})
                  
    
    
    
    
    -논리 연산자
    
    
    $and: 모든 쿼리절과 일치하는가
    $or: 쿼리절 중 하나라도 일치하는가
    $nor: 모든 쿼리절과 일치하지 않는가
                  
    => {<operator>:[{state1}, {state2}, ...]}
                  
                  
                 
    $not: 쿼리와 일치하지 않는가
                 
    => {$not:{state}}
    
    
    
    
    
    -표현 연산자
    
    
    $expr
    {"$expr":{"$eq":["$start", "$end"]}}	=> $는 해당 필드의 값을 뜻함
    
    
    
    
    
    -배열 연산자와 projection
    
    
    배열에 담아서 조건으로 찾을 경우 순서가 다르면 결과값이 나오지 않음
    $all을 사용하면 배열요소의 순서와 상관없이 지정 요소를 포함된 결과 도출
    $size를 이용해서 배열의 길이 제한 가능
    
    {"$size": 숫자, "$all":{"필드명", ...}}
     
    0, 1을 사용해 결과를 표시할지 말지 설정 가능[0, 1을 혼합해서 사용 불가, but id만 예외적으로 가능]
    배열필드에서 $eleMatch를 사용해서 결과값 도출