군장병 AI 트랙(중급) PART 4-2 필기

배코딩·2022년 12월 4일
0

군장병 AI 교육

목록 보기
6/8

1강 : DBMS & 3 Steps of Data Modeling

1960년대 계층적 데이터베이스를 시작으로 네트워크형, 관계형, 객체형을 거치면서 발전해왔다.

요즘에는 관계형 데이터베이스(R DBMS)를 널리 쓰고 있다.


Data Warehouse, ELT

-> 데이터를 창고에 정리해서 넣어놨다가 나중에 꺼내씀

옛날에 지금과 달리 데이터의 양이 상대적으로 적던 시절에 쓰던 방법


Data Lake, ETL

-> 데이터를 호수에 막 집어넣어놨다가 필요한 데이터가 생기면 꺼내서 전처리 후 사용

현재와 같이 데이터의 양이 방대할 때 쓰는 방법


데이터 모델링 3단계


1) 개념적 데이터 모델링

현실 세계로부터 개체(Entity)를 추출하고(ex 회원, 제품), 개체들 간의 관계를 정의하여(구매) E-R 다이어그램(ERD, 개념 스키마)을 만드는 과정

개체에는 여러가지 속성(Attribute, ex 회원의 경우 이름, 이메일, 전화번호, 나이 등)이 있고, 회원과 제품 사이의 "구매"라는 관계가 있다.

보통 개체가 하나의 테이블이 된다. (속성이 하나의 열)




2) 논리적 데이터 모델링

E-R 다이어그램을 바탕으로, 데이터베이스에 저장이 가능한 논리적인 구조를 Relation 모델(표라고 생각하면 됨, 논리적 스키마)로 표현하는 과정


member

회원 ID 이름  이메일  전화번호  나이 
1김공군asd@...010-...22
2김파이썬qwe@...010-...35
3김코딩zxc@...010-...42

개체 하나가 한 행을 나타내고, 각 열은 속성을 의미한다.

이 때 개체 하나하나를 나타내는 ID 열도 추가해야됨.

Relation : 위의 표 같은 것의 명칭. 개체에 대한 데이터를 2차원 테이블 구조로 표현한 것.(relationship 데이터도 포함) 위 예제에선 member.

Attribute : 열(column) = 필드(field)

tuple : 행(row) = 레코드(record) = 인스턴스(instance)

Degree : 차수. relation 내 속성의 개수(=열의 개수, 위 예제에서 5)

Cardinality : 카디널리티. relation 내 튜플의 총 개수(=행의 개수, 위 예제에서 3)


데이터베이스에서 실제로는 table, field, record(or instance), degree, cardinality 라는 용어로 많이 씀




3) 물리적 데이터 모델링

: Relation 모델을 DBMS 종류에 따라 실제 물리 저장 장치에 저장할 수 있는 물리적 구조(ex. SQL, 데이터베이스 스키마)로 구현하는 과정


SQL

Structured Query Language : 구조적 질의 언어

RDBMS에서 데이터 관리&처리를 위해 만들어진 언어

SQL의 표준으로 ANSI SQL이 정립되어있다.

여러 DBMS 프로그램들은 이 ANSI SQL을 기반으로 SQL을 자체적으로 개발하여 사용한다. 따라서 DBMS 프로그램마다 SQL이 약간씩 다른 점이 있다.



1) DDL (Data Definition Language, 데이터 정의 언어)

각 relation(데이터베이스 테이블)을 정의하기 위해 사용하는 언어

CREATE (테이블 생성) / ALTER (테이블 변경) / DROP (테이블 삭제) 등


2) DML (Data Manipulation Language, 데이터 조작 언어)

데이터 관리(데이터의 CRUD)를 위한 언어

SELECT (Read) / INSERT (Create) / UPDATE (Update) / DELETE (Delete)


3) DCL (Data Control Language, 데이터 제어 언어)

사용자 관리 & 사용자별 권한 (relation 및 데이터에 대한 관리/접근)을 다루기 위한 언어

GRANT (권한 부여) / REVOKE (권한 해제)


Tips for SQL programming

1) SQL은 대소문자를 구분하지 않는다.

그렇지만 보통은 SQL 문법에 관련된 키워드들은 대문자로, 필드명같은 건 소문자로 적어줌

다만 서버 환경 또는 DBMS 종류에 따라 간혹 데이터베이스 이름 또는 필드 이름에 대해 대소문자를 구분하기도 한다.


2) SQL 명령은 반드시 세미콜론으로 끝맺음해줘야함


3) 고유값은 따옴표로 감싸줌

ex) SELECT * FROM member WHERE name='James';


4) 한 줄 주석 : --

멀티라인 주석 : / ~~~ /

ex) -- SELECT * FROM member;

/
SELECT
FROM member
WHERE memid=10;
*/


5) 반복을 통해 아래 키워드들의 순서를 익혀두자.

SELECT ~
FROM ~
INNER JOIN ~ ON ~.~ = ~.~
WHERE ~
GROUP BY ~
HAVING ~
ORDER BY ~
LIMIT ~ OFFSET ~


SQL 문법 다 배우고나서 아래 링크들 통해 숙련도 높이고 내용도 정리하자

https://techbeamers.com/sql-query-questions-answers-for-practice/

https://wikidocs.net/71334

https://myjamong.tistory.com/172


2강 : Intro to SQLite (1) - SQL with Python

파이썬에는 SQLite3라는 DBMS가 있음. 서버를 따로 만들지않고 바로 DB를 파일에 저장해서 가볍고 빠름. OracleDB 등 다른 DBMS의 경우 서버를 띄우고 IP, Port로 connect를 하는 DBMS도 있음

따로 설치해서 CLI 환경에서 명령을 줄 수도 있지만 그냥 주피터 노트북에서 편하게 쓰자

dbpath = "maindb.db"

conn = sqlite3.connect(dbpath)

활용하는 함수는 크게 4가지가 있음.

1) conn.cursor()

말 그대로 DB 파일 위에 커서를 조작하여 명령을 실행할 위치를 지정함


2) conn.commit()

DB에 변경사항을 저장해줌


3) conn.rollback()

ctrl + z 같은 느낌

세이브 포인트는 가장 최근의 commit을 실행한 지점임.

즉 마지막 저장본으로 되돌아가주는거임.

commit을 한 번도 실행안했으면 맨 처음 빈 DB파일로 돌아감


4) conn.close()

DB와의 연결 끊기


conn.cursor()

cur = conn.cursor()

커서 객체를 저장해두고 그 객체로 수행할 수 있는 몇가지 메소드가 있음.

마우스 커서와 같이 DB를 hovering 하고 있다.


cur.execute('CREATE TABLE ~~~;')
: SQL 명령 실행

cur.execudescript('~~~')
: 다수의 SQL 명령들을 한꺼번에 실행함 (SQL문을 모아둔 script 문자열)

cur.executemany('~', ~)
: 앞에는 SQL문, 뒤의 arg는 파이썬 리스트같은 데이터임. 하나의 SQL문을 여러 변수에 대해 실행해주고 싶다면 이 메소드를 활용하자.

cur.fetchone()
cur.fetchall()
: excute로 실행한 쿼리가 SELECT일 때, 거기서 하나 또는 전체 행을 꺼내는 메소드임


Datatypes

Datatype 지칭하는 이름은 DBMS 종류마다 조금씩 다를 수 있지만 거의 비슷함

NULL

INTEGER(or INT)

REAL : float임

TEXT(or VARCHAR)

BLOB : Binary Large OBject. 파이썬의 변수같은 걸 통째로 저장할 수도 있음. 이미지 파일도 가능하지만 보통 이미지 파일은 AWS같은 클라우드에 S3에 업로드해놓고 접근 링크를 TEXT로 저장해두는 방식을 사용함.


sql_query = """
CREATE TABLE employees( 
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
salary REAL,
department TEXT,
position TEXT,
hireDate TEXT);
"""

conn.execute(sql_query)
con.commit()

보통 sql 문은 따옴표 3개로 감싸서 작성함. 이렇게하면 멀티라인으로 가독성을 높혀 작성할 수 있다.


executemany

하나의 쿼리문에 여러 데이터를 차례로 끼워넣어 각각 실행할 때 쓰는 메소드

data = [('Elena', 510, 'Recruiter', 'LV3', '2020-07-01'), 
        ('Sujan', 710, 'HR', 'LV5', '2014-06-01'),
        ('Jake', 210, 'CEO', 'LV8', '2012-01-01')]

cur.executemany("INSERT INTO employees(name, salary, department, position, hireDate) VALUES(?, ?, ?, ?, ?);", data)
conn.commit()

위 방법을 활용해서 데이터를 조회하고 꺼내쓰기에는 조금 번거롭다. pandas를 활용하면 더 편하다.

df = pd.read_sql_query("SELECT문", conn)

DB에 연결되어 있는 객체를 같이 넘겨줘야된다.

read_sql_query로는 대개 SELECT문만 넘겨서 쓰는 듯 하다.

앞으로는 SELECT문을 쓸 때는 cursor로 땡겨오지말고 pandas로 가져오자.


3강 : Intro to SQLite3 (2) - DB Browser for SQLite

파이썬말고도 DB를 조회 및 수정까지도 가능한 간편한 프로그램이 있다.

DB Browser for SQLite인데,

안에 SQL 콘솔 창도 있어서 코드 입력도 가능하고, GUI 느낌으로 손쉽게 코드 없이 데이터 수정 및 추가가 가능하다. 전체적으로 둘러본다거나 간단하게 수정이 필요할 때 애용하자.


4강 : Intro to SQLite3 (3) - DDL

회원 테이블

script = """
CREATE TABLE contacts ( 
    contact_id INTEGER PRIMARY KEY,
    likes INTEGER DEFAULT 0,
    first_name TEXT NOT NULL,
    last_name TEXT NOT NULL,
    email TEXT NOT NULL UNIQUE, --중복 값 입력 시 에러 발생
    phone TEXT NOT NULL UNIQUE CHECK (LENGTH (phone) >= 10) -- 조건 걸기(미충족 시 에러 발생)
);
""" 

참고로 먼저 INTEGER로 필드를 생성 후 PRIMARY KEY (contact_id)로 기본키를 지정할 수도 있다.


제품 테이블

script = """
CREATE TABLE groups (
   group_id INTEGER PRIMARY KEY AUTOINCREMENT,
   name TEXT NOT NULL
);
""" 

구매 테이블 (회원과 제품의 relationship)

script = """
CREATE TABLE contact_groups(
   contact_id INTEGER,
   group_id INTEGER,
   PRIMARY KEY (contact_id, group_id), 
   FOREIGN KEY (contact_id) 
      REFERENCES contacts(contact_id) -- contacts 테이블의 contact_id 필드를 참조하여 이 테이블의 contact_id 필드 생성
         ON DELETE CASCADE, -- 참조 원본 테이블에서 삭제되면 여기서도 삭제
   FOREIGN KEY (group_id) 
      REFERENCES groups(group_id)
         ON DELETE CASCADE
);
""" 

여기선 기본키가 두개로 이루어진 쌍 하나인데 필드 하나 추가해서 그걸 이 테이블만의 단일 기본키로 삼는게 더 깔끔하긴 할 듯


참고로, NOT NULL 없이 UNIQUE만 썼을 때, 여러 행에 NULL이 들어왔을 때 이 들을 SQLite에서는 모두 다른 것으로 취급하므로 UNIQUE를 만족한다.


ALTER Table

열을 삭제하는 것은 권장되지 않는다. 무결성을 해치는 등 여러 문제를 야기할 수 있음. 그냥 필요없는 열은 비운 채로 두자.

script = """
INSERT INTO devices (name, model, serial)
VALUES('HP ZBook 17 G3 Mobile Workstation','ZBook','SN-2015');
""" 
cur.execute(script) 

만약 행을 INSERT할 때 모든 열의 값을 넣어줄 때는 INTO 문에 필드명을 아예 기입안해줘도 됨

ex) INSERT INTO devices VALUES ~;


ALTER TABLE table_name RENAME TO table_new_name;

: table_name 테이블의 이름을 table_new_name으로 바꿈



ALTER TABLE table_name ADD COLUMN field_name TEXT;

: table_name 테이블에 field_name 필드를 TEXT 형으로 추가함

FIELD로 안쓰고 COLUMN으로 쓰는 부분을 유의하자.



ALTER TABLE table_name RENAME COLUMN field_name TO field_new_name;

: 필드명을 바꿔줌


DROP Table

DROP TABLE table_name
: 테이블 삭제


DB 내 Table 목록 & Table Structure 확인하기

SELECT field_name FROM sqlite_master WHERE 조건

: sqlite_master 테이블의 각 행은 하나의 테이블(또는 INDEX)의 정보를 담고 있음.

위 코드는 거기서 테이블들의 name만을 SELECT하는 쿼리

걍 굳이 이렇게 안하고 DB Browser로 편하게 보면 됨


5강 : SQL CRUD (1) - DML

SELECT, INSERT, UPDATE, DELETE


UPDATE

UPDATE table_name SET field_name = '~~~' WHERE field_name_ = 3;

: WHERE이 먼저 실행된 후 SET이 실행됨. 만약 WHERE이 없으면 모든 행에 대해 SET을 수행



UPDATE table_name SET field_name = '~~~', field_name_2 = '~~~' WHERE field_name_ = 3;

: 여러 열을 동시에 수정(SET)할 수도 있음



이메일 주소 필드 값 수정하는 코드

UPDATE employees SET UPPER(mail = firstname || "." || lastname || "@naver.com");

|| : shift + 원화키, concatenate 기능을 수행함

LENGTH, UPPER, || 등을 SQLite String Functions 라고함. 더 많은 내용은 구글링하자


DELETE

DELETE FROM table_name WHERE field_name = 2;

: 테이블에서 행을 지워줌


6강 : SQL CRUD (2) - ORDER BY & DISTINCT

ORDER BY

SELECT * FROM table_name ORDER BY field_name DESC

default 값은 ASC임. 필드명 뒤에 암것도 안쓰면 오름차순 정렬

쉼표 적고 이어서 여러 기준 필드를 더 추가할 수도 있음

참고로 SQLite에서 None도 Null data이고, Null data는 가장 작은 값으로 인식하고 정렬을 수행함.


DISTINCT

SELECT DISTINCT field_name FROM table_name

: 중복을 제거해줌.


  • DISTINCT field_name_1, field_name_2

이런 식으로 쓰면 두 필드 모두 일치할 때를 중복으로 간주하여 제거해줌. 하나만 같은게 아니라 둘 다 같아야함


DISTINCT를 쓸 때 or처럼 쓰거나 하나는 DISTINCT고 하나는 평범하게 쓰는거는 기술적으로 지원이 안됨.

여러 필드 꺼낼 때 DISTINCT를 쓸 때에는 반드시 대상이 되는 모든 필드가 일치하는 것만 DISTINCT로 간주함.


None(Null)의 경우에도 마찬가지로 중복을 제거하고 딱 하나만 남음

UNIQUE의 경우와 다르기에 혼동이 오기 쉬움. 유의하자


7강 : SQL CRUD (3) - WHERE & LIMIT

분류연산자
비교=, <>, <, <=, >, >=WHERE milliseconds < 250
범위BETWEEN, NOT BETWEENWHERE total BETWEEN 14.91 AND 18.86
집합IN, NOT INWHERE mediatypeid IN (1, 4, 5)
패턴LIKE, NOT LIKEWHERE name LIKE '%Wild%'
NULLIS NULL, IS NOT NULLWHERE composer IS NULL
복합조건AND, OR, NOTWHERE (milliseconds < 250) AND (name LIKE '%Wild%')


와일드카드매칭되는 문자열 패턴문자열 패턴 예시
%0개 이상의 문자열과 일치'%wild%' : wild를 포함하고 앞 뒤에 문자열이 0개 이상 있는 문자열
[ ]1개의 문자와 일치'[0-8]%' : 0~8 중 숫자 하나로 시작하는 문자열
[^]1개의 문자와 불일치'[^0-9]%' : 0~9 사이 숫자 하나로 시작하지 않는 문자열
_특정 위치의 1개의 문자와 일치'%Br_wn%' : Br과 wn 사이에 1개의 문자열이 존재하는 문자열
+문자열을 연결'test' + 'string' : 'test string'

LIMIT ~ OFFSET ~

SELECT field_name FROM table_name LIMIT 10 OFFSET 7

table_name에서 맨 위부터 7개의 행을 제외하고, 8번째부터 10개의 행을 선별한 후 거기서 field_name 값을 SELECT한다.


BETWEEN ~ AND ~

SELECT field_name FROM table_name WHERE field_name_ BETWEEN 14.2 AND 18.5

양 끝 구간을 포함함. (A 이상 B 이하)

NOT BETWEEN도 가능함.

문자열 사전순 비교도 가능


8강 : Merge & Adv. techniques (1) - JOIN

INNER JOIN

: 교집합을 생각하자

SELECT table1.field1, table2.field2 FROM table1 INNER JOIN table2 ON table1.key = table2.key;

여기서 field_name은 table_name의 field이고 field_name_2는 table_name_2의 field임

참고로 key를 SELECT할 때는 어떤 테이블의 key인지를 명시해서 꺼내줘야함. 두 테이블 중 암거나 하나.

key가 아닌 다른 필드들도 테이블을 명시해주면 코드가 명료해진다.



  • Alias

테이블 명의 별명을 지어 쓸 수 있다.

SELECT t1.field1, t2.field2 FROM table1 t1 INNER JOIN table2 t2 ON t1.key = t2.key;

테이블 명 뒤에 별명을 써주면 alias로 동작한다.


위 예제처럼 키 필드가 서로 같은 필드라면, 굳이 저렇게 안쓰고 ON t1.key = t2.key 이 부분을 USING(key)로 대체해서 써도된다.

ex) INNER JOIN table2 USING(key)


주의할 점이 있는데, 두 키가 반드시 같은 필드여야되는건 아니다.

만약 다른 필드라면 두 필드의 값이 같은 것끼리 INNER JOIN을 하는 것이다.


참고로 JOIN은 여러번 계속 쓸 수 있다.


SELECT할 필드명은 AS 키워드로 별명을 지어줄 수 있다.

ex) SELECT field1 AS f1, field2 AS f2


LEFT JOIN

벤 다이어그램 상 A-B와 A교B를 취함(=A)



A-B를 뽑고싶을때는 LEFT JOIN에 WHERE로 A교B에 해당하는 부분 걸러주면됨 (B에서 SELECT한 필드의 값이 NULL인 경우만 선택)


같은 테이블에서 INNER JOIN

script = """
SELECT m.firstname || ' ' || m.lastname AS 'Manager',
       e.firstname || ' ' || e.lastname AS 'Receives reports from'  
FROM 
    employees e
INNER JOIN 
    employees m 
ON 
    m.employeeid = e.reportsto
ORDER BY 
    manager;
""" 

ex) n개의 직원 행이 있고, 각 직원은 어떤 직원(상사)에게 보고를 해야하는지 상사의 직원 번호를 담고있는 열이 있다고 하자.

이 때 같은 테이블에 대해 직원 번호 필드와 보고할 상사 번호 필드를 키로 INNER JOIN을 실행하면 직원과 그에 대응되는 상사 행을 합칠 수 있다.


9강 : Merge & Adv. techniques (2) - GROUP BY & HAVING

SQLite에는 여러가지 집계함수(SUM, AVG, COUNT, MAX/MIN, ROUND 등),
날짜함수(DATE, TIME, DATETIME, STRFTIME 등),
문자열함수(LENGTH, UPPER, || 등)가 있음.


GROUP BY & HAVING

script = """
SELECT
    albumid,
    COUNT(trackid)
FROM
    tracks
GROUP BY
    albumid
HAVING 
    COUNT(trackid) BETWEEN 18 AND 20;
""" 

위 코드에서, albumid가 같은 값인 행들끼리 그룹지어 묶은 후, 각 그룹의 albumid와 그 그룹 내의 행들의 trackid 개수를 카운팅함.

HAVING은 그룹핑에 대한 조건을 검.

WHERE와의 차이점은,

WHERE는 그룹핑 이전에 데이터를 추려냄. 예를 들어 WHERE albumid = 1 GROUP BY albumid를 쓰면, 모든 행을 albumid가 1인 행들만 남겨두고 그것만을 그룹핑해준다.

반면 HAVING은 모든 행에 대해 albumid을 기준으로 그룹핑을 진행 후 그 그룹들 중에서 albumid가 1인 그룹만 추려냄.

WHERE는 데이터를 미리 추려낸 후 그 것만을 그룹핑한다는점에서 효율성 측면에서 유리하다.

대신 HAVING은 WHERE와 달리 집계함수를 사용할 수 있다는 차이점이 있다.

기본적으로는 WHERE를 쓰고, 만약 그룹핑한 결과를 대상으로 집계함수 등을 활용해 조건을 걸고싶다면 HAVING을 사용하자.


물론 쿼리로 데이터를 일단 다 받아오고, df을 대상으로 여러 함수를 실행해서 분석해도된다. 선호에 맞게 하자.


10강 : Merge & Adv. techniques (3) - Subquery

Subquery

script = """
SELECT
    TrackId, 
    Name, 
    AlbumId
FROM
    Tracks
WHERE
    AlbumId IN (
        SELECT
            AlbumId
        FROM
            albums
        WHERE
            ArtistId = 12
    );
""" 

외래키가 참조하고 있는 테이블의 field를 조건으로 걸어 외래키를 고르고, 그 외래키로 현재 테이블에서 조건을 거는 방법이다.

외부 테이블에서 ArtistId가 12일 때를 조건으로 걸고 싶다면,

외래키인 AlbumId가 참조 테이블에서 ArtistId가 12인 행의 AlbumId만을 SELECT하여 그 안에 있는 AlbumId 값들을 원래 테이블 SELECT문에서 조건으로 걸면 된다.


참고로 AVG(SUM('field_name')) 같이 함수를 중첩해서 쓸 수는 없음. Subquery를 활용하여 구현하도록 하자.

script = """
SELECT
    AVG(SIZE)
FROM
    (SELECT
         SUM(bytes) AS SIZE
     FROM
         tracks
     GROUP BY
         albumid);
""" 

11강 : Selenium & SQLite3 (1) - 여행 상품 정보 DB 저장

BeautifulSoup에서는 tag에 대해 attrs['attr_name']으로 attribute value에 접근했는데, Selenium에서는 get_attribute('attribute_name')으로 접근한다.


12강 : Selenium & SQLite3 (2) - 여행 상품 이미지 자동 다운로드

glob

glob.glob('data/*.csv')

: data 폴더 내의 확장자가 csv인 모든 파일의 경로 및 파일명을 리스트 형태로 리턴해줌.

이를 활용해서 특정 경로에 있는 폴더들을 순차적으로 접근하여 활용할 수 있음

만약 column이 동일한 여러 파일이 있다면 그걸 순차적으로 접근해서 모두 concat해서 하나의 DataFrame으로 합칠 수도 있음


파일 삭제 및 URL 접근 후 파일 다운로드

import urllib.request
import glob
import os
%matplotlib inline

# 폴더에 있는 기존 jpg 파일 다 지우기
previous_images = glob.glob('images/*.jpg')
for image in previous_images:
    os.remove(image)

# 크롤링한 image url들
img_urls = list(df['image'])

for index, url in enumerate(img_urls):
    urllib.request.urlretrieve(url, "images/{}.jpg".format(index)) # 특정 url에 접근하여 파일을 다운로드하는 메소드. 첫 번째 arg : url, 두 번째 arg : 저장할 파일명 지정
    print('Downloaded image # :', index)
    time.sleep(0.3)
    
print('Download completed!')

image들을 행렬 형태로 plotting

fig = plt.figure(figsize=(15, 15)) 
rows = len(df['image']) // 5 + 1
cols = 5
i = 1

for filename in glob.glob("images/*.jpg"):
    
    ax = fig.add_subplot(rows, cols, i) # 전체 plot area를 rows, cols로 나눴을 때 i번 째 sub plot area를 생성
    ax.axis('off') # sub plot area도 하나의 독립적인 plot area임. 즉 메소드들이 그대로 있음. x축과 y축을 제거
    ax.imshow(Image.open(filename)) # image를 numpy array 값으로 리턴 후 imshow에 arg로 넘겨줌
    i += 1

plt.tight_layout(pad=0) # 불필요한 여백 제거
plt.show()

13강 : NoSQL & 추가 학습 자료

NoSQL

  • 대부분 오픈소스이다.

  • 관계형 모델을 사용하지 않는다.(RDBMS의 외래키 등)

  • 명시적인 스키마가 없다.(필드, 데이터 타입의 선언 설계 등)

  • 대용량 데이터를 다루기 용이하고, 데이터의 클러스터(컴퓨터) 내 멀티 노드 분산 저장(데이터 베이스 복사본)을 통해 fault tolerance

  • 데이터 모델에 4가지 종류가 있음(Key-Value, Document, Wide Column, Graph)

  • NoSQL에서 처리하기 어려운 5가지 작업 : Sorting, Join, Grouping, Range Query, Index

  • RDB : Oracle, MySQL(MariaDB), SQLite, Microsoft SQL server(MS SQL), PostgreSQL 등

  • No-SQL : MongoDB, ElasticSearch, Redis, Cassandra, HBase, Amazon DynamoDB 등

  • 상황과 목적에 맞게 NoSQL과 RDB를 병행해서 쓰면 됨 (대립 관계가 아님)

profile
PS, 풀스택, 앱 개발, 각종 프로젝트 내용 정리 (https://github.com/minsu-cnu)

0개의 댓글