Posting

Machbase의 최신 소식을 지금 만나보세요

[MACHBASE R] R연동

마크베이스(Machbase) 와 R과 연동하기  (리눅스 환경)

최근 들어 오픈소스 분석 도구인 R의 사용자가 크게 늘어났다.
무료이고 많은 사용자들이 다양한 방법으로 R 커뮤니티에 공헌을 하고 있으며, 응용 분야도 넓기 때문에 저변이 점점 더 확장된다고 보인다. 
여기에서는 데이터 분석의 준비 단계로서 마크베이스와 R과의 연동을 통해 향후 데이터 분석을 통한 기본적인 사항을 점검해 보도록 하겠다.

마크베이스의 빠른 데이터 로딩과 분석 성능을 기반으로 데이터를 R과 함께 분석할 수 있다면 좋은 조화가 아닐까 생각이 되기 때문이다.

수행 환경

여기서는 리눅스의 우분투 14.04 환경에서 연동을 해 보는 것으로 한다. 그러나, 다른 환경(윈도우 포함) 에서도 크게 어려움은 없을 것으로 생각된다.

ODBC 환경 체크

R과 마크베이스의 연동에는 기본적으로 ODBC를 통한 연결을 기본으로 한다. 따라서, 해당 리눅스 시스템에 마크베이스를 위한 ODBC 환경이 설치되어 있는지 확인한다. 자세한 내용은 관련 ODBC 설치 블로그 내용을 참조하면 될 것으로 보인다. 다음과 같이 machbase 라는 DSN으로 unixodbc가 연동되는 것을 확인한다.

mach2@mach-Precision-T1700:~$ isql machbase
+---------------------------------------+
| Connected! |
| |
| sql-statement |
| help [tablename] |
| quit |
| |
+---------------------------------------+
SQL> help
+----------+------------+-----------------------------------------+-----------+--------+
| TABLE_CAT| TABLE_SCHEM| TABLE_NAME | TABLE_TYPE| REMARKS|
+----------+------------+-----------------------------------------+-----------+--------+
| IFLUX | SYS | MACH | TABLE | |
| IFLUX | SYS | SAMPLE_TABLE | TABLE | |
+----------+------------+-----------------------------------------+-----------+--------+
SQLRowCount returns 2
2 rows fetched
SQL> quit
mach2@mach-Precision-T1700:~$ 

RODBC 라이브러리에 대해위와 같이 ODBC가 성공적으로 동작하는 환경을 가정한다.

DSN은 machbase 이다.
R에서는 일반 데이터베이스와의 쉬운 연동을 위해서 RODBC라는 훌륭한 라이브러리를 제공하고 있다.
RODBC는 기본적으로 모든 DBMS에 대한 접근을 추상화시킨 API를 가지고 있는데, 아래와 같은 링크에서 기본적인 정보를 얻을 수 있다.

공식 홈페이지 : https://cran.r-project.org/web/packages/RODBC/index.html
매뉴얼 PDF : https://cran.r-project.org/web/packages/RODBC/RODBC.pdf

그러나 해당 매뉴얼을 모두 읽고 세세하게 따지기에는 분량이 적지 않기 때문에 아래의 간단한 도표를 보고 넘어가도 무방하다.
나중에 샘플을 통해서 몇가지 API만 사용해도 충분하기 때문이기 때문에 부담을 가지지 말자.

아래표는 마크베이스에서 RODBC API 리스트를 나타낸 것이며, 간단할 설명과 지원 유무를 표시한 것이다.
주로 사용되는 5~6 가지 함수들에 대해서는 색깔로 표시해 놓았으니 참고하자.

RODBC API설 명마크베이스 지원 (O, X)
odbcConnect()연결 수행O
odbcClose()연결 해지O
odbcCloseAll()모든 연결 해지O
sqlClear()테이블 데이터 비우기 (모두 지움)O
sqlDrop()테이블 DropO
sqlQuery()쿼리 수행 및 레코드 가져 오기O
sqlFetch()레코드 가져 오기O
sqlFetchMore()남은 레코드 가져오기O
sqlColumns()컬럼 정보 얻기O
sqlTables()모든 테이블 정보O
sqlTypeInfo데이터 타입 얻기O
sqlCopy한 테이블의 데이터를 다른 테이블로 복사O
sqlSaveframe의 데이터를 테이블로 저장O
odbcDriverConnect연결 수행O
odbcGetErrMsg에러 메시지 가져 오기O
odbcClearError에러 스택을 초기화함.O
sqlGetResults남은 레코드 가져오기O
odbcFetchRows특정 갯수 만큼 데이터 가져 오기O
odbcQuery질의 수행 및 데이터 가져 오기O
odbcTables특정 테이블 정보 추출O
odbcSetAutoCommitautocommit 수행 플래그O
odbcGetInfoODBC 드라이버 정보(dll 등..)O
getSqlTypeInfo데이터베이스별 지원되는 ODBC 타입O
sqlPrimaryKeys주기 확인O
odbcReConnect연결을 재시도O
sqlCopyTable테이블 복사O
odbcDataSourcesODBC 데이터 소스 확인X
odbcEndTran트랜잭션 완료X
odbcUpdate데이터 갱신X
setSqlTypeInfo타입 설정X
sqlUpdate데이터 갱신X

간단하게 R의 마크베이스 연동해 보기

여기에서는 간단하게 연동해서 동작하는지 확인을 해보는 것으로 마치겠다. 우선 마크베이스가 동작하고, ODBC가 설정된 환경을 가정한 상태에서 아래와 같이 R 혹은 R-studio를 설치하자. 설치는 다음과 같이 한다.

Ubuntu 계열
sudo apt-get install R-base

CentOS 계열 
sudo yum install R

아래와 같이 R을 수행하고 RODBC 사용 명령어를 입력해 보자.
library(“RODBC”)

mach2@mach-Precision-T1700:~$ R
R version 3.4.1 (2017-06-30) -- "Single Candle"
..................
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.
> library("RODBC");
Error in library("RODBC") : there is no package called 'RODBC'

위와 같이 에러가 발생하면 RODBC가 설치되지 않은 것이다.
그래서 다음과 같이 R을 위한 설치 과정을 수행한다. (아래는 개인 디렉토리에 설정하였다)

install.packages(“RODBC”)

> install.packages("RODBC")
Installing package into '/usr/local/lib/R/site-library'
(as 'lib' is unspecified)
Warning in install.packages("RODBC") :
'lib = "/usr/local/lib/R/site-library"' is not writable
Would you like to use a personal library instead? (y/n) y # <========= 개인 디렉토리에 설치
Would you like to create a personal library
~/R/x86_64-pc-linux-gnu-library/3.4
to install packages into? (y/n) y # <========= 내 디렉토리 지정
--- Please select a CRAN mirror for use in this session ---
trying URL 'https://cran.ism.ac.jp/src/contrib/RODBC_1.3-15.tar.gz'
Content type 'application/x-gzip' length 1163967 bytes (1.1 MB)
==================================================
downloaded 1.1 MB

* installing *source* package 'RODBC' ...
** package 'RODBC' successfully unpacked and MD5 sums checked
checking for gcc... gcc -std=gnu99
.......................... 생략 ........................................
** installing vignettes
** testing if installed package can be loaded
* DONE (RODBC)

위와 같이 성공적으로 설치되었다. 혹시나 설치가 실패한 경우에는 뭔가 문제가 발생한 것이므로 관련 자료를 찾아서 해결해야 한다.
다시 RODBC를 사용해 보자.

> library("RODBC");
>

위와 같이 나오면 접속이 성공한 것이다... (성공 메시지도 없고....)

그럼 본격적으로 마크베이스에 접속해 보도록 하자.
odbcConnect() 함수를 사용하는데, 중요한 것은 두번째와 세번째 인자는 반드시 아래의 예제대로 넣어야 한다는 것이다. DBMS에 특성에 따라 많은 플래그와 변수들이 존재하므로 그대로 따라야 한다.

물론 다른 데이터베이스에 대한 접속시에는 인자의 갯수 및 값도 바뀔 것이라고 추측된다.

> channel <- odbcConnect("machbase", believeNRows=FALSE, case="toupper")

역시 아무 말 없으면 성공! 만일 접속시에 에러가 나면 여러가지 형태로 에러를 나타낸다.
혹시나 마크베이스 서버를 구동하지 않았다면 다음과 같은 에러가 나니 참조하자.

> channel <- odbcConnect("machbase", believeNRows=FALSE, case="toupper")
Warning messages:
1: In RODBC::odbcDriverConnect("DSN=machbase", believeNRows = FALSE, :
[RODBC] ERROR: state 08001, code 0, message [unixODBC][IFLUX][ODBC IFLUX Driver][0]Client unable to establish connection
2: In RODBC::odbcDriverConnect("DSN=machbase", believeNRows = FALSE, :
ODBC connection failed

테이블 생성

myr 이라는 테이블을 생성해보자.

> res <- sqlQuery(channel, "create table myr (id integer)");



테이블이 생성되었는지

sqlTables

() 함수를 통해 확인해 보면

> sqlTables(channel)
TABLE_CAT TABLE_SCHEM TABLE_NAME TABLE_TYPE REMARKS
1 IFLUX SYS MYR TABLE

MYR 이라는 테이블이 생성된 것을 볼 수 있다.
컬럼 정보도 확인해 보자. sqlColumns()를 수행.

> sqlColumns(channel, "myr")
TABLE_CAT TABLE_SCHEM TABLE_NAME COLUMN_NAME DATA_TYPE TYPE_NAME COLUMN_SIZE
1 SYS MYR ID 4 INTEGER 11
BUFFER_LENGTH DECIMAL_DIGITS NUM_PREC_RADIX NULLABLE REMARKS COLUMN_DEF
1 0 0 10 1
SQL_DATA_TYPE SQL_DATETIME_SUB CHAR_OCTET_LENGTH ORDINAL_POSITION IS_NULLABLE
1 4 0 0 1 YES

ID라는 컬럼이 생성된 것을 알 수 있다.

데이터 넣기

이제 간단하게 데이터를 넣어보자.
sqlQuery를 통해 insert 를 몇개 수행하면 된다.

> res <= sqlQuery(channel, "insert into myr values(1)");
logical(0)
> res <= sqlQuery(channel, "insert into myr values(1)");
logical(0)
> res <= sqlQuery(channel, "insert into myr values(2)");
logical(0)
> res <= sqlQuery(channel, "insert into myr values(2)");
logical(0)
> res <= sqlQuery(channel, "insert into myr values(2)");
logical(0)
> res <= sqlQuery(channel, "insert into myr values(3)");
logical(0)
> res <= sqlQuery(channel, "insert into myr values(4)");
logical(0)

데이터 확인

sqlQuery를 통해서 SELECT를 수행하면, 아래와 같다.

> rs <- sqlQuery(channel, "select * from myr")
> rs
ID
1 2
2 2
3 1
4 4
5 3
6 2
7 1

rs 변수에 데이터가 아름답게 입력된 것을 볼 수 있다. 쉽다!!!

이제 아주 간단한 통계 쿼리를 날리고, 화면에 출력해 보자.

쿼리는 ID의 종류와 갯수를 연산하는 GROUP BY 쿼리이다.

GROUPING 통계 연산

> rs2 <- sqlQuery(channel, "select id, count(id) from myr group by id ");
> rs2
id count(id)
1 2 3
2 4 1
3 3 1
4 1 2

위를 보면, 각각의 아이디에 대한 갯수가 rs2에 통계 값으로 저장되었다.

화면에 plot으로 찍으면 다음과 같이 간단하지만 우아하게 나온다!

가로축은 ID 종류이고, 세로축은 각 ID의 갯수인 것을 볼 수 있다.

연결 종료

> odbcClose(channel)

성공적으로 ODBC 연결 종료!

전체 소스코드

library("RODBC")
channel <- odbcConnect("machbase", believeNRows=FALSE, case="toupper")
res <- sqlQuery(channel, "drop table myr");
res <- sqlQuery(channel, "create table myr (id integer)");
sqlTables(channel)
sqlColumns(channel, "myr")
sqlQuery(channel, "insert into myr values(1)");
sqlQuery(channel, "insert into myr values(1)");
sqlQuery(channel, "insert into myr values(2)");
sqlQuery(channel, "insert into myr values(2)");
sqlQuery(channel, "insert into myr values(2)");
sqlQuery(channel, "insert into myr values(3)");
sqlQuery(channel, "insert into myr values(4)");
rs <- sqlQuery(channel, "select * from myr")
rs2 <- sqlQuery(channel, "select id, count(id) from myr group by id ");
plot(rs2)
odbcClose(channel)

위의 코드를 잘 활용하도록 하자.

여기에서는 간단하게 마크베이스와 R과의 연동을 RODBC를 통해서 해 보았다.
생각보다 연결과 쿼리의 수행이 매우 쉬웠고 SQL만 제대로 이해하면 꽤 쉬운 편이다.

다음에는 천만 건 이상의 실제 데이터를 가지고 분석을 해 보는 시간을 가져보도록 하겠다.

Contact the Machbase team with your questions!
info@machbase.com

연관 포스트

C언어로 Binary data를 Machbase에 넣기

1.개요 Data를 다루다 보면 numeric, varchar 형 데이터뿐만 아니라 JPG, PNG, MP3와 같은 Binary data도 database에 저장해야 할 때가 존재한다. 그러나 일반 data들과는 달리 Binary

[MACHBASE 연동] Android studio에서 JDBC 연결하기

마크베이스 기술지원본부 이현민 1. 개요 수많은 데이터들이 많은 환경에서 생성되고 있는 오늘날, 우리 현대인들의 동반자인 스마트폰 또한 데이터생성의 주체로써 또는 전달자로서 알게 모르게 그 구실을