Home

Jeong-Yoon

07 Apr 2020

Mongodb(1)

MongoDB

  • mongo (mongo.exe) : 서버 접속 (몽고 쉘 실행)
    • mongo를 수행한다는 건 스크립트 명령을 수행하기 위한 서버 접속
  • mongod (mongod.exe) : 서버 구동(서버 실행)
  • mongoimport (mongoimport.exe)
    • import 역할을 가진 실행 파일 가지고 넣겠다.
      -> 그냥 cmd 후 사용 가능한 이유? 환경 변수 설정.
  • NoSQL 은 구조화된 SQL이 아니다 라는 뜻.(Not Only SQL)
    -> SQL이 아니다. 라는 뜻은 아니다.
  • show dbs : 현재 database확인
  • db.hostInfo() : 현재 host 정보 확인. (현재 구동시키고 있는 서버 정보)

[RDBMS vs NoSQL]

RDBMS

  • 스키마
    • 데이터베이스 사용에 있어서의 규칙, *제약사항 존재.
    • 효율적으로 공간을 사용
  • 무결성으로 인한 데이터가 들어간다는 확신과(무결성 보장) 보완성이 뛰어남

    NoSQL

  • 제약 사항이 없고, 데이터를 무더기로 넣는 느낌
  • 데이터의 빠른 처리가 가능
  • Sharding(샤딩) : 데이터 분할 저장
  • Replica Set(복제 셋) : 데이터 복제 세트 (백업, 복구)

[Scale-Up vs Scale-Out]

Scale-Up

  • 수직 확장, 성능 확장, H/W(장비 성능 확장)
  • 유지 비용이 비교적 변화가 적다.
  • 장애 발생 시 전체 영향을 줄 수 있다.

    Scale-Out

  • 수평 확장, 지속 확장
  • 유지 비용이 확장 대수에 따라 변화가 크다.
  • 장애 발생 시 전체 영향의 가능성이 적다.

collections

  • 문서 기반이기 때문에 collections로 불러옴.
  • show collections
    • 컬렉션 정보 확인

[메소드]

find()

  • db.COLLECTION_NAME.find()
  • SQL의 SELECT와 같은 역할
  • 형태
    • find( {조건절} , {필드} )
  • ObjectId 필드
    • 객체 식별자, 내부 검색을 위함.
    • 기본 값 UUID 지정
// SELECT * FROM employees; 
db.employees.find() -> 스크립트 함수 호출
db.employees.find().pretty()

// SELECT ename, empno FROM employee;
db.employees.find(
    {},
    {ename: 1, empno:1}
)
  • .pretty() 를 붙이면 보기 편하게 정렬됨.
    • db.COLLECTION_NAME.find().pretty()

createCollection()

  • db.createCollection(name, options)
    • 컬렉션 생성
    • CREATE TABLE emp (…)
    • data type이 없기때문에 지정해주지 않음.
db.createCollection(
    name : 생성할 컬렉션의 이름,
    options : (선택) 메모리 관련 옵션 지정
        capped(Boolean)
        : true 경우 고정된 크기의 컬렉션
        size option 설정 필수
        size over  오래된 항목을 덮어 씌움
    autoIndexID(Boolean)
        : true  자동으로 _id Field  지정
    size(Number)
        : capped 크기를 지정 (capped = true)
    max (Number)
        : 최대 document 개수
)

ex)
db.createCollection(
    "members",
    {
        capped : true,
        size: 2100000000,
        max : 500000
    }
)
  • capped
    • 데이터의 유지를 하지 않는다.
      크기 21억 바이트가 채워지면, 데이터를 모두 지우고 사용.
      false라면 이어서 붙여서 사용.

drop

  • db.COLLECTION_NAME.drop()
  • 컬렉션 삭제
  • 결과는 true, false로 나옴.

insert

  • db.COLLECTION_NAME.insert(document)
  • 컬렉션 데이터 삽입
    • INSERT INTO emp(empno, ename) VALUES (1001, “cafe”)
    • WriteResult({ “nInserted” : 1 }) : 결과가 1개 insert 됨.
db.employees.insert(
    {empno:7369, ename:"SMITH", job: "CLERK", 
    hiredate: "17-12-1980", salary: 800, deptno: 20}
)
  • 컬렉션을 생성하지 않고 삽입하면 자동으로 컬렉션을 생성
    • ex) 굳이 employees 라는 collection을 만들어주지 않아도 자동으로 생성된다.

update

  • 기존의 데이터를 수정하는 방식
  • db.COLLECTION_NAME.update(SELECTION_CRITERIA, UPDATED_DATA)
db.employees.update(
    { "ename":"SMITH" }, 
    { $set:{"ename":"UPDATE_DATA"} }
)

save

  • 기존의 데이터에 덮어 씌우는 방식
  • db.COLLECTION_NAME.save({_id:ObjectId(), NEW_DATA})
// 기존 ObjectId가 존재 한다면 덮어 씌우는 방식으로 동작
db.employees.save(
    {
        "_id":ObjectId("5e8a8befea8aac01d2a56036"), 
        "ename":"SAVE_DATA", "height":170
    }
)
// 기존 ObjectId가 존재하지 않으면, 새로 추가하는 방식으로 동작
db.employees.save(
    {
        "_id":ObjectId("5e8a8befea8aac01d2a56044"), 
        "ename":"SAVE_DATA", "height":190
    }
)

limit

  • 조회할 데이터 개수 제한
  • db.COLLECTION_NAME.find().limit(NUMBER)
db.employees.find().limit(2)

skip

  • 조회할 데이터 시작 부분을 설정
  • db.COLLECTION_NAME.find().skip(NUMBER)
  • db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)
db.employees.find().skip(2)
db.employees.find().limit(3).skip(1)

sort

  • 데이터 정렬
  • db.COLLECTION_NAME.find().sort({ : SORT_NUMBER })
db.employees.find().sort({ "sal" : 1 })
db.employees.find({}, {"sal":1, _id:0}).sort({"sal":-1})
// 급여를 내림차순으로 정렬하되, 부서 번호를 오름차순으로
db.employees.find({}, {"sal":1, _id:0, "deptno":1}).sort({"sal":-1, deptno:1})

조건 연산자

  • { : }
    • Equality
    • db.COLLECTION_NAME.find({“name”:”latte”})
    • sql > WHERE name = “latte”
  • { : {$lt:}}
    • Less Than
    • db.COLLECTION_NAME.find({“age”:{$lt:7}})
    • sql > WHERE age < 6 …
  • { : {$ne:}}
    • Not Equals
    • db.COLLECTION_NAME.find({“age”:{$ne:3}})
    • sql > WHERE age != 3

[JSON Data import]

mongoimport --db [데이터베이스 이름]
            --collection [컬렉션 이름]
            --type [데이터 형식]
            --drop[] // 기존에 같은 이름의 collection이 있으면 삭제하고 import
            --file"[파일 이름.확장자]"
mongoimport --db test --collection zipcode --type json --drop --file zipcode.json
  • mongoimport(명령어, 실행 파일)
    • mongoimport.exe
    • MongoDB 설치 경로의 bin 폴더에 존재
  • – file “[파일 이름.확장자]”
    • 파일 경로 (불러들일 파일의 전체 경로 및 상대 경로)
  • mongoimport.exe를 실행하기 위해 필요한 경로는 환경 변수에 등록.
    • 어디 기준이든 mongoimport를 수행할 수 있다.
-------------------------------------------------------------
***
mongo.exe   (mongo)       - 서버 접속 (쉘 실행)
mongod.exe   (mongod)      - 서버 구동 (서버 실행)
mongoimport.exe (mongoimport) - 불러오기 (import)
그냥 cmd 후 사용 가능한 이유? 환경변수를 설정했기 때문에!
-------------------------------------------------------------

[연산자]

[비교 연산자]

$eq   해당 값과 일치하는 값
$ne   해당 값과 일치하지 않은 값
$gt   해당 값보다 큰 값
$gte   해당 값보다 크거나 같은 값
$lt   해당 값보다 작은 값
$lte   해당 값보다 작거나 같은 값
$in   해당 배열에 포함되어 있는 값
$nin   해당 배열에 포함되어 있지 않은 값

[논리 연산자]

$or   조건 중 하나라도 true -> false
$and   조건 모두가     true -> true
$not   조건이         true -> false, false -> true
$nor   조건 모두가    false -> true

예시

// SELECT * FROM employees WHERE sal > 2000 OR sal < 1000;
db.employees.find(
    { $and: [
        {sal : {$gt:1000}},
        {deptno : {$lt:30}}
        ]   
    }
)

// SELECT * FROM employees WHERE sal > 2000 OR sal < 1000;
db.employees.find(
    { $or: [
        {sal : {$gt:2000}},
        {sal : {$lt:1000}}
        ]
    }
)

// SELECT * FROM employees WHERE deptno = 30 ORDER BY ename DESC;
db.employees.find(
    {
        deptno: 30
    }
).sort({ename:1}).pretty()
  • sort({ename:1}) : 오름 차순
  • sort({ename:-1}) : 내림 차순
// SELECT COUNT(*) FROM employees WHERE sal > 2500;
db.employees.find(
    {
        sal: {$gt:2500}
    }
).count()
  • .count() : 갯수 세기
// SELECT * FROM employees WHERE deptno IN(10,30)
db.employees.find(
    {
        deptno: {$in :[10, 30]} // deptno가 10, 30인 것만.
    }
)

// SELECT * FROM employees WHERE ename LIKE '%A%'
// -> A포함
db.employees.find(
    {
        ename: /A/
    }
)
// SELECT * FROM employees WHERE ename LIKE '%S'; 
// -> S로 끝남
db.employees.find(
    {
        ename: /S$/
    }
)
  • 해당 필드의 존재 유무 검사
// Q. empno 필드가 있는 직원
db.employees.find(
    {
        empno: {$exists: true}
    }
) 
  • 해당 필드의 타입 검사
    • 1: double
      2: String
      3: Object
      4: Array
// Q. 해당 필드의 데이터 타입이 1번인 직원만 조회
db.employees.find(
    {
        comm: {$type: 1}
    }
)

Aggregate

  • 집계 함수
  • 내부 문서 연산 시 속도를 빠르게 처리
    • RDBMS에서의 min, sum, max, …
  • $match : 연결 연산자 (WHERE, HAVING)
  • $project : 결과를 투영(SELECT)
  • $group : 그룹화(GROUP BY)
// 부서별 급여 합계
db.employees.aggregate([
    { $group: {_id:"$deptno", total_sal: {$sum: "$sal"}} },
    { $project:{_id:1,total_sal:1} }
])
// GROUP BY deptno, SUM(sal) AS total_sal

// 부서번호가 30인 직원의 직업별 총 급여
db.employees.aggregate([
    { $match: {deptno:30} },
    { $group: {_id:"$job", total_sal: {$sum: "$sal"} } },
    { $project: {id_:1, total_sal:1} }
])

aggregation framework

  • 변경 연산자(결과 반영)
  • $add
    • 두 개의 값을 합산
  • $subtract
    • 두 개의 값의 차이 결과
  • $multiply
    • 두 개의 값을 곱한 결과
  • $devide
    • 두 개의 값을 나눈 결과
  • $mod
    • 첫 번째 값을 두 번째 값으로 나눈 나머지 값
  • $ifNull
    • null 검사
    • ifNull:[“$comm”, 0]
      comm이 Null이면 0으로, 아니면 원래 값.

Til next time,
Jeong-Yoon at 00:00

scribble