오래 전에 이런 글이 올라 온 적이 있읍니다.
http://www.cubrid.com/bbs/view.php?id=s3700&page=1&sn1=&divpage=1&sn=off&ss=on&sc=on&keyword=limit&select_arrange=headnum&desc=asc&no=8502&coid=8502
mysql 의 limit 가 mysql 을 빅히트시킨 기능이니까
이 기능을 추가하는 것이 어떻겠냐는 제안이었죠.
여기서 CUBRID 관계자분께서 답변을 하셨는데
http://www.cubrid.com/bbs/view.php?id=s3700&page=1&sn1=&divpage=1&sn=off&ss=on&sc=on&keyword=limit&select_arrange=headnum&desc=asc&no=8507&coid=@1553|1|4
-- 이미 LIMIT 를 대체하는 좋은 기능을 CUBRID 는 가지고 있다.
-- 따라서 호환성을 위하여 큐브리드의 철학을 버리고 MySQL을 복사하기보다는,
-- 마이그레이션 경로를 지원하고자 한다.
라는 내용이었읍니다. 이 말씀은, "이미 다른 좋은 기능이 있기 때문에
별도로 LIMIT 를 지원하려는 계획은 당분간 있지 않다" 는 뜻으로 풀이됩니다.
그런데 이 글 중에 ''''CUBRID 의 철학'''' 이라는 ''''용어''''를 사용하셨읍니다.
여기서 문득 제가 애용하는 DB 프로그램인 PGSQL 의 철학에 대해서 생각을 하게 되었읍니다.
물론 PGSQL 이 최초에 무슨 철학을 가지고 태동했는지는 제가 정확하게 알 수는 없습니다.
그런데 PGSQL 이 걸어온 길을 곰곰히 살펴보고, 또 지원하는 기능을 생각해 본다면,
어느 정도 답이 나올 것 같습니다.
PGSQL 의 철학은, ''''개발자를 위한 DB'''' 가 아닐까 합니다.
속담으로 표현하지만 ''''과부사정은 과부가 잘 안다'''' 정도로 표현할 수도 있겠읍니다.
''''개발자를 위한 DB'''' 임을 나타내 주는 근거로, 첫번째로 꼽을 수 있는 것은
C 기반 저장프로시저 작성을 위한 SPI(Server Programing Interface) 의 지원입니다.
MSSQL 도 C 기반 저장프로시저는 MSSQL 2000 까지는 직접적으로 지원을 했지만
그때도 쿼리를 수행할 수는 없었고, 쿼리를 수행할려면 ODBC 관련 C-API 로
별도의 컨넥션을 생성시켜주어야 했읍니다. 결국은 반쪽 짜리입니다.
왜 MSSQL 이 이렇게 반쪽짜리로 어슬프게 C 기반 저장프로시저를 지원했는지 참 수수께끼입니다.
그러다가 MSSQL 2003 부터는 아예 ''''이런 어설픈 지원''''조차도 막아버렸읍니다.
전부 닷넷기반으로 바꾼 것입니다. 물론 닷넷용 C/C++ 이 있으나,
이전에 닷넷 플랫폼이라는 중간 단계를 거치지 않고 다이렉트로 서버의 context 내에서
수행할 수 있게 저장프로시저를 만들수 있었던 개발자의 ''''자유''''는 사라진 것입니다.
이것에 대해서는 이전에 관리자분께서
http://www.cubrid.com/bbs/view.php?id=s3700&page=1&sn1=&divpage=1&sn=on&ss=on&sc=on&keyword=초보대왕&select_arrange=headnum&desc=asc&no=8411&coid=8411
-- 이 방식(확장저장프로시저)은 T-SQL이 닷넷언어에 비해 표현력이 떨어져,
-- 어쩔 수 없이 C 등으로 서버를 직접 확장해야 하던 시절에
-- 궁여지책으로 지원하던 API로 알고 있다.
-- 이제 2005에서 닷넷언어(VB, C/C++/C# 등등)가 모두 일반 저장프로시저를 만드는 데
-- 사용될 수 있기 때문에 XP API는 obsolete된 것으로 알고 있다
라는 내용의 글을 올리셨읍니다. 이 내용에 의하면
''''C 기반 저장프로시저 작성법이 obsolete 될 만 하니까 obsolete 되었다'''' 하는 생각을 하시는 듯합니다.
그런데 저는 이것을, 그 이전에 작성해 놓은 C 기반 저장프로시저 소스들을
사용할 수 없게 되었다는 것만으로도, MS 의 횡포(?) 라고 생각하고 있읍니다.
따라서 관리자께서 ''''(obsolete 될 만 하니까) obsolete 되었다'''' 라고 MS 에
다소 우호적으로 언급하신 것은 약간 의외였읍니다.
MS 가 닷넷을 정책적으로 미는 것은 그러려니 하지만,
그렇다고 그 전에 사용하던 C-API 까지 사장시켜야 했는지는 의문입니다.
과연, 때때로 무겁다고 느껴지는 닷넷 프레임워크를 통해서만
서버측 DB 프로그램을 해야 하는 상황이 개발자에게 바람직 한것일까요.
글쓰신 관리자분께서는 이전에 MS 에 몸담으셨던 만큼,
MS 에 충분히 우호적일 수 있읍니다.
그러나 혹시라도 MSSQL 에 대해서 이전에 있던 반쪽짜리의 자유마저 사라진 것에
저처럼 분개(?)하는 개발자는 없었을까요.
■ 거꾸로 생각하면 ''''서버측 C-API'''' 가 없어진 것이 분개할 만큼
■ ''''서버측 C-API'''' 라는게 필요한 것일까요.
http://database.sarang.net 에서 활동하고 있는 ''''김상기'''' 라는 분이
PGSQL 의 간략한 역사를 적은 글이 있는데
http://database.sarang.net/?inc=read&aid=7053&criteria=pgsql&subcrit=columns&id=&limit=20&keyword=&page=1
여기에 ''''(PGSQL 의) 무한 확장성은 참으로 놀랍습니다.'''' 라는 구절이 있읍니다.
김상기님이 PGSQL 의 어떤 특징을 가지고 ''''무한 확장성'''' 이라고 표현했는지는
정확하게 적지는 않았읍니다. 아마도 추측하자면 PGSQL 은 많은 확장 모듈을 지원하고 있고,
이것은 PGSQL 에 많은 오픈소스 개발자들이 참여한다는 뜻이니
앞으로도 확장 모듈은 계속 만들어 질 것이고 그것이 ''''무한 확장성'''' 이라고 표현한 것이
아닌가 생각합니다. 그렇다면 PGSQL 의 많은 확장 모듈은 서버측 C-API 에 기반한 것이기 때문에
PGSQL 의 ''''무한 확장성''''은 서버측 C-API 가 1 등 공신이라고 봐도 됩니다.
물론 김상기님의 이 표현에는 다른 뜻이 내포되 있을 수도 있읍니다.
저 또한 ''''무한 확장성''''의 근거가 되는 다른 의미를 찾자면
-- ''''PGSQL 은 단순히 데이타를 관리하는 툴을 넘어서 미들웨어의 역할까지 한다''''
는 것입니다. DB 를 미들웨어나 미들티어로 사용한다는 개념은 특별한 개념은 아닙니다만
실제로 DB 를 미들웨어로 보기는 어렵다는 것이 개발자들의 일반적인 생각인듯 합니다.
여기에는, 미들웨어로 사용한다면 비즈니스 로직을 DB 쪽에서 처리를 해주어야 하는데
기능적으로 DB 는(DB 의 저장프로시저는) 비즈니스 로직을 처리하기에는 부족하지 않냐는
인식이 깔여 있는 것입니다. 이것을 증명하기라도 하듯
볼랜드 포럼에서 아주 유명한 박지훈 님이 이런 글을 올린 적이 있읍니다.
http://www.borlandforum.com/impboard/impboard.dll?action=read&db=free&no=14793
-- 물론 스토어드 프로시저를 디비 서버에 존재하는 일종의 미들티어다, 비즈니스 로직이다, 라고
-- 간주해버리면 머릿속의 스트레스 리스트에서 빼버릴 수도 있겠지만...
-- 실제로는 스토어드 프로시저가 비즈니스 로직을 완전히 대체하기에는
-- 기능적으로 너무 미약하고, 미들티어로 보기에는 더욱 그렇죠
이 글에서 박지훈 님은 ''''저장 프로시저라는 것이 기능적으로 너무 미약하기 때문에
미들티어로 보기 힘들다'''' 는 주장을 하셧는데 댓글로 볼때도 많은 개발자들이
그렇게 생각하고 있는 듯합니다.
제가 PGSQL 을 몰랐었다면 이 주장에 당장 동의를 했을 것입니다.
그러나 PGSQL 을 미들웨어나 미들티어로까지 활용할 수 있고,
실제로도 그렇게 활용해 오고 있다고 생각하는 지금은 당연히 동의할 수 없습니다.
복잡한 비즈니스 로직을 저장프로시저가 대체할 수 없는 것이 아니라
''''C/C++ 같은 좀 더 저수준의 서버측 API 가 지원되지 않는 DB 환경이
비즈니스 로직을 대체하기에는 무리다'''' 라고 보는 것이 옳겠읍니다.
아마 박지훈님의 생각으로는 저장프로시저라는 것이 대부분의 DB 가
어떤 스크립트 형태로 지원하기 때문에, 스크립트로는 복잡한 비즈니스로직을
처리하기가 힘들지 않겠나 하는 의견으로 여겨집니다.
그런데 서버측 C-API 를 지원하는 DB 는 아무리 로직이 복잡해도 C/C++ 로 짜버리면
그만입니다. C/C++ 로 짤 수 없는 로직이 과연 있을까요.
그리고 MSSQL 이나 ORALCE 도 간접적으로 C/C++ 을 지원하니까
(MSSQL 은 닷넷을 통해, ORALCE 은 C/S 기반 라이브러리를 통해)
이들 DB 또한 개발자가 마음만 먹으면 미들웨어로까지의 활용이 충분히 가능합니다.
상황이 이렇다면 PGSQL 이 서버측 C-API (즉 SPI) 를 지원하는 것이 크게 메리트가
없어 보이기도 합니다. 그런데 PGSQL 이 SPI 라는 무기를 가지고 있다 보니
저장프로시저를 다른 스크립트 언어로 포팅하는 것이 상대적으로 쉽고,
그러다보니 C/C++ 로 처리할 비즈니스 로직이 많아서 생산성이 걱정된다면
이들 스크립트 언어로 처리를 해버리면 아주 간단합니다.
PGSQL 이 지원하는 스크립트를 나열하면
pl/Python, pl/Ruby, pl/R, pl/pgsql, pl/java, pl/php, pl/Lua, pl/Perl
등등 실로 다양합니다. 이 모두는 서버측 C-API (즉 SPI) 에 기반하기 때문에
SPI 를 얼마간 연구하면 다른 저장프로시저 언어를 PGSQL 에 추가하는 것은 별로 어렵지 않습니다.
바로 이렇기 때문에 ''''무한 확장성'''' 이라는 말이 안 나올 수가 없는 것이죠.
실무에서 많이 쓰는 스크립트는 대부분 들어가 있지 않습니까.
한 발 더 나아가서 일종의 개발 프레임워크나 플랫폼으로도 생각할 수 있읍니다.
일전에 어느 사이트를 PGSQL + XHTML 기반으로 만들어준 적이 있었는데
이때 모든 페이지를 특정 저장프로시저와 1:1 로 대응시키고 웹서버가
PGSQL 로부터 받는 데이타는 전부 XHTML 로 맞추었읍니다.
XHTML 이다보니 바로 XML 로 사용할 수 있고,
별도의 parsing 없이도 클라이언트의 javascript 수준에서
쉽게 PGSQL 로부터 넘겨 받은 데이타에 접근할 수 있었읍니다.
(javascript 로 데이타를 뿌려주면 다소 느리기 때문에,
실제로는 조금이라도 속도를 높이고자 간단한 parsing 라이브러리와
스마티 비슷한 웹템플릿을 제작하여 사용하였읍니다.)
결국 웹서버가 해당 페이지에서 필요한 데이타를 PGSQL 에 요청하면
PGSQL 은 필요한 비즈니스 로직까지 처리를 끝낸 후 관련 데이타를 한꺼번에 XHTML 로 던져주는,
이런 구조입니다. 구조 자체는 간단하지만, 저는 나름대로 프레임워크라고 생각하며
마치 성능좋은 무기를 가진 것처럼 뿌듯하기도 합니다.
화면과 저장프로시저를 1:1 로 대응시켜 개발하는 경우는 간혹 볼 수 있는데
이런 개발 방법의 문제점을 박지훈 님은 위 인용 링크의 글에서
-- 가장 흔한 경우가, 각 화면 하나 단위, 혹은 디비에 액세스하는 대부분의 쿼리 단위로
-- 스토어드 프로시저를 만들어 쌓아대는 것입니다.
-- 이렇게 할 경우 화면 갯수와 비슷한 갯수 만큼, 혹은 그보다 많은 스토어드 프로시저가
-- 디비에 쌓이게 되죠.
-- 이렇게 작업을 하는 이유는 하나의 미신 때문입니다.
-- SQL은 기본적으로 스토어드 프로시저로 만들어야 최고의 성능을 낼 수 있고..
-- 디비로 가는 네트워크 부하도 줄일 수 있고.. 뭐 이런 식입니다.
-- 물론 말은 맞습니다. 원론적으로 봤을 때, 일반적인 SQ문들은 처음 실행시에
-- 스토어드 프로시저는 작성 즉시, 그리고 디비의 기동 즉시 그 프로시저의 실행 계획이 생성됩니다.
-- 또, 수없이 길어질 수 있는 SQL 문 대신에 프로시저 이름과 파라미터 정도로만 호출하니까
-- 네트워크 부하도 적어질 수 있지요.
-- 그런데, 그 반대편으로는, 디비 서버에 수없이 쌓이는 프로시저들을 어떻게 관리할 것이냐의
-- 문제도 생깁니다. 특히 테이블의 경우 갯수가 많아지더라도 사용되는 것과 사용되지 않는 것의
-- 구별이 비교적 직관적으로 이루어질 수 있지만, 프로시저는 도대체 사용되는지의 여부와 사용된다면
-- 어디에서 사용되는지를 한눈에 알아보기가 쉽지 않습니다.
-- 물론 부지런해서 프로시저 앞부분에 주석을 잘 작성해두면
-- 이런 문제는 줄일 수 있습니다만, 역시 이것도 관리의 부담입니다
-- 그럼 과연 스토어드 프로시저가 이런 부담을 감수하고라도 써야 할 궁극의 해결책인가..하면,
-- 그렇지 않습니다.
''''저장 프로시저 관리의 부담'''' 이라는 의견을 제시하였읍니다.
웹의 경우 각 화면이 어떤 실제 페이지로 연결되어 있기 때문에
사용되는 페이지, 사용되지 않는 페이지는 확실히 구분이 되며
결국 사용되는 혹은 사용되지 않는 저장프로시저의 구분이 명확합니다.
C/S 기반의 경우는 물리적인 페이지이름이 없기 때문에 따로 각 화면을 구별하는 어떤
식별법이 있어야 합니다. 이런 식별법을 수립할려면 다소의 노력이 필요하겠지만
이것 자체를 관리의 부담이라고는 말하기는 힙듭니다.
이 정도의 관리는 개발자들이 수많은 클래스를 관리하면서 항상 느끼는 부담입니다.
이 식별법이 정립된 후라면 ''''사용되는지의 여부와 사용된다면 어디에서 사용되는지''''
웹보다는 알기가 약간 힘들겠지만 역시 ''''못해먹을'''' 정도는 아니고
"결국은 할만한 것입니다."
따라서 박지훈님의 "그럼 과연 스토어드 프로시저가 이런 부담을 감수하고라도 써야 할 궁극의 해결책인가"
라는 의문은 적절히 않아 보입니다.
"그럼 과연 스토어드 프로시저가 복잡한 비즈니스로직을 처리할 수 있도록 DB 의 기능이 받쳐주는가"
라는 질문이 오히려 더 적절합니다. 이 질문에 PGSQL 은 당연히 "그렇다" 입니다.
그런데 PGSQL 이 이정도 할 수 있다면 MSSQL 도, ORACLE 도 할 수 있읍니다.
그러나 PGSQL 은 위에서 열거한 다양한 스크립트언어가 저장프로시저로 포팅이 되어 있기 때문에
굳이 서버측 C-API 가 아니어도 자신에게 익숙한 스크립트로 저장프로시저 작업, 다시 말하면
비즈니스 로직작업이 가능하다는 것입니다.
이것으로 PGSQL 이 생산성 면에서 MSSQL 이나 ORACLE 을 훨~씬 앞지를 수 있는 것이죠.
......
앞서 제가 ''''과부사정은 과부가 잘 안다'''' 는 속담을 인용했는데,
이렇게 생각한 이유 중 하나는 PGSQL 이 SELECT ~ LIMIT x OFFSET y 형태를 지원한다는 것입니다.
처음 MYSQL 을 배울때 LIMIT 가 참 편했읍니다.
그런데 LIMIT x, y 의 구문에서 어느 것이 Offset 인지 헷갈릴 때가 많았읍니다.
그러다가 PGSQL 에서는 LIMIT x OFFSET y 형태로 한다는 것을 알았을때
참 잘되있다고 생각했읍니다. 다른 DB 를 익히다보면 LIMIT x OFFSET y 형태가 없는 것이
얼마나 불편한 지 모릅니다. 그래서 다른 DB 를 사용할 수록 PGSQL 에 감사(?)하게 되더군요.
처음부터 PGSQL 이 LIMIT x OFFSET y 을 지원했던 것은 아니고
7.3 인가 그 이전에는 MYSQL 처럼 LIMIT x, y 형태였읍니다.
그러다가 OFFSET 이라는 키워드를 사용하게 되었는데
아마 이것은 저처럼 머리가 나빠서 어느 것이 Offset 인지 했갈리는 사람을 위해서
PGSQL 이 배려한 것이 아닌가 생각합니다.
그런데 어느 순간부터(아마 MYSQL 4 부터) MYSQL 도 LIMIT x OFFSET y 형태를
지원하고 있는 것이 아니겠읍니까! MYSQL 이 PGSQL 을 따라햇는지는 모르겠지만
개발자들이 생각하는 것은 비슷하구나 하는 생각에 참 흐뭇했읍니다 ^^.
따라서 CUBRID 가 LIMIT 키워드를 지원한다면 그것은 LIMIT x OFFSET y 형태여야 합니다.
이 언저리에서 다시 한 번 생각하게 되는 것이, 관리자분께서 CUBRID 철학을 언급하시면서
이 키워드의 도입을 완곡하게 거절하셨는데,
"과연 LIMIT ~ OFFSET ~ 를 지원하는 것이 CUBRID 철학에 위배될까"
하는 것입니다. MSSQL 이나 ORACLE 한테 LIMIT ~ OFFSET ~ 좀 지원해 달라고 하면
그들은 아마
같은 기능을 하는 키워드가 이미 있는데
개발자들이 아주 쬐끔 편하자고 LIMIT ~ OFFSET ~ 를 새로 지원할 필요는 없다
라고 할 것입니다.
그런데 제 경험상 이것은 쪼금 편한 정도가 아니라, "매우" 편합니다.
그래서 충분히 지원할 가치가 있다고 생각은 되는데...
문제는 과연 CUBRID 가 이 키워드를 지원한다고 해서
MYSQL 처럼 빅히트가 될 것인지... 그건 잘 모르겠읍니다.
사실 따지고 보면 LIMIT ~ OFFSET ~ 키워드의 도입을 제안하는 것 자체는
쪼금이라도 편해지려는 개발자의 욕심 이외에 아무것도 아닙니다.
또한 CUBRID 가 이 키워드를 지원 안한다고 해서 ORACLE 급으로 성장하는데 방해가 될 것 같지도 않습니다.
그런데 ''''나비효과''''라는 것이 있지 않을까요.
북경의 나비 한마리의 날개짓이 뉴욕에서 푹풍을 가져왔듯이
일견 단순해 보이는 키워드의 도입이 혹시라도 CUBRID 에 날개를 달아 줄지...
그동안 CUBRID 는 개발자의 목소리에 귀를 기울이는 자세를 자주 보여왔읍니다.
이것이 개발자들 사이에서 좋은 평가를 받기는 하였지만
부작용으로 저처럼 자꾸 떼(?) 쓰는 허접 개발자도 생겨났읍니다.
그래서 CUBRID 철학이 침범당하는 경우도 생겨나지 않았을까 생각합니다.
이전에 C++ 관련 글에서 글쓴이가 차기 표준에 제안하기를 아래 선언의 경우에
class CClass
{
public: enum{EnumData=1};
};
멤버 EnumData 에 접근할 때 CClass.EnumData 의 표기도 허용하자고 했읍니다.
만약 이 표기가 인정되면 저는 화를 낼 것 같습니다.
점(.) 은 인스턴스 뒤에 붙여야 되는데 CClass 는 클래스이지 인스턴스가 아닙니다.
아마 이 개발자분도 저처럼 쪼금이라도 편리함을 누리고자 하는 것입니다만
이것은 C++ 의 정신, 그리고 C++ 의 철학을 무시하는 행위일 것 같고
만약 이 표기가 C++ 표준에 인정된다면 저는 표준위원회로 쳐들어가 난리를 칠지도 모르겠읍니다 ~~.
이런 생각을 해보면,
''''CUBRID 철학''''이 무엇인지는 알 수 없으나, 역시 존중받아야 한다
는 결론에 이르게 되네요...
긴 글 읽어주셔서 감사합니다.
PS) 이전에 서버측 C-API 에 대해서 몇 마디 제안을 한 적이 있었는데
이때 아주 긍정적으로 답변해 주셔서 거의 감동을 했읍니다.