질문에 대답하기 전에 몇 가지 배경 지식이 있다고 생각합니다.
문제의 핵심
수년간 개발자를 인터뷰하고 고용 한 후 두 가지를 배웠습니다.
대다수의 개발자는 데이터베이스 디자인 경험이 거의 없습니다.
나는 데이터베이스를 이해하지 못하는 사람들과 ORM을 싫어하는 사람들 사이 의 느슨한 상관 관계를 발견했습니다 .
(참고 : 예, ORM을 싫어하는 데이터베이스를 잘 이해하는 사람들이 있다는 것을 알고 있습니다)
사람들은 당신이에 제조업체 이름을 포함하지 않는 이유 외래 키가 중요한 이유를 이해하지 않는 경우 item
테이블, 또는 왜 customer.address1
, customer.address2
그리고 customer.address3
필드 쓰기 데이터베이스 버그에 대한보다 쉽게하기 위해 ORM을 추가, 좋은 아이디어 없습니다 아무것도 도와주지 않을 것입니다.
대신 적절하게 설계된 데이터베이스와 OLTP 사용 사례를 사용하여 ORM은 황금색입니다. 많은 작업 이 사라지고 DBIx :: Class :: Schema :: Loader 와 같은 도구 를 사용하면 몇 분 만에 훌륭한 데이터베이스 스키마에서 작동하는 Perl 코드로 이동할 수 있습니다. 파레토 규칙을 인용하고 내 문제의 80 %가 20 %의 작업으로 해결되었다고 말하지만 실제로는 그보다 더 큰 이점이 있습니다.
솔루션 남용
일부 사람들이 ORM을 싫어하는 또 다른 이유는 추상화 유출을 허용하기 때문입니다. MVC 웹 앱의 일반적인 경우를 고려해 봅시다. 다음은 우리가 일반적으로 볼 수있는 것입니다 (의사 코드).
GET '/countries/offices/$company' => sub {
my ( $app, $company_slug ) = @_;
my $company = $app->model('Company')->find({ slug => $company_slug })
or $app->redirect('/');
my $countries = $app->model('Countries')->search(
{
'company.company_id' => $company->company_id,
},
{
join => [ offices => 'company' ],
order_by => 'me.name',
},
);
$app->stash({
company => $company,
countries => $country,
});
}
사람들은 이와 같은 컨트롤러 경로를 작성하고 뒷면에 자신을 두드려서 깨끗하고 깔끔한 코드라고 생각합니다. 컨트롤러에서 SQL을 하드 코딩하는 데는 놀랍지 만 다른 SQL 구문을 노출시키는 것 이상은 거의 수행하지 않았습니다. ORM 코드는 모델로 푸시 다운해야하며 다음과 같이 할 수 있습니다.
GET '/countries/offices/$company' => sub {
my ( $app, $company_slug ) = @_;
my $result = $app->model('Company')->countries($company_slug)
or $app->redirect('/');
$app->stash({ result => $result });
}
지금 무슨 일이 있었는지 알아? 모델을 올바르게 캡슐화하고 ORM을 노출하지 않았으며 나중에 데이터베이스 대신 캐시에서 해당 데이터를 가져올 수있는 경우 컨트롤러 코드를 변경할 필요가 없습니다. 테스트를 작성하고 로직을 재사용하기 위해).
실제로 사람들은 자신의 컨트롤러 (및 뷰) 전체에서 ORM 코드를 유출하고 확장 성 문제에 부딪 치면 아키텍처가 아니라 ORM을 비난하기 시작합니다. ORM은 나쁜 랩을 얻습니다 (많은 고객에게 반복적으로 봅니다). 대신, ORM 한계에 도달했을 때 코드를 ORM에 너무 밀접하게 연결하지 않고 문제에 대한 적절한 솔루션을 선택할 수 있도록 추상화를 숨기십시오.
보고 및 기타 제한
Rob Kinyon이 위에서 분명히 밝힌 바와 같이,보고는 ORM에서 약한 경향이 있습니다. 이는 여러 테이블에 걸쳐있는 복잡한 SQL 또는 SQL이 ORM에서 제대로 작동하지 않는 더 큰 문제의 하위 집합입니다. 예를 들어, ORM은 때때로 원하지 않는 조인 유형을 강제하고이를 수정하는 방법을 알 수없는 경우가 있습니다. 또는 MySQL에서 색인 힌트 를 사용하고 싶지만 쉽지 않습니다 . 또는 때로는 SQL이 너무 복잡하여 제공된 추상화 대신 SQL을 작성하는 것이 더 좋을 수도 있습니다.
이것이 DBIx :: Class :: Report 작성을 시작한 이유 중 일부입니다 . 지금까지는 잘 작동하고 사람들이 여기에서 가지고있는 대부분의 문제를 해결합니다 (읽기 전용 인터페이스로 괜찮다면). 그리고 목발처럼 보이지만 실제로는 이전 섹션에서 설명한 것처럼 추상화를 유출하지 않는 한 DBIx::Class
더 쉽게 작업 할 수 있습니다.
그렇다면 언제 DBIx :: Class를 선택하겠습니까?
나를 위해 데이터베이스에 대한 인터페이스가 필요한 대부분 의 시간을 선택했습니다 . 나는 몇 년 동안 그것을 사용 해왔다. 그러나 나는 OLAP 시스템을 위해 그것을 선택하지 않을 수도 있으며, 새로운 프로그래머는 확실히 그것을 고투 할 것입니다. 또한 메타 프로그래밍이 필요한 경우가 많으며 DBIx::Class
도구 를 제공하는 동안 문서화가 잘되어 있지 않습니다.
DBIx::Class
올바르게 사용하는 열쇠 는 대부분의 ORM과 동일합니다.
추상화를 누설하지 마십시오.
저주받은 테스트를 작성하십시오.
필요에 따라 SQL로 드롭 다운하는 방법을 알고 있습니다.
데이터베이스를 정규화하는 방법을 배웁니다.
DBIx::Class
, 일단 배운 후에는 대부분의 어려운 작업을 처리하고 응용 프로그램을 빠르게 작성할 수 있습니다.