C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
분야별 포럼
C++빌더
델파이
파이어몽키
C/C++
프리파스칼
파이어버드
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

자유게시판
세상 살아가는 이야기들을 나누는 사랑방입니다.
[10104] 반론 드립니다.
박지훈.임프 [cbuilder] 3797 읽음    2004-11-19 18:20
안녕하십니까. 코난님.
금요일이라 업무때문에 정신이 없는데, 친히 코난님께서 오셔서 한마디 해주시니 저도 시간을 내지 않을 수가 없네요.
저도 SQLER에 종종 들리는 사람입니다. 회원가입은 하지 않았지만 여러 강좌도 보고 검색도 해서 좋은 자료들 많이
참고하고 있답니다.

근본적으로 저희 시스템이 과부하로 허덕이는 이유는 물론 있습니다. 짐작하시는 대로 2번, 즉 잘못된 쿼리나 인덱스
때문입니다. 간단히 튜닝을 하면서 그런 부분은 대부분 파악했습니다. 그래서 제가 손을 댄 부분도 주로 인덱스 쪽이고요.
그런데 더 근본적으로 디비 구조 자체가 어그러진 부분이 많기 때문에, 전체 재개발이 필요한 상황입니다.
그러니까 튜닝을 했다고 하더라도 문제의 근원에 대한 수정이 된 것이 아니라 겨우 달래놓은 정도죠.

제가 입사하기 이전에 개발했던 외주 업체가 해놓은 일인데다 앞으로 두어달 정도는 재개발을 할 수 있는 상황이 아니기
때문에 그냥 달래놓고 쓰고 있습니다.
제가 튜닝을 했다고 말했던 것은 이정도의 상황을 말씀드린 겁니다. MS에서 툴로서나 문서로서 제공하는 방법들은 거의
빼놓지 않고 검토 혹은 적용을 했다고 할 수 있습니다. 물론 말씀하신 방법들도 이미 해보았습니다.
하지만 시간을 내셔서 좋은 조언들을 주신데 감사드립니다.

그러면, 코난님이 말씀하신 다른 이슈들에 대해 제 의견을 드리지요.
"만든 업체의 디자인 컨셉과 설계 철학이 틀리기 때문입니다."

코난님이 예제까지 들어가며 친절하게 설명하시기를, 오라클과 마이크로소프트가 선택한 방법의 차이라고 하셨는데요.
저도 SQL 서버가 그렇게 한 것은 말씀하신 것처럼 성능과 리소스의 문제 때문일 것이라고 짐작합니다.
그런데 성능을 위해 이렇게 만들었다, 그러면 모든 문제와 혼란에 대한 답이 되는 것입니까?

짜짜로니와 사천짜장을 예로 드셨는데, 저는 좀 더 과격한 예를 들어보지요.
새로 나온 라면을 사먹었는데, 먹다 보니 면발이 밀가루가 아니라 횟가루로 만든 겁니다.
그 사실을 알고 항의를 하면 그 업체나 그 라면을 좋아하는 매니아분들이 이렇게 항변을 합니다.
횟가루로 만든 라면에도 충분한 영양이 있고 나름대로의 장점이 있다, 그리고 그 사실을 모르고 먹은 니가 잘못이다.

이 업계에는 표준과 상식이 있습니다. 물론 제품에는 당연히 업체의 컨셉과 철학이 적용되게 마련입니다.
그래서 그만큼 어떤 부분에서는 더 최적화되거나 간혹은 더 나빠질 수도 있겠지요.
그런데 문제는 표준, 혹은 업계에서 표준에 준한다고 일반적으로 생각되는 상식에 대한 준수 여부입니다.

트랜잭션의 ACID 개념에 대해서는 관계형 디비를 다루는 이 IT 업계의 대부분의 사람들이 생각하는 상식이 있습니다.
그리고 상식 뿐만 아니라 X/Open에서 정한 표준도 있습니다.

제가 마이크로소프트의 철학을 몰라서 버그가 아닌 것을 버그라고 말한 것입니까? 물론 그렇습니다.
그런데 그게 제 잘못입니까? 아닙니다.

대학이든 다른 교육기관이든 전산관련의 교육을 받은 사람이면 기본적으로 배우는 과정중에 트랜잭션이 빠지지 않습니다.
거기서 ACID는 당연히 등장합니다. 그리고 대부분의 SQL 입문서에서도 ACID를 언급합니다. 왜 정규 혹은 비정규
교육과정에서 꼭 언급합니까? 기본이기 때문입니다. 기본은 무엇입니까? 다른 모든 중고급 기술 지식의 기초에 있고
또 다른 기술들을 습득하는 데 바탕이 되기 때문입니다.

저는 방금 표준과 기본을 얘기했습니다. ACID 원칙은 표준임과 동시에 기본이기도 합니다.
그래서 저는 기본과 표준을 알고 있는 대로 MS SQL을 사용했습니다. 그리고 문제가 발생했습니다. 누구 책임입니까?

그러면 마이크로소프트가 이런 표준을 몰라서 지키지 않은 것입니까? 당연히 아니겠지요.
말씀하신 대로 마이크로소프트가 생각하는 디자인 컨셉과 설계 철학에 따라 의도적으로 지키지 않은 것입니다.

만약 코난님이나, 혹은 위의 김상욱님(한마디 하기 위해 친히 가입까지 하셨다는)께서 제가 몰라서 그런 것이고
공부를 하지 않은 제가 잘못한 것이라고 한다면 더 할 말이 없어지겠군요.

마이크로소프트의 기본 디자인 개념과 철학이 그렇다는 것이라면, 저도 한수 배웠으니까 이제는 알겠습니다.
그리고 SET XACT_ABORT ON 설정이라도 만들어주어서 마이크로소프트에 참 황공합니다.

그런데, 사소한 것도 아니고 에러 상황에서 치명적일 수도 있는 이런 중요한 '철학'이 왜 충분히 공지되지 않고 있습니까?
"기본 설정 상태에서 트랜잭션 중에 에러가 날 경우 이미 인서트된 데이터는 삭제되지 않는다" 이런 내용을
SQL 서버를 사용하기 시작하는 입문자가 '혹 그런 황당한 설정이 있나' 하고 찾아봐야 하는 것이 아니라, 굳이 찾아보지
않아도 처음 사용하기 시작할 때 바로 알 수 있게 되어있어야 하지 않습니까? 표준을 어긴 것은 마이크로소프트이기
때문에 그런 사실을 충분히 공지할 책임도 마이크로소프트에게 있는 것 아닙니까?

비용을 들여 제품을 구입한 소비자의 입장에서 각 RDBMS마다 그런 기본을 벗어나는 특성이 있는지 걱정을 하면서 써야
하는 겁니까?  SQL에 대한 기본부터 해서 인덱스, 트랜잭션과 잠금, 전부 다시 공부해야 당연한 겁니까?

혹시 이 질문에 '네'라고 말하는 분이 이 글을 보고 계십니까? 그런 분이 엔지니어시라면, 평생 공부만 하다가 죽을 겁니다.
혹 엔지니어가 평생 공부만 하는 것이 당연하다고 생각하시는 분이 계시다면, 그러면 도대체 개발은 언제 하고 자기
생활은 언제 찾느냐고 물어보고 싶습니다. 엔지니어의 정의가 평생 공부만 하는 사람입니까?

물론 오라클도 특성이 있고 DB2도 나름의 철학이 있겠습니다. 하지만 크리티컬할 수 있는 부분에서 표준과는 다르게
만들어놓고 그렇게 한 것이 우리 설계 철학이니 모르는 소비자가 잘못이라고 하지는 않습니다.
그런데도 제가 SQL 서버라는 제품을 탓하는 것이 잘못입니까?


얘기가 나왔으니 계속해보지요.

먼저 역시 SQL 서버에 대한 문제입니다. 클러스터 인덱스라는 넘 말입니다.
이거 아주 웃기는 넘이더군요. 클러스터 인덱스라는 것은 물리적인 레코드 데이터에 연결되어 있어서 이걸 걸었다가
중간에 레코드가 삽입되면 그 이후의 모든 물리적 데이터가 다 시프트된다고요. 그리고 별도 지정을 하지 않는
한, PK 필드는 이 클러스터 인덱스가 기본으로 잡혀버린다고요. 이게 무슨 뜻입니까?

고객 데이터를 주민번호를 키로 테이블로 저장한 상태에서 새 고객이 등록되면 새 주민번호가 인서트되죠.
그러면 그 주민번호보다 이후의 번호들은 모조리 디스크상에서 이동됩니다. 최악의 경우에, 100만명의 고객이 있는데
1940년생의 새 고객이 인서트되면, 그 테이블의 대부분의 데이터가 디스크상에서 읽혀진 후 새로 씌여집니다.

이런 상황은 드문 경우가 아닙니다. 굳이 주민번호가 아니더라도 이런 경우는 흔합니다.
클러스터 인덱스가 효율적이려면 그 필드는 항상 기존의 데이터보다 증가만 하는 데이터, 즉 일련번호와 같은 경우만
가능합니다.

디스크상에서 100만건 이상이 한번에 이동되면, 당연히 그 테이블은 락이 걸리겠지요.
그 테이블의 데이터를 요구하는 다른 쿼리 동작들은 느려지거나 대기하게 됩니다.
전체 성능에 엄청난 영향이 있는 겁니다. 제가 튜닝하던 도중에도 초당 수십, 수백번 인서트되는 테이블에
클러스터 인덱스가 설정된 걸 봤습니다. 하루에 두세번씩 멈추던 데이터베이스 서버가 클러스터 인덱스를 넌클러스터로
바꾸니까 쌩쌩하게 돌아가더군요. 그러면 제가, 클러스터 인덱스 외에 다른 RDB의 그냥 인덱스에 해당하는 넌클러스터
인덱스를 선택할 수 있도록 배려해준마이크로소프트에 감사해야 합니까? 아닙니다. 다른 RDB가 하는 대로 기본 상태는
넌클러스터로 하고 DBA의 선택으로 클러스터 인덱스를 선택할 수 있어야 당연한 겁니다.

그런데도 왜 이 클러스터 인덱스 설정이 기본으로 되어있습니까? 꼭 고객이 클러스터 인덱스라는 넘이 그런 것이라는
것을 공부해서 SQL 서버의 철학에 굴복해야 합니까? 이 업계에는 마이크로소프트의 독단적인 철학 외에 대부분의
구성원들이 동의하는 상식과 표준이 있습니다. 그걸 위반하고 철학과 설계탓을 하는 마이크로소프트에 제가 호의적이어야 할 이유가 있습니까? 소비자가 표준과 상식을 지키지 않는 제품에 당황하는 것이 이상합니까?

이번에는 개발툴인 비주얼 C++을 예로 듭시다.
비주얼 C++이 6.0 버전에 이르기까지 ANSI/ISO C++ 표준을 따르지 않았다는 것은 주지의 사실입니다.
상황에 따라 민감할 수도 있는 키워드들을 여러가지로 재정의해놓았지요. 마이크로소프트가 C++ 언어에 표준이 있다는
것을 몰라서 그랬습니까? 마이크로소프트라는 회사는 원래 상식과 표준을 잘 무시하고 독자적인 철학을 주장하길
즐긴다는 것을 모르는 소비자가 죄인입니까?

(닷넷 버전에 가서는 비주얼 C++의 표준 준수성을 높였다고 강조하더군요. 그동안 그토록 비난을 받으면서도 오랫동안
표준을 무시해왔던 마이크로소프트가 갑자기 왜 표준을 들먹이는지 첨에는 의아했는데, 그럴만한 이유들이 있겠더군요)


커뮤니티 운영자로서 코난님은 존경스러운 분입니다. 규모있는 커뮤니티 운영이 얼마나 어려운지 저도 잘 아니까요.
하지만 표준과 상식을 무시하는 마이크로소프트의 독단적인 '설계 철학'에 대한 제 불만에 대답이 되지는 않는군요.



김대우 님이 쓰신 글 :
: 박지훈님 안녕하세요. 반갑습니다. 제이름은 김대우라고 합니다.
:
: 평소 볼랜드 포럼에 가끔 들려 눈팅도 하고 업계 뉴스나 보다 가다가
:
: 여기 자유게시판에서 박지훈님의 글을 보고 늦은 밤이지만... 토끼같은 와이프가
:
: 눈비비고 졸립다고 하지만 몇줄 적어 보려 합니다. ^_^
:
:
: 저는 개인적으로 http://sqler.pe.kr 이라는 SQL서버와 DBMS와 관련된 여러 생각을 나누는
:
: 작은 사이트를 운영하고 있습니다.
:
: 여러 DBMS 공부를 시작한건 98년이니 햇수로 7년이네요. 사이트 운영은 99년부터 했으니
:
: 6년이란 시간이 벌써 지났나 봅니다. 지나보니 빠른데 세보니 참 오랜 시간이군요. ^_^
:
:
: LG텔레콤에서 SQL로 마이그레이션 한다는 말을 듣고 개인적으로는 흐뭇~ 합니다.
:
: 지훈님도 마찬가지시겠지만 자신이 가장 관심있는 솔루션이 잘된다는 이야기를 듣는 것이니까요.
:
:
: 그런데 지훈님 시스템에 약간의 문제가 있는듯 해서 짧은 경험이지만 제가 가진 지식을 나눠 드리려 합니다.
:
: 여러번의 SQL서버 관련 컨설팅 경험과 문제 해결, 기술 지원 경험이 있으니 믿어 주시길 바랍니다. ^_^
:
: ----------------------------------------------------------------
: 이 디비 서버는 제온 4CPU짜리 서버 한대에서 돌리는데, 바쁠 때는 1~2초 간격으로 두개 이상의 CPU가
: 100%를 칩니다.
: 데이터는 백만건 단위로 그렇게 대규모는 아니지만, 트래픽이 대단히 많고 시스템의 특성상 시간이 지날 수록 제곱배로
: 부하가 커질 수밖에 없는 구조인데요. 이미 4CPU로도 한계에 가까워지고 있어서 곧 디비 클러스터링을 고려해야 할 상황입니다.
: ----------------------------------------------------------------
:
: 우선 Clustering은 기본 컨셉이 High Availability를 위한 솔루션입니다. 만약 성능을 위한 선택이라고 생각 하신다면
:
: 조금 어색한 분위기가 될듯 합니다.
:
: 설마 Clustering의 개념을 잘못 알고 계신것은 아니리라 생각하며 아마 CPU 성능 이야기와
:
: 클러스터링 이야기를 별개로 위에 적으신 것이리라 생각합니다.
:
: 클러스터링은 알고 계신듯 하니 넘어갑니다.
:
:
: CPU가 100을 친다면 왜 치는 것입니까? 그리 많지 않은 데이터에 제온 Quad CPU인데요?
:
: 제 소견으론 먼저 어떤 쿼리나 모듈이 CPU 100%을 치게 만드는지 원인을 분석하는게 급선무라 생각 합니다.
:
: 이렇게 해 보십시요.
:
: SQL서버 툴들중 프로필러 툴 수행 -> 서버 선택 -> 템플릿을 SQL Profiler Tuning으로 선택
: 화일에 저장 선택후 화일 지정-> 데이터 탭에서 CPU, Reads, Writes, 필요시 Application Name, 또는 NT User Name 추가 -> 필요시 필터 탭에서 적절히 CPU에 대해서 수치 필터 지정
:
: 그럼 SQL서버에 전달되는 모든 쿼리와 저장 프로시져가 기록 됩니다. 여기서 딱 보시면
: CPU가 높은 쿼리가 있을 겁니다. CPU가 높으면 당연히 Disk IO인 Read나 Write가 높을 겁니다.
:
: 1. CPU, Duration 높음 : 내부에 복잡한 수치연산, 다양한 변환 함수 튜닝 필요
: 2. CPU, Disk IO높음 : 대부분의 경우 잘못된 쿼리, 잘못 생성된 인덱스, 의도적인 Full scan 가능성
: 3. CPU와 Disk IO는 낮고 Duration이 길 경우 : 잠금, 트렌젝션 처리로 인한 일시적인 Blocking, 또는 DeadLock. 상호 상관되는 쿼리 확인후 잠금 처리 필요.
:
: 2번일 겁니다. CPU의 문제라기 보다는 개발자, 관리자의 잘못된 쿼리 수행과 인덱스 생성이 문제죠.
:
: 분석하는 방법은 헤아릴 수 없이 많습니다. Microsoft에서 무료로 제공하는 분석툴을 이용하면
:
: 위의 프로필러로 잡은 쿼리의 재현과 실행 계획도 그자리에서 통계까지 포함해 볼 수 있으며
:
: 위의 프로필러 작업도 스크립트로 사실상 백그라운드로 UI없이 저장 및 구성이 가능합니다.
:
: 하지만 분석을 하시기 위한 가장 쉬운 방법을 가이드 해 드리면
:
: 해당 쿼리를 클릭하면 아래 아래 창에 전체 쿼리가 뜹니다. 복사해서 쿼리 분석기에 붙이신후
:
: 컨트롤 + K를 눌러 실행계획을 표시하고 수행해 보세요.
:
:
: 실행계획 탭을 보시면 Index Scan, 또는 Full Scan이 있을 겁니다. 보시면 엄청나게 많은 데이터 PUMP가
:
: 일어나 있을 거구요. 자 문제를 찾았습니까? 혹시 어떻게 튜닝을 하는지도 알고 싶으시면 저에게 회신 주세요.
:
:
: 자~~~ 그럼 다음 이야기 전에 제가 지훈님께 질문 올리겠습니다.
:
: 쿼리가 빠르게 수행 안되는 이유는 누구의 잘못 입니까?
:
: 이쁜 김정은을 전화줄 "앙~~~" 물게하는 어디처럼 64 Way CPU에 수백기가 메모리를 꼽으면 그냥 빨라집니까?
:
: 지훈님 회사와 같은 갯수의 CPU로도 어디 사이트는 "안녕하세요. 배철숩니다" 광고까지 하면서
:
: 현재 수백억건의 데이터를 가지고 사용자를 끝도 없이 끌어 모으는 이유는 무엇입니까?
:
: 아니, 97년부터 테라데이터를 상업용으로 서비스해온 SQL서버는 1997년도에 펜티엄4 3Ghz CPU 였습니까?
:
: 정녕 CPU가 100%를 치는것이 SQL서버에 문제가 있는 것입니까?
:
: 지금 현업에서 실제로 서버를 운영, 개발하시는 지훈님의 생각은 어떠십니까?
:
:
: 다른 이야기는 접고 트랜젝션 처리 이야기로 넘어가 보시지요.
:
: "설마 SET XACT_ABORT ON 이슈는 아니겠지...
:
: 설마... 그래도 사이트 주인장님에 프로그래밍 경력이 있지..."
:
: 지금 제 솔직한 심정은 트렌젝션에서 ACID는 기본 상식인걸 아신다는게 다행이라고 생각 합니다.
:
: 개념은 알고 계시다는 것이기 때문입니다.
:
: 일부러 제작사명 말하고 지훈님께 여쭤보겠습니다.
:
: 농심 짜짜로니 - 삼양 사천짜장 두개의 짜장라면이 있습니다.
:
: 옷~ 이게 웬걸 짜짜로니는 스프가 세개나 됩니다. 근데 젠장 사천짜장은 비닐에 든 짜장 스프뿐.
:
: 좀전에 야식으로 와이프와 아침에 눈 팅팅 붓게 될걸 각오하고 먹었습니다.
:
:
: 제 느낌에 짜짜로니~ 약간 느끼한게 바로 그 짜장맛입니다. 나름대로 제가 최고라 생각하는 짜장라면입니다.
:
: 사천짜장은 와이프의 Favorite입니다. 고소한게 짜짜로니보다 훨씬 낫다나요...
:
: 뭐 닭살이라고 하셔도 할말 없습니다.
:
:
: 여기서 질문  브레인~ 서바이버~~ 처럼 순식간에 후다닥~ 들어 갑니다.
:
: "왜 짜짜로니는 스프가 세개인데 사천짜장은 하나 뿐입니까?"
:
:
: 제가 생각하는 최고의 대답- 우문현답은 이겁니다.
:
: "만든 업체의 디자인 컨셉과 설계 철학이 틀리기 때문입니다. ~"
:
:
: 많은 "어플리케이션"에서 트렌젝션 사용은 이렇습니다.
:
: //코드 시작
: 선언문~~
:
: //예외 처리 모듈 선언
: 예외 처리 시작
:
: //트렌젝션 시작
: 처리 모듈 1
: 처리 모듈 2
: 처리 모듈 3
:
: //트랜젝션 끝
:
: //성공적으로 완료시
: 모듈 10으로 이동
:
: //실패가 하나라도 있을 때
: 에러 표시 후 모듈 9로 이동
:
: //완료
:
: 모든 모듈이 완료해야 완료로 가며 1개라도 틀리면 오류로 가죠.
:
: 그렇다면 DBMS는 어떻습니까?
:
: 먼저 오라클에서 역시 위의 방법과 비슷합니다. 결론부터 이야기해
:
: 오라클은 Implicit Transaction 방식으로 INSERT, UPDATE, DELETE가 발생하면
:
: "자동"으로 트렌젝션이 시작되는 방식입니다.
:
:
: SQL Server는
:
: Auto COMMIT 으로 불리는 방식을 쓰며 매 INSERT, UPDATE, DELETE 구문마다 처리 됩니다.
:
:
: 화끈한 이야기 들어 갑니다. 트렌젝션은 하나의 BATCH구문에서 최소한의
:
: 자원을 가지고 최소한의 시간동안 수행되는 것이 성능에 엄청난 영향을 줍니다.
:
: SQL서버의 설계자는 이 컨셉을 지상과제로 설계 했으며 개별 데이터 수정 구문에 자동으로 COMMIT을 하게해
:
: 높은 완성도와 동시성, 성능을 보장합니다.
:
:
: 오라클의 잠금 철학은 또한 다음과 같습니다.
:
: A사용자가 1을 2로 변경하면 A사용자의 세션에서는 1이 2로 메모리상에 Rollback segment와 함께
:
: 저장됩니다.
:
: 그럼 이때 B사용자가 들어와서 1을 읽으려 하면? 1이라는 Uncommited 값을 잠금 없이 바로 읽을 수 있습니다.
:
: 1을 3으로 바꾸려 하면? A사용자는 명시적으로 COMMIT을 하지 않았기 때문에
:
: B사용자와 경합이 생기며 B사용자는 대기하게 됩니다. A사용자가 COMMIT 또는 ROLLBACK할때까지 대기하게 되지요.
:
:
: 여기서 다시한번 짜장라면을 생각해 봅니다.
:
: 왜 그렇게 만든 겁니까? 양쪽 모두 나름대로의 최선의 방법이라고 생각했기 때문 아닐까요?
:
: SQL서버 개발팀의 설계가 그런 것입니다.
:
:
: 그럼 여기서 실질적인 문제를 짚어 봅니다.
:
:
: 2001년 7월에 제가 데브피아라는 곳에서 온라인 세미나를 진행하면서 사용한 구문 입니다.
: ----------------------------------------------------------------------------------------------------
: --프로시져에서 트랜젝션 처리
: USE pubs
: GO
:
: CREATE TABLE konan_TR_Test(
:     c1    int    not null    PRIMARY KEY
: ,    c2     int
: )
: GO
:
: --데이터 삽입
: insert into konan_TR_Test(c1,c2) VALUES(1, 1)        --성공
: insertT into konan_TR_Test(c1,c2) VALUES(1, 1)        --신텍스 에러
: insert into konan_TR_TestTTT(c1,c2) VALUES(1, 1)    --객체명 에러
: insert into konan_TR_Test(c1,c2) VALUES(1, 1)        --PK 제약 에러
:
: --데이터 조회
: select * from konan_TR_Test
:
: --수행
: BEGIN TRAN
: insert into konan_TR_Test(c1,c2) VALUES(2, 2)        --2라는 값 삽입
: insert into konan_TR_Test(c1,c2) VALUES(2, 2)        --2라는 값으로 PK오류 생성
: insert into konan_TR_Test(c1,c2) VALUES(3, 3)
: COMMIT TRAN
: GO
:
: --데이터 조회 - 결과는? 2는? 3은?
: SELECT * FROM konan_TR_Test
:
: --현업에서 문제.
: --학생 테이블을 생성한다.
: --drop table 수강
: --drop table 학생
: --drop table 과목
:
: CREATE TABLE 학생(
:     학생ID         varchar(10) primary key
: ,     학번        varchar(10) not null
: )
: GO
:
: CREATE TABLE 과목(
:     과목ID         varchar(5) primary key
: ,     과목명         varchar(20) not null
: )
:
: CREATE TABLE 수강(
:     수강ID         int primary key
: ,     학생ID         varchar(10) not null
:             FOREIGN KEY REFERENCES 학생 (학생ID)
: ,     과목ID         varchar(5)
:             FOREIGN KEY REFERENCES 과목 (과목ID)
: )
:
: --학생 삽입
: BEGIN TRAN
: INSERT 학생 VALUES ('KONAN', '1111')
: INSERT 학생 VALUES ('JOMIRYO', '2222')
: COMMIT TRAN
:
: --과목 삽입
: BEGIN TRAN
: INSERT 과목 VALUES ('공수', '공업수학')
: INSERT 과목 VALUES ('디비', '데이터베이스')
: INSERT 과목 VALUES ('게임', '게임프로그래밍')
: COMMIT TRAN
:
: --데이터 조회
: select * from 학생
: select * from 과목
:
: BEGIN TRAN
: INSERT 수강 VALUES (1, 'KONAN', '공수')
: INSERT 수강 VALUES (2, 'KONAN', '디비')
: INSERT 수강 VALUES (3, 'KONAN', '겜')
: COMMIT TRAN
:
: --조회
: select * from 학생
: select * from 과목
: select * from 수강
:
: --겜 과목은??
: --데이터 삭제
: delete from 수강
: select * from 수강
:
: --넣을 경우?  - 에러
: BEGIN TRAN
: INSERT 수강 VALUES (1, 'KONAN', '공수')
: IF @@ERROR <> 0 GOTO ERROR_TRANSACTION
: INSERT 수강 VALUES (2, 'KONAN', '디비')
: IF @@ERROR <> 0 GOTO ERROR_TRANSACTION
: INSERT 수강 VALUES (3, 'KONAN', '겜')
:
: IF @@ERROR <> 0 GOTO ERROR_TRANSACTION
: --성공
: print '삽입이 성공했습니다.'
: COMMIT TRAN
: GOTO END_BATCH
:
: ERROR_TRANSACTION:
: print '삽입 실패'
: ROLLBACK TRAN
:
: END_BATCH:
: print 'BATCH가 끝났습니다.'
: GO
:
:
: --넣을 경우?  - 성공
: BEGIN TRAN
:
: INSERT 수강 VALUES (1, 'KONAN', '공수')
: IF @@ERROR <> 0 GOTO ERROR_TRANSACTION
: INSERT 수강 VALUES (2, 'KONAN', '디비')
: IF @@ERROR <> 0 GOTO ERROR_TRANSACTION
: INSERT 수강 VALUES (3, 'KONAN', '게임')     --게임임.
: IF @@ERROR <> 0 GOTO ERROR_TRANSACTION
:
: --성공
: print '삽입이 성공했습니다.'
: COMMIT TRAN
: GOTO END_BATCH
:
: ERROR_TRANSACTION:
: print '삽입 실패'
: ROLLBACK TRAN
:
: END_BATCH:
: print 'BATCH가 끝났습니다.'
: GO
:
: --데이터 조회
: SELECT * FROM 수강
:
: --만약 BATCH가 1000건이라면??
: --테이블 데이터 삭제
: delete from 수강
:
: --새롭게 바뀐 처리.
: SET XACT_ABORT ON
: BEGIN TRAN
: INSERT 수강 VALUES (1, 'KONAN', '공수')
: INSERT 수강 VALUES (2, 'KONAN', '디비')
: INSERT 수강 VALUES (3, 'KONAN', '겜')     --에러
: COMMIT TRAN
:
: --데이터 조회
: SELECT * FROM 수강
:
: --새롭게 바뀐 처리.
: SET XACT_ABORT ON
: BEGIN TRAN
: INSERT 수강 VALUES (1, 'KONAN', '공수')
: INSERT 수강 VALUES (2, 'KONAN', '디비')
: INSERT 수강 VALUES (3, 'KONAN', '게임')    --정상
: COMMIT TRAN
:
: --데이터 조회
: SELECT * FROM 수강
:
: --아울러 ASP 또는 COM+에서 에러 처리 루틴
:
: ------------------------------------------------------------------------------------------------
:
: 자 스크립트 테스트 해 보셨습니까? 여기서 여쭤 봅니다.
:
: SQL서버는 SET XACT_ABORT ON 구문을 이용해야만 합니다. 어떤 경우에 그렇습니까?
:
: "Run-Time 오류"일 경우와 "분산 트렌젝션"일 경우에 필요합니다.
:
: "Run-Time"이 뭡니까?
:
: SQL서버는 빠른 속도로 쿼리를 처리하기 위해 파싱, 개체 검사, 실행
:
: 작업을 통해 수행됩니다. 트렌젝션의 처리시 만약 위의 에러 구문에서 보는 것처럼
:
: PK제약 오류와 같은 Run-Time의 오류에 대해서는 처리를 안합니다.
:
: 사실상 SQL서버의 BEGIN TRAN은 트렌젝션 처리 모듈 시작 진입 포인트를 명시한다라는 의미입니다.
:
:
: 왜 그렇습니까?
:
: 오라클은 작업을 주욱~ 진행하다가 하나만 문제가 생기면 무조건 롤백합니다.
:
: 즉, 쿼리 수행 절차가 SQL서버와 틀린 방식으로 진행되며
:
: 오라클은  트렌젝션 처리를 진입 포인트가 아닌 선언문처럼 사용하는 개념입니다.
:
: 여기서 질문 하나 던집니다. 둘중에 뭐가 더 빠릅니까? 나중에 시간나면 해 보십시요.
:
: 방식이 틀려도 성능의 차이는 특수한 상황이 아닌 이상 크지 않습니다.
:
:
: 또 질문 하나 던집니다.
:
: "SQL서버는 왜 그런겁니까?"
:
: "설계의 컨셉이 그렇습니다."
:
: "왜 오라클이나 SQL서버가 똑같지 않습니까?"
:
: "볼랜드 C++ 빌더랑 Visual C++은 왜 틀립니까?"
:
:
: 그럼 박지훈님에게 제가 묻습니다.
:
: 모든 SQL서버 "기본" 책들에서 심도있게 다루는 트렌젝션과 잠금 처리.
:
: SQL서버 개발을 하시면서 기초가 되는 책을 한권이라도 보셨다면 모르실리가 없다고 생각 합니다.
:
: 당연히 모두가 그렇게 쓰는 부분을 지훈님만 선언문을 빼고 쓰셨고 그걸 SQL서버의 문제 / 버그라고
:
: 하신 거군요. 
:
:
: 지훈님이 보신다는 프로페셔널이라는 책은 제가 없어서 모르겠습니다만... Step by Step 책이나 기초 책은
:
: 안보시고 프로 책으로 넘어가신듯 하네요. 참 글을 읽으면서 궁금한건 도데체 한달동안 튜닝을 하셨다면서
:
: 이런 기초적인 부분은 하나도 안 보시고 도데체 뭘 튜닝 하신 것인지 궁금합니다.
:
:
: 그래도 끝까지 "사람을 당황스럽게 하는 SQL서버"라고 하시는걸 보니 개발자 기질과
:
: 엔지니어 기질이 보이시네요.
:
:
: 저역시 몇마디만 더 드리겠습니다.
:
: SQL서버를 처음 공부할때 였을 겁니다. 당시 다양한 언어와 그 매력에 푹 빠져서
:
: 한참 재미있을때 SQL서버 초급 책을 두어권 끝까지 독파 했습니다.
:
: 샘플도 다 돌려 보고 프로그램에 붙여도 보고... SQL서버의 모든걸 안것 같았습니다.
:
: 그러다 MCDBA라는게 있다길래 껌이지~~ 하고 시험 공부 하는데
:
: 웬걸 난이도가 엄청난겁니다. 열심히 온라인 도움말을 보면서 공부했지만 떨어졌습니다.
:
: 부끄럽지만... 하지만 참 감사하게도... 덕분에 SQL서버의 깊이를 알게 되었죠.
:
: SQL서버의 온라인 도움말을 파고 또 파면서 인덱스 부분과 이해가 안가는 부분은 프린트 해서 씹어 먹으면서
:
: 이 악물고 공부했습니다. 니가 이기나 내가 이기나 해 보자잉~~~
:
: Microsoft의 KB를 보면서... 또 3rd업체의 SQL서버 관련 Tip들을 보면서
:
: 지훈님도 볼랜드 제품에 대한 매력을 느끼시는 것처럼 저역시 SQL서버의
:
: 매력에 푹~ 빠지게 되었죠.
:
: 덕분에 SQL서버 튜닝, 컨설팅도 해보고... 좋은 기회도 많았구요.
:
: 하지만 지금 또 SQL서버를 공부하면서 느끼는건 정말 깊이 들어갈수록 한도 끝도 없다는
:
: 것입니다. 특히나 최근 이기종간의 분산 트렌젝션 처리나 이기종 DBMS와 관련된 작업을
:
: 많이 하면서 더더욱 그런 느낌을 가지게 되었고 요즘엔 주변의 SQL전문가 분들을 보면서
:
: 세상엔 숨어있는 초고수님들이 이리도 많구나 하는 생각만 듭니다.
:
:
: 저역시 SQL서버라는 시스템에 열정이 있습니다. 지훈님도 그러시겠죠.
:
: 지훈님이 이렇게 멋지게 꾸며 놓으신 사이트를 보면서 저역시 지훈님의 열정을 잘 보고 있습니다.
:
: 제 사이트에서 나름대로 튜닝한 게시판 제작후 열심히 질문 답변도 달고, 강좌도 열심히 무료로
:
: 등록 같은 것 안해도 모두 볼 수 있게 무료로 아무런 대가 없이 적었고
:
: 더더욱 많은 분들에게 SQL서버의 여러 6만 2천건이 넘는 QnA를
:
: 좀더 많은 분들이 손쉽게 검색 할 수 있도록 하기 위해 QnA게시판의 내용을
:
: 로컬 오프라인으로도 검색 가능하도록 하는 SQLER 탐쉐이~ 라는 툴도 만들었습니다.
:
: 물론 무료죠. 등록도 필요 없습니다. 그냥 다운로드 해서 쓰세요.
:
:
: MS가 지원 해 줬냐구요? 아니요~ 배너 하나 얼마얼마에~ 해준다는 말 한번도 없었습니다. ㅋㅋㅋ
:
: MS가 지원해 준다고 해도 내가 안했을 겁니다. 그럼 MS에게 하고싶은 말을 제 웹사이트에서
:
: 조차 할 수 없었을 테니까요.
:
: 이런 무료 봉사 쌩 뻘짓거리를 왜 했냐구요? 그것도 내직장 다니며, 9시에 출근해 11시에 퇴근하면서
:
: 새벽까지 강좌쓰고 게시판에 답글달고... 누가 돈주는 것도 아닌데 왜 했냐구요?
:
: 이 참 잘 만든 SQL서버를 많은 분들이 너무 몰라 주셔서, 잘못알고 계셔서,
:
: 많은 분들이 단순히 MS에 대한 악감정과  억하 감정만을 가지고 접근 하셔서 제가 직접 만들었습니다.
:
:
: 지훈님께 부탁 드립니다.
:
: 아주 잘만드신 웹사이트입니다. 저역시 많은 업계의 정보와 볼랜드측 자료를 여기서 봅니다.
:
: 항상 감사 드리고 있는 그런 눈팅만 해온 사람입니다.
:
:
: 한마디만 드리자면 지훈님은 웹사이트의 주인장님이신 많은 분들이 주목하는 공인입니다.
:
: 저역시 지훈님의 웹사이트에선 한명의 정보를 얻어가는 손님일 뿐이구요.
:
: 부디 공인의 입장에서 치우침 없이... 여기 지훈님이 버그 덩어리라고 느끼시는 그 SQL서버에
:
: 대한 열정만 있는 제 마음도 좀 편하게 해 주시길 간곡히 부탁 드립니다.
:
:
: 읽어 주셔서 감사합니다. 혹시 기회가 되면 제가 잘익은 생삽겹살 구이에 참이슬 따라드리면서
:
: 이런 저런 이야기 나누고도 싶네요.
:
:
: PS. SQL 서버를 운영하시면서 버그인것 같으시다면... 제게 메일, 게시판에 질문 주세요.
:
: 제가 처리 가능한 일이라면  해 드리고 다른 관련된 채널이 있으니 도움 드릴 수 있는 부분은 최대한
:
: 도움 드리겠습니다.
:
: 이만.
:
:
:
: 박지훈.임프 님이 쓰신 글 :
: : 최근 며칠 사이에 MS SQL서버 2000의 버그로 강하게 의심되는 사례를 두차례나 겪어 글을 써봅니다.
: : 마침 방금 올린 IT뉴스 기사중에도 LG텔레콤이 오라클에서 SQL서버로 마이그레이션을 시도한다는 기사도 있고 해서요.
: :
: : 제가 다니는 회사에서 사용하는 DBMS 제품이 나오는 관계로 회사가 어디인지 공개적으로 밝히진 않겠습니다.
: : IT쪽 회사는 아니지만 해당 분야에서는 아주 잘 알려진 중견 기업이구요. 최근 오프모임에서 만난 분들은 물론 아시죠.
: :
: : 저희 회사에서는 전사적으로 MS SQL서버를 사용하고 있습니다.
: : 파트별로 디비를 별개로 운영하고 있기 때문에 디비서버가 꽤 여러 대 되는데, 다 SQL서버를 돌리고 있죠.
: : 그중에 제가 직접 관여한 시스템이 가장 많은 트래픽을 기록하는데요.
: :
: : 이 디비 서버는 제온 4CPU짜리 서버 한대에서 돌리는데, 바쁠 때는 1~2초 간격으로 두개 이상의 CPU가 100%를 칩니다.
: : 데이터는 백만건 단위로 그렇게 대규모는 아니지만, 트래픽이 대단히 많고 시스템의 특성상 시간이 지날 수록 제곱배로
: : 부하가 커질 수밖에 없는 구조인데요. 이미 4CPU로도 한계에 가까워지고 있어서 곧 디비 클러스터링을 고려해야 할
: : 상황입니다.
: :
: : 사실 저는 디비 전문가는 전혀 아니지만, 그동안 개발을 하면서 당연히 디비쪽도 이래저래 꽤 다루기도 했고요.
: : 또 어떻게 하다보니 이 회사에 입사하고 처음 한 일이 SQL서버 튜닝이었는데, 입사후 거의 한달 가까이 디비 튜닝, 특히
: : SQL서버 튜닝에 대한 관련 자료들을 뒤적거려서 성공적으로 튜닝을 마쳤습니다.
: : 그러니까 디비쪽으로 DBA 수준의 아주 전문은 아니어도 알만큼은 알고 다뤄볼 만큼은 다뤄본 정도라고 할 수 있지요.
: :
: : SQL서버의 버그로 의심되는 문제가 발생한 것은, 고객 정보를 DB에 등록하는 루틴에서였습니다.
: : 고객 정보를 등록할 때 동시에 입력되는 정보가 꽤 많기 때문에 여러 테이블.. 대략 10개 이상의 테이블에 한방에
: : 인서트를 합니다. 당연히 트랜잭션을 먼저 걸고 인서트 쿼리들을 날린 후에 커밋을 하지요. 그리고 트랜잭션의 특성상
: : 어떤 에러라도 발생하면 전체 트랜잭션내의 모든 쿼리가 취소되지요.
: :
: : 며칠전.. 그러니까 지난주 금요일부터 갑자기 고객 정보 입력을 하는 ASP 페이지에서 에러가 나면서 입력이 안되는
: : 문제가 발생했습니다. 입사한지 얼마 안되는 제가 알기로도 1년 이상 아무 문제없이 써오던 부분이라 꽤 당황스러웠죠.
: : 하루에도 수십명씩의 고객을 등록해야 하는데, 입력 작업이 장난아니게 노가다이기 때문에 며칠 정도만 입력이 미뤄져도
: : 감당 못하게 입력할 데이터가 쌓이고, 여러가지로 문제가 복잡해집니다.
: :
: : 보통 오랫동안 잘 동작하던 부분에서 문제가 생기면 어디서부터 뒤져봐야 할지 난감해지잖습니까.
: : 월요일에야 문제를 찾았는데요. 문제의 직접적인 원인은 트랜잭션의 롤백이 제대로 이루어지지 않은 거였습니다.
: :
: : 에러가 발생하기 시작한 시점의 직전에 고객 데이터를 입력하다가 에러로 롤백된 데이터가 있었나보더군요.
: : 당연히 고객 정보 전체의 마스터 테이블에서 고객 번호를 딴 후에 그 고객번호로 디테일 테이블에 차례로 데이터를 넣는
: : 흐름으로 처리되게 되어있는데, 마스터를 포함한 다른 모든 테이블의 레코드들은 모두 롤백되어 사라졌는데, 세번째
: : 디테일 테이블에 추가되었던 레코드가 지워지지 않고 남아있더군요.
: :
: : 게다가 하필이면 찌꺼기 레코드가 남은 이 디테일 테이블이 마스터 테이블과 1:1 관계에 있는 테이블이었습니다.
: : 다시 말해서 마스터 테이블의 PK는 고객번호인데, 이 디테일 테이블의 PK도 고객번호로 되어 있다는 얘깁니다.
: : 테이블의 PK인 고객번호 필드에 연결되어 있습니다.
: :
: : 고객번호를 딴다는 표현에서 짐작하셨겠지만 이 고객번호가 일련번호로 되어있습니다.
: : 그러니까 새로 고객을 등록할 때마다 1씩 증가하는 새 번호를 만드는 건데요.
: : 먼저 마스터테이블에서 번호를 따고 마스터 테이블에 1:1로 연결된 디테일 테이블에 새 레코드를 인서트하려고 시도할 때,
: : 이미 해당 고객번호의 레코드가 있기 때문에 트랜잭션이 커밋되지 못하고 매번 롤백되어버린 거였습니다.
: : 마스터테이블에는 해당 고객 번호가 없고 디테일에는 남아있는 상황이죠.
: :
: : 아시다시피 MySQL과 같이 기본적으로 트랜잭션을 지원하지 않는 디비를 제외하면, 데이터베이스에 있어 트랜잭션의
: : 특성은 기본중의 기본입니다. ACID라고 해서 4원칙도 있잖습니까. 그런데 MS가 그렇게 안정적이라고 장담에 장담을 하는
: : SQL 서버에서 롤백된 데이터중 일부가 지워지지 않고 남아버리는 어처구니 없는 상황이 벌어져서 며칠동안 대혼란이
: : 일어난 겁니다.
: :
: : 이쯤 되면, SQL 서버를 상당기간 잘 써오신 분들은 제 말에 의심부터 드시겠지요.
: : 정상적인 입력작업이 아닌 경로로 추가된 레코드가 아닌가? 라든지 말이죠.
: :
: : 그런데 이 DB 서버는 웹서버 머신과 저희팀의 네명의 PC 외에는 접근조차 할 수 없도록 IP가 막혀 있고요.
: : 또 저도 설마, 혹시나, 하면서 저희 시스템의 전체 소스를 다 뒤져서 이 테이블에 인서트를 하는 다른 루틴이 있나 다시
: : 찾아보기도 했습니다만 전혀 없었습니다. 게다가 남아있는 찌꺼기 레코드의 데이터와 입력되지 못하고 대기중이던
: : 고객정보 문서들을 대조해본 결과 대기중이던 문서들중 하나에 그 레코드 내용들이 있더군요.
: :
: : 결과적으로 다르게 어떻게도 변명할 수 없는, SQL서버 자체의 버그가 아니면 있을 수가 없는 문제입니다.
: :
: : 게다가, 불과 이틀 후에 같은 문제가 다시 재발했습니다. 바로 며칠전에 겪은 일도 있고 해서 입력 에러가 생기기 시작하자
: : 마자 바로 찌꺼기 레코드가 있나 찾아봤는데, 역시나 있더군요. 그런데 황당하게도 며칠전에 문제를 일으켰던 것과 똑같은
: : 디테일 테이블에 똑같은 형태로 레코드가 남아있더라구요.
: :
: : 같이 인서트되는 테이블이 디테일 테이블이 열몇개나 되는데 불과 며칠 사이에 유독 이 테이블에만 두차례나 문제가
: : 생기는 것이 신기하고 황당해서, 다른 테이블과 다르게 설정된 특이한 점이 있나 해서 이래저래 뒤져봤는데요.
: : 한가지 차이점이 있었습니다. 실수로 FK가 안잡혀있더군요. 구조상 FK를 잡아줘야 하는데, 그걸 빼먹은 겁니다.
: : 다른 테이블에는 다 잡혀있었고요.
: :
: : FK가 안잡혀있는 것은 분명히 실수이긴 하지만, FK가 안잡혀있다고 해서 롤백이 제대로 되지 않아서는 안되죠?
: : 이번 케이스의 경우 서로 연관된 테이블들을 함께 인서트하는 거지만, 디비를 다루다보면 연관성이 없는 레코드들도
: : 하나의 트랜잭션 안에서 커밋/롤백하는 경우도 종종 생깁니다. 트랜잭션의 All or Nothing 원칙에은 FK가 잡혀있건
: : 안잡혀있건 무관하게 무조건 지켜져야 하는 겁니다.
: :
: : 아마도, 어떤 복잡하게 꼬인 조건에만 발생하는 버그가 있어서 그 조건중의 하나로 FK가 안잡혀있다는 조건이 포함되는
: : 것 같습니다. 앞에서도 말했듯이 다른 경로로 이 찌꺼기 레코드가 들어갔을 가능성은 전무한 상태이므로 SQL 서버의
: : 버그가 아니라면 있을 수가 없는 일이지요.
: :
: : 다시 한번 확인할 기회를 갖기 위해..
: : 그 디테일 테이블에 FK를 잡지 않고 그대로 뒀습니다. 불과 3일만에 두번이나 발생한 문제이므로 다시 발생할 가능성이
: : 높겠죠. 세번째까지 확인한 후에 FK를 잡아놓고 그 이후에 더이상 발생하지 않는다면 SQL서버의 버그일 가능성이
: : 거의 틀림없겠죠.
: :
: : 하지만 FK를 잡기 전에 다시 발생하지 않는다거나 FK를 잡은 후에도 발생한다고 해서 SQL서버의 버그가 아니라고
: : 할 수도 없습니다. 이런 종류의 버그는 발생하는 패턴을 잡아내기가 대단히 힘드니 예상한 방식으로 다시 나타나지
: : 않을 가능성도 충분히 높죠. 그리고 이미 정황상 SQL서버의 버그가 틀림없어보이기도 하고요.
: :
: : 물론, 대부분의 다른 사이트에서는 잡음이 들리지 않는 걸로 봐서(들리지 않는다고 발생하지도 않는 것은 아니지만)
: : SQL서버를 채택한 기업들이 적어도 그럭저럭은 쓰고 있다는 말일텐데요. 그렇다고 안심할 것이 못됩니다.
: : 저희 회사에서 발생한 이번 건의 경우 그나마 고객 정보 입력 단계에서 발생한 문제여서 그렇게 시분초를 다툴 정도의
: : 큰 문제는 아니었지만, 이런 문제가 만약 1초 1초가 급한 업무에서 발생해버린다면?
: : 그야말로 대란이 일어나는 거지요 뭐.
: :
: : 바로 이런 면 때문에 기업에서 미션 크리티컬한 업무에는 "충분히" 검증되지 않은 DBMS를 쓰지 못한다는 건데..
: : 아직 SQL 서버는 충분히 검증되지 않은 상태인데 시스템 구축시에 SQL 서버를 채택한 것이 성급했다고 할 수 있죠.
: :
: : MS에서 SQL서버는 사실상 7.0에서 완전히 새로 개발했다고 그렇게 자랑을 해대는데...
: : 거꾸로 말하면 7.0이 출시된 98년인가 이후로 불과 6년 정도의 검증기회밖에 없었다는 얘기가 되죠.
: :
: : 어쨌든... 저희 회사에서는 현재 오라클로 마이그레이션할 것을 진지하게 고려하고 있습니다.
: : 사실 오라클 마이그레이션 외에 다른 대안이 없죠.
엔서버 [enserver]   2004-11-20 06:24 X
임프님, ACID지원문제하고 Clustered index문제는 SQL서버를 사용하는 사용자에게는 중요한 것 같아서  요약하여 허락도 없이 팁으로 퍼갔습니다. ( http://enserver.co.kr )
좋은 내용 감사합니다.
못된똥 [lancelot]   2004-11-23 15:19 X
어머나...지나가다 다시들렀는데..참 많은 토론이 있었네요...
그런데 임프님 SQL 서버의 클러스터드 인덱스는 중간에 데이터 값이 삽입이 되면
그뒤의 모든 데이터가 밀려나서 이동되지 않습니다..큰일날 말씀이군요...
해당 페이지가 더이상 데이터로우가 삽입될 공간이 없을 경우 해당 페이지의 데이터들이
분리되어 새로운 페이지로 이동하고 인덱스 페이지간의 링크 정보만 변경됩니다.

반드시 참고하시기 바랍니다.

+ -

관련 글 리스트
10092 MS SQL서버 2000의 치명적 버그를 의심하다... 박지훈.임프 5554 2004/11/17
10102     Re:안녕하세요. SQLER의 코난 김대우라고 합니다. 지나가다가 몇자 적습니다. 김대우 12908 2004/11/19
10104         반론 드립니다. 박지훈.임프 3797 2004/11/19
10107             (지적해 주셔서 감사합니다. 수정했습니다.)결국 SQL서버의 문제/버그가 아니란거군요. 김대우 5560 2004/11/21
10114                 김대우님... 박지훈.임프 2602 2004/11/23
10117                     참 안타깝습니다... 반MS, 친MS라니요... 김대우 2314 2004/11/24
10119                         저도 안타깝습니다. 누구나 아는 엄연한 사실을 루머라니요. 박지훈.임프 2245 2004/11/24
10128                             주제넘게 두 분께 싫은 말씀 드립니다. 소프트진™ 2201 2004/11/24
10120                             Re:반MS님이 말씀 하시는 누구나 다 아는 "사실"이 참 궁금합니다. 김대우 2356 2004/11/24
10125                                 보여드린 것을 보지 못하셨나봅니다. 박지훈.임프 2274 2004/11/24
10137                                     점심때 너무 날씨 좋았죠? 그동안 토론을 진행해 주신 지훈님께 감사 드립니다. 김대우 2332 2004/11/25
10230                                         두분께서 직접 만나셔서 담판을 짓고 알려 주세요.- 공개 세미나 소리바람.OJ 2039 2004/11/26
10141                                         Re:점심때 너무 날씨 좋았죠? 그동안 토론을 진행해 주신 지훈님께 감사 드립니다. 이성호 2040 2004/11/26
10123                                 잠시 휴식시간을 가지세요. 소리바람.OJ 1649 2004/11/24
10108                 Re:결국 SQL서버의 문제/버그가 아니란거군요. civilian,안영제 2373 2004/11/21
10111                     Re:Re: 그냥...... 서주형.무소유 2113 2004/11/22
10098     MS SQL서버 2000 사용자는 아닙니다만... 바람 10690 2004/11/18
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.