https://opentutorials.org/course/2136/
생활코딩 강의를 이용해 진행하는 스터디 2주차.
4/5(목) :: 20강 'OrientDB 소개 및 기본 사용법' 부터 21강 'OrientDB로 웹애플리케이션 구현' 까지.
강의에서 사용하는 OrientDB는 처음 알게된 DB인데 내용이 꽤나 흥미롭다. MongoDB를 사용해본 적이 없어서 MongoDB로 수업이 진행 되었으면 더 좋았겠지만..
OrientDB
OrientDB는 NoSQL(Not Only SQL) 이면서 GraphDB이다. NoSQL 솔루션은 많이 알려졌듯이 RDB에 비해 확장성, 스키마 유연성 측면에서 강점이 있다.
GraphDB?
그래프 데이터베이스는 그래프 이론에 토대를 둔 일종의 NoSQL 데이터베이스이다. 객체나 노드로 불리는 데이터 포인트를 플롯하고, 이들의 관계를 선으로 연결해 데이터의 복잡한 관계를 더 쉽고 빠르게 파악하게 해준다.
1) 관계형 데이터베이스는 데이터를 열과 행으로 저장한다.
2) NoSQL 데이터베이스는 많은 비정형 데이터를 저장한다.
3) 그래프 데이터베이스는 더 나아가 데이터 포인트를 연결, 데이터 네트워크를 구축한다.
무엇이 더 좋냐 나쁘냐의 문제는 아니고, 해결하려는 문제에 더 적합한 데이터베이스의 형태가 있다고 할 수 있겠다. 어쨌든 OrientDB에서 제공하는 그래프 화면은 아래와 같다.
OrientDB는 MongoDB와 같이 도큐먼트 베이스로 동작하지만 Object-Oriented 특성을 추가로 갖는 특징이 있고,
RDB에서 사용하던 일반적인 SQL 구문을 이용해 데이터를 쉽게 찾을 수 있는 등의 이점이 있다.
OrientDB의 설치와 초기 설정
Enterprise는 돈을 지불해야 사용할 수 있는 것 같고, Community Edition을 내려받으면 된다. (*OrientDB는 Java로 만들어진 데이터베이스 엔진이기 때문에 사전에 Java가 설치되어 있어야 한다.) 설치방법은 매우 간단하다. Windows에서도 그냥 압축파일 형태로 되어있고, 아무데서나 압축을 해제한 후 생성된 bin 폴더의 server.bat를 시작하면 데이터베이스 서비스가 시작된다. (server.bat 파일을 열어보면 힙 메모리 크기, 동작 머신-x64/x86 등을 지정할 수 있으니 필요하면 건드리자.)
server.bat를 처음 시작하면 password를 물어보는데 root password에 해당되니 기억해두자. 서비스가 시작되고 나서 웹 브라우저를 이용해 localhost의 2480 포트로 접속하면 데이터베이스 관리자 화면을 확인할 수 있다. 여기서 데이터베이스를 생성하거나 스키마를 지정해줄 수 있다. 참고로 데이터베이스의 기본 접속 포트는 2424이고, 데이터베이스 GUI 관리자 화면의 접속 포트는 2480이 기본값이다.
Node.js에서 OrientDB 사용하기.
Node.js에서 OrientDB를 사용하려면 orientjs라 하는 모듈이 설치되어 있어야 한다.
npm install orientjs --save
사용 흐름과 쿼리 방식은 아래 스크린 샷과 같은데. 크게 어렵거나 하지 않아서. 사진으로 대체한다.
insert 후엔 insert 결과를 반환하는데 여기에서 @rid를 얻을 수 있다.
update/delete후엔 영향을 받은 row 수가 ['1'] 과 같은 형태로 반환된다.
OrientDB로 웹애플리케이션 구현
파일 기반으로 작성된 웹애플리케이션을 OrientDB로 변환하는 과정에 대한 내용이다. 아래와 같이 강사님처럼 API 지도를 만들어주면 전체적인 흐름을 파악하기에 좋다.
get('topic/') : view.jade
get('topic/:id') : view.jade
get('topic/add') : add.jade
ㄴpost('topic/add')
ㄴget('topic/:id')
get('topic/:id/edit') : edit.jade
ㄴpost('topic/:id/edit')
ㄴget('topic/:id')
get('topic/:id/delete') : delete.jade
ㄴpost('topic/:id/delete')
ㄴget('topic/')
자료를 OrientDB로 부터 읽어와 화면에 전달하는 로직은 크게 어렵지 않지만 주의할 점이 몇가지 있다.
1) OrientDB의 식별자는 '@rid'란 이름을 갖는데, jade에서 object.@rid와 같이 표현할 경우 에러를 뱉는다. 따라서 object['@rid']와 같은 표현으로 식별값에 접근해야 한다.
2) @rid의 값은 '#숫자:숫자' 형식으로 되어있는데, @rid를 이용해 링크 URL 등을 생성할 경우 '#', ':' 문자에 대한 처리를 해주어야 한다. '#'의 경우 페이지의 특정 위치로 스크롤하는데 쓰이는 특수 기호이기 때문이다. 강의에서는
encodeURIComponent(topic['@rid']) 와 같은 처리를 통해 @rid 값을 인코딩해 서버로 전달되게끔 구현하였다.
view.jade의 풀 소스는 다음과 같다. if / else 구문을 jade에 바로 사용할 수 있는 부분이 반갑다. '|'는 태그 없이 문자열을 출력하고 싶을 때 사용하면 된다.
doctype html
html
head
meta(charset='utf-8')
body
h1
a(href='/topic/') Server Side JavaScript
ul
each topic in topics
li
- rid = encodeURIComponent(topic['@rid'])
a(href='/topic/' + rid)= topic.title
article
if topic
h2= topic.title
= topic.description
else
h2 Welcome
| This is server side javascript tutorial.
br
div
a(href='/topic/new') new
이에 대한 핸들링 함수는 아래와 같다. 지저분해 보이지만 일단 동작하는게 우선.
조회 부분을 구현하고나면 다음. 추가 / 편집 / 삭제은 비교적 편하게 구현할 수 있다.
개발 과정에서 잘 모르는 건 console이든 browser로 보내든 output을 찍고 보는 습관.
추가 - INSERT
app.post('/topic/add', function(req, res) {
var title = req.body.title;
var description = req.body.description;
var author = req.body.author;
var sql = 'INSERT INTO topic (title, description, author) VALUES (:title, :description, :author)';
db.query(sql, {
params: {
title: title,
description: description,
author: author
}
}).then(function (results) {
res.redirect('/topic/' + encodeURIComponent(results[0]['@rid']));
});
});
편집 - UPDATE
편집 기능을 선택하면. 조회 로직과 유사하게 선택된 아이템의 값을 가져와 화면에 뿌려주는 부분을 구현하면 된다. 그리고나서 action의 URI를 edit로 지정하고, edit POST 요청에 대한 서비스를 구현하면 된다.
jade
article
- rid = encodeURIComponent(topic['@rid'])
form(action='/topic/' + rid + '/edit' method='post')
p
input(type='text' name='title' placeholder='title' value=topic.title)
p
textarea(name='description' placeholder='description')
=topic.description
p
input(type='text' name='author' placeholder='author' value=topic.author)
p
input(type='submit')
js
app.post('/topic/:id/edit', function (req, res) {
var sql = 'UPDATE topic SET title=:t, description=:d, author=:a WHERE @rid=:id';
var id = req.params.id;
var title = req.body.title;
var desc = req.body.description;
var author = req.body.author;
db.query(sql, {
params: {
id: id,
t: title,
d: desc,
a: author
}
}).then(function(topics) {
res.redirect('/topic/' + encodeURIComponent(id));
});
});
삭제 - DELETE
특별한 내용은 없지만 주의할 점이 있다. 데이터에 변경을 가하는 INSERT / UPDATE / DELETE 등의 작업에 대해 GET 메서드를 사용하지 않는 것과 더불어 그러한 기능을 수행하는 태그에 <a> 태그를 쓰지 않도록 한다.
<a> 태그를 사용하는 경우에 크롤링 엔진 등에 의해 해당 기능이 자동 실행될 수 있어 예기치 않게 데이터에 손상을 입힐 수 있기 때문이다.
jade
article
h1= 'Delete? ' + topic.title
- rid = encodeURIComponent(topic['@rid'])
form(action='/topic/' + rid + '/delete' method='post')
p
input(type='submit' value='YES')
a(href='/topic/' + rid) No
js
app.post('/topic/:id/delete', function (req, res) {
var sql = 'DELETE FROM topic WHERE @rid=:id';
var id = req.params.id;
db.query(sql, { params: { id: id }}).then(function(topics) {
res.redirect('/topic/');
});
});