본문 바로가기
Server

11. 데이터베이스(2)

by Doromi 2018. 1. 13.
728x90
반응형

5-2-3. 테이블 생성

 

테이블 생성은 mnesia:create_table(Name, Args) 함수를 사용한다.

Name은 생성할 테이블 이름을 Atom 형식으로 작성, record 이름을 사용하면 편리하다.

Args에는 테이블의 타입과 각종 테이블 관련 설정값들을 튜플의 리스트로 입력한다.

 

Mnesia에서 생성할 수 있는 테이블에는 3가지 종류가 있다.

 

ram_copies

disc_only_copies

disc_copies : 데이터를 디스크와 메모리에 동시에 저장한다. 가장 추천하는 옵션

 

mnesia:create_table 함수의 주요 설정값

{attributes, List} : 테이블의 칼럼 이름을 리스트 형식으로 입력한다.

예를 들어 전에 정의했던 users라는 record를 사용하는 테이블이라면  {attributes, record_info(fields, users)}라고 작성

 

간단한 테이블 예제로 users 테이블을 disc_copies 테이블로 생성한다면

mnesia:create_table(users, [attributes, record_info(fields, users)},{disc_copies, [node()]}])

리턴값으로 {atomic,ok}가 나오면 생성되었다는 뜻이다.

에러가 났을 경우 {aborted, Reason} 형식의 값이 리턴된다.

 

5-2-4. 쓰기 읽기

 

생성한 테이블에 값을 읽고 쓰는 것은 트랜잭션을 하느냐 안하느냐에 따라서 방법이 다르다.

트랜잭션 없이 간단하게 읽고 쓰려면 dirty 함수를 이용하면 된다.

 

mnesia:dirty_read(Table, Key) -> ValueList | exit({aborted, Reason})

mnesia:dirty_write(Table, Record) -> ok | exit({aborted, Reason})

mnesia:dirty_delete(Table, Key) -> ok | exit({aborted, Reason})

 

간단하고 빠른 장점이 있다.

 

 

5-3. DB 연동 구현

 

mon 서버에 Mnesia를 연동할 때가 왔다.

users record를 살펴보면, 너무 빈약하다. 좀 더 풍성하게 만들어보겠다.

 

mon_record.hrl 파일을 고친다.

 

 

 

 

record 이름을 users라고 한 이유는 얼랭에 기본으로 존재하는 user라는 모듈과 이름이 중복된다는 점.

 

 

 

 

 

 

 

 

데이터베이스 관련된 작업을 하는 모듈을 하나 생성하겠다.

이름은 mon_db.erl

 

그리고 vm.args에 마지막 문장을 또 추가한다.

-mnesia dir '"./db"'

Mnesia에서 생성하는 디렉토리도 설정한다.

디렉토리 설정하는 옵션은 -mnesia dir이다.

큰따옴표 ""으로 묶고 작은 따옴표 ''으로 한번 더 감싸야 한다.

 

 

이렇게 하면 앞으로 db라는 디렉토리 밑에 Mnesia와 관련된 파일들이 생성될 것이다.

 

-include("mon_record.hrl").

%% API
-export([install/0, uninstall/0]).

install() ->
ok = mnesia:create_schema([node()]),
application:start(mnesia),
mnesia:create_table(users, [{attributes, record_info(fields, users)},
{disc_copies, [node()]}]),
application:stop(mnesia).

uninstall() ->
application:stop(mnesia),
mnesia:delete_schema([node()]).

mon_db.erl에 추가한다.

 

-include는 record 데이터를 사용하기 위해 헤더 파일을 추가한 것이다.

컴파일 진행한 후, 서버를 실행시켜서 mon_db:install()을 실행한다.

 

 

프로젝트 디렉토리를 확인하면 db라는 폴더가 생기고

안에 3개의 파일이 생성된 것을 확인할 수 있다.

 

 

 

 

 

 

 

 

Mnesia 데이터베이스가 초기화 되었으니 이제 서버가 시작될 떄에 Mnesia도 실행시켜 주어야 한다.

 

mon_app.erl에서 44라인에 applicaiton:start(mnesia)를 추가하고, ETS 테이블을 생성했던 코드는 이제 삭제하겠다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

컴파일 하고 다시  서버를 시작한다.

그냥 봐서는 Mnesia가 실행된건지 아닌건지 알길이 없다.

mnesia:info()를 실행해본다.

 

 

현재 동작중인 mnesia의 정보를 확인할 수 있다.

이제 남은 구현 작업은 users 테이블에 쓰고, 읽는 부분이다.

users 데이터를 관리하기 위해 모듈을 분리하는 것이 좋을 것 같다.

 

 

 

 

 

 

 

 

 

 

 

mon_users.erl을 추가한다.

회원 가입을 위한 join/2 함수를 만들어서 Id와 Password를 데이터베이스에 저장하면 될 것 같고,

로그인을 위한 login/2 함수를 만들어서 데이터베이스에서 해당값을 읽고 확인하면 될 것 같다.

 

 

mon_users.erl에 추가한다.

 

33라인에 U는 할당만 하고 사용하지 않아서 컴파일 시 Warning이 뜰 수 있는데, 우선은 그냥 넘어가도록 한다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

%% API
-export([init/3, handle/2, terminate/3]).

init(_Type, Req, []) ->
{ok, Req, no_state}.

handle(Req, State) ->
{Api, Req1} = cowboy_req:binding(api, Req),
{What, Req2} = cowboy_req:binding(what, Req1),
{Opt, Req3} = cowboy_req:binding(opt, Req2),
%% 데이터 로딩
{ok, Data, Req4} = cowboy_req:body_qs(Req3),

io:format("api=~p, what=~p, opt=~p ~n",[Api, What, Opt]),

Reply = handle(Api, What, Opt, Data),

{ok, Req5} = cowboy_req:reply(200, [
{<<"content-type">>, <<"text/plain">>}
], Reply, Req4),
{ok, Req5, State}.

handle(<<"login">>, _, _, Data) ->
Id = proplists:get_value(<<"id">>, Data),
Password = proplists:get_value(<<"password">>, Data),
case mon_users:login(Id, Password) of
ok ->
<<"{\"result\":\"ok\"}">>;
_ ->
<<"{\"result\":\"fail\"}">>
end;
handle(<<"join">>, _, _, Data) ->
Id = proplists:get_value(<<"id">>, Data),
Password = proplists:get_value(<<"password">>, Data),
case mon_users:join(Id, Password) of
fail ->
<<"{\"result\":\"duplicated\"}">>;
ok ->
<<"{\"result\":\"join\"}">>
end;
handle(<<"hello">>, <<"world">>, _, _) ->
<<"{\"result\":\"Hello world!\"}">>;
handle(_,_,_,_) ->
<<"{\"result\":\"error\"}">>.

terminate(_Reason, _Req, _State) ->
ok.

mon_http.erl 파일을 수정한다. ets를 사용했던 부분을 고쳤다.

이제 완료되었다. 다시 컴파일후 실행한다음 curl을 이용해서 테스트하겠다.

 

 

문제 없이 동작한다.

다시 껐다가 켠 후 테스트해도 데이터베이스에 유저의 정보가 잘 저장되어 있어서 문제없이 로그인이 된다.

 

 

 

테스트를 하지 않아도 바로 확인하는 방법은 얼랭 쉘에서 mnesia 명령어를 통해서 데이터를 읽는 것이다.

 

 

트랜잭션이 없는 dirty 함수를 이용해서 데이터를 읽어 보았다.

처음에는 record 정보가 없어서 단순한 튜플 형태

rr()함수로 record 정보를 읽은 후에는 users의 각각의 필드 내용까지 확인 가능하다.

 

 

 

 

 

 

 

또 다른 방법으로는 얼랭의 디버깅 툴 중에 하나인 observer를 이용하는 것이다.

얼랭 쉘에서 observer:start()를 입력한다.

 

그러면 창이 하나 뜬다.

우리는 Mnesia의 테이블 정보를 확인하고 싶으니, 상단의 여러 가지 탭중에서 Table Viewer를 선택한다.

그다음 메뉴에서 View를 클릭하고 나오는 항목 중에서 Mnesia Tables를 선택한다.

 

 

 

그럼 우리의 users 테이블이 보일 것이다.

테이블을 클릭하면 데이터까지 보인다.

 

Edit 메뉴를 이용하면 Search나 Delete 등의 작업이 가능하니 마음대로 사용할 수 있다.

 

728x90
반응형

'Server' 카테고리의 다른 글

13. 유저 세션(2)  (0) 2018.01.15
12. 유저 세션(1)  (0) 2018.01.15
10. 데이터베이스(1)  (0) 2018.01.12
9. 로그인(3)  (0) 2018.01.11
8. 로그인(2)  (0) 2018.01.11