원시 SQL을 사용하지 않고 쿼리 빌더를 사용하면 이점이 있습니까?
예 :
$q->select('*')
->from('posts')
->innerJoin('terms', 'post_id')
->where(...)
vs :
SELECT * FROM posts WHERE ...
많은 프레임 워크에서 이러한 종류의 추상화 계층을 사용하지만 이점을 이해하지 못합니다.
원시 SQL을 사용하지 않고 쿼리 빌더를 사용하면 이점이 있습니까?
예 :
$q->select('*')
->from('posts')
->innerJoin('terms', 'post_id')
->where(...)
vs :
SELECT * FROM posts WHERE ...
많은 프레임 워크에서 이러한 종류의 추상화 계층을 사용하지만 이점을 이해하지 못합니다.
답변:
프레임 워크를 통해 SQL을 작성하는 추상화는 추상화됩니다.
손으로 SQL을 작성하는 것만으로는 나쁘지 않지만 탈출과 위생 문제가 발생하기 시작합니다. 추상화 계층은이 모든 것을 배후에서 처리하여 코드를 깨끗하게하고 많은 mysql_real_escape_string()
통화 등을하지 않아도 됩니다.
또한 이는 SQL의 다른 방언을 설명 할 가능성을 가져옵니다. 모든 데이터베이스가 동일하게 구축 된 것은 아니며 키워드 나 특정 기능의 구문에 차이가있을 수 있습니다. 추상화 계층을 사용하면 변형에 대한 올바른 구문을 동적으로 생성 할 수 있습니다.
추상화 계층은 성능에 영향을 줄 수 있지만 대가로받는 코드의 청결성과 견고성과 비교할 때 일반적으로 무시할 수 있습니다.
쿼리 빌더는 내 애완 동물을 싫어하므로 너무 사용하지 않기 위해 자체 프레임 워크 (Apeel)를 작성했습니다!
PDO를 사용하면 (정확히 권장합니다) 입력을 처리하는 것이 처리됩니다.
다른 사람들이 말했듯이 데이터베이스 간을 쉽게 전환 할 수 있지만 "최소 공통 분모"기능을 지원하는 경향이 있으며 고급 기능의 성능을 지원하지 않거나 성능이 떨어집니다.
나는 1986 년경부터 데이터베이스가있는 시스템을 개발해 왔으며 항상 더 나은 성능이 필요할 때가 아닌 다른 데이터베이스를 실제로 변경하는 회사가 거의 없었습니다. 더 나은 성능을 위해 데이터베이스를 변경하는 경우 단순성을 위해 쿼리 빌더를 사용하지 않고 새 데이터베이스를 최대한 활용하기 위해 쿼리를 수동으로 최적화하는 데 시간을 보내는 것이 훨씬 더 합리적입니다.
쿼리 작성기의 문제를 파악하는 데 소요 된 시간 (보다 나은 쿼리로 전환 할 때 다시 학습)은 SQL을 최적화하는 방법을 배우는 데 훨씬 생산적으로 소비됩니다.
어쨌든 하나를 사용하지 않는 이유는 있지만 어떤 사람들은 그들을 좋아합니다.
이론적으로? 예. 글렌 넬슨은 그들이 종종 당신을 도울 방법을 지적했습니다 . (좋은 쿼리 작성기 인 경우).
실제로? 항상 이론에 부응하지는 않으며 실제로 문제를 일으킬 수 있습니다. 일부 인기있는 DBMS에 대해 쿼리 빌더를 사용하고 있으며 모든 것이 복잡하다고 가정하십시오. 그런 다음 고객이 선택한 쿼리 빌더가 처리 할 수없는 문제가있는 DBMS를 치도록 요청합니다. (이전 버전의 Pervasive로 작업해야 할 때이 문제가 발생했습니다.)
그러나! 반드시해야 할 일은 데이터 액세스 계층을 분리하고 필요한 경우 새 계층으로 바꿀 수 있는지 확인하는 것입니다. 그렇게하면 모든 기능을 갖춘 멋진 쿼리 작성기를 만들 수 있지만 문제의 DB에 대해 이상한 의사 SQL을 사용하는 새로운 기능을 연결 해야하는 경우.
쿼리 작성기의 실질적인 일상적인 이점은 코드 재사용과 DRY 원칙을 따르는 기능이라고 생각합니다.
쿼리 빌더를 사용하면 반복되는 SQL 부분을 메소드에 넣을 수 있습니다. 그런 다음이 방법을 사용하여 복잡한 SQL을 작성하십시오. 예를 들어 재사용 가능한 JOIN 절이 있습니다.
function joinTaskWithClient($queryBuilder) {
$queryBuilder->join('task', 'contract', 'task.contract_id = contract.id')
->join('contract', 'client', 'contract.client_id = client.id');
}
따라서 사용법은 다음과 같습니다.
$queryBuilder->select('client.name')
->from('client')
->where('task.id=:task')->setParameter('task', 42);
joinTaskWithClient($queryBuilder);
참고로, 쿼리 빌더를 사용하면 SQL 문자열을 수동으로 수집하는 경우와 달리 임의의 순서로 SQL 부분을 추가 할 수 있습니다 (예 : WHERE 후 부분에 참여). 또한 빌더 패턴 에 대해 읽으면 의도와 이점을 볼 수 있습니다 .
이스케이프 및 살균에 대해 동의하지만 쿼리 작성기 없이도 달성 할 수 있습니다. DB 유형 / 방언 추상화와 관련하여 이것은 실제로 거의 사용되지 않는 이론적이고 의심스러운 이점입니다.
나는 내 사용자 정의 SQL 빌더의 Readme 파일을 기반으로 답변을 제공 할 것입니다 ( Dialect )
(일반 텍스트 다음에 라이브러리 특정 참조가 제거됨)
요구 사항
풍모
위의 기능과 요구 사항이 SQL 추상화 빌더를 사용하는 이유를 스케치한다고 생각합니다.
위의 기능 중 대부분은 대부분의 SQL 빌더에서 지원합니다 (내가 아는 한 나열된 모든 기능이 지원되는 것은 아닙니다)
사용 사례 :
마지막으로, 내가 가진 유스 케이스의 예입니다. 기본 DB 스키마 (wordpress)가 수행 해야하는 데이터 쿼리 유형에 적합하지 않은 응용 프로그램을 작성하고 일부 WP 테이블 (예 : 게시물)을 사용해야했습니다 (따라서 완전히 새로운 테이블이 있음) 모든 응용 프로그램 데이터에 대해 옵션이 아닙니다).
이 경우 사용자 지정 / 동적 조건에 따라 모델을 쿼리 할 수있는 MVC와 같은 응용 프로그램을 만들 수 있기 때문에 쿼리가 거의 악몽이되었습니다. 조인을 사용하여 최대 2-3 개의 테이블을 쿼리하고 조건을 필터링하여 조인 할 테이블을 확인하고 필요한 별칭을 처리하는 등의 작업을 지원해야한다고 상상해보십시오.
분명히 이것은 쿼리 추상화 유스 케이스였으며, 더 나아가 사용자 정의 소프트 뷰 (모델에 적합한 하나의 사용자 정의 테이블 인 것처럼 결합 된 테이블의 대기업) 를 정의 할 수 있는 기능 이 필요했습니다. . 그런 다음 훨씬 쉽고 깨끗하고 모듈 식이며 유연했습니다. 다른 양상에서, 애플리케이션 (코드)은 또한 쿼리 추상화 계층을 (db 스키마) 정규화 도구로서 사용했다. 일부 사람들이 말했듯이 미래 지향적 이었습니다 .
내일 사람들이 추가 옵션이나 데이터가 필요하다고 결정하면 몇 줄로 모델에 추가하고 잘 작동합니다. 또한, 사람들이 내일로 사람들이 더 이상 워드 프레스를 사용하지 않기로 결정하면 (응용 프로그램이 플러그인으로 워드 프레스에 느슨하게 연결되어 있기 때문에 ) 몇 줄로 모델 을 변경하는 것이 비교적 쉽습니다 ( 단지 정의 ). 새로운 스키마에 적응하는 코드.
무슨 말인지 알 겠어?
종종 이러한 쿼리에 대한 일부 주장은 실제로 상수가 아닌 일부 값입니다. 이제 많은 것들이 본질적으로 사용자 양식 게시물에서 파생되었습니다. 따라서 SQL 주입 공격에 대한 많은 가능성이 있습니다. 따라서 본질적으로 쿼리 구성에는 전체 유효성 검사가 필요합니다.
이제 이것은 개발자를 신뢰하지는 않지만 쿼리를 작성하는 것은 쉽지만 가능한 모든 유효성 검사를 반복하면 실수로 누락되거나 쿼리를 수정하지만 쿼리를 수정하지는 않지만 유효성 검사를 업데이트하지 않습니다. 일부 초보자는 이것에 빠질 수있는 모든 위험을 알 수도 있습니다. 따라서 쿼리 빌더 추상화는 매우 필수적입니다.
쿼리 빌더는 GUI를 사용하여 테이블을 선택하고 그래픽으로 조인 할 수있는 GUI 애플리케이션이라고 생각했지만, 이제는 SQL 빌더를 순수 SQL 쿼리를 작성할 필요가없는 API를 호출하는 것으로 이해합니다. SQL 특징의 잠재적 차이를 추상화하십시오.
이러한 쿼리 작성기를 사용하는 것이 좋습니다 , 에 많이 의존하는 사람들은 DBA에게 묻지 않는 경향이 있다고 생각합니다. "이봐 요.
내가 틀리지 마
테이블이 아닌 뷰에 대해 쿼리를 작성해야한다고 생각합니다. 보안이나 필터링을위한 것이 아니라 좋은 이유이지만, 같은 이유로 구체적인 클래스가 아닌 인터페이스에 대해 코드화해야합니다 : 디커플링. 뷰는 "계약"과 비슷하지만 인터페이스가 OOP에서 "계약"과 같은 방식입니다. 기본 테이블을 변경할 수 있지만 뷰가 프로그래머에게 동일한 "계약"을 표시하도록 강요하는 한 코드가 손상되지 않아야합니다.
다시 한 번 말하지만, 쿼리 빌더를 사용하여 뷰를 쿼리 할 수 있지만, 많은 뷰가 쿼리를 작성하고 DBA에 다음과 같이 요청하는 결과 인 광란 과정으로 존재하게됩니다. .
쿼리를 작성하지 않으면 특정 뷰를 생성 할 필요성을 감지하지 못한다고 생각하는 것이 잘못입니까?
저와 관련된 또 다른 것은 초보자가 프로그래머가 만들지 않은 가장 아름다운 기술 중 하나 인 SQL을 마스터하지 않는 것입니다.