요컨대 귀하의 CTO에 동의합니다. 확장 성을 희생하면서 약간의 성능을 얻었을 것입니다 (이러한 용어가 혼동되는 경우 아래에서 설명하겠습니다). 내 두 가지 가장 큰 걱정거리는 유지 관리 성과 수평 확장 옵션이 부족하다는 것입니다 (필요하다고 가정).
데이터 근접성 : 한 발 뒤로 물러 갑시다. 코드를 DB로 푸시하는 데에는 몇 가지 이유가 있습니다. 가장 큰 것은 데이터와의 근접성이라고 주장합니다. 예를 들어 소수의 값을 반환하는 계산을 기대하는 경우 수백만 개의 레코드를 집계하여 수백만 개의 레코드를 주문형으로 보냅니다. 다른 곳에 모아질 네트워크는 매우 낭비이며 시스템을 쉽게 죽일 수 있습니다. 이렇게 말하면 기본적으로 일부 집계가 사전에 수행되는 캐시 또는 분석 DB를 사용하여 다른 방식으로 이러한 데이터 근접성을 달성 할 수 있습니다.
DB의 코드 성능 :"실행 계획 캐싱"과 같은 2 차 성능 효과는 논쟁하기가 더 어렵습니다. 때로는 잘못된 실행 계획이 캐시 된 경우 캐시 된 실행 계획이 매우 부정적인 것일 수 있습니다. RDBMS에 따라 이러한 기능을 최대한 활용할 수 있지만 대부분의 경우 매개 변수화 된 SQL을 능가하지는 않습니다 (대개 계획도 캐시에 저장 됨). 또한 대부분의 컴파일 또는 JIT 언어는 기본 작업 및 비 관계형 프로그래밍 (문자열 조작, 루프 등)에서 일반적으로 SQL과 동등한 기능 (예 : T-SQL 또는 PL / SQL)보다 성능이 우수하다고 주장합니다. Java 또는 C #과 같은 것을 사용하여 숫자를 처리하면 아무것도 손실되지 않습니다. 세밀한 최적화도 매우 어렵습니다-DB에서는 종종 유일한 데이터 구조로 일반 B- 트리 (인덱스)가 붙어 있습니다. 공정하게하기 위해, 더 오래 실행되는 트랜잭션, 잠금 에스컬레이션 등을 포함한 전체 분석이 책을 채울 수 있습니다.
유지 관리 성 : SQL은 설계된 언어를위한 훌륭한 언어입니다. 응용 프로그램 논리에 가장 적합한 지 잘 모르겠습니다. 우리 삶을 견딜 수있는 툴링과 관행 (TDD, 리팩토링 등)의 대부분은 데이터베이스 프로그래밍에 적용하기가 어렵습니다.
성능 및 확장 성 :이러한 용어를 명확히하기 위해서는 다음과 같은 의미를 갖습니다. 성능은로드가 적다고 가정하는 한 순간에 단일 요청이 시스템을 통과하고 사용자에게 다시 전달되기를 얼마나 빨리 기대할 수 있는가입니다. 이것은 종종 통과하는 물리적 계층의 수, 계층의 최적화 수준 등과 같은 것들에 의해 제한 될 것입니다. 확장 성은 사용자 / 부하의 수가 증가함에 따라 성능이 어떻게 변하는가입니다. 중간 / 낮은 성능 (예 : 요청에 5 초 이상)이 있지만 놀라운 확장 성 (수백만 명의 사용자를 지원할 수 있음)이있을 수 있습니다. 귀하의 경우에, 당신은 아마 좋은 성능을 경험할 것이지만, 당신의 확장 성은 물리적으로 구축 할 수있는 서버의 크기에 의해 제한 될 것입니다. 어느 시점에서, 당신은 그 한계에 부딪 히고 샤딩과 같은 것을 강요해야 할 것입니다. 이는 응용의 특성에 따라 실현 가능하지 않을 수 있습니다.
조기 최적화 : 궁극적으로, 귀하는 조기 최적화를 잘못했다고 생각합니다. 다른 사람들이 지적했듯이 실제로 다른 접근 방식이 어떻게 작동하는지 보여주는 측정 결과는 없습니다. 글쎄, 우리는 이론을 증명하거나 반증하기 위해 항상 본격적인 프로토 타입을 만들 수는 없습니다 ... 그러나 일반적으로 성능에 대한 유지 관리 성 (아마도 응용 프로그램의 가장 중요한 품질)을 교환하는 접근 방식을 선택하는 것이 주저합니다 .
편집 : 긍정적 인 말로, 경우에 따라 수직 스케일링이 상당히 확장 될 수 있습니다. 내가 아는 한 SO는 단일 서버에서 꽤 오랫동안 실행되었습니다. 나는 그것이 10 만 명의 사용자와 어떻게 일치하는지 잘 모르겠습니다 (시스템에서 수행하는 작업의 특성에 달려 있다고 생각합니다).하지만 실제로 수행 할 수있는 작업에 대한 아이디어를 제공합니다 더 인상적인 예는 사람들이 쉽게 이해할 수있는 인기있는 것입니다).
편집 2 : 다른 곳에서 제기 된 몇 가지 사항을 분명히하고 의견을 제시하십시오.
- Re : 원자 일관성-ACID 일관성은 시스템의 요구 사항 일 수 있습니다. 위의 내용은 실제로 그와 반대되는 것은 아니며 ACID 일관성은 DB 내에서 모든 비즈니스 로직을 실행할 필요가 없다는 것을 알아야합니다. DB에있을 필요 가없는 코드를 DB로 옮기면 나머지 DB의 물리적 환경에서 실행되도록 제한 할 수 있습니다. DB의 실제 데이터 관리 부분과 동일한 하드웨어 리소스를 놓고 경쟁합니다. 실제 데이터베이스가 아닌 다른 DB 서버로 코드를 확장하는 경우 가능할 수 있지만 대부분의 경우 추가 라이센스 비용을 제외하고는 여기서 정확히 무엇을 얻을 수 있습니까? DB에있을 필요가없는 것을 DB에서 보관하십시오.
- Re : SQL / C # 성능-관심있는 주제 인 것처럼 보이기 때문에 토론에 조금 추가하십시오. 확실히 DB 내부에서 네이티브 / Java / C # 코드를 실행할 수 있지만, 내가 아는 한, 여기에서는 논의되지 않았습니다. 우리는 일반적인 응용 프로그램 코드를 T-SQL과 C #과 같은 방식으로 구현하는 것을 비교하고 있습니다. 과거에 관계형 코드로 해결하기 어려운 여러 가지 문제가 있습니다. 예를 들어, 로그인 또는 로그 아웃을 나타내는 레코드 및 시간이있는 "최대 동시 로그인"문제를 고려하십시오. 한 번에 로그인 한 최대 사용자 수입니다. 가장 간단한 해결책은 레코드를 반복하고 로그인 / 로그 아웃이 발생할 때 카운터를 증가 / 감소시키고이 값의 최대 값을 추적하는 것입니다.할 수있다, 모르겠다) 당신이 할 수있는 최선의 방법은 CURSOR입니다 (순수 관계형 솔루션은 모두 다른 순서로 복잡하며 while 루프를 사용하여 해결하려고하면 성능이 저하됩니다). 이 경우 C # 솔루션은 실제로 T-SQL에서 달성 할 수있는 것보다 빠릅니다. 그것은 먼 것처럼 보일지 모르지만, 상대적 변화를 나타내는 행으로 작업하고 그에 대한 창 집계를 계산 해야하는 경우이 문제는 재무 시스템에서 쉽게 나타날 수 있습니다. 저장된 proc 호출도 더 비싼 경향이 있습니다. 사소한 SP를 백만 번 호출하고 이것이 C # 함수 호출과 비교되는 방식을 확인하십시오. 위의 몇 가지 다른 예를 암시했습니다. 아직도 T-SQL에서 적절한 해시 테이블을 구현하는 사람이 없었습니다 (실제로 이점을 제공하는 테이블) .C #에서는 수행하기가 쉽습니다. 다시 말하지만, DB가 훌륭하고 훌륭하지 않은 것이 있습니다. C #에서 JOIN, SUM 및 GROUP BY를 수행하고 싶지 않은 것처럼 T-SQL에서 CPU를 많이 사용하는 것을 작성하고 싶지 않습니다.