Search
▪️

SQL Introduction

SQL vs NoSQL: Chossing a Database

두 형태의 데이터베이스에 대해서 공통 목표는 데이터를 저장하고 서버에서 쉽게 접근할 수 있게 하는 것이다.
파일과 차이가 무엇이길래 데이터베이스를 쓰는가? → 데이터베이스를 이용하면 정말 일부의 데이터를 읽기 위해서 모든 데이터를 다 읽을 필요가 없다.
SQL 데이터베이스로는 MySQL 등, NoSQL 데이터베이스로는 MongoDB 등이 있다.
SQL 데이터베이스는 Tables, Attributes, Records 3개의 요소로 구성된다.
또한 가장 큰 특징은 Table간 Relate 시킬 수 있다는 것이다.
따라서 한 테이블에 모든 정보를 다 저장할 필요 없이, 테이블 범주에 맞는 데이터만 저장 후 Relate 시켜서 정보를 불러올 수 있다는 것이다.
SQL 데이터베이스의 또 다른 큰 특징은 Schema를 갖는다는 것이다.
Data Schema는 Table을 구성하는 Attribute들의 Type에 대해서 정의할 뿐 아니라, Table에 데이터를 넣기 위해서 이 Schema를 만족하지 않으면 데이터를 삽입할 수 없다.
데이터베이스를 Relate시킬 때는 Data Relation에 대해서 3가지 유형을 갖는다.
One-to-One
One-to-Many
Many-to-Many
NoSQL 데이터베이스는 SQL 데이터베이스의 Query Language와는 다른 Query Language를 이용한다.
또한 SQL 데이터베이스처럼 Schema나 Relation에 대해서 제약이 없다. (존재하지 않는다 하지만 Relate시키려면 강제로 시킬 수는 있다. 강제로 Relate 시키는 것은 대체로 권장하지 않는다. 이유는 여러 Query들을 중복하면서 처리를 해줘야 해서 굉장히 느려질 수 있다.)
NoSQL 데이터베이스는 SQL에서 Table역할을 하는 Collection들로 구성된다. 또한 Collection들은 Document라는 특별한 형태를 가진 Data들을 갖는다. Document내에 존재하는 데이터들은 JSON 형태와 굉장히 유사하게 생겼다.
NoSQL 데이터베이스는 SQL 데이터베이스의 엄격한 데이터 타입들이나 형태를 강제하는 Schema를 따르지 않기 때문에 상대적으로 유동적인 데이터 형태를 갖는다.
SQL 데이터베이스와의 또 다른 가장 큰 차이점은 Relation을 갖지 않아서 관계 정의가 없다는 것이다. 이것이 중요한 이유는, SQL 데이터베이스에는 Relation을 갖기 때문에 중복 데이터를 갖지 않아도 Relationship을 갖는 두 테이블의 JOIN으로 데이터를 쉽게 접근할 수 있었다면, NoSQL 데이터베이스는 이런 것이 불가능하기 때문에 중복 데이터에 대해서 용인한다. 따라서 NoSQL에서 Collection이 갖는 데이터들을 살펴보면, 정확히 그 Collection이 필요로하는 데이터들을 모두 온전히 가지고 있다.
SQL의 경우 여러 Table에 중복 데이터를 갖지 않기 때문에 데이터 변화에 대해서는 빠르게 대처할 수 있지만, 필요로하는 데이터를 취득하기 위해서는 여러 Table로부터 데이터를 가공하여 얻어야 한다.
반대로 NoSQL의 경우 한 Collection내에는 목적에 맞는 데이터들이 이미 존재하기 때문에 (다른 테이블에 있는 정보와 중복되더라도 말이다.) 필요로하는 데이터를 취득하는데는 빠르지만, 변화가 많이 일어나는 데이터에 대해서는 중복되는 부분들을 Multiple하게 처리해야하므로 이런 부분에는 취약하다.

Horizontal Scaling vs Vertical Scaling

Horizontal Scaling: Add More Servers (and merge Data into one Database)
Vertical Scaling: Improve Server Capacity / Hardware
Horizontal Scaling is difficult or impossible on SQL Database
Vertical Scaling is possible on SQL Database
** SQL 동작 방식으로 인해 Horizontal Scaling은 현실적으로 어렵다.
** 혹여나 추가를 한다고 하더라도, 하나의 공유하고 있는 데이터에 대해서 여러 서버를 구동하는 것은 굉장히 어렵다.
** 또한 성능이 좋은 서버를 여럿 둔다고 했을 때, 각 서버가 날리는 Query들이 어마어마하게 많은 JOIN 연산 등을 요구하는 것들이라면 제약이 생길 수 밖에 없다.
Both Horizontal & Vertical Scaling is possible on NoSQL
NoSQL에서 Horizontal Scaling을 수행할 때, 특정 기능을 수행하는 서버들을 여럿 두어 운영하는 것이 가능하다. 즉, 분산 운영이 가능하다는 것이다. 그리고 SQL처럼 복잡한 Query 연산 들이 없어도 주어진 데이터만으로 잘 처리할 수 있기 때문에 많은 서버를 두어도 하나의 CPU로 데이터베이스를 구동했을 때 큰 제약은 없다. 따라서, 대용량을 차지하는 데이터 처리에 용이하다는 것이다. 이를 통해 NoSQL은 분산 시스템과 빅 데이터에 유리하다는 것을 알 수 있다.

Connecting our App to the SQL Database

MySQL과 MySQL Workbench를 설치한 후, Workbench를 통해 Database Schema를 만들었다면 작성 중인 프로젝트에도 MySQL 관련 Third Party Package들을 설치해야 한다. 이를 통해 SQL Code를 쓸 수 있고 Node.js에서도 Database와 Interact할 수 있게 해준다.
npm install —save mysql2
Package를 설치했다면, SQL 데이터베이스와 연결할 수 있는 코드를 작성해줘야 한다. (Helper Function) 이 코드들을 통해서 Connection Object를 받으면, 데이터베이스에 Query를 던질 수 있게 된다. 아래와 같은 인스턴스를 사용하도록 한다.
const mysql = require('mysql2')
데이터 베이스 인스턴스를 생성했다면, 인스턴스에 연결해줘야 하는데 Single Connection과 Multiple Connection이 가능하다. Single Connection의 경우 createConnection()을 이용하고, Multiple Connection은 createPool()을 이용한다. Pool을 이용한다면, 원하는 Query를 제시했을 때마다 Pool에서는 새로운 Connection을 만들어주고 Pool은 이런 Multiple한 Connection에 대해서 관리하게 된다. Query는 각자만의 Connection을 갖게 되고 이런 Multiple Connection을 Pool에서 관리하므로 여러 Query를 동시에 수행할 수 있게 된다. 아래와 같이 이용한다.
const pool = mysql.createPool()
createPool에서는 JSON형태의 데이터를 인자로 받는다. 해당 인자에는 데이터베이스의 엔진과 데이터베이스의 호스트에 대한 정보들이 들어가게 된다.
{ host: 'localhost', user: 'root' database: '$databaseName', password: '$password' }
이렇게 Pool에 대한 설정이 끝났다면, 이를 Export해줘야 하는데 기존 Export와는 달리 Promise로 Export해줘야 한다. (Connection과 관련된 이런 비동기 작업들에 대해서는 여러 Callback들을 두어 코드를 복잡하게 하는 것보다 Promise를 통해 조금 더 Structured된 코드로 처리하게 한다.)
아래와 같이 Export를 하고 나면, 해당 Export 모듈을 이용하여 Pool에 접근하고 데이터베이스에 연결하여 Query를 날릴 수 있게 된다.
module.exports = pool.promise()
Pool Module을 Import하고 execute() Method를 통해서 Query를 작성하여 보낼 수 있다.
execute() Method로 데이터베이스에서 Promise로 데이터를 갖고 오고 후처리를 하고 싶다면, then() Method와 catch() Method 를 이용하도록 한다.
execute() Method로 처리한 데이터들을 then() Method로 results를 받으면, results는 Array 형태로 들어오게 되는데, 0번째 Index가 실질 데이터들이고 나머지는 Meta 데이터들이다.
만일 데이터를 execute로 받아오고 이들을 이용하기 위해서는 별도의 처리가 필요하다. 받아온 데이터들을 then으로 처리하기 위해서 then의 인자로 Argument List를 주어야 한다. 주어지는 Array는 [rows, fieldData]와 같이 주어지는데 rows가 실질 데이터들, fieldData가 Meta 데이터들이다.