문제

어떤 이유로든 LINQ를 사용할 수 없다고 가정하면 쿼리를 저장 프로시저에 배치하는 것이 더 나은 방법입니까, 아니면 쿼리를 실행하는 것도 좋은 방법입니까? 애드 혹 데이터베이스에 대한 쿼리(예: 인수를 위한 SQL Server)?

도움이 되었습니까?

해결책

주로 WinForms 클라이언트/서버 앱을 작성해 본 경험을 통해 다음과 같은 간단한 결론을 얻었습니다.

저장 프로시저 사용:

  1. 복잡한 데이터 작업에 적합합니다.실제로 커서나 임시 테이블이 필요한 작업을 수행하려면 일반적으로 SQL Server 내에서 수행하는 것이 가장 빠릅니다.
  2. 데이터에 대한 액세스를 잠가야 하는 경우.사용자(또는 역할 등)에게 테이블 액세스 권한을 부여하지 않으면 생성한 SP를 통해서만 데이터와 상호 작용할 수 있습니다.

임시 쿼리를 사용합니다.

  1. 데이터 액세스를 제한할 필요가 없는 경우(또는 다른 방식으로 제한하는 경우) CRUD의 경우.
  2. 단순 검색용입니다.다양한 검색 기준에 대해 SP를 생성하는 것은 번거롭고 유지 관리가 어렵습니다.합리적으로 빠른 검색어를 생성할 수 있다면 이를 사용하세요.

대부분의 응용 프로그램에서 SP와 임시 SQL을 모두 사용했지만 SP는 결국 C#과 같은 코드가 되고 버전 제어, 테스트 및 유지 관리가 더 어려워지기 때문에 SP를 점점 더 적게 사용하고 있습니다.특별한 이유가 없는 한 임시 SQL을 사용하는 것이 좋습니다.

다른 팁

SQL Server 이외의 다른 것에 대해서는 말할 수 없지만 성능 논쟁은 ~ 아니다 6.5 이하 버전을 사용하지 않는 한 상당히 유효합니다.SQL Server는 현재 약 10년 동안 임시 실행 계획을 캐싱해 왔습니다.

저장 프로시저는 데이터베이스에 대해 수행되는 작업을 캡슐화하는 소프트웨어 계약을 나타냅니다.프로시저의 코드와 심지어 데이터베이스 자체의 스키마도 컴파일되고 배포된 코드에 영향을 주지 않고 변경될 수 있으므로 프로시저의 입력과 출력은 동일하게 유지됩니다.

애플리케이션에 쿼리를 포함하면 데이터 모델과 긴밀하게 연결됩니다.

같은 이유로 데이터베이스의 모든 테이블에 대해 단순히 CRUD 쿼리인 저장 프로시저를 만드는 것도 여전히 긴밀한 결합이므로 좋은 습관이 아닙니다.대신 절차는 부피가 크고 조잡한 작업이어야 합니다.

보안 관점에서 보면 애플리케이션에서 db_datareader 및 db_datawriter를 허용하지 않고 저장 프로시저에 대한 액세스만 허용하는 것이 좋습니다.

이는 데이터베이스를 유지해야 하는 사람과 사용자 인터페이스를 개발하는 사람 사이의 근본적인 갈등이라고 생각합니다.

데이터 전문가로서 저는 임시 쿼리를 통해 액세스되는 데이터베이스 작업을 고려하지 않을 것입니다. 왜냐하면 데이터베이스는 효과적으로 조정하거나 관리하기 어렵기 때문입니다.스키마 변경이 어떤 영향을 미치는지 어떻게 알 수 있나요?또한 보안상의 이유로 사용자에게 데이터베이스 테이블에 대한 직접 액세스 권한을 부여해서는 안 된다고 생각합니다. 이는 단순히 SQL 주입 공격을 의미하는 것이 아니라 직접적인 권한을 허용하지 않고 모든 사용자에게 다음을 요구하는 기본적인 내부 제어이기 때문입니다. 앱용으로 설계된 프로세스만 사용하세요.이는 사기 가능성을 방지하기 위한 것입니다.테이블에 대한 직접 삽입, 업데이트 또는 삭제 권한을 허용하는 금융 시스템은 사기 위험이 큽니다.이것은 나쁜 일입니다.).

데이터베이스는 객체 지향적이지 않으며 객체 지향 관점에서 좋아 보이는 코드가 데이터베이스 관점에서는 매우 나쁠 수 있습니다.

우리 개발자들은 모든 데이터베이스 액세스가 프로세스를 통해 이루어진다는 사실이 기쁘다고 말합니다. 왜냐하면 데이터 중심 버그를 수정한 다음 새로운 코드 분기를 생성하고 다시 컴파일하는 대신 프로덕션 환경에서 프로세스를 실행하는 것이 훨씬 더 빠르기 때문입니다. 프로덕션으로 다시 로드합니다.우리는 모든 프로세스가 전복 상태에 있어야 하므로 소스 제어는 전혀 문제가 되지 않습니다.Subversion에 없으면 dbas에 의해 주기적으로 삭제되므로 소스 제어 사용에 대한 저항이 없습니다.

저장 프로시저가 확실히 좋은 방법입니다. 컴파일되고 실행 계획이 사전에 있으며 이에 대한 권한 관리를 수행할 수 있습니다.

저장 프로시저에 대한 전체 소스 제어 문제를 이해하지 못합니다.약간만 훈련을 받는다면 확실히 소스를 제어할 수 있습니다.

항상 저장 프로시저의 원본인 .sql 파일로 시작하세요.코드를 작성한 후에는 이를 버전 관리에 넣으세요.다음에 저장 프로시저를 편집하려면 데이터베이스가 아닌 소스 제어에서 가져오십시오.이를 따르면 코드만큼 좋은 소스 제어를 갖게 됩니다.

Oracle의 Tom Kyte의 말을 인용하고 싶습니다. 코드 작성 위치에 대한 그의 규칙은 다음과 같습니다. 약간 관련은 없지만 알아두면 좋을 것 같습니다.

  1. PL/SQL의 저장 프로시저로 시작...
  2. PL/SQL의 저장 프로시저를 사용하여 수행할 수 없는 작업이 있다고 생각되면 Java 저장 프로시저를 사용하세요.
  3. Java 저장 프로시저를 사용하여 무언가를 수행할 수 없다고 생각되면 Pro*c를 고려하십시오.
  4. Pro*C를 사용하여 무언가를 달성할 수 없다고 생각한다면, 수행해야 할 작업을 다시 생각해 볼 수 있습니다.

우리 애플리케이션에는 쿼리 내용을 제공하는(때로는 저장 프로시저에 대한 호출이기도 함) 코드 계층이 있습니다.이를 통해 우리는 다음을 수행할 수 있습니다.

  • 버전 관리 하에 모든 쿼리를 쉽게 보유
  • 다양한 데이터베이스 서버에 대한 각 쿼리에 필요한 변경 사항을 적용하려면
  • 코드 전체에서 동일한 쿼리 코드의 반복을 제거합니다.

액세스 제어는 데이터베이스가 아닌 중간 계층에서 구현되므로 거기에는 저장 프로시저가 필요하지 않습니다.이는 어떤 면에서는 임시 쿼리와 저장된 프로세스 사이의 중간 지점입니다.

내 대답 다른 것에서 우편:저장 프로시저는 다음과 같은 이유로 유지 관리가 가능합니다.

  • 일부 SQL을 변경하려고 할 때마다 C# 앱을 다시 컴파일할 필요가 없습니다.
  • 결국 SQL 코드를 재사용하게 됩니다.

코드 반복은 최악의 유지 관리 가능한 애플리케이션을 구축하려고 할 때 할 수 있는 일입니다!

여러 곳에서 수정해야 할 논리 오류를 발견하면 어떻게 되나요?코드를 복사하여 붙여넣은 마지막 지점을 변경하는 것을 잊어버리기 쉽습니다.

제 생각에는 성능 및 보안상의 이점이 추가로 제공됩니다. 여전히 안전하지 않거나 비효율적인 SQL 저장 프로시저를 작성할 수 있습니다.

다른 DB로 포팅하기가 더 쉬움 - 포팅을 위한 절차가 없음

다른 DB에서 생성하기 위해 모든 저장 프로시저를 스크립트로 작성하는 것은 그리 어렵지 않습니다.사실 - 그렇죠 더 쉽게 걱정할 기본/외부 키가 없기 때문에 테이블을 내보내는 것보다.

두 가지 모두에 대한 설득력 있는 주장이 있습니다. 저장 프로시저는 모두 중앙 저장소에 있지만 (잠재적으로) 마이그레이션하기 어렵고 임시 쿼리는 코드와 마찬가지로 디버깅하기가 더 쉽지만 암호.

저장 프로시저가 더 효율적이라는 주장은 더 이상 설득력이 없습니다.링크 텍스트

저장 프로시저와 동적 쿼리에 대해 Google을 수행하면 어느 쪽이든 적절한 주장이 표시되며 아마도 스스로 결정을 내리는 것이 가장 좋을 것입니다.

SQL을 코드에 작성하는 것이 이미 미래에 골치 아픈 일이 될 수 있는 상황이라면 저장 프로시저를 최대한 많이 사용해야 합니다.SPROC를 작성하는 데는 코드로 작성하는 데 걸리는 시간과 거의 같은 시간이 걸립니다.

중간 부하에서는 훌륭하게 실행되는 쿼리가 풀타임 프로덕션에 들어가면 잘못 최적화된 쿼리가 시스템을 망치고 크롤링하게 만드는 경우를 생각해 보세요.대부분의 SQL 서버에서 이를 사용하는 유일한 애플리케이션/서비스는 아닙니다.귀하의 지원서는 이제 많은 화난 사람들을 귀하의 집으로 데려왔습니다.

SPROC에 쿼리가 있는 경우 친절한 DBA가 앱을 다시 컴파일하거나 중단하지 않고도 관리하고 최적화할 수 있습니다.DBA는 이 분야의 전문가이므로 해야 할 일과 하지 말아야 할 일을 알고 있습니다.그들의 더 큰 지식을 활용하는 것이 합리적입니다!

편집하다:누군가 재컴파일은 게으른 변명이라고 말하더군요!네, 앱을 다시 컴파일하고 수천 대의 데스크톱에 배포해야 할 때 얼마나 게으른지 살펴보겠습니다. 이는 모두 DBA가 임시 쿼리가 서버 시간을 너무 많이 잡아먹고 있다고 말했기 때문입니다!

누군가 재컴파일은 게으른 변명이라고 말하더군요!네, 앱을 다시 컴파일하고 수천 대의 데스크톱에 배포해야 할 때 얼마나 게으른지 살펴보겠습니다. 이는 모두 DBA가 임시 쿼리가 서버 시간을 너무 많이 잡아먹고 있다고 말했기 때문입니다!

1000개의 데스크탑을 데이터베이스에 직접 연결하게 한다면 좋은 시스템 아키텍처인가요?

여기서 생각해 볼 몇 가지 사항은 다음과 같습니다. 어쨌든 저장 프로시저가 필요한 사람은 누구일까요?

분명히 그것은 자신의 필요와 선호도의 문제이지만 공개 환경에서 임시 쿼리를 사용할 때 고려해야 할 매우 중요한 사항 중 하나는 보안입니다.항상 매개변수화하고 다음과 같은 일반적인 취약점을 주의하세요. SQL 주입 공격.

저장 프로시저는 재컴파일 없이 변경할 수 있다는 점에서 훌륭합니다.나는 가능한 한 자주 사용하려고 노력할 것입니다.

나는 사용자 입력을 기반으로 동적으로 생성되는 쿼리에만 임시를 사용합니다.

다른 사람들이 언급한 이유로 인해 프로시저가 발생하며 프로파일러나 프로시저의 일부를 사용하여 프로시저를 조정하는 것이 더 쉽습니다.이렇게 하면 SQL 서버로 전송되는 내용을 확인하기 위해 누군가에게 자신의 앱을 실행하라고 지시할 필요가 없습니다.

임시 쿼리를 사용하는 경우 해당 쿼리가 매개변수화되어 있는지 확인하세요.

매개변수화된 SQL 또는 SPROC...성능 측면에서는 중요하지 않습니다. 둘 중 하나를 쿼리 최적화할 수 있습니다.

나에게 SPROC의 마지막 남은 이점은 sprocs를 실행할 수 있는 로그인 권한만 부여하여 많은 SQL 권한 관리를 제거할 수 있다는 것입니다... 매개변수화된 SQL을 사용하는 경우 연결 문자열이 포함된 로그인에는 더 많은 권한이 있습니다(ANY 작성). 예를 들어 액세스 권한이 있는 테이블 중 하나에 대한 일종의 select 문입니다.

그래도 나는 여전히 매개변수화된 SQL을 선호합니다.

임시 쿼리 사용에 대한 설득력 있는 주장을 찾지 못했습니다.특히 C#/Java/PHP 코드와 혼동되는 경우가 많습니다.

sproc 성능 주장은 논쟁의 여지가 있습니다. 상위 3개 RDBM은 쿼리 계획 캐싱을 사용하며 한동안 사용되어 왔습니다.문서화되었습니다 ...아니면 1995년이 아직인가요?

그러나 앱에 SQL을 포함시키는 것도 끔찍한 디자인입니다. 코드 유지 관리는 많은 사람들에게 누락된 개념인 것 같습니다.

ORM을 사용하여 애플리케이션을 처음부터 시작할 수 있는 경우(그린필드 애플리케이션은 거의 없습니다!) 클래스 모델이 DB 모델을 구동하고 많은 시간을 절약하므로 탁월한 선택입니다.

ORM 프레임워크를 사용할 수 없는 경우 SQL 리소스 XML 파일을 생성하여 필요할 때 SQL 문자열을 조회하는 하이브리드 접근 방식을 취했습니다(그런 다음 리소스 프레임워크에 의해 캐시됩니다).SQL에 사소한 조작이 필요한 경우 코드에서 수행됩니다. 주요 SQL 문자열 조작이 필요한 경우 접근 방식을 다시 생각합니다.

이 하이브리드 접근 방식은 개발자가 쉽게 관리할 수 있도록 하며(우리 팀은 쿼리 계획을 읽을 만큼 똑똑하기 때문에 소수일 수도 있음) 배포는 SVN에서 간단하게 체크아웃할 수 있습니다.또한 RDBM 전환이 더 쉬워집니다. SQL 리소스 파일만 교체하면 됩니다(물론 ORM 도구만큼 쉽지는 않지만 레거시 시스템이나 지원되지 않는 데이터베이스에 연결하면 작동합니다).

당신의 목표가 무엇인지에 따라 다릅니다.예를 들어, 항목 목록을 검색하려고 하는데 애플리케이션이 전체 실행되는 동안 한 번만 발생한다면 저장 프로시저를 사용하는 노력은 아마도 가치가 없을 것입니다.반면, 반복적으로 실행되고 실행하는 데 (상대적으로) 오랜 시간이 걸리는 쿼리는 성능이 향상되므로 데이터베이스 저장에 탁월한 후보입니다.

애플리케이션이 거의 전적으로 데이터베이스 내에 있는 경우 저장 프로시저를 사용하는 것은 당연한 일입니다.데이터베이스가 부분적으로만 중요한 데스크톱 애플리케이션을 작성하는 경우 임시 쿼리가 더 나은 옵션일 수 있습니다. 모든 코드를 한 곳에 보관.

@테라핀:수정하기 위해 앱을 다시 컴파일할 필요가 없다는 사실이 저장 프로시저를 더 나은 옵션으로 만든다는 귀하의 주장은 시작에 불과하다고 생각합니다.임시 쿼리 대신 저장 프로시저를 선택해야 하는 이유가 있을 수 있지만 다른 설득력 있는 항목이 없으면 컴파일 문제는 실제 이유라기보다는 게으른 것처럼 보입니다.

내 경험에 따르면 쿼리 및/또는 저장 프로시저의 90%는 전혀 (적어도 직접) 작성해서는 안 됩니다.

데이터 액세스는 어떻게든 자동으로 생성되어야 합니다.컴파일 타임에 프로시저를 정적으로 생성할지 아니면 런타임에 동적으로 생성할지 결정할 수 있지만 테이블에 열(객체에 대한 속성)을 추가하려면 하나의 파일만 수정해야 합니다.

나는 모든 데이터를 유지하는 것을 선호합니다 입장 데이터 액세스 계층이 직접 SQL 쿼리를 실행하는 프로그램 코드의 논리.반면, 데이터 관리 트리거, 저장 프로시저, 사용자 정의 함수 등의 형태로 데이터베이스에 논리를 넣었습니다.제가 데이터베이스화할 가치가 있다고 생각하는 것의 예는 데이터 생성입니다. 고객이 FirstName과 LastName을 가지고 있다고 가정합니다.이제 사용자 인터페이스에는 몇 가지 중요하지 않은 논리에서 파생된 DisplayName이 필요합니다.이번 세대에서는 행(또는 다른 소스 데이터)이 업데이트될 때마다 트리거에 의해 실행되는 저장 프로시저를 만듭니다.

데이터 액세스 계층이 데이터베이스이고 데이터 및 데이터 액세스에 관한 모든 것이 "그냥" 거기에 들어간다는 다소 일반적인 오해가 있는 것 같습니다.이것은 단순히 잘못된 것이지만 이 아이디어에서 파생된 디자인이 많이 보입니다.아마도 이것은 지역적 현상일 것이다.

나는 잘못 설계된 SP를 너무 많이 본 후에 SP에 대한 아이디어를 꺼버릴 수도 있습니다.예를 들어, 제가 참여한 한 프로젝트에서는 모든 테이블과 가능한 모든 쿼리에 대해 일련의 CRUD 저장 프로시저를 사용했습니다.그렇게 함으로써 그들은 완전히 무의미한 또 다른 레이어를 추가했을 뿐입니다.그런 일들을 생각하는 것조차 고통스럽습니다.

요즘에는 저장 프로시저를 거의 사용하지 않습니다.코드에서는 쉽게 수행할 수 없는 복잡한 SQL 쿼리에만 사용합니다.

주된 이유 중 하나는 저장 프로시저가 OR 매퍼와 잘 작동하지 않기 때문입니다.

요즘에는 일종의 OR 매퍼를 사용하지 않는 비즈니스 애플리케이션/정보 시스템을 작성하려면 아주 좋은 이유가 필요하다고 생각합니다.

저장 프로시저는 코드 블록으로 작동하므로 임시 쿼리 대신 빠르게 작동합니다.또 다른 것은 저장 프로 시저가 저장된 절차에 저장된 절차를 사용하는 저장 절차 옵션을 제공하는 저장 절차입니다.

쿼리와 저장 프로시저의 일부 결과가 다르며 이는 내 개인 경험입니다.이를 확인하려면 캐스트 및 은닉 기능을 사용하십시오.

성능을 향상하려면 대규모 프로젝트에 저장 프로시저를 사용해야 합니다.

내 프로젝트에는 420개의 프로시저가 있었는데 제겐 잘 작동했습니다.나는 이 프로젝트를 위해 지난 3년 동안 일했습니다.

따라서 모든 거래에는 절차만 사용하십시오.

1000 데스크탑을 데이터베이스에 직접 연결하면 시스템 아키텍처가 좋습니다.

아니요, 분명히 그렇지 않습니다. 좋지 않은 예일 수도 있지만 제가 말하려는 요점은 분명하다고 생각합니다. DBA는 데이터베이스 인프라를 관리합니다. 이는 DBA의 전문 지식입니다. 코드에 SQL을 채우면 DBA와 그들의 전문 지식에 대한 문이 잠깁니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top