저장 프로 시저 대신 ORM 사용을 제안하는 방법은 무엇입니까?


31

모든 데이터 액세스에 저장 프로 시저 만 사용하는 회사에서 일하므로 로컬 데이터베이스를 동기화하여 새 프로세스를 실행해야 할 때마다 데이터베이스를 동기화하는 것이 매우 성가신 일입니다. 과거에는 몇 가지 기본 ORM을 사용해 왔으며 경험이 훨씬 좋고 깨끗합니다. 개발 관리자와 팀원들에게 향후 개발을 위해 어떤 종류의 ORM을 사용할 것을 제안하고 싶습니다. 팀의 나머지 팀은 저장 프로 시저에만 익숙하고 다른 것을 사용한 적이 없습니다. 현재 아키텍처는 .NET 1.1과 같이 작성된 .NET 3.5이며, 이상한 GodRecord 구현을 사용하고 코드 숨김 파일에서 반복되는 형식화되지 않은 DataSet을 반환하는 "신 클래스"와 함께 .NET 3.5입니다. 클래스는 다음과 같이 작동합니다.

class Foo { 
    public bool LoadFoo() { 
        bool blnResult = false;
        if (this.FooID == 0) { 
            throw new Exception("FooID must be set before calling this method.");
        }

        DataSet ds = // ... call to Sproc
        if (ds.Tables[0].Rows.Count > 0) { 
            foo.FooName = ds.Tables[0].Rows[0]["FooName"].ToString();
            // other properties set
            blnResult = true;
        }
        return blnResult;
    }
}

// Consumer
Foo foo = new Foo();
foo.FooID = 1234;
foo.LoadFoo();
// do stuff with foo...

디자인 패턴은 거의 적용되지 않습니다. 테스트는 전혀 없습니다 (아무도 단위 테스트를 작성하는 방법을 모르며 테스트는 웹 사이트를 수동으로로드하고 파킹하여 수행합니다). 데이터베이스를 살펴보면 199 개의 테이블, 13 개의 뷰, 926 개의 저장 프로 시저 및 93 개의 함수가 있습니다. 배치 작업 또는 외부 작업에 약 30여 개의 테이블이 사용되고 나머지는 핵심 응용 프로그램에 사용됩니다.

이 시나리오에서 다른 접근법을 추구 할 가치가 있습니까? "작동하는"이후 기존 코드를 리팩터링 할 수 없으므로 ORM을 사용하도록 기존 클래스를 변경할 수 없지만 새 모듈을 얼마나 자주 추가하는지는 잘 모르겠습니다. ORM이 올바른 접근 방식인지 (저장 프로 시저 및 데이터 세트에 너무 많이 투자했는지) 확실하지 않습니다. 그것이 올바른 선택이라면, 그것을 사용하는 경우를 어떻게 제시해야합니까? 내 머리 꼭대기에서 내가 생각할 수있는 유일한 이점은 코드가 깨끗하다는 것입니다 (현재 아키텍처가 ' ORM을 염두에두고 기본적으로 미래 모듈에 ORM을 배심원으로 배치 할 것이지만 오래된 모듈은 여전히 ​​DataSets를 사용하고 있습니다) 등등이지만 그게 전부이고, 나는 논쟁이 얼마나 설득력이 있는지 모르겠습니다. 유지 보수성은 또 다른 관심사이지만 나 외에는 아무도 염려하지 않는 것입니다.


8
단순히 팀에게 ORM을 사용하도록 설득하는 것보다 더 많은 문제가있는 것 같습니다. 귀하의 팀이 좋은 개발 관행 (예 : 디자인 패턴, 단위 테스트)을 인식하지 못하는 것 같습니다. 이것들은 더 중요한 문제입니다.
Bernard

6
아이러니하게도, 나는 약 5 년간의 개발에서 디자인 패턴이나 단위 테스트와 같은 것을 알고있는 소수의 사람들 / 팀을 만났다고 생각합니다. 보통 나는 회사에서 그 일들에 대해 아는 유일한 사람입니다.
Wayne Molina

3
@ Wayne M : 나는 약간 혼란 스럽지만 이것에 놀라지 않습니다.
Bernard

2
나는 그것을 매우 낙담했다는 것을 발견했다. 다른 사람이 당신이 무슨 말을하고 있는지 또는 왜 그렇게 생각하는지 모호한 아이디어를 나타내지 않았다는 것을 나타내는 무언가를 제안하고 "사슴에 헤드 라이트"모양을 보일 때 이상합니다. 나는 과거에 꽤나 여러 번 일어났다.
Wayne Molina

2
저는 Stored Procedure의 열렬한 팬이므로 의견이 편향되어 있지만 전제에 전적으로 동의하지 않습니다. ORM을 좋아하고 이것을 사용하고 싶습니다. 그러나 나머지 팀은 Stored procs로 괜찮습니다. 왜 당신이 좋아하는 것을 강요합니까?
Darknight

답변:


47

저장 프로시 저는 좋지 않습니다. 보통 일반 클라이언트 쪽 코드만큼 느리고 효율적입니다.

[속도 향상은 일반적으로 클라이언트와 저장 프로 시저 인터페이스가 설계되고 트랜잭션이 짧고 집중적 인 SQL 버스트로 작성되는 방식에 기인합니다.]

저장 프로시 저는 코드를 저장하기에 최악의 장소 중 하나입니다. 종종 임의의 규칙에 따라 응용 프로그램을 두 가지 언어와 플랫폼으로 나눕니다.

[이 질문은 많은 사람들이 저장 프로 시저에 마법의 힘이 있으며 문제가 발생하더라도 사용해야한다고 생각하기 때문에 점수가 약 -30 점으로 하향 조정됩니다.]

모든 저장 프로 시저 코드를 클라이언트로 옮기면 모든 사람이 훨씬 쉽게 작업 할 수 있습니다.

여전히 스키마 및 ORM 모델을 업데이트해야합니다. 그러나 스키마 변경은 ORM 변경과 분리되어 응용 프로그램과 데이터베이스 스키마간에 약간의 독립성을 허용합니다.

모든 저장 프로 시저를 다시 작성할 때 테스트, 수정, 유지 관리, 이해 및 적용 할 수 있습니다. 더 이상 두 가지 다른 기술로 침입하지 않기 때문에 앱이 거의 동일하게 실행되고 취약성이 줄어 듭니다.

ORM은 마술이 아니며 훌륭한 데이터베이스 디자인 기술이 작동하기 위해서는 절대적으로 필요합니다.

또한 클라이언트 SQL이 많은 프로그램은 트랜잭션 경계에 대한 잘못된 생각 때문에 느려질 수 있습니다. 저장 프로 시저가 빠른 것처럼 보이는 이유 중 하나는 저장 프로 시저가 매우 신중하게 트랜잭션을 디자인해야한다는 것입니다.

ORM은 신중하게 거래 디자인을 강요하지 않습니다. 저장 프로 시저를 작성할 때와 마찬가지로 트랜잭션 디자인을 신중하게 수행해야합니다.


19
저장 프로시 저는 작업하기가 매우 어려우므로 +1
Gary Rowe

3
: '(저장 프로 시저에는 아무런 문제가 없습니다. 그것은 또 다른 추상화 계층입니다.
Mike Weller

3
SP를 생성하면 데이터베이스 엔진은이를 컴파일 된 형태로 저장하고 실행 경로를 생성하여 최대한 빨리 실행되도록합니다. 그러나 ORM은 데이터베이스 엔진에서 컴파일하고 실행해야 할 때마다 SQL을 보냅니다. Stored Procedure 대신 ORM을 사용하는 것이 느릴 것이라고 생각합니다.
개발자

4
이상한. ORM에서 저장 프로 시저로 다시 전환했습니다. SPEED. 프로그래밍에 필요한 시간은 아니지만 ORM이 객체 구체화, 객체 검색, 다른 클라이언트 업데이트와 같은 작업에 필요한 시간입니다. SP가 훨씬 더 빠릅니다. 예를 들어, 새로운 최신 ORM을 사용하여 DB에서 30.000 개의 객체를 읽는 것이 필요합니다. 2 분 후 시간 초과 저장 프로 시저 호출 및 결과 얻기-2 초 예-DB에서 callign을 많이 줄이기 위해 페이징과 같은 많은 트릭이 있습니다. 그러나 ORM을 사용할 수 있거나 사용할 수 있다면 큰 차이가 있습니다.
Offler

2
@DeveloperArnab : 20 년 전에는 사실 이었지만 최신 DB 엔진은 상당히 정교하고 이전에 실행 된 쿼리를 인식하고 실행 계획을 재사용 할 수 있습니다. 요즘의 속도 차이는 너무 작아서 추가 SP의 번거 로움을 거의 보증하지 않습니다.
whatsisname

20

저장 프로시 저는 훌륭하고 빠르며 매우 효율적이며 데이터 관련 코드를 넣을 수있는 이상적인 장소입니다. 이 코드를 모두 클라이언트로 옮기면 클라이언트 개발자로서 약간 쉬워집니다 (약간 커밋이 변경 될 때 스키마와 ORM 모델을 업데이트해야하기 때문에) 기존 코드를 모두 잃어 버릴 것입니다. 모든 SQL 기술의 손실을 고려할 때 앱이 느리고 취약합니다.

DBA가 "오, 모든 커밋, 클라이언트를 다시 풀다운해야합니다. 대신 모든 코드를 DB 폼으로 옮겨야합니다"라고 말하는 것이 궁금합니다.

귀하의 경우, 기존의 맞춤형 ORM (예를 들어 재미있는 클래스)을 코드 숨김 코드 작성 방식의 변경을 제외하고 손실없이 다른 사람으로 대체 할 수 있어야합니다. 대부분의 ORM이 행복하게 SP를 호출 할 때 SP도 유지할 수 있습니다. 따라서 "Foo"클래스를 ORM으로 바꾸고 거기서 나가는 것이 좋습니다. SP를 교체하지 않는 것이 좋습니다.

추신. 코드 숨김 클래스에는 많은 공통 코드가있어 디자인 패턴이됩니다. 디자인 패턴이 무엇이라고 생각하십니까? (좋아요, 그것은 최고가 아니거나 심지어 좋은 것이 아니지만 여전히 DP입니다)

편집 : 이제 Dapper 를 사용하면 헤비급 ORM에서 sprocs를 피해야 할 이유가 사라집니다.


3
+1, 명백한 첫 번째 단계는 ORM으로 이동하여 기존 스토어드 프로 시저의 결과를 오브젝트에 맵핑하는 데 사용합니다. 모든 ds.Tables[0].Rows[0]["FooName"].ToString()쓰레기를 제거하십시오 . 관리자는 저장 프로 시저를 좋아합니까? 그는 그들을 유지합니다. 그러나 반복적 인 상용구 코드를 모두 LINQ to SQL에 의해 생성 된 것으로 옮기는 것은 나쁜 일이라고 주장하는 것은 물리적으로 불가능합니다.
Carson63000

11
글쎄, 당신의 게시물에 얼마나 "잘못"이 있는지 믿을 수 없습니다. 코드를 가져와야한다는 DBA와의 비교는 부적절하고 완전히 의미가 없습니다. 우선, 데이터베이스는 스토리의 끝에서 데이터를 저장하고 검색하기위한 서비스입니다. LOGIC이라는 이름은 API 코드의 일부인 Business Logic Layer에 들어갑니다. sprocs에서 멀어지기 쉬운 앱? 당신은 진지합니까 아니면 트롤링입니까? sprocs에 논리가있는 앱을 TDD하고 얼마나 재미 있는지 알려주세요. 또한 ORM은 전환되지 않습니다. 데이터베이스는 단순한 서비스이므로 데이터베이스입니다.
Matteo Mosca

5
나는 왜 일부 사람들이 데이터베이스가 모든 것이 신성한 성지라고 생각하는지 이해할 수 없다. 이것에 대해 생각하다. 타사가 귀하에게 서비스를 공개 할 때, 귀하는 귀하의 데이터베이스에 직접 액세스 할 수 있습니까, 아니면 API 뒤에서 마스킹합니까? 인기있는 예를 사용하려면 모든 Google 서비스를 이용하십시오. 개발자는 공개 API에 연결하여 어떤 데이터베이스가 있는지 또는 데이터베이스가 있는지조차 모릅니다. 이것이 견고하고 분리 된 소프트웨어를 설계하는 방법입니다. 데이터베이스는 응용 프로그램에서 직접 액세스 할 수 없습니다. 이를 위해 중간 계층이 있습니다.
Matteo Mosca

5
@Matteo Mosca : 물론 미들웨어가 DB에 액세스하는 방법은 DB의 클라이언트입니다. "client"는 "GUI"또는 "desktop app"을 의미하지 않습니다. 응용 프로그램 계층에는 많은 회색 영역이 있습니다. GUI 또는 서버 / 비즈니스 로직에서 유효성 검사를 수행합니까? 서버는 깔끔한 디자인이되어야하지만 성능과 사용자 응답 성이 떨어질 수 있습니다. 마찬가지로 성능과 데이터 정확성을 향상시킬 때 DB에 로직을 추가하는 경우가 많습니다.
gbjbaanb

4
죄송하지만 여전히 동의하지 않습니다. 사용했던 것과 동일한 DB 기술이없는 다른 환경에서 응용 프로그램을 배포해야하는 날에는 새로운 데이터베이스에 모든 sproc이 없기 때문에 앱을 실행할 수없는 상황에 처하게됩니다 .. 그리고 심지어 (전체적인 고통 인) 그것들을 재 작성하더라도 SQL 언어의 차이 등으로 인해 다를 수 있습니다. SOAP 및 REST와 같은 표준을 통해 노출되는 논리 및 유효성 검사를 가진 중앙 집중식 API는이를 해결합니다. 테스트 가능성, 버전 관리 및 일관성을 추가합니다.
Matteo Mosca

13

팀을 하나의 극단적 인 (저장 프로 시저 및 데이터 세트)에서 다른 것 (완전한 ORM)으로 이끌려 고하는 것 같습니다. 데이터 액세스 계층의 코드 품질을 향상시키기 위해 구현할 때 설정할 수있는 다른 점진적인 변경 사항이 더 있다고 생각합니다.

귀하가 게시 한 반 구운 활성 레코드 구현 코드는 특히 elegent하지 않습니다. 이해하고 구현하기 쉽고 .NET 개발자에게 인기있는 리포지토리 패턴을 조사하는 것이 좋습니다. 이 패턴은 종종 ORM과 관련이 있지만 일반 ADO.NET을 사용하여 리포지토리를 쉽게 만들 수 있습니다.

DataSet의 경우도 마찬가지입니다. 정적으로 (또는 동적으로) 유형이 지정된 객체를 반환하면 클래스 라이브러리를 사용하는 것이 훨씬 쉽습니다. 나는 생각 이 그림은 내가 할 수있는 것보다 더 나은 데이터 집합의 내 의견을 설명합니다.

또한 ORM으로 점프하지 않고 저장된 프로 시저를 버릴 수 있습니다. parameterzed SQL을 사용하는 데 아무런 문제가 없습니다. 실제로 서버에 여러 번의 왕복 여행을 절약하는 복잡한 절차가 없다면 저장 프로 시저를 사용하는 것보다 확실히 선호합니다. 레거시 데이터베이스를 열고 끝없는 CRUD 프로 시저 목록을 볼 때 나는 그것을 싫어합니다.

나는 ORM의 사용을 권장하지 않습니다-나는 일반적으로 내가 작업하는 대부분의 프로젝트에서 사용합니다. 그러나 나는이 프로젝트와 당신의 팀에 하나를 소개하려고 할 때 왜 많은 마찰이있을 수 있는지 알 수 있습니다. Dapper (이 사이트를 강력하게 사용하는 데 사용됨) 및 Massive 와 같은 새로운 유형의 "Micro ORM"을 확실히 살펴 보겠다고 말하면서 , 둘 다 엄청나게 사용하기 쉽고 SQL에 더 가깝게 유지합니다. 일반적인 ORM은 귀하의 팀이 더 기꺼이 받아 들일 것입니다.


2
문제는 앱이 작성되었을 때 .NET에 대한 실제 ORM이 없기 때문에 다른 방법 (ASP.NET 1.1 방식)으로 수행되었으며 아무도 다른 방식으로 (또는 다른 것을) 생각하지 않았다고 생각합니다. 몇 달 전에 합류 할 때까지
Wayne Molina

1
Dapper의 경우 +1 방금 프로젝트에서 사용하기 시작했으며 구현 및 사용이 매우 쉽습니다. 나는 이미 큰 팬입니다.
SLoret

4

비슷한 상황에 처해 있습니다. 실제로 하드웨어, 전원 및 정치는 데이터베이스쪽에 의존하므로 모든 것이 저장 절차를 거칩니다. 불행히도, 이들은 메타 데이터와 코드 생성에있어 코더에게 고통을줍니다. 테이블과 같이 스토어드 프로 시저에 풍부한 메타 데이터가 없기 때문입니다.

그럼에도 불구하고, 저장된 procs를 사용하여 우아하고 깨끗한 코드를 작성할 수 있습니다. 현재 모든 저장 프로 시저로 리포지토리 패턴을 직접 구현하고 있습니다. 데이터 리더에서 비즈니스 객체로 다시 매핑 할 때 FluentAdo.net에서 훌륭한 아이디어를 찾아 보는 것이 좋습니다. 나는 그 아이디어를 가져 와서 내 자체 솔루션으로 재사용했습니다.


3

JFTR-저는 저개발 PHP 개발자입니다. 그러나 이것은 주로 정치적 문제처럼 들립니다.

앱을 지원하는 "부패"의 규모를 고려할 때 모범 사례를 제외 하고 앱 을 근절하기 위해서는 상당한 오버 헤드가 발생합니다. 다시 쓰기 영역에서 접경하는 것처럼 들립니다.

제안한 대안이 비즈니스 비용을 정당화하는 데 도움이 될 것이라고 보장 할 수 있습니까? 이 벤처 기업의 ROI는 사업에 팔기 어려울 것으로 생각됩니다. 앱이 불안정하거나 재정적 측면에서 정밀 검사의 장점을 입증 할 수 없다면 – 이것은 어려울 수 있습니다.

ORM이 SPROCS 의 유일한 대안입니까? 완전한 ORM과 바닐라 SQL 사이에는 몇 가지 디자인 패턴이 있습니다. 아마도 이러한 SPROCS를 점차적으로 DB에서 DBAL로 가져 와서 프로세스를 시작할 수 있습니다. 물론 이것이 시간이 지남에 따라 자체 양조 ORM으로 성장할 위험이 있지만 목표에 더 가까워 질 것입니다.


2

몇 년 전에 SP에서 ORM으로 전환했습니다.

어떤 경우에는 80 개의 테이블을 업데이트해야했습니다. 이전 추정 모델은 entlib 및 SP를 사용하여 80 시간을 추정했을 것입니다. 우리는 10시에 해냈습니다 :)

데이터 액세스 계층을 개발하는 데 사용하는 시간이 80 % 단축되었습니다.


1
그리고 왜 테이블 업데이트를 스크립팅 할 수 없습니까?
Darknight

이것은 복잡한 개체를 메모리에 가져 와서보고를 위해 관계형 데이터베이스로 저장했습니다. 우리는 테이블 구조를 만들기 위해 객체를 반영하는 프로그램을 작성했습니다.
쉬라즈 바이지

-1

기본 문제는 배포가 올바르게 자동으로 작동하지 않는다는 것입니다.

커밋 후에 필요에 따라 데이터베이스를 조작하는 방법을 알고있는 연속 빌드 엔진을 설정하는 것이 더 쉬울 수 있습니다.

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