"코드에서 SQL 서버를 효과적으로 활용할 수있는 방법을 절대로 사용하지 마십시오"-이것은 나쁜 설계를위한 레시피입니까?


204

소수의 장소에서 반복해서 들었던 아이디어입니다. SQL에서 순수하게 문제를 해결하려고 시도하면 특정 수준의 복잡성을 초과한다는 사실을 어느 정도 인정하는 것이 실제로 코드에서 처리해야한다는 것입니다.

아이디어의 논리는 대부분의 경우 데이터베이스 엔진이 코드에서 할 수있는 것보다 작업을 완료하는 가장 효율적인 방법을 찾는 데 더 나은 작업을 수행한다는 것입니다. 특히 데이터에서 수행되는 작업에 대해 결과를 조건부로 만드는 것과 같은 경우에 특히 그렇습니다. 아마도 현대 엔진을 사용하면 쿼리의 컴파일 된 버전을 효과적으로 JIT + 캐싱 할 수 있습니다.

문제는 데이터베이스 엔진을 이런 식으로 활용하는 것이 본질적으로 나쁜 설계 관행인지 그 이유입니다. 모든 논리가 데이터베이스 내에 존재하고 ORM을 통해 명중하면 선이 더 흐려집니다.


60
이것은 신중하게 취해야 할 말 중 하나입니다. 다른 엔지니어가 'select * from table'을 수행 한 다음 where 절을 사용하고 열을 지정하는 대신 결과 집합을 빗질 할 때마다 채찍질됩니다. 그러나 당신이 그것을 너무 멀리 가져 가면 결국 다른 혼란으로 끝납니다.
Michael Kohne

154
"never"또는 "always"로 문구를 시작하는 것은 거의 항상 나쁜 설계를위한 레시피입니다.
vsz

34
SQL에서 너무 많은 일을 시도하는 것은 가능 하지만 30 년의 개발 및 컨설팅에서 실제로 심각한 사례는 보지 못했다고 말할 수 있습니다 (사소한 사례). 다른 한편으로, 나는 문자 그대로 SQL에서해야했던 "코드"로 많은 일을하려는 수백 명의 심각한 개발자 사례를 보았습니다. 그리고 나는 여전히 그들을 볼 수 있습니다. 자주 ...
RBarryYoung

2
@MrEdmundo 메타로 가져 가라.
ta.speot.

4
이 질문은 하나에 2 개입니다. 분할해야한다고 생각합니다. 1) SQL에서 얼마나해야합니까? 2) DBMS에서 얼마나해야합니까? 저장 프로시 저는 중간에 속합니다. 전체 응용 프로그램이 저장 프로 시저로 코딩 된 것을 보았습니다.
reinierpost

답변:


321

평신도의 말로 :

이것들은 SQL이 할 일 이며, 믿거 나 말거나, 코드에서 본 것입니다.

  • 조인 -코드 단위로 복잡한 배열 조작이 필요합니다.
  • 데이터 필터링 (어디서나)-코드 방식으로 목록에서 항목을 많이 삽입하고 삭제해야합니다.
  • 열 선택 -코드 방식으로 무거운 목록 또는 배열 조작이 필요합니다.
  • 집계 함수 -코드 방식으로 값과 복잡한 스위치 케이스를 보유하기 위해 배열이 필요합니다.
  • 외래 키 무결성 -코드 단위로 삽입하기 전에 쿼리가 필요하며 아무도 앱 외부의 데이터를 사용하지 않는다고 가정합니다.
  • 기본 키 무결성 -코드 단위로 삽입하기 전에 쿼리가 필요하며 아무도 앱 외부의 데이터를 사용하지 않는다고 가정

SQL 또는 RDBMS에 의존하는 대신 이러한 작업을 수행하면 값이 추가되지 않은 수많은 코드가 작성 되므로 디버그 및 유지 관리해야 할 코드가 더 많아집니다. 그리고 데이터베이스를 응용 프로그램을 통해서만 액세스 할 것이라고 위험합니다.


88
모든 것이 응용 프로그램을 통해서만 발생할 것이라고 위험하다고 가정하면 +10000000000입니다.
HLGEM

11
@skynorth 데이터베이스 디자인이 잘못되었습니다. 결론적으로 데이터베이스는 결국 모든 사후 처리로 인해 해당 응용 프로그램에서만 의미있게 액세스 수 있습니다.
Sirex

21
@skynorth 키의 무결성을 유지하기 위해 코드를 사용하는 경우 DB에서 RDBMS의 기본 원칙을 제거하는 것입니다. DB에 액세스하는 모든 응용 프로그램은 해당 기능을 정확하게 복제해야하기 때문에 이치에 맞지 않습니다. DB가 처리하도록 설계된 이유는 무엇입니까? 예를 들어, DB는 복제 키를 기본적으로 방지 할 수 있습니다.
Buttle Butkus

10
거래를 잊지 마세요!
Sklivvz

24
@skynorth : tl; dr : 데이터 일관성을 유지하는 규칙은 데이터베이스에서 구현해야합니다. 즉, 지금까지 작성된 응용 프로그램의 99 %에 대해 응용 프로그램이 종료되고 사라진 후에도 데이터 (및 데이터베이스)는 looooooooooong 수명을 유지 합니다. 나는 여러 해 동안 이것을 여러 번 보았습니다. (여기서, {insert old platform here}이 (가) 죽어 가고 있기 때문에 Windows / iPhone / Android / 무엇보다 새로운 것에 버전을 배포해야합니다.) 호스트 또는 Oracle 데이터베이스 것이다 여기에 새로운 UI를 만들 수 있다 ). 이 추세가 오늘이나 곧 중단 될 이유가 없습니다.
이진 걱정

122

나는 "당신을 위해 무엇을 할 수있는 SQL 서버 코드에서 할 절대로 해당 바꿔 것이 아니라 ".

문자열 조작, 정규식 작업 및 SQL Server에서 수행하지 않는 SQL CLR과 같은 것들.

위의 내용은 조인, 설정 작업 및 쿼리와 같은 것들에 대해 이야기하는 경향이 있습니다. 그 뒤에 의도는 많은 양의 리프팅을 SQL Server에 위임하고 가능한 한 IO의 양을 줄이는 것입니다 (SQL이 조인을 수행하고 WHERE절로 필터링 하여 많은 것을 반환하도록하십시오) 다른 것보다 작은 데이터 세트).


27
SQL이 응용 프로그램 코드를 SQL 계층에 넣는 것보다 SQL이 더 나은 모든 것을 수행한다면, 데이터베이스에는 결국 더 나은 또는 더 나쁜 결과를 초래할 많은 비즈니스 논리가 있습니다. 나는 이것을 보았습니다. 그렇습니다. 성능은 훌륭했습니다. 그러나 운 좋게도 개발 팀은 모두 앱 개발과 SQL을 매우 잘 알고있었습니다. 나는 이것을 시작점으로 제안하지 않고 시스템이 엄청난 인기를 얻고 시간이 지남에 따라 성능이 저하 된 후의 끝점을 제안합니다.
Jimmy Hoffa

3
코스 innit guv에 대한 말?
StuperUser

28
@NathanLong 왜 아직도 많은 사람들이 SQL을 소스 제어로 유지할 수 없다고 생각하는지 모르겠습니다. 처음에는 소스 제어에서 데이터베이스를 처음부터 새로 만드는 데 필요한 모든 저장 프로 시저 / 테이블 스크립트 등이 있었고 나중에 Visual Studio 데이터베이스 프로젝트를 사용했습니다. 프로젝트없이 잘 작동했으며 더 잘 작동했습니다. 시스템을 만드는 데 필요한 다른 모든 변경 가능한 것과 마찬가지로 SQL은 버전 제어를 받아야합니다! 작성 스크립트를 버전 제어 상태로 유지하고 diff 스크립트 사용 도구를 유지하지 않는 경우 대부분의 RDBMS에 대해 redgate diff 도구를 사용하여 배치를 수행 할 수 있습니다.
Jimmy Hoffa

3
SQL이 REGEX 조작 및 문자열 조작을 지원하는 경우 SQL에서 수행하는 것이 좋습니다.
kevin cline

3
@NathanLong : DB 테이블은 텍스트 파일로 작성된 코드에 의해 정의되며 구문은 "create table ..."줄에 따라 결정됩니다. 이제 필요한 API를 호출하는 즐겨 사용하는 앱 언어로 DB 테이블 생성 코드가 있고 해당 텍스트 파일을 SCM에 저장하는 것처럼 원하는 텍스트 파일을 원하는 SCM에 저장할 수 있습니다. 문제는 어떤 사람들은 DB가 어떻게 든 마법의 짐승이라고 생각하고 VB 코드 (또는 무엇이든)를 작성하는 방법 만 알고 있으므로 알고있는 응용 프로그램 언어의 관점에서만 생각한다는 것입니다.
gbjbaanb

47

SQL 서버가 당신 을 위해 할 수있는 것을 코드로 작성하지 마십시오 (강조는 내 것입니다)

대답의 핵심은 단순히 무언가를하는 것이 아니라 SQL이 잘하는 것을 찾아야한다는 것입니다. SQL은 놀랍도록 강력한 언어입니다. 내장 함수와 결합하여 잠재적으로 많은 일을 할 수 있습니다. 그러나 SQL에서 무언가를 할 수 있다는 사실이 실제로 SQL에서 그것을 수행하는 데 변명해서는 안됩니다.

결정을 내리는 구체적인 기준은 되 찾는 데이터의 양과 왕복 횟수를 확인하는 것입니다. 트립되면 작업이 서버에 속합니다. 왕복 횟수를 동시에 줄이지 않고 데이터 양이 동일하거나 증가하면 작업이 코드에 속합니다.

다음 예를 고려하십시오.

  • 생년월일을 저장하면 사용자 그룹의 연령을 계산해야합니다. SQL 서버에서 빼기를 수행하거나 코드에서 수행 할 수 있습니다. 왕복 횟수는 동일하게 유지되며 사용자에게 다시 전송되는 데이터 양이 증가합니다. 따라서 코드 기반 솔루션이 승리합니다
  • 생년월일을 저장하고 20 세에서 30 세 사이의 사용자를 찾아야합니다. 모든 사용자를 클라이언트에 다시로드하고 빼기를 수행하여 나이를 찾은 다음 필터링을 수행하고 논리는 SQL Server로 전달할 수 있습니다. 추가 왕복을 요구하지 않고 데이터 양을 줄입니다. 따라서 SQL 기반 솔루션이 승리합니다.

1
비즈니스 로직이 SQL로 비정질 화 된 곳에서 일했을 때, 우리는 여러 번의 왕복에 문제가 없었습니다. 그 규칙이 좀 거기 나누기 있도록 규칙의 정신은 황금 평균을 목표로 꽤 좋은 불구하고 우리는 단지, 하나의 왕복 여러 결과 집합을 사용
지미 호파에게

2
+1 이것은 양방향을 지원하는 구체적인 예를 제공하기 때문에 환상적인 답변입니다.
Brandon

1
두 번째 예에서. 사용자와 bday는 캐시이며 레코드 크기는 1000-2000입니다. 메모리 에서이 작업을 수행하는 것이 더 빠르지 않습니까? 데이터가 캐시되어 있으므로 'in between'SQL 작업을 피할 때 db 호출이 필요하지 않습니다. 처리는 메모리에 1000 명 이상의 사용자 목록을 반복하고 일치하는 위치를 찾습니다. 이것은 db에서하는 것보다 빠르지 않을 것입니다.
user4677228

1
@ user4677228 그러나 스케일 업을 시도하십시오 :-p. 코드에서 모든 연령을 계산하기 위해 모든 데이터를 스캔해야하고 원하는 결과가 "20 세 이상 30 세 미만의 사용자 수"인 경우 캐시는 전혀 도움이되지 않습니다. 여전히 전체 테이블을 클라이언트로 스트리밍하지만 데이터베이스 서버 메모리 / 캐시 에서 모든 작업을 수행 할 수 있으며 db 클라이언트가 로컬 소켓을 통해 연결하는지 또는 네트워크를 통해 원격으로 연결하는지에 관계없이 빠른 답변을 제공 할 수 있습니다 당신은 WHERE절 에서 나이를 계산하고자합니다 .
binki

21

간단히 말해서 , " 코드베이스에서 데이터베이스 특정 작업 을 수행하지 마십시오"라고 말하는 것이 정확 합니다.

기본 설정 조작의 예를보십시오 . 아시다시피 RDBMS 는 일반적인 데이터 저장 및 조작 작업을 처리하도록 구축되었습니다.

또한 데이터베이스의 프로젝트 선택은 중요한 역할을 합니다. RDBMS (MS SQL, Oracle 등)를 갖는 것은 RavenDB와 같은 NoSQL 데이터베이스와 다릅니다.


코드 기반에 집합 연산을 넣지 않으면 LINQ에서 컬렉션 (선택, 합계, 위치, 단일)에 대한 모든 작업 이 앱이 아닌 SQL로 수행되어야한다는 것을 의미 하므로 많은 비즈니스 로직이 데이터베이스에 저장됩니다.
Jimmy Hoffa

4
설명하는 것은 클라이언트 코드가 아닙니다. 자체 조작 로직을 가질 수있는 비즈니스 계층입니다. 그러나 1M + 레코드에서이 논리를 수행하면 문제가 발생합니다.
EL Yusubov

@JimmyHoffa : 사실이 아닙니다. 때로는 앱 메모리에 이미있는 데이터로 처리해야하는 일시적인 정보를 생성하기도합니다. Linq는 그것에 대해 놀라운 일을합니다.
Fabricio Araujo

@FabricioAraujo 내가 LINQ가 좋은 이유를 알고 있어요,하지만이 대답은 상태가 절대로 당신이 경우 집합 기반 작업이 응용 프로그램 코드에서, 할 절대로 응용 프로그램 코드에서 설정 작업을하지 않았다 즉 LINQ의 전체 목적이기 때문에 당신이 LINQ를 사용하지 않을 것입니다. 나는 지점 만들고있어 절대로 응용 프로그램 코드에서 설정 작업을 수행하지 것은 다음과 나쁜 규칙입니다
지미 호파

@JimmyHoffa : 아니요, 규칙은 "RDBMS가 당신을 위해 할 수있는 일을 절대 앱에서하지 마십시오"라고 말합니다. 그리고 나는 정보가 데이터베이스에 유지되지 않는 일시적인 정보 에 대해 이야기 하고 있습니다. 비즈니스 규칙을 완전히 채우려면 코드 처리가 필요한 시스템에서 작업했습니다. DB에서 과도한 처리를 한 후 해당 데이터에 대해 추가 처리를 수행하여 (매우 중요한) 보고서를 생성 한 비즈니스 규칙을 기억합니다. 나는 linq를 사용할 수 있습니다 (지금은 없어진 Delphi.Net에서 수행되었습니다). 즉, linq는 해당 규칙을 따르는 경우에도 사용할 수 있습니다.
Fabricio Araujo

13

일반적으로 DB에는 애플리케이션보다 많은 정보가 있으며 일반적인 데이터 작업을보다 효율적으로 수행 할 수 있습니다. 예를 들어, 데이터베이스는 색인을 유지 관리하는 반면 응용 프로그램은 검색 결과를 즉시 색인화해야합니다. 따라서 다른 모든 것이 동일하면 응용 프로그램이 아닌 데이터베이스로 작업을 푸시하여 전체 작업 부하를 줄일 수 있습니다.

그러나 제품이 확장되면 일반적으로 DB를 확장하는 것보다 앱을 확장하는 것이 더 쉬워집니다. 대규모 설치에서는 응용 프로그램 서버가 데이터베이스 서버보다 10 대 1 이상 많은 경우가 드물지 않습니다. 더 많은 응용 프로그램 서버를 추가하는 것은 기존 서버를 새로운 하드웨어에 복제하는 간단한 문제입니다. 반면에 새 데이터베이스 서버를 추가하는 것은 대부분의 경우에 훨씬 더 어렵습니다.

따라서이 시점에서 진언은 데이터베이스를 보호하게됩니다 . 데이터베이스 결과를 캐싱 memcached하거나 응용 프로그램 측 로그의 업데이트를 큐 에 넣거나 데이터를 한 번 가져오고 앱에서 통계를 계산하면 데이터베이스 워크로드를 획기적으로 줄일 수 있습니다. 훨씬 더 복잡하고 취약한 DB 클러스터 구성.


1
돈은 하드웨어 확장 성 문제를 해결할 수 있지만 돈은 소프트웨어 복잡성을 해결할 수 없습니다.
Tulains Córdova

3
@ user1598390 실제로 : 하드웨어는 저렴하고 프로그래머는 비싸다 . 돈 소프트웨어 복잡성을 해결할 수 있습니다 . 프로그래머에게 보낸 돈. 그러나 우리는 깨끗한 코드와 speghetti에 대해 이야기하지 않습니다. 앱 측과 DB 측에서 작업을 수행하는 것에 대해 이야기하고 있습니다. 두 옵션 모두 우수한 설계 원칙을 따를 수 있기 때문에 소프트웨어 복잡성은 거의 관련이 없습니다. 더 좋은 질문은 " 어느 디자인이 더 비쌉니까? "입니다.
tylerl

코드 기반이 엉뚱하고 지방이 많고 대부분 비즈니스 이외의 일을하는 경우 하드웨어보다 비용이 많이 들고 불확실성이 너무 많은 모든 리엔지니어링의 어머니뿐입니다. 좋은 하드웨어를 어디에서 찾을 수 있는지 항상 알 수 있지만 좋은 프로그래머는 다른 이야기입니다. 반면 경쟁 업체는 시간을 사용하여 개선하고 변화에 적응하며 고객을 행복하게 만듭니다.
Tulains Córdova

1
답변에서 스케일링을 언급 한 유일한 사람이 +1되었습니다.
Matt

하드웨어는 더 이상 저렴하지 않았습니다. 데이터 센터에서 전기 및 하드웨어는 운영 비용의 88 % (Microsoft가 인용 한)에 달하므로 효율적인 코드를 작성하기 위해 프로그래머에게 더 많은 비용을 지출하는 것은 매우 비용 효율적이며 무제한이 될 때까지 계속됩니다. 저렴한 퓨전 파워.
gbjbaanb

12

데이터베이스를 원래 용도로 사용하지 않는 것이 좋지 않은 디자인이라고 생각합니다. 좋은 데이터를 가진 데이터베이스 외부에서 규칙이 적용되는 데이터베이스는 본 적이 없습니다. 그리고 수백 개의 데이터베이스를 살펴 보았습니다.

따라서 데이터베이스에서 수행해야 할 사항 :

  • 감사 (애플리케이션 전용 감사는 데이터베이스의 모든 변경 사항을 추적하지 않으므로 무가치합니다).

  • 모든 데이터에 항상 적용해야하는 기본값, 외래 키 제약 조건 및 규칙을 포함하여 데이터 비구 속성 제약 조건 모든 데이터가 항상 응용 프로그램을 통해 변경되거나 삽입되는 것은 아닙니다. 특히 한 번에 하나의 레코드를 수행하는 데 실용적이지 않은 대규모 데이터 세트의 일회성 데이터 수정이 있습니다 (수행해야 할 때 상태 1로 잘못 표시된 10 만 개의 레코드를 업데이트하십시오) 응용 프로그램 코드 버그로 인해 2이거나 회사 B가 회사 A를 구입했기 때문에 클라이언트 A에서 클라이언트 B로 모든 레코드를 업데이트하십시오.

  • JOINS 및 where 절 필터링 (네트워크를 통해 전송되는 레코드 수를 줄이기 위해)


6

"조기 최적화는 컴퓨터 프로그래밍에서 모든 악의 근원 (대부분은 어쨌든)"- Donald Knuth

데이터베이스는 바로 그 것입니다. 응용 프로그램의 데이터 계층 그 임무는 응용 프로그램에 요청 된 데이터를 제공하고 제공된 데이터를 저장하는 것입니다. 응용 프로그램은 실제로 데이터와 작동하는 코드를 넣을 수있는 곳입니다. 표시, 확인 등

제목 줄에 감정이 점에 감탄하고, 정확하지만 (필터링의 핵심적 껄끄 러운, 투사 등 그룹화 한다 ,에있을 수 있습니다 "잘"의 정의를 케이스의 압도적 인 다수하면 DB에 남아있을) 주문. SQL Server가 높은 수준의 성능으로 실행할 수있는 작업은 많지만 시연 할 수있는 작업SQL Server가 격리되고 반복 가능한 방식으로 올바르게 작동한다는 것은 매우 적습니다. SQL Management Studio는 훌륭한 데이터베이스 IDE입니다 (특히 TOAD와 같이 다른 옵션을 사용했을 때).하지만 그중에는 제한이 있습니다. 먼저 사용하는 모든 작업 (또는 실행중인 모든 절차 코드) 아래의 DB)는 정의에 따라 "부작용"(프로세스 메모리 공간의 도메인 외부에있는 상태 변경)입니다. 또한 최신 IDE 및 도구를 사용하여 SQL Server의 절차 코드는 지금 막 관리 범위 코드 및 경로 분석을 사용하여 관리 코드가 측정 할 수있는 방식을 측정 할 수 있습니다. , Y 및 Z 및 테스트 X는 조건을 true로 만들고 절반을 실행하도록 설계되었으며 Y 및 Z는 "else"를 실행합니다. . 즉, 특정 시작 상태로 데이터베이스를 설정하고, 조치를 통해 데이터베이스 절차 코드를 실행하고, 예상되는 결과를 주장 할 수있는 테스트가 있다고 가정합니다.

이 모든 것은 대부분의 데이터 액세스 계층에서 제공하는 솔루션보다 훨씬 어렵고 복잡합니다. 데이터 계층 (그리고 그 문제에 대해 DAL)은 올바른 입력이 주어지면 작업을 수행하는 방법을 알고 코드가 올바른 입력을 제공하는지 테스트합니다. SP 및 트리거와 같은 절차 적 코드를 DB 외부로 유지하고 대신 애플리케이션 코드에서 이러한 유형의 작업을 수행함으로써 애플리케이션 코드가 훨씬 더 쉽게 실행됩니다.


잠깐만, 뭐? 정확성 증명에서 테스트까지 어떻게 얻었습니까? 버그가 있음을 증명할 수는 있지만 코드가 정확하다는 것을 결코 증명할 수는 없습니까?
메이슨 휠러

2
저장 프로시 저는 절차 코드가 아닙니다. SP는 DB 내부에 저장되고 실행되는 미리 계산 된 SQL 쿼리입니다. 응용 프로그램 코드가 아닙니다.
gbjbaanb

1
SP가 SQL 쿼리로 제한되어 있다면 맞습니다. 조건부 브레이크, 루프, 커서 및 / 또는 기타 비 조회 논리를 포함하여 T-SQL 또는 PL / SQL 인 경우 잘못되었습니다. 그리고 사이버 공간 전체에있는 DB의 많은 SP, 기능 및 트리거에는 이러한 추가 요소가 있습니다.
KeithS

5

사람들이 깨닫지 못하는 것 중 하나는 SQL 서버에서 모든 처리를 수행하는 것이 코드 품질에 미치는 영향에 관계없이 반드시 좋은 것은 아니라는 것입니다.

예를 들어, 일부 데이터를 가져온 다음 데이터에서 무언가를 계산 한 다음 해당 데이터를 데이터베이스에 저장해야합니다. 두 가지 선택이 있습니다 :

  • 데이터를 응용 프로그램으로 가져와 응용 프로그램 내에서 계산 한 다음 데이터를 데이터베이스로 다시 보냅니다.
  • 저장 프로 시저 또는 이와 유사한 것을 만들어 데이터를 가져 와서 계산 한 다음 단일 호출에서 SQL Server로 모두 저장합니다.

두 번째 솔루션이 항상 가장 빠르다고 생각할 수도 있지만 이는 사실이 아닙니다. SQL이 문제 (예 : 정규식 및 문자열 조작)에 적합하지 않더라도 무시하고 있습니다. 데이터베이스에 강력한 언어가있는 SQL CLR 또는 이와 유사한 것으로 가정 해 봅시다. 왕복하는 데 1 초가 걸리고 데이터를 가져 오는 데 1 초가 걸리고 저장하는 데 1 초가 걸린 다음 10 초 동안 계산을 수행합니다. 데이터베이스에서 모든 작업을 수행하면 잘못되고 있습니다.

물론, 당신은 2 초 면도. 그러나 10 초 동안 데이터베이스 서버에서 하나 이상의 CPU 코어를 100 % 낭비 했습니까? 아니면 웹 서버에서 그 시간을 낭비 했습니까?

웹 서버는 확장이 쉬우 며 데이터베이스는 특히 SQL 데이터베이스와 같이 매우 비쌉니다. 대부분의 경우 웹 서버는 "상태 비 저장"상태이며로드 밸런서 외에는 추가 구성없이 추가 및 제거 할 수 있습니다.

따라서 작업에서 2 초를 면도하는 것뿐만 아니라 확장 성도 생각하십시오. 상대적으로 작은 성능 영향으로 훨씬 저렴한 웹 서버 리소스를 사용할 수있는 경우 데이터베이스 서버 리소스와 같은 비싼 리소스를 낭비하는 이유


1
네트워크 트립도 잊고 있습니다. 효율성에 영향을주지 않으면 서 서버를 추가하여 수평 적으로 확장 할 수는 없습니다. 따라서 where 절을 추가하여 데이터로드를 줄이는 것이 분명하지만 다른 SQL 작업으로 인해 반드시 성능이 저하되는 것은 아닙니다. 당신의 요점은 일반적으로 정확하지만 DB를 바보 데이터 저장소로 취급하는 요지는 아닙니다. 필자가 작업 한 가장 확장 성이 뛰어난 앱은 모든 데이터 호출에 대해 사용 된 저장 프로 시저 (복잡한 쿼리 2 개 제외)입니다. 세 번째 솔루션이 가장 좋습니다. "필요한 데이터 만 가져 오기위한 저장 프로 시저"입니다.
gbjbaanb

4

SQL 자체는 데이터 자체 만 다루어야한다고 생각합니다. 쿼리 모양을 결정하는 비즈니스 규칙은 코드에서 발생할 수 있습니다. 정보의 정규식 또는 검증은 코드로 수행해야합니다. 테이블을 조인하고 데이터를 쿼리하고 깨끗한 데이터를 삽입하는 등의 작업을 수행하려면 SQL을 그대로 두어야합니다.

SQL에 전달되는 것은 데이터가 깨끗해야하며 SQL은 실제로 저장, 업데이트, 삭제 또는 검색하는 데 필요한 것 이상을 알 필요가 없습니다. 너무 많은 개발자가 데이터를 비즈니스로 생각하기 때문에 비즈니스 로직과 코딩을 SQL로 던지기를 원하는 방식을 보았습니다. 데이터에서 논리를 분리하면 코드가 더 깨끗하고 관리하기 쉬워집니다.

그래도 내 $ 0.02.


데이터베이스에 이미있는 데이터에 대해 정규식 또는 유효성 검사를 실행하는 이유는 무엇입니까? 제약 조건은 잘못된 데이터가 도착하는 것을 방지해야하며 정규 표현식을 사용하면 더 유용한 열이 필요할 수 있습니다.
Brendan Long

데이터베이스에서 오는 데이터에 정규식이나 유효성 검사를 사용한다고 말하지 않았습니다. 나는 그것이 데이터베이스로가는 데이터를 명확히해야한다고 생각합니다. 필자는 DAL에 도달하기 전에 데이터를 정리하고 유효성을 검사해야한다고 지적했다.
Stanley Glass Jr

3

일반적으로 코드는 비즈니스 로직을 제어하고 DB는 로직 프리 해시 여야한다는 데 동의합니다. 그러나 여기 몇 가지 반점이 있습니다.

기본, 외래 키 및 필수 (널 (null) 아님) 제약 조건은 코드에 의해 시행 될 수 있습니다. 제약은 비즈니스 로직입니다. 코드가 수행 할 수있는 작업을 복제하므로 데이터베이스에서 제외해야합니까?

통제권이없는 다른 사람이 데이터베이스를 만지나요? 그렇다면 데이터에 가까운 제약 조건을 적용하는 것이 좋습니다. 액세스는 논리를 구현하는 웹 서비스로 제한 될 수 있지만 이는 "먼저"있다고 가정하고 상대방의 서비스 사용을 강제 할 권한이 있다고 가정합니다.

ORM은 각 개체에 대해 별도의 삽입 / 업데이트를 수행합니까? 그렇다면 큰 데이터 세트를 일괄 처리 할 때 심각한 성능 문제가 발생합니다. 작업을 설정하는 방법입니다. ORM은 작업을 수행 할 수있는 가능한 모든 조인 세트를 정확하게 모델링하는 데 문제가 있습니다.

"계층"이 서버에 의한 물리적 분할 또는 논리적 분할이라고 생각하십니까? 이론적으로 모든 서버에서 논리를 실행하면 논리 계층에 속할 수 있습니다. 서버를 단독으로 분할하지 않고 다른 DLL로 컴파일하여 분할을 구성 할 수 있습니다. 이것은 우려의 분리를 유지하면서 응답 시간을 급격히 증가시킬 수 있습니다. 처리 시간을 늘리기 위해 (응답 시간이 소요됨) 새로운 빌드없이 분할 DLL을 나중에 다른 서버로 옮길 수 있습니다.


왜 downvote?
mike30

5
나는 공감하지는 않았지만 모든 데이터베이스 sepcialist는 데이터베이스를 고려할 때 로직 프리 해시가 매우 나쁜 아이디어라고 말할 것입니다. 데이터 무결성 문제 나 성능 문제 또는 둘 다를 유발합니다.
HLGEM

1
@HLGEM. 대답 은 데이터베이스 에서 논리를 유지 하거나 DB 서버에 앉아 있는 이유를 설명 합니다. 여전히 설명하지 않습니다.
mike30

내가했던 것처럼 그들은 반대 지점에 도착하지 않았을 수 있습니다.
HLGEM

3

관용구는 비즈니스 규칙을 유지하고 관계 (데이터 및 구조 및 관계)와 함께 데이터와 관련이 있습니다. 모든 문제에 대한 원 스톱 상점은 아니지만 수작업과 같은 것을 피하는 데 도움이됩니다. 데이터베이스 레벨에서 사용 가능한 경우 레코드 카운터 유지 보수, 수동으로 관계 무결성 유지 보수 등. 따라서 다른 사람이 와서 프로그램을 확장하거나 데이터베이스와 상호 작용하는 다른 프로그램을 작성하는 경우 이전 코드에서 데이터베이스 무결성을 유지하는 방법을 알 필요가 없습니다. 수동으로 유지 관리되는 레코드 카운터의 경우 다른 사람이 동일한 데이터베이스와 상호 작용하기 위해 새 프로그램을 작성하려고 할 때 특히 적합합니다. 새로 만든 프로그램에 카운터에 대한 올바른 코드가있는 경우에도 원래 프로그램과 거의 동시에 실행되는 새 프로그램이 손상 될 수 있습니다. 가능한 경우 insert 또는 update 문에서 종종 달성 할 수있는 새 코드 나 업데이트 된 레코드를 작성하기 전에 (코드 또는 별도의 쿼리로) 레코드를 검색하고 조건을 확인하는 코드도 있습니다. 데이터 손상이 다시 발생할 수 있습니다. 데이터베이스 엔진은 원 자성을 보장합니다. 조건이있는 업데이트 또는 삽입 쿼리는 조건을 충족하는 레코드에만 영향을 미치며 외부 쿼리는 업데이트를 통해 데이터를 절반 만 변경할 수 없습니다. 데이터베이스 엔진이 더 잘 작동 할 때 코드가 사용되는 다른 많은 환경이 있습니다. 성능에 관한 것이 아니라 데이터 무결성에 관한 것입니다. 심지어 가능하다면 insert 또는 update 문에서 종종 달성 될 수있는 새로운 코드 또는 업데이트 된 레코드를 작성하기 전에 (코드 또는 별도의 쿼리로) 레코드를 검색하고 조건을 확인하는 코드도 있습니다. 데이터 손상이 다시 발생할 수 있습니다. 데이터베이스 엔진은 원 자성을 보장합니다. 조건이있는 업데이트 또는 삽입 쿼리는 조건을 충족하는 레코드에만 영향을 미치며 외부 쿼리는 업데이트를 통해 데이터를 절반 만 변경할 수 없습니다. 데이터베이스 엔진이 더 잘 작동 할 때 코드가 사용되는 다른 많은 환경이 있습니다. 성능에 관한 것이 아니라 데이터 무결성에 관한 것입니다. 심지어 가능하다면 insert 또는 update 문에서 종종 달성 될 수있는 새로운 코드 또는 업데이트 된 레코드를 작성하기 전에 (코드 또는 별도의 쿼리로) 레코드를 검색하고 조건을 확인하는 코드도 있습니다. 데이터 손상이 다시 발생할 수 있습니다. 데이터베이스 엔진은 원 자성을 보장합니다. 조건이있는 업데이트 또는 삽입 쿼리는 조건을 충족하는 레코드에만 영향을 미치며 외부 쿼리는 업데이트를 통해 데이터를 절반 만 변경할 수 없습니다. 데이터베이스 엔진이 더 잘 작동 할 때 코드가 사용되는 다른 많은 환경이 있습니다. 성능에 관한 것이 아니라 데이터 무결성에 관한 것입니다. 데이터베이스 엔진은 원 자성을 보장합니다. 조건이있는 업데이트 또는 삽입 쿼리는 조건을 충족하는 레코드에만 영향을 미치며 외부 쿼리는 업데이트를 통해 데이터를 절반 만 변경할 수 없습니다. 데이터베이스 엔진이 더 잘 작동 할 때 코드가 사용되는 다른 많은 환경이 있습니다. 성능에 관한 것이 아니라 데이터 무결성에 관한 것입니다. 데이터베이스 엔진은 원 자성을 보장합니다. 조건이있는 업데이트 또는 삽입 쿼리는 조건을 충족하는 레코드에만 영향을 미치며 외부 쿼리는 업데이트를 통해 데이터를 절반 만 변경할 수 없습니다. 데이터베이스 엔진이 더 잘 작동 할 때 코드가 사용되는 다른 많은 환경이 있습니다. 성능에 관한 것이 아니라 데이터 무결성에 관한 것입니다.

따라서 실제로 좋은 디자인 관용구 나 경험 법칙입니다. 손상된 데이터가있는 시스템에서는 어느 정도의 성능도 도움이되지 않습니다.


0

앞에서 언급했듯이 왕복 여행은 시간이 많이 걸리므로 데이터베이스에서 가능한 한 적게 보내고받는 것이 목표입니다. SQL 통계를 계속해서 다시 보내는 것은 특히 복잡한 쿼리에서 시간 낭비입니다.

데이터베이스에서 저장 프로 시저를 사용하면 개발자가 복잡한 스키마에 대해 걱정할 필요없이 API와 같은 데이터베이스와 상호 작용할 수 있습니다. 또한 이름과 몇 가지 매개 변수 만 전송되므로 서버로 전송되는 데이터가 줄어 듭니다. 이 시나리오에서 대부분의 탈취 논리는 여전히 코드 형태이지만 SQL 형식은 아닙니다. 이 코드는 본질적으로 데이터베이스에서 보내거나 요청되는 것을 준비합니다.


0

기억해야 할 것이 몇 가지 있습니다.

  • 관계형 데이터베이스는 외래 키를 통한 참조 무결성을 보장해야합니다.
  • 하나의 데이터베이스를 확장하는 것은 어렵고 비용이 많이들 수 있습니다. 더 많은 웹 서버를 추가하여 웹 서버를 확장하는 것이 훨씬 쉽습니다. 더 많은 SQL 서버 성능을 추가하려고 노력하십시오.
  • C #과 LINQ를 사용하면 코드를 통해 "조인"을 수행 할 수 있으므로 많은 경우에 두 가지 이점을 최대한 활용할 수 있습니다

0

"조기 최적화는 모든 악의 근원"-Donald Knuth

작업에 가장 적합한 도구를 사용하십시오. 데이터 무결성을 위해 이것은 종종 데이터베이스입니다. 고급 비즈니스 규칙의 경우 JBoss Drools와 같은 규칙 기반 시스템입니다. 데이터 시각화의 경우 이는보고 프레임 워크입니다. 기타

성능 문제가있는 경우 나중에 데이터를 캐시 할 수 있는지 또는 데이터베이스에서 구현이 더 빠른지 확인해야합니다. 일반적으로 추가 서버 구매 또는 추가 클라우드 비용은 추가 유지 관리 비용 및 추가 버그의 영향보다 훨씬 저렴합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.