사진을 찍자 – #2. 사진기 살펴보기

사진을 찍자 – #1. 개요 그리고 잡설

사진을 찍자 – #3. 노출

사진을 찍자 – #4. 구도

너무나 당연하지만 사진을 찍으려면 카메라가 있어야 한다. 돼지 목에 진주목걸이라 아무리 비싼 카메라를 들고 있어도 배터리 구멍에 메모리 카드를 아무리 밀어 넣어봤자 카메라는 그냥 비싼 벽돌일 뿐이니… 카메라의 종류와 상관 없이 대부분의 카메라에 공통으로 적용할 수 있는 몇 가지 기본적인 것들을 알아보자.

마운트

전투형, 중고 K-3 / 정면에서 보면 대충 이렇게 생겼다.

저 동그랗고 크고 아름다운 구멍에 렌즈를 꽂으면 된다.
저 구멍의 모양(규격)은 제조사마다 다르고 사람들이 ‘E-마운트’니 ‘K-마운트’니 하는 것이 그 제조사가 규격을 정하고 이름을 붙인 것이다.

좌측 하단의 SR1Shake Reduction: 카메라를 들고 있는 동안 사람의손이 떨리므로 이를 줄이기위해 촬상소자(CCD / COMS)를 미세하게 움직이는 기술. 촬상소자를 움직이는 방식, 렌즈를 움직이는 방식(렌즈 자체가 뱀처럼 움직이는 것이 아니라 내부의 렌즈들이 움직인다) 두 가지가 있다. 동영상에서의 손떨방은 조금 다른 의미로 이해 해야 한다. 글씨 바로 우측의 동그란 버튼은 렌즈를 고정하는 버튼으로써 그냥 두면 고정상태, 누르면 움직일 수 있는 상태가 된다.

그 버튼 오른쪽으로 보이는 금속의 접접들은 사진기의 본체와 렌즈가 통신하기 위한 접점이다. 렌즈 안의 조리개나, 렌즈를 움직이려면 전기도 들어가야 하고, 당연히 정도를 조절하기 위한 신호를 주고 받아야 한다.
여기서 하나 알고 갈 것은 바로 이 접접을 통해 통신하는 내용은 제조사가 공개하지 않는 다는 것이다. 그래서 흔히 알고 있는 서드파티2Third party: 원래 제조사 또는 제조사 또는 하청 등의 연관이 있는 회사가 아닌 제 3자의 회사, 개발자 등을 이야기 한다. (시그마, 탐론 등등)의 렌즈는 핀이 안맞네 어쩌네 하는 말이 나오는 것이 저 마운트 정보를 역으로 유추하여 취득해야 하므로 실제 동작이 원활하지 않을 수 있는 것.

미러

거울. Mirror

한 개의 렌즈를 통해 들어온 빛이 – 거울을 통해 반사되어 – 뷰파인더에 들어온다.
이래서 Single Lens Reflex = SLR3여기를 참조 카메라 되시겠다. 이게 뭐 대단해 하고 생각할 수 있겠지만.. 렌즈-촬영자의 눈 사이엔 필름이 있기 때문에 렌즈를 통해 보이는 사물을 사람이 볼 방법이 없다. 그래서 렌즈에 들어오는 대상과 비슷한 각도로 보이도록 별도로 뷰파인더를 달아서 사용하는데 4Range Finder 연동 카메라 같은 녀석들 당연히 렌즈와 연동일 뿐이지 정확히 일치할 수 없어서 초점을 맞추는 것도, 조리개 확인도 불가능하다는 단점을 해소하는데 의미가 있겠다.
SLR 앞에 Digital이 붙으면 D-SLR이 된다.
D-SLR 카메라에서 미러가 빠지면 ‘Mirror-less 카메라’가 된다. 미러리스 카메라의 크기가 작은 이유는 저 미러가 빠지고 프리즘이 빠지면서 그만큼의 공간을 줄였기 때문이다.
그리고 사진을 찍을 때 셔터가 물리적으로 움직이기 때문에 소리가 난다. 휴대폰 카메라 등에서 나는 ‘찰칵’ 소리가 마로 이 미러가 움직일 때 나는 소리이다.
SLR이 렌즈교환식 카메라를 의미하는 것이 아님을 꼭 기억하자

셔터(Shutter)

셔터, shutter / 샤따맨의 그 샤따가 맞다.
셔터 뒤엔 이렇게 ‘필름 역할’을 하는 촬상소자가 있다.

요즘엔 실제 물리 셔터5https://ko.wikipedia.org/wiki/%EC%85%94%ED%84%B0가 없는 카메라도 있지만 기본적으로 사진이 찍히는 과정은 다음과 같다.
1. ‘셔터버튼을 누른다’
2. ‘미러가 올라간다’ (일안 반사식 카메라가 아닌 경우는 이 과정이 생략된다.)
3. ‘셔터가 열린다’
4. ‘촬상소자(필름)에 빛이 닿는다’
이 과정에서 셔터를 누르면 전기신호를 발생 시켜서 셔터를 움직이면 전자식, 셔터버튼을 누르고 그 힘에 의해 셔터가 열리면 기계식 되시겠다.

초점(포커스, focus)

촬상소자에 상이 ‘선명하게 맺히도록 하는 점’을 의미한다.

18-35mm는 초점거리, 1:1.8은 렌즈의 최대 밝기, DC는 규격, 파이 값은 렌즈 구경

초점 거리는 렌즈-촬상소자 사이의 거리를 의미한다.

사람의 눈의 경우는 수정체의 두께를 조절하여 초점을 맞춘다. (카메라에 난시는 없지만..)

인간의 눈은 성능이 워낙 좋다보니 초점을 맞추는 작업을 한다는 사실을 인지하기도 전에 초점을 맞추는 작업이 끝난다.6 눈 앞에 손가락을 세우고 손가락과 손가락 뒤 모니터를 번갈아서 보자. 일단 초점을 맞추려는 대상은 선명하게 보이고 그 반대 대상은 흐리게 보임과 동시에 두개로 보인다.(눈이 두개니까)
카메라의 초점도 마찬가지다. 다만 렌즈의 성능이 인간의 눈에 한참 못 미치다보니 렌즈의 두께를 조절하지도 못해서 여러개의 렌즈를 겹쳐 두고, 렌즈를 움직임으로써 초점 영역을 맞추게 된다.
이 렌즈를 움직이는 작업이 자동으로 이뤄지면 AF(자동 초점, Auto Focus)
사람이 눈으로 보면서 렌즈를 수동으로 움직여서 작업해야 하면 MF(수동 초점, Manual Focus) 카메라가 된다.

사람의 눈도 이렇게 상이 거꾸로 맺히지만 뇌가 알아서 이를 보정한다.
external/www.pba...

이 과정에서 ‘Out of Focus’ 라는 말이 생겨났는데 이는 초점을 맞추는데 실패 한 것을 의미한다. 초점이 맞는 영역을 제외하고는 초점이 맞지 않아서 실패한 영역이 되는데 되려 원하는 피사체(예를들어 사람의 얼굴)를 제외하고는 흐리다보니 피사체에 집중할 수 있게 되는 효과를 얻게 됐다.
즉, 아웃포커싱 이라는 말은 잘못된 말이라는 것이다. (하지만.. 무슨 기술인냥 사용하고 있다..) 카메라 들고 아는체좀 하고 싶으면 아웃포커싱이란 말은 쓰지 말자.

AF카메라가 초점 영역을 검출하는 방법에 따라, 위상차 검출이지 적외선이니 하는 것들로 나뉜다. 이 검출 방식에 따라 핀 교정이 필요하게 된다. 상당히 공돌이스러운 내용이고 이를 설명하기엔 너무 많은 공간을 할애 해야 하므로 여기를 참조하면 된다.
위상차 검출 방식의 카메라를 사용할 경우 초점을 잡을 때엔 그 특성상 ‘경계선’이 될만한 곳을 초점 영역으로 삼아야 된다는 것을 참고하자. 7하늘을 찍을 때 구름이 있다면 구름과 하늘의 중간 지점이 초점 영역이 되어야 초점이 잘 잡힌다. 비슷한 색으로 이루어진 공간을 초점 영역으로 설정하면 안된다는 이야기다.

대부분의 AF카메라는 반셔터(셔터 버튼의 스위치는 이중으로 되어있다.)를 누르면 자동으로 초점이 맞춰진다.

조리개 (Aperture)

빛이 들어오는 구멍이다.

렌즈에 있는 가변식(크기 조절이 가능한) 구멍이다. 값은 ‘f숫자’ 로 표기한다. f 값이 작을 수록 렌즈가 밝다(=상대적으로 어두운 곳에서도 촬영이 가능하다)고 이야기 한다.
기본적으로 (렌즈의 초점거리)/(입사동공8(조리개 구멍)의 직경)으로 계산된다. 입사동공은 렌즈의 앞에서 본 조리개의 상을 말한다. 조리개의 지름이 커지면 f값은 작아지고, 빛이 모이는 양은 많아진다(즉 밝아진다). 초점거리가 길어질수록 같은 f값을 유지하기 위한 렌즈의 지름이 커져서 f값을 작게 제조하기 힘들어진다. 그래서 초점거리가 길고(멀고) f 값이 낮은 렌즈가 비싸다.

수동 조리개 렌즈는 렌즈의 하단(바디 쪽)에 조리개를 조절하는 장치(ring)이 달려있다. 보통의 카메라는 바디에서 조리개 값을 설정하면 셔터를 누를 때 조리개를 조절하도록 되어있다.
모든 렌즈는 기본적으로 조리개가 최대 개방상태로 유지되고, 촬영을 할 때 설정 한대로 조리개가 닫히도록 만들어져있다. 9그래야 렌즈-미러-프리즘-뷰파인더 로 빛이 많이 들어오니까

뷰파인더 (View finder)

뷰파인더를 들여다 본 모습, 스플릿 스크린이 장착된 모습

렌즈를 통해 들어온 대상을 사람도 볼 수 있게 뚫어놓은 구멍이다.
촬영의 편의를 위해 현재 상태 정보도 표시된다. 좌측부터 ‘셔터속도10셔터버튼을 누른 시점부터 셔터를 열어둘 시간‘, ‘조리개 값’, ‘측광 정보11빛이 얼마나 들어오는지 측정한 값을 기반으로 한 정보‘, ‘감도12ISO로 표시한다. 감도가 높으면 촬상소자가 적은 광량에 더 민감하게 반응한다는 이야기이다.‘ 순으로 정보를 표시 해 준다.

비싼 카메라일 수록 실제 촬영되는 영역과 뷰파인더에 보이는 영역의 넓이가 비슷해진다. 뷰파인더의 시야율이라고 한다.

미러리스 카메라의 경우는 미러와 프리즘이 없기 때문에 전자식 뷰 파인더를 탑재 하는 경우가 있다. (아예 없거나)

사진을 찍자 – #1. 개요 그리고 잡설

사진을 찍자 – #2. 사진기 살펴보기

사진을 찍자 – #3. 노출

사진을 찍자 – #4. 구도

※ 우선 필자는 사진이나, 디자인 등과 관련해서는 전문적인 지식이 전혀 없음을 밝힌다. 다만 사진기를 들고 다니면서 배운 것(a.k.a 꼼수)들을 남기는 것임을 밝힌다.

사진을 찍는 기술(꼼수)에 대해 이야기 하기 전에 감히 ‘좋은 사진’에 대해 얘기 해보고 싶다.
2000년 쯔음, 인터넷의 보급과 컴퓨터의 보급, 그리고 디지털 카메라의 가격이 현실성 있는 가격이 되면서 많은 사람들이 사진에 관심을 가지고 또 사진기를 들고 다니기 시작했던 것 같다. 덕분에 나처럼 사진에 문외한이던 사람들도 사진을 접할 수 있었고, 나름 ‘사진’이 취미로써 사람들의 주요 관심사 중 하나가 될 수 있었다. 단지 사진기의 가격에 대한 접근성 뿐 아니라 부가적인, 그러니까 필름이나 인화, 현상에 들어가는 비용까지 생각해보면 접근에 대한 비용은 더 낮게 느껴졌었고.

대충 2001~ 2002년 쯤 디지털 카메라를 처음 샀던 것 같고, 아직까지 종종 사진을 목적으로 집을 나서니 어림잡아 20년 가까이 사진을 취미로 가지고 있다. 물론 ‘사진 찍는 기술’은 그때나 지금이나 오십보 백보 차이는 없지만. 아직까지 누군가가 내가 찍은 사진을 보고 ‘와!’하고 감탄을 해 준 적도 없다. 카메라도 바꿔보고, 남들 좋다는 렌즈도 사보고, 또 포토샵이니 뭐니 디지털의 힘을 빌어보기도 했지만, 역시 재능은 재능인가보다. 난 재능은 없다.
하지만 서당개 삼년이면 풍월을 읊는다 하는 것처럼 한가지 확실히 배운 것은 있다.

‘셔터를 누르는데 주저하지 말라’

필름 카메라가 주이던 시절 셔터 한번 누르는 것은 상당히 큰 고민을 안겨주는 행위임에 틀림 없을 것이다. ‘셔터 한번’ = ‘돈’ 이었으니까. 내가 필름 카메라를 쓰던 당시 36컷 리얼라가 4000원 쯤 했으니 최소 필름 값만 셔터 한번에 100원이었다. 여기에 현상1현상(現象, development)은 필름 또는 인화지에 약품처리를 하여 사진의 상이 나타나도록 하는 작업에 들어가는 비용이 추가되고, 인화2인화(print, Photographic print)는 네거티브(음화)를 통해서 종이에 이미지를 포지티브(양화)하는 것 비용은 4*6 크기의 사진 한장에 대충 200~600원 정도 했었으니 분명 적은 돈은 아니었다.
하지만 지금은 디지털이다. 거리에 돌아다니는 카메라 십 중 팔구는 디지털이다. 카메라 배터리 충전에 들어가는 전기 사용료를 제외하고는 돈이 들지 않는다.
거기에 심.지.어 바로 확인도 된다. 현상을 기다릴 필요가 없다. 일단 주제가 있다면 셔터를 누르고, 바로 확인하고 지우면 된다.
만약 당신이 이제 막 카메라를 사서 사진을 잘 찍는 법을 알고자 한다면 고뇌하는 영화속 시인처럼 뭔가 뚫어지게 처다보지 말고 일단 셔터를 눌러 카메라의 액정으로 결과부터 확인 해도 전혀 문제 되지 않는다. 어느날 문득 광화문 광장의 세종대왕상을 남보기에 멋지도록 찍어보고 싶다면, 구도가 어쩌고 고민할 시간에 동상의 사방을 돌면서 조리개 값이니 뭐니 바꿔보면서 메모리카드 가득 세종대왕상을 담길 권하고 싶다.
지금은 한번 찍고나면 수정할 수 없던 그 때가 아니다. 세종대왕의 발끝부터 머리까지 구석구석 조각조각 촬영하고 나중에 이어붙이는 것도 가능하고, 렌즈커버를 닫은체 사진을 찍은 것이 아니라면 컴퓨터를 이용해 수정하면 된다.
일단, 셔터를 누르길 바란다.

‘바로 지금 찍어라’

처음 사진을 시작한다거나, 혹은 카메라의 사용법이 어쩌고, 화소가 어쩌고, 풀프레임이 어쩌고, 렌즈 밝기가 어쩌고 하면서 아무도 보이지 않는 빌딩의 밤을 찍겠다고 산에 오르려고 준비하고 있다면, ‘와 멋져요~’ ‘와 어떻게 이런 풍경을’ ‘어떻게 저 멀리 있는 달을 이리도 선명하게’ 같은 이야기를 들을만한 사진을 찍고 싶은 사람에게 꼭 이렇게 묻고 싶다.
‘지금 당신 컴퓨터엔 어머니,아버지의 사진이 몇장이나 저장 돼 있나요?’
달력에서 볼법한 사진, SLR클럽의 1면에 있는 사진, 퓰리쳐상을 수상한 사진, 신문에 실린 20년만에 나타난 무슨무슨 신기한 달 사진. 물론 이런 사진 나도 찍어보고 싶다. 나도 그런 사진들을 찍을 재능을 가지고 싶다. 누구인들 다르겠는가.
감히 이런 이야기를 글로 남기는 나 역시도 내일 새벽 지리산에서의 일출보다 지금 당장 김치 한조각에 소주를 털어넣고 계신 아버지의 얼굴이 훨씬 귀하다는 것을 깨닿는데 오랜 시간이 걸렸고, 카메라를 들이밀면 손사레를 치는 어머니를 찍는 일은 이상하리만지 어렵다는데 동의 한다.
하지만 꼭 기억했으면 한다.

지리산의 일출은 당신의 아버지가, 어머니가, 할아버지가, 할머니가, 형이, 누나가, 동생이 세상에 없어도 분명 떠오른다는 사실을.
지금 대충 눌러 찍은 노출과다의 어머니의 얼굴은 언젠가 당신이 찍은 그 어떤 사진보다 잘 찍은 사진임을 깨닿게 된다는 사실을.



TPC-H #1 . 준비

The TPC Benchmark™H (TPC-H) is a decision support benchmark. It consists of a suite of business oriented ad-hoc queries and concurrent data modifications.
라고 한다.
동일한 구조 동일한 데이터를 가진 테이블들을 대상으로 쿼리를 실행하여 하드웨어 성능을 비교할 때 사용한다. 1..고 한다. TPC 홈페이지에 가면 다양한 시험 방법을 제공한다.

설치
여타 소프트웨어의 설치와는 다르게 DBMS에 맞는 테이블 생성 쿼리와 샘플 데이터를 만드는 툴을 이용해 DDL과 샘플 데이터를 생성하는 것이 목적이다.
TPC 홈페이지에서 필요한 도구를 다운로드한다. 2예제는 tpc-h를 기준으로 한다. 계정,권한 관련 제한이 없으므로 아무 계정으로 다운로드 해서 진행 해도 무방하다.

PostgresQL에 테이블을 생성하고 데이터를 넣을 것이다.

dbgen(샘플데이터 생성기) 컴파일
압축 해제

[root@tpc tpc]$ ls
tpc-ds-tool.zip  tpc-h-tool.zip  v2.13.0rc1
[root@tpc tpc]# unzip tpc-h-tool.zip
...생략...
  inflating: 2.18.0_rc2/ref_data/300/supplier.tbl.19998
  inflating: 2.18.0_rc2/ref_data/300/supplier.tbl.29997
  inflating: 2.18.0_rc2/ref_data/300/supplier.tbl.30000
  inflating: 2.18.0_rc2/ref_data/300/supplier.tbl.9999
  inflating: 2.18.0_rc2/specification.docx
  inflating: 2.18.0_rc2/specification.pdf
[root@tpc tpc]$ ls
2.18.0_rc2  tpc-ds-tool.zip  tpc-h-tool.zip  v2.13.0rc1
[root@tpc tpc]$ cd 2.18.0_rc2
[root@tpc tpc]$ ls
EULA.txt  dbgen  dev-tools  ref_data  specification.docx  specification.pdf
[root@tpc 2.18.0_rc2]$ cd dbgen
[root@tpc 2.18.0_rc2]$ ls
BUGS           README   bcd2.h      check_answers    dbgen.dsp  dss.ddl  dsstypes.h      permute.c  qgen.c       reference  rnd.h    shared.h      text.c    tpch.sln           variants
HISTORY        answers  bm_utils.c  column_split.sh  dists.dss  dss.h    load_stub.c     permute.h  qgen.vcproj  release.h  rng64.c  speed_seed.c  tpcd.h    tpch.vcproj        varsub.c
PORTING.NOTES  bcd2.c   build.c     config.h         driver.c   dss.ri   makefile.suite  print.c    queries      rnd.c      rng64.h  tests         tpch.dsw  update_release.sh

dbgen 컴파일을 위한 설정 파일 수정

 # makefile 생성
[root@tpc dbgen]$ cp    makefile.suite      makefile
[root@tpc dbgen]$ vi     makefile
 # 컴파일러,  대상 DBMS종류, 시스템 종류, workload 정보를 변경한다.
 # CC = , DATABASE = , MACHINE = , WORKLOAD = 항목을 찾는다.
 # 리눅스에 설치된 ORACLE 을 기준으로 다음과 같이 변경. (아래 주석 참고)
CC      = gcc
DATABASE= ORACLE
MACHINE = LINUX
WORKLOAD = TPCH
# Current values for DATABASE are: INFORMIX, DB2, TDAT (Teradata)
#                                  SQLSERVER, SYBASE, ORACLE, VECTORWISE
# Current values for MACHINE are:  ATT, DOS, HP, IBM, ICL, MVS,
#                                  SGI, SUN, U2200, VMS, LINUX, WIN32
# Current values for WORKLOAD are:  TPCH

컴파일 및 확인
dbgen 파일이 생성되면 정상적으로 컴파일이 된 것이다.

[root@tpc dbgen]$  make
gcc -g -DDBNAME=\"dss\" -DLINUX -DORACLE -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64    -c -o build.o build.c
gcc -g -DDBNAME=\"dss\" -DLINUX -DORACLE -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64    -c -o driver.o driver.c
gcc -g -DDBNAME=\"dss\" -DLINUX -DORACLE -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64    -c -o bm_utils.o bm_utils.c
gcc -g -DDBNAME=\"dss\" -DLINUX -DORACLE -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64    -c -o rnd.o rnd.c
gcc -g -DDBNAME=\"dss\" -DLINUX -DORACLE -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64    -c -o print.o print.c
gcc -g -DDBNAME=\"dss\" -DLINUX -DORACLE -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64    -c -o load_stub.o load_stub.c
gcc -g -DDBNAME=\"dss\" -DLINUX -DORACLE -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64    -c -o bcd2.o bcd2.c
gcc -g -DDBNAME=\"dss\" -DLINUX -DORACLE -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64    -c -o speed_seed.o speed_seed.c
gcc -g -DDBNAME=\"dss\" -DLINUX -DORACLE -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64    -c -o text.o text.c
gcc -g -DDBNAME=\"dss\" -DLINUX -DORACLE -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64    -c -o permute.o permute.c
gcc -g -DDBNAME=\"dss\" -DLINUX -DORACLE -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64    -c -o rng64.o rng64.c
gcc -g -DDBNAME=\"dss\" -DLINUX -DORACLE -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64  -O -o dbgen build.o driver.o bm_utils.o rnd.o print.o load_stub.o bcd2.o speed_seed.o text.o permute.o rng64.o -lm
gcc -g -DDBNAME=\"dss\" -DLINUX -DORACLE -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64    -c -o qgen.o qgen.c
gcc -g -DDBNAME=\"dss\" -DLINUX -DORACLE -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64    -c -o varsub.o varsub.c
gcc -g -DDBNAME=\"dss\" -DLINUX -DORACLE -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64  -O -o qgen build.o bm_utils.o qgen.o rnd.o varsub.o text.o bcd2.o permute.o speed_seed.o rng64.o -lm
[root@tpc dbgen]$  ll
total 920
...중략...
-rwxr-xr-x 1 root root 111910 Aug  2 13:01 dbgen
-rw-r--r-- 1 root root   5154 Dec  5  2018 dbgen.dsp
...중략...
-rwxr-xr-x 1 root root 103060 Aug  2 13:01 qgen
-rw-r--r-- 1 root root  14404 Dec  5  2018 qgen.c
-rw-r--r-- 1 root root  48984 Aug  2 13:01 qgen.o
-rw-r--r-- 1 root root   4916 Dec  5  2018 qgen.vcproj
drwxr-xr-x 2 root root   4096 Feb 18 12:03 queries
-rw-r--r-- 1 root root  17617 Dec  5  2018 README

※ TPC-H는 정확하게 PostgresQL용 쿼리를 제공하지 않는다. ORACLE용 쿼리와 데이터를 생성하고 이를 이용해 PostgresQL에 데이터를 넣을 것이다.

데이터 및 테스트 쿼리 생성
dbgen을 실행하면 실험용 쿼리와 데이터가 자동으로 생성된다.

# 데이터 및 쿼리 생성
[root@tpc dbgen]$  ./dbgen
TPC-H Population Generator (Version 3.0.0)
Copyright Transaction Processing Performance Council 1994 - 2010
 # 편의를 위해 쿼리파일과 샘플 데이터를 한곳으로 옮긴다.
[root@tpc dbgen]# mkdir data
[root@tpc dbgen]# cp *.ddl data/
[root@tpc dbgen]# cp *.tbl data/
# 확인 - 중간에 dss.ddl 파일에 테이블 생성 스크립트가 존재한다.
[root@tpc dbgen]$ ll data
total 1074924
-rw-r--r-- 1 root root  24346144 Aug  2 13:07 customer.tbl
-rw-r--r-- 1 root root      3814 Dec  5  2018 dss.ddl
-rw-r--r-- 1 root root 759863287 Aug  2 13:07 lineitem.tbl
-rw-r--r-- 1 root root      2224 Aug  2 13:07 nation.tbl
-rw-r--r-- 1 root root 171952161 Aug  2 13:07 orders.tbl
-rw-r--r-- 1 root root 118984616 Aug  2 13:07 partsupp.tbl
-rw-r--r-- 1 root root  24135125 Aug  2 13:07 part.tbl
-rw-r--r-- 1 root root       389 Aug  2 13:07 region.tbl
-rw-r--r-- 1 root root   1409184 Aug  2 13:07 supplier.tbl
[root@tpc dbgen]$ ll queries/
total 88
-rw-r--r-- 1 root root  646 Dec  5  2018 10.sql
-rw-r--r-- 1 root root  631 Dec  5  2018 11.sql
-rw-r--r-- 1 root root  720 Dec  5  2018 12.sql
-rw-r--r-- 1 root root  470 Dec  5  2018 13.sql
-rw-r--r-- 1 root root  442 Dec  5  2018 14.sql
-rw-r--r-- 1 root root  641 Dec  5  2018 15.sql
-rw-r--r-- 1 root root  609 Dec  5  2018 16.sql
-rw-r--r-- 1 root root  411 Dec  5  2018 17.sql
-rw-r--r-- 1 root root  581 Dec  5  2018 18.sql
-rw-r--r-- 1 root root 1090 Dec  5  2018 19.sql
-rw-r--r-- 1 root root  666 Dec  5  2018 1.sql
-rw-r--r-- 1 root root  711 Dec  5  2018 20.sql
-rw-r--r-- 1 root root  804 Dec  5  2018 21.sql
-rw-r--r-- 1 root root  797 Dec  5  2018 22.sql
-rw-r--r-- 1 root root  815 Dec  5  2018 2.sql
-rw-r--r-- 1 root root  518 Dec  5  2018 3.sql
-rw-r--r-- 1 root root  474 Dec  5  2018 4.sql
-rw-r--r-- 1 root root  605 Dec  5  2018 5.sql
-rw-r--r-- 1 root root  363 Dec  5  2018 6.sql
-rw-r--r-- 1 root root  926 Dec  5  2018 7.sql
-rw-r--r-- 1 root root  900 Dec  5  2018 8.sql
-rw-r--r-- 1 root root  741 Dec  5  2018 9.sql

테이블 생성

PostgresQL은 텍스트파일3i.e. csv 파일을 import 할 때 문자열 끝에 구분자가 있으면 컬럼이 하나 더 있는 것으로 인식한다. 따라서 이를 위한 dummy column 을 추가한다.

-- 더미 컬럼에는 데이터가 들어가지 않는다. 따라서 붙여넣기 하다가 not null 도 따라 붙여 넣지 않도록 주의한다.

CREATE TABLE public.NATION  ( N_NATIONKEY  INTEGER NOT NULL,
                            N_NAME       CHAR(25) NOT NULL,
                            N_REGIONKEY  INTEGER NOT NULL,
                            N_COMMENT    VARCHAR(152),
                            N_DUMMY   VARCHAR(1));
                           
CREATE TABLE public.REGION  ( R_REGIONKEY  INTEGER NOT NULL,
                            R_NAME       CHAR(25) NOT NULL,
                            R_COMMENT    VARCHAR(152),
                            R_DUMMY VARCHAR(1));

CREATE TABLE public.PART  ( P_PARTKEY     INTEGER NOT NULL,
                          P_NAME        VARCHAR(55) NOT NULL,
                          P_MFGR        CHAR(25) NOT NULL,
                          P_BRAND       CHAR(10) NOT NULL,
                          P_TYPE        VARCHAR(25) NOT NULL,
                          P_SIZE        INTEGER NOT NULL,
                          P_CONTAINER   CHAR(10) NOT NULL,
                          P_RETAILPRICE DECIMAL(15,2) NOT NULL,
                          P_COMMENT     VARCHAR(23) NOT null,
                          P_DUMMY VARCHAR(1));

CREATE TABLE public.SUPPLIER ( S_SUPPKEY     INTEGER NOT NULL,
                             S_NAME        CHAR(25) NOT NULL,
                             S_ADDRESS     VARCHAR(40) NOT NULL,
                             S_NATIONKEY   INTEGER NOT NULL,
                             S_PHONE       CHAR(15) NOT NULL,
                             S_ACCTBAL     DECIMAL(15,2) NOT NULL,
                             S_COMMENT     VARCHAR(101) NOT NULL,
                             S_DUMMY    VARCHAR(1));

CREATE TABLE public.PARTSUPP ( PS_PARTKEY     INTEGER NOT NULL,
                             PS_SUPPKEY     INTEGER NOT NULL,
                             PS_AVAILQTY    INTEGER NOT NULL,
                             PS_SUPPLYCOST  DECIMAL(15,2)  NOT NULL,
                             PS_COMMENT     VARCHAR(199) NOT NULL, );

CREATE TABLE public.CUSTOMER ( C_CUSTKEY     INTEGER NOT NULL,
                             C_NAME        VARCHAR(25) NOT NULL,
                             C_ADDRESS     VARCHAR(40) NOT NULL,
                             C_NATIONKEY   INTEGER NOT NULL,
                             C_PHONE       CHAR(15) NOT NULL,
                             C_ACCTBAL     DECIMAL(15,2)   NOT NULL,
                             C_MKTSEGMENT  CHAR(10) NOT NULL,
                             C_COMMENT     VARCHAR(117) NOT NULL,
                             C_DUMMY VARCHAR(1));

CREATE TABLE public.ORDERS  ( O_ORDERKEY       INTEGER NOT NULL,
                           O_CUSTKEY        INTEGER NOT NULL,
                           O_ORDERSTATUS    CHAR(1) NOT NULL,
                           O_TOTALPRICE     DECIMAL(15,2) NOT NULL,
                           O_ORDERDATE      DATE NOT NULL,
                           O_ORDERPRIORITY  CHAR(15) NOT NULL,
                           O_CLERK          CHAR(15) NOT NULL,
                           O_SHIPPRIORITY   INTEGER NOT NULL,
                           O_COMMENT        VARCHAR(79) NOT NULL,
                           O_DUMMY VARCHAR(1));

CREATE TABLE public.LINEITEM ( L_ORDERKEY    INTEGER NOT NULL,
                             L_PARTKEY     INTEGER NOT NULL,
                             L_SUPPKEY     INTEGER NOT NULL,
                             L_LINENUMBER  INTEGER NOT NULL,
                             L_QUANTITY    DECIMAL(15,2) NOT NULL,
                             L_EXTENDEDPRICE  DECIMAL(15,2) NOT NULL,
                             L_DISCOUNT    DECIMAL(15,2) NOT NULL,
                             L_TAX         DECIMAL(15,2) NOT NULL,
                             L_RETURNFLAG  CHAR(1) NOT NULL,
                             L_LINESTATUS  CHAR(1) NOT NULL,
                             L_SHIPDATE    DATE NOT NULL,
                             L_COMMITDATE  DATE NOT NULL,
                             L_RECEIPTDATE DATE NOT NULL,
                             L_SHIPINSTRUCT CHAR(25) NOT NULL,
                             L_SHIPMODE     CHAR(10) NOT NULL,
                             L_COMMENT      VARCHAR(44) NOT NULL,
                             L_DUMMY VARCHAR(1));

데이터 입력

※ 테이블 명, 컬럼명 등은 대소문자 구분을 하지 않지만 소스 파일 명 및 경로는 대소문자를 구분하므로 주의한다.

COPY public.nation(N_NATIONKEY,N_NAME,N_REGIONKEY,N_COMMENT,N_dummy)
FROM '/home/tpc/2.18.0_rc2/dbgen/sample/nation.tbl'
DELIMITER '|'
;

COPY public.region(R_REGIONKEY,R_NAME,R_COMMENT,R_DUMMY)
FROM '/home/tpc/2.18.0_rc2/dbgen/sample/region.tbl'
DELIMITER '|'
;

COPY public.part(P_PARTKEY,P_NAME,P_MFGR,P_BRAND,P_TYPE,P_SIZE,P_CONTAINER,P_RETAILPRICE,P_COMMENT,P_DUMMY VARCHAR)
FROM '/home/tpc/2.18.0_rc2/dbgen/sample/part.tbl'
DELIMITER '|'
;

COPY public.supplier(S_SUPPKEY,S_NAME,S_ADDRESS,S_NATIONKEY,S_PHONE,S_ACCTBAL,S_COMMENT)
FROM '/home/tpc/2.18.0_rc2/dbgen/sample/supplier.tbl'
DELIMITER '|'
;

COPY public.partsupp(PS_PARTKEY,PS_SUPPKEY,PS_AVAILQTY,PS_SUPPLYCOST,PS_COMMENT,PS_DUMMY)
FROM '/home/tpc/2.18.0_rc2/dbgen/sample/partsupp.tbl'
DELIMITER '|'
;

COPY public.customer(C_CUSTKEY,C_NAME,C_ADDRESS,C_NATIONKEY,C_PHONE,C_ACCTBAL,C_MKTSEGMENT,C_COMMENT,C_dummy)
FROM '/home/tpc/2.18.0_rc2/dbgen/sample/customerp.tbl'
DELIMITER '|'
;
                           
COPY public.orders(O_ORDERKEY,O_CUSTKEY,O_ORDERSTATUS,O_TOTALPRICE,O_ORDERDATE,O_ORDERPRIORITY,O_CLERK,O_SHIPPRIORITY,O_COMMENT,O_DUMMY)
FROM '/home/tpc/2.18.0_rc2/dbgen/sample/orders.tbl'
DELIMITER '|'
;

COPY public.lineitem(L_ORDERKEY,L_PARTKEY,L_SUPPKEY,L_LINENUMBER,L_QUANTITY,L_EXTENDEDPRICE,L_DISCOUNT,L_TAX,L_RETURNFLAG,L_LINESTATUS,L_SHIPDATE,L_COMMITDATE,L_RECEIPTDATE,L_SHIPINSTRUCT,L_SHIPMODE,L_COMMENT,L_DUMMY)
FROM '/home/tpc/2.18.0_rc2/dbgen/sample/lineitem.tbl'
DELIMITER '|'
;

확인

 # 실행 예
 # PostgresQL import 문법이므로 기억하자
tpc=$ COPY public.customer(c_custkey,c_name,c_address,c_nationkey,c_phone,c_acctbal,c_mktsegment,c_comment,c_dummy)
tpc-$ FROM '/home/tpc/2.18.0_rc2/dbgen/sample/region.tbl'
tpc-$ DELIMITER '|'
tpc-$ ;
COPY 150000
tpc=$
 # 확인
tpc=$ select count(*) from public.customer;
 count
--------
 150000
(1개 행)

tpc=$ select * from public.customer limit 1;
 c_custkey |       c_name       |     c_address     | c_nationkey |     c_phone     | c_acctbal | c_mktsegment |                           c_comment                            | c_dummy
-----------+--------------------+-------------------+-------------+-----------------+-----------+--------------+----------------------------------------------------------------+---------
         1 | Customer#000000001 | IVhzIApeRb ot,c,E |          15 | 25-989-741-2988 |    711.56 | BUILDING     | to the even, regular platelets. regular, ironic epitaphs nag e |
(1개 행)

tpc=$ \dt
       릴레이션(relation) 목록
 스키마 |   이름   |  종류  | 소유주
--------+----------+--------+--------
 public | customer | 테이블 | tpc
 public | lineitem | 테이블 | tpc
 public | nation   | 테이블 | tpc
 public | orders   | 테이블 | tpc
 public | part     | 테이블 | tpc
 public | partsupp | 테이블 | tpc
 public | region   | 테이블 | tpc
 public | supplier | 테이블 | tpc
(8개 행)

tpc=$

PostgresQL #.2 설정

인터페이스 변경

이전 포스트에서 구동 한 PostgresQL서버는 기본 값 loopbak(127.0.0.1) 인터페이스로 구동 되었다. 외부 연결을 위해서는 서비스 리슨 인터페이스를 변경 해 줘야 한다.
Listen 인터페이스 관련 설정은 postgresql.conf 파일에 정의 돼 있다. 이전 포스트의 내용대로 설치 했을 경우 설정 파일은 /var/lib/pgsql/12/data 아래에 존재한다. 1설치 할 때의 조건에 따라 /etc/postgresql/version 디렉토리 아래에 존재할 수 도 있다.

[postgres@centos7:/home/]$  vi /var/lib/pgsql/12/data/postgresql.conf
 
 # 아래 "listen_addresses"와 "port" 값을 변경해 주면 되는데 주석처리가 돼 있으므로 파일 끝에 새 값을 삽입한다.
      ... 중략...
#------------------------------------------------------------------------------
# CONNECTIONS AND AUTHENTICATION
#------------------------------------------------------------------------------
# - Connection Settings -
#listen_addresses = 'localhost'         # what IP address(es) to listen on;
                                        # comma-separated list of addresses;
                                        # defaults to 'localhost'; use '*' for all
                                        # (change requires restart)
#port = 5432                            # (change requires restart)
max_connections = 100                   # (change requires restart)
#superuser_reserved_connections = 3     # (change requires restart)
#unix_socket_directories = '/var/run/postgresql, /tmp'  # comma-separated list of directories
                                        # (change requires restart)
#unix_socket_group = ''                 # (change requires restart)
#unix_socket_permissions = 0777         # begin with 0 to use octal notation
                                        # (change requires restart)
#bonjour = off                          # advertise server via Bonjour
                                        # (change requires restart)
#bonjour_name = ''                      # defaults to the computer name
                                        # (change requires restart)

# - TCP settings -
# see "man 7 tcp" for details

#tcp_keepalives_idle = 0                # TCP_KEEPIDLE, in seconds;
                                        # 0 selects the system default
#tcp_keepalives_interval = 0            # TCP_KEEPINTVL, in seconds;
                                        # 0 selects the system default
#tcp_keepalives_count = 0               # TCP_KEEPCNT;
                                        # 0 selects the system default
    ....중략...

 # 여기부터 파일 끝에 삽입한다.
listen_addresses = '0.0.0.0'
 # 인터페이스가 여러개일 경우 0.0.0.0을 입력하면 모든 인터페이스가 연결을 받아들이고
 # 특정 IP를 입력하면 지정한 IP로만 연결이 가능한다.
port = 5432                         

인증 방법 설정

 # 패스워드 인증을을 통한 접속 허용을 위한 설정
[postgres@centos7:/home/]$  vi /var/lib/pgsql/12/data/pg_hba.conf
 # 파일의 끝에 아래를 붙여넣기 한다.

host    all             all             0.0.0.0/0               md5
#호스트를 기준으로 모든 계정을 이용해 모든 IP에서 들어오는 연결에 대해 패스워드 인증을 허용하는 설정이다.
 #인터페이스 관련 설정을 변경할 경우 재기동이 필요하다.
[postgres@centos7:/home/]$  /usr/pgsql-12/bin/pg_ctl -D /var/lib/pgsql/12/data -l /var/lib/pgsql/12/data/pgsql.log stop
[postgres@centos7:/home/]$  /usr/pgsql-12/bin/pg_ctl -D /var/lib/pgsql/12/data -l /var/lib/pgsql/12/data/pgsql.log start

계정 생성

 # 생성하는 계정에 관리자 권한을 부여할 때
[postgres@centos7:/home/]$   /usr/pgsql-12/bin/createuser psqluser --interactive
createuser dataware --interactive
새 롤을 superuser 권한으로 지정할까요? (y/n) y
 # 관리자 권한을 부여하지 않을 때.
[postgres@centos7:/home/]$   /usr/pgsql-12/bin/createuser psqluser --interactive
새 롤을 superuser 권한으로 지정할까요? (y/n) n
이 새 롤에게 데이터베이스를 만들 수 있는 권할을 줄까요? (y/n) y
이 새 롤에게 또 다른 롤을 만들 수 있는 권한을 줄까요? (y/n) y
 # SQL을 이용한 사용자 생성
[postgres@centos7:/home/]$   /usr/pgsql-12/bin/psql
psql (12.4)
도움말을 보려면 "help"를 입력하십시오.

postgres=# CREATE USER datauser WITH ENCRYPTED PASSWORD 'password';
CREATE ROLE
postgres=#

데이터 베이스 생성

[postgres@centos7:/home/]$   /usr/pgsql-12/bin/psql
psql (12.4)
도움말을 보려면 "help"를 입력하십시오.

postgres=# CREATE DATABASE data OWNER data ENCODING 'utf-8';
CREATE ROLE
postgres=#

접속 확인

 # postgres 가 아닌 다른 계정으로 시도해본다. 원격지에서도 가능하다.
root@centos7:/home/]#   psql -U dataware -W -h localhost

다음과 같이 입력을 쉘이 변하면 정상 구동 중인 상태

암호:
psql (12.4)
도움말을 보려면 "help"를 입력하십시오.

postgres=# select * from pg_tables;
     schemaname     |        tablename        | tableowner | tablespace | hasindexes | hasrules | hastriggers | rowsecurity
--------------------+-------------------------+------------+------------+------------+----------+-------------+-------------
 pg_catalog         | pg_statistic            | postgres   |            | t          | f        | f           | f
 pg_catalog         | pg_type                 | postgres   |            | t          | f        | f           | f
 pg_catalog         | pg_foreign_server       | postgres   |            | t          | f        | f           | f
 pg_catalog         | pg_authid               | postgres   | pg_global  | t          | f        | f           | f
 pg_catalog         | pg_statistic_ext_data   | postgres   |            | t          | f        | f           | f
 pg_catalog         | pg_user_mapping         | postgres   |            | t          | f        | f           | f
 pg_catalog         | pg_subscription         | postgres   | pg_global  | t          | f        | f           | f
 pg_catalog         | pg_attribute            | postgres   |            | t          | f        | f           | f
 pg_catalog         | pg_proc                 | postgres   |            | t          | f        | f           | f
 pg_catalog         | pg_class                | postgres   |            | t          | f        | f           | f
... 중략...
 information_schema | sql_sizing_profiles     | postgres   |            | f          | f        | f           | f
(70개 행)

PostgresQL #.1 설치 및 구동

개요

PostgreSQL은 확장 가능성 및 표준 준수를 강조하는 객체-관계형 데이터베이스 관리 시스템(ORDBMS)의 하나이다. BSD 허가권으로 배포되며 오픈소스 개발자 및 관련 회사들이 개발에 참여하고 있다. 데이터베이스 서버로서 주요 기능은 데이터를 안전하게 저장하고 다른 응용 소프트웨어로부터의 요청에 응답할 때 데이터를 반환하는 것이이다. 소규모의 단일 머신 애플리케이션에서부터 수많은 동시 접속 사용자가 있는 대형의 인터넷 애플리케이션(또는 데이터 웨어하우스용)에 이르기까지 여러 부하를 관리할 수 있으며 macOS 서버의 경우 PostgreSQL은 기본 데이터베이스이다. 마이크로소프트 윈도우, 리눅스(대부분의 배포판에서 제공됨)용으로도 이용 가능하다. PostgresQL의 전신은 Ingres DB로 실제 프로젝트의 공식 명칭은 “post-Ingres” 데이터베이스이다.

설치

Postgresql 사이트에서 yum 리포지터리 RPM을 다운로드 받을 수 있다.

이렇게 제공된다. 아래 텍스트를 복사-붙여넣기 하여 설치하면 된다.
 # repository RPM 설치
 # 설치하면 postgresql repo 파일이 /etc/yum.repos.d 아래 생성된다.
[root@centos7:/root/]# yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
 # PostgresQL 설치
[root@centos7:/root/]# yum install -y postgresql12-server
 
 # 이렇게 설치 해도 된다.
[root@centos7:/root/]# yum install -y postgresql12-*

초기화
initdb를 이용해 데이터 디렉토리 생성 및 지정이 필요하다.
postgresql 서버를 설치하면 postgres 계정이 자동으로 생성되고 DBMS의 최고 권한은 이 postgres 계정이 가지게 된다. 서버 프로세스의 구동부터 모든 작업이 postgres 계정으로 진행되어야 하므로 디렉토리 생성등을 할 경우 postgres 계정에 모든 권한을 부여해야 한다.

 # DB 초기화 등 작업

 # 초기화 :  /var/lib/pgsql/12/data 가 데이터 디렉토리로 '자동'지정된다.
[postgres@centos7:/home/]$ /usr/pgsql-12/bin/initdb 
이 데이터베이스 시스템에서 만들어지는 파일들은 그 소유주가 "postgres" id로
지정될 것입니다. 또한 이 사용자는 서버 프로세스의 소유주가 됩니다.

데이터베이스 클러스터는 "ko_KR.UTF-8" 로케일으로 초기화될 것입니다.
기본 데이터베이스 인코딩은 "UTF8" 인코딩으로 설정되었습니다.
initdb: "ko_KR.UTF-8" 로케일에 알맞은 전문검색 설정을 찾을 수 없음
기본 텍스트 검색 구성이 "simple"(으)로 설정됩니다.

자료 페이지 체크섬 기능 사용 하지 않음

이미 있는 /var/lib/pgsql/12/data 디렉터리의 액세스 권한을 고치는 중 ...완료
하위 디렉터리 만드는 중 ...완료
사용할 동적 공유 메모리 관리방식을 선택하는 중 ... posix
max_connections 초기값을 선택하는 중 ...100
기본 shared_buffers를 선택하는 중... 128MB
기본 지역 시간대를 선택 중 ... Asia/Seoul
환경설정 파일을 만드는 중 ...완료
부트스트랩 스크립트 실행 중 ... 완료
부트스트랩 다음 초기화 작업 중 ... 완료
자료를 디스크에 동기화 하는 중 ... 완료

initdb: 경고: 로컬 접속용 "trust" 인증을 설정 함
이 값을 바꾸려면, pg_hba.conf 파일을 수정하든지,
다음번 initdb 명령을 사용할 때, -A 옵션 또는 --auth-local,
--auth-host 옵션을 사용해서 인증 방법을 지정할 수 있습니다.

작업완료. 이제 다음 명령을 이용해서 서버를 가동 할 수 있습니다:

    ./pg_ctl -D /var/lib/pgsql/12/data -l 로그파일 start
# 초기화 : -pgdata= 로 지정한 디렉토리가 지정된다. 
 # 이경우 지정한 디렉토리의 소유자는 postgres이어야 하고 모든 권한을 가져야 한다.
[root@centos7:/home/]# mkdir /home/postgres
[root@centos7:/home/]# chown -R postgres /home/postgres
 # 쉘에 주의하자 여기까지는 root 이다.
[postgres@centos7:/home/]$ mkdir /home/postgres/data
[postgres@centos7:/home/]$ /usr/pgsql-12/bin/initdb  --pgdata=/home/postgres/data

/usr/pgsql-12/bin/postgresql-12-setup initdb
systemctl enable postgresql-12
systemctl start postgresql-12

구동
initdb 작업 결과의 명령대로 구동하면 된다.

[postgres@centos7:/home/]$ /usr/pgsql-12/bin//pg_ctl -D /var/lib/pgsql/12/data -l /var/lib/pgsql/12/data/pgsql.log start
서버를 시작하기 위해 기다리는 중.... 완료
서버 시작됨

확인

[root@host0 bin]# netstat -nltp |grep postgres
tcp        0      0 127.0.0.1:5432          0.0.0.0:*               LISTEN      96383/postgres

사랑스러운 나의 도시 #1-2. 타이페이 둘째날

타이페이 첫째날

타이페이 셋째날

타이페이 넷째 날, 그리고 처음의 그 끝

인생 첫 ‘나홀로’ ‘해외 여행’ 목적지 타이페이. 시작은 책 한권 분량의 경험을 가지고 돌아오겠노라 원대했으나 막상 그 원대한 꿈은 너무나도 어려운 것이었다. 나와 다른 말을 쓰는 사람들이 가득찬 이 도시는 오로지 두려움과 신선함 이 둘 말고는 내게 주는 것이 없었다. 그나마 두려움보다 신선함이 더 컸던 것은 큰 행운이었다.

그렇게 첫날을 보내고 부랴부랴 숙소를 찾고 예약을 마쳤다. 둘째 날의 목표는 새 숙소까지 무사히 도착하는 것. 다시 첫날이다. 주섬주섬 짐을 챙기고, 캐리어와 가방을 짊어지고 구글 지도를 따라 길을 걸었다. 큰 사고 없이 도착한 Bouti city capsule Inn. 이른 아침 움직인터라 아직은 체크인 전이었기에 짐을 맡겨두고 다시 거리로 나왔다.

그리고 기억은 잘 안나는 어느 식당에서 먹은 아침. 뭔가 밀가루 반죽을 튀긴 건데 맛은 잘 기억나지 않는다.

또다시 시작된 무작정 걷기. 그렇게 거다 당도한 Wenchang Tepmle. 절이다. 그리고 절 앞은 시장이다. 한국과 다르게 도시 한가운데, 그리고 시장 안에 절이 있다. 또. 절 주위가 시장인건지, 시장 한가운데에 절인건지 아직은 모르겟다. 아무튼 한국인인 내게는 신기한 풍경이었다.

야시장이 아닌 시장에서 무대포 여행초보인 내가 할 일은 없었다. 나름의 고집이 있어 가능하면 가게에 무작정 카메라를 들이미는건 자제하는편이니까. (덕분에 사진을 찍기 위해 쓸모 없는 지출도 하게 되고, ‘더’ 많이 먹게 된다.) 뭔가 관광지 스러운 곳을 찾아보자.

그렇게 도착한 곳은 대만 국립박물관의 Land Bank Exhibition Hall.
(아마 과거 은행으로 쓰였던 건물이었다고 하더라)

국립 대만 박물관에 속한 은행 정시관이 있으니 근처에 국립 대만 박물관도 분명히 있을 터, 그렇다 길을 하나 건너면 얼얼바 평화 기념공원 (228 peace monument), 그 가운데 국립 대만 박물관이 있다.

그렇게 공원과 박물관을 둘러보고 나니 시간 잘지키기로는 둘째가라면 서러운 내 배는 점심 시간을 알렸고 대만에서의 첫 ‘밥’을 먹었다.

이런 종류의 음식을 파는 식당이 많기에 한군데 들어가서 맛있게 밥을 먹고 나와 현지인에게 물어봤더니 이건 홍콩 음식이지 대만풍 음식은 아니란다. (대만에서의 첫 식사가 홍콩풍 음식이라니..)

다시 발을 떼어 마주친 한 건물. 정확한 이름과 용도는 기억이 안나고, 정부? 지자체?의 한 건물이었다. 월요일인가는 관광도 가능 했던 곳. 아쉽지만 입장 가능일은 아니었던터라 들어가보지는 못했다.

하루 종일 걷는 것은 힘들더라.. 숙소로 돌아와 대충 씻고 젖은 수건 따위를 정리하는데 한 방을 쓰게 된 누군가가 들어왔다. 라커를 못 열기에 도움을 주기 위해 대화를 하다보니 이게 무슨일인가! 한국인이었다. 이역만리 타국 땅에서 내 나라 사람을 만나다니! 이렇게 반가울 수가. 서로 이름은 무어네, 나이는 몇이네 어디서 일하네 반가움을 마구 내뱉는 사이 또 한명이 들어왔다. 이번엔 타이중에서 온 대만인이었다. 나이는 대충 (당시에) 29정도 였던 듯.
사내놈들이 모이면 늘 그렇다. 서로 내가 잘났네 자랑도 좀 하고, 여자 이야기도 좀 하다가 결국 술 이야기. 타이중에서 온 친구가 자신의 고향에 한국의 막걸리와 비슷한 탁주가 유명하다 했다. 맛있는 술이 있다는데 짧은 영어가 대수랴 고향을 떠나온 사내 셋은 밤 열한시에 길을 나섰다.
(이것도 역시나 무식하기에 가능 했던 일이다. 다행스럽게도 대만은 안전한 나라이긴 하지만 타국 땅에서 처음 만난 사람과 그것도 밤 열한시에 술을 찾아 길을 나서다니)
하지만 안타깝게도 우린 그 술을 찾을 수 없었고 한시간을 헤맨 끝에 눈에 들어온 펍에 들어갔고 맥주만 마시고 돌아와야 했었다.