태그 보관물: database-design

database-design

관계형 데이터베이스 (예 : PostgreSQL)에 대한 트리거가 실제로 필요합니까? 수행하지 않는

데이터베이스를 일관성있게 유지하기 위해 트리거를 사용하여 저장된 데이터의 유효성을 검사 할 수 있습니다. 그러나 데이터베이스에 데이터를 저장하기 전에 애플리케이션 측에서 데이터 유효성 검증을 수행하지 않는 이유는 무엇입니까?

예를 들어 클라이언트를 저장하고 DDL 수준에서 쉽게 수행 할 수없는 일부 유효성 검사를 수행하려고합니다.
https://severalnines.com/blog/postgresql-triggers-and-stored-function-basics

또 다른 예는 감사입니다.

최신 정보

트리거와 데이터베이스 트랜잭션이 함께 작동하는 방식 예를 들어 삽입되는 데이터의 유효성 검사를 수행하려는 경우. 트랜잭션 내부에서 수행됩니다. 이전에 수행 된 작업 : 트랜잭션이 커밋되거나 트리거가 실행됩니까?



답변

어떤 종류의 응용 프로그램 시스템을 구축하고 있는지에 따라 다릅니다.

  • 이 응용 프로그램 전용 데이터베이스와 함께 하나의 기본 응용 프로그램 만 포함하고 응용 프로그램과 데이터베이스를 나란히 개발하는 팀이 이상적인 응용 프로그램 중심 시스템을 만드는 경우 모든 유효성 검사 논리를 유지하고 감사 할 수 있습니다 응용 프로그램 내부의 논리.

    이것의 주요 이점은 응용 프로그램과 db간에 비즈니스 로직을 분배 할 필요가 없으므로 시스템을 유지 보수 및 전개하는 것이 더 쉬워진다는 것입니다. 또한 응용 프로그램을 특정 유형의 DBMS 또는 DBMS 공급 업체에 너무 많이 묶지 않습니다. 애플리케이션이 트리거를 제공하지 않는 경량 DB 시스템을 사용하려면이 방법이 필요합니다.

  • 그러나 많은 다른 응용 프로그램이 공통 데이터베이스를 공유하는 시스템을 만들고 향후에 어떤 응용 프로그램에 쓸 것인지 또는 앞으로 팀에 데이터를 채우기위한 응용 프로그램을 개발할 팀을 미리 계획 할 수없는 경우 데이터베이스가 가능한 한 많은 데이터 일관성을 보장해야합니다. 그리고 그것이 방아쇠가 정말로 도움이되는 곳입니다. 더 큰 시스템에서는 참조 제한이 충분하지 않은 경우가 많지만 저장 프로 시저를 호출하는 트리거는 필요한 모든 종류의 유효성 검사를 구현할 수 있습니다.

트리거를 사용하는 또 다른 이유는 성능 일 수 있습니다. 복잡한 데이터 모델에서는 클라이언트 애플리케이션에서 사용 가능한 현재 작업 세트의 일부가 아닌 많은 추가 데이터를 사용해야하는 복잡한 일관성 규칙이 자주 발생하지 않습니다. 클라이언트 측에서 검증이 가능하도록 네트워크를 통해 모든 데이터를 먼저 전송하면 성능에 큰 영향을 줄 수 있습니다.

이 이전 SE 게시물 : 데이터베이스 정리를위한 Application Logic Vs DB 트리거 참조

따라서 어떤 종류의 시스템을 구축하고 있는지 결정한 다음 트리거가 귀하의 경우에 적합한 도구인지 여부를 결정하십시오.


답변

질문은 데이터 품질에 대한 책임에 관한 것입니다.

대답은 시스템을 보는 방법에 따라 다릅니다.

데이터베이스가 응용 프로그램과 별 개인 독립적이고 고유하며 자율적 인 서비스 인 경우 데이터베이스는 데이터베이스에 포함 된 데이터의 일관성과 품질을 보장해야합니다. 기본적으로 해당 데이터베이스를 다른 응용 프로그램에서 사용할 수 있기 때문에 일관성과 품질이 동일한 두 번째 응용 프로그램에 의존 할 수 없습니다. 이러한 상황에서 데이터베이스는 API 및 자율적 인 동작을 노출하도록 설계되어야합니다. 이보기에는 최소한 두 개의 응용 프로그램이 있습니다. 그 중 하나는 데이터베이스이고 다른 하나는이를 사용하는 응용 프로그램입니다.

반대로 데이터베이스는 응용 프로그램을 직접적이고 완벽하게 제어하는 ​​복잡한 파일 형식으로 간주 될 수 있습니다. 이런 의미에서 데이터베이스는 순수한 직렬화 및 문서 탐색 도구가됩니다. 쿼리 및 문서 유지 관리 (JSON 또는 XML 도구와 같은)를 지원하는 몇 가지 고급 동작을 제공 할 수 있지만 (대부분의 파일 스트림처럼) 다시 할 필요는 없습니다. 이 경우 파일 내에서 올바른 형식과 내용을 유지하는 것은 전적으로 프로그램의 책임입니다. 이보기에는 하나의 응용 프로그램이 있습니다.

두 가지 관점에서 다음 질문은 데이터베이스 사용을 멋진 파일 또는 별도의 서비스로 지원하는 방법입니다. 이를 통해 다음을 달성 할 수 있습니다.

  • 데이터베이스 플랫폼이 테이블 / 뷰 / 저장 프로 시저 / 트리거 / 등의 형태로 제공하는 도구 사용
  • 모든 클라이언트가 데이터베이스에 액세스하기 위해 사용해야하는 서비스 내에서 데이터베이스 자체 랩핑
  • 데이터에 액세스하기 위해 모든 클라이언트가 사용해야하는 라이브러리에 데이터베이스를 래핑합니다.

각각에는 장단점이 있으며 시스템이 작동하는 환경의 구조적 제약에 따라 달라집니다.

어떤보기를 사용하든 항상 경계에서 데이터의 유효성을 검사하기 위해 비용을 지불합니다.

  • 사용자가 입력 한 UI에서 필드의 유효성을 검사합니다
  • 클라이언트를 떠나기 전에 네트워크 / API 요청의 유효성을 검사하십시오
  • 작업을 수행하기 전에 서버에서 네트워크 / API 요청을 확인하십시오.
  • 비즈니스 규칙으로 전달되는 데이터의 유효성 검사
  • 지속되기 전에 데이터 유효성 검사
  • 지속성에서 검색된 후 데이터 유효성 검증
  • 등등

각 경계에서 얼마나 많은 검증이 보증되는지는 그것을 검증하지 않는 것이 얼마나 위험한 지에 달려 있습니다.

  • 두 숫자를 곱하면?
    • 당신은 잘못된 숫자가 문제입니까?
  • 주어진 메모리 위치에서 프로 시저를 호출합니까?
    • 그 메모리 위치에 무엇입니까?
    • 개체가 존재하지 않거나 상태가 좋지 않으면 어떻게됩니까?
  • 한자를 포함하는 문자열에 정규식을 사용합니까?
    • 정규식 모듈이 유니 코드를 처리 할 수 ​​있습니까?
    • 정규식으로 유니 코드를 처리 할 수 ​​있습니까?

답변

아니요, 유효성 검사를 위해 트리거를 사용해서는 안됩니다.

데이터베이스는 자체 무결성에 대해서만 책임이 있습니다. 유효성 검사에 직면 한 모든 사용자는 응용 프로그램에서 수행해야합니다.

데이터베이스는 무결성을 위해 세 가지 수준의 유효성 검사를 수행합니다. 첫 번째는 필드 레벨 검증입니다. 값이 없으면 필드가 필요할 수 있습니다 (널). 점검 제한 조건이 될 수도 있습니다. 도메인에는 열거 된 수의 값이 있습니다.

두 번째로 테이블간에 관계가 있습니다. 한 테이블에서이 테이블을 다른 테이블과 관련시키고 값이 “다른 테이블”에 유효한 키가되도록 요구하는 하나 이상의 외래 키를 저장합니다. 다른 국가의 주소를 지원하는 주소 데이터베이스를 생각해보십시오. 주소의 국가 키는 알려진 국가를 가리켜 야합니다. 데이터 (예 : 우편 번호)가 유효한지 여부는이 무결성 검사와 관련이 없습니다.

셋째로 가장 복잡한 것은 트리거입니다. 일반적으로 이들은 조건부 인 무결성 규칙에 대해 다루어야합니다. 주소 예로 돌아가려면 : 국가에 우편 번호가없는 경우이 목록의 국가에 우편 번호가 있으면 문제가됩니다. 따라서이 국가에 우편 번호가없는 경우 우편 번호 필드는 null이어야합니다.

유효성 검사는 응용 프로그램의 관심사입니다. 독일 우편 번호가 숫자만으로 구성되어 있다는 사실은 응용 프로그램이 데이터베이스가 아니라 확인해야한다는 것입니다. 회선은 얇기 때문에 어떤 경우 트리거 (데이터베이스의 무결성을 보호) 또는 응용 프로그램 (유저 검증에 직면 한)에 있어야하는 경우 일부 사고 / 토론이 필요할 수 있습니다.


답변

감사는 트리거를 효과적으로 사용하는 전형적인 예입니다. 트리거로 구현 된 감사 테이블 덕분에 테스터가 클라이언트를 한 수준의 서비스에서 다른 수준으로 이동시키는 데 따른 오류를 발견했습니다. 감사를 위해 트리거를 사용하는 것이 좋습니다.

프런트 엔드 수준에서 유효성 검사를 수행 수는 있지만 처리 한 데이터베이스 (3000에서 태어난 사람들 등)에서 이상한 오류가 발생했으며 그중 일부이기 때문에 추가 계층을 갖는 것이 좋습니다. 만일의 경우를 대비하여 데이터베이스에서 유효성 검사 물론 이러한 유형의 오류는 검사 제한 조건으로 피할 수 있으며 여러 번 더 효과적입니다 (MS SQL에서는 선호되는 방법입니다. 항상 문서를 확인하십시오).


답변

관계형 데이터베이스에 대한 트리거가 실제로 필요한지에 대한 질문이므로 트리거를 사용하는 다른 사용 사례가 있습니다.

  1. 다른 답변에 설명 된대로 감사합니다.
  2. 보다 넓은 의미의 감사 : 데이터베이스 항목이 변경되면 트리거는 비동기적인 사후 처리를 위해 이벤트를 기록 할 수 있습니다 (예 : 다른 애플리케이션으로 야간 내보내기).
  3. 뷰에 대한 트리거 : 트리거를 정의 할 수 있습니다 instead of. 따라서 뷰에서 항목을 삽입, 업데이트 및 삭제할 수 있습니다. 트리거는 이러한 조치를 여러 테이블에 분산시킬 수 있습니다. 이는 기본 테이블의 세부 사항을 노출시키지 않고 제한된보기를 사용 가능하게하는 방법입니다.
  4. 데이터베이스 전환을 명시 적으로 저장하려면 : 테이블 A와 B와 중간 테이블 R 사이의 N : M 관계를 가정합니다. R에서 A와 B 사이의 외래 키 제약 조건을 정의 할 수 있습니다. B의 해당 항목이 삭제됩니다. 그러나 비즈니스 논리에 따라 A의 항목이 B의 항목과 하나 이상의 관계를 가져야하는 경우가 있습니다.이 경우 R 삭제시 트리거가이 논리를 적용하는 데 도움이 될 수 있습니다. A의 항목의 경우 R의 마지막 항목 애플리케이션 중심 뷰에서 적어도 두 번의 전환이 필요합니다. 이것은 유효성 검사의 예입니다. 다른 사례도 생각할 수 있습니다 : 사용 사례 (1), (2),
  5. 신뢰 : 때때로 데이터베이스 관리자가 응용 프로그램을 사용하지 않는 명령 행에서 항목을 변경합니다. 관리자는 신중하게 작업하고 자신이하는 일을 알고 있습니다. 그러나 때로는 틀릴 수도 있습니다. 일관성이 중요한 경우 트리거는 안전 벨트입니다.

단점은 비즈니스 로직이 계층간에 분산되므로 유지 관리에 대한 주요 단점입니다. 다른 저자가 쓴 것처럼, 응용 프로그램과 데이터베이스 사이의 경계가 좁고 선택이 항상 명확한 것은 아닙니다. 내 개인적인 의견은 트리거가 개발자에게 부담이된다는 것입니다. 개발 시간을 절약 할 수 있습니다. 그들은 느린 네트워크 연결을 통해 성능을 향상시키기 때문에 사용자 경험을 향상시킵니다.


답변