문제

과거에는 데이터베이스 테이블에서 트리거를 사용하는 것을 좋아하지 않았습니다.나에게 그들은 항상 내 애플리케이션 코드의 제어에서 멀리 떨어진 데이터베이스 측에서 일어날 "마법"을 나타냈습니다.또한 DB가 수행해야 하는 작업량을 제한하고 싶었습니다. DB는 일반적으로 공유 리소스이고 부하가 높은 시나리오에서는 트리거가 비용이 많이 들 수 있다고 항상 가정했기 때문입니다.

즉, 나는 트리거를 사용하는 것이 타당한 몇 가지 사례를 발견했습니다(적어도 제 생각에는 타당하다고 생각합니다).하지만 최근에는 때때로 트리거를 "우회"해야 하는 상황에 처하게 되었습니다.나는 이것을 할 수 있는 방법을 찾아야 한다는 것에 대해 정말로 죄책감을 느꼈고, 더 나은 데이터베이스 디자인이 이러한 우회의 필요성을 완화할 것이라고 여전히 생각합니다.불행히도 이 DB는 여러 응용 프로그램에서 사용되며 그 중 일부는 스키마 변경에 대해 비명을 지르는 매우 비협조적인 개발 팀에 의해 유지 관리되므로 막혔습니다.

트리거에 대한 일반적인 합의는 무엇입니까?사랑해요?싫어?일부 시나리오에서는 목적에 부합한다고 생각하시나요?트리거를 우회해야 한다는 것이 "잘못하고 있다"는 뜻이라고 생각하시나요?

도움이 되었습니까?

해결책

트리거는 일반적으로 잘못 사용되며 버그를 유발하므로 피해야 합니다.테이블의 행을 교차하는 무결성 제약 조건 검사를 수행하도록 트리거를 설계하지 마십시오(예: "부서별 평균 급여는 X를 초과할 수 없음)."

톰 카이트, Oracle의 부사장은 다음을 선호한다고 밝혔습니다. Oracle의 기능으로 트리거를 제거합니다. 버그에서 빈번한 역할로 인해 데이터베이스.그는 그것이 단지 꿈일 뿐이라는 것을 알고 있으며 트리거는 여기에 남아 있지만 가능하다면 Oracle에서 트리거를 제거할 것입니다(WHEN OTHERS 절 및 자율 트랜잭션과 함께).

트리거를 올바르게 사용할 수 있나요?전적으로.

문제는 - 너무 많은 경우에 올바르게 사용되지 않아서 그로 인한 학대 (및 버그)를 제거하기 위해 인식 된 혜택을 기꺼이 포기할 의향이 있습니다.- 톰 카이트

다른 팁

데이터베이스를 매우 큰 개체로 생각하십시오. 데이터베이스를 호출할 때마다 논리적으로 일관된 상태에 있어야 합니다.

데이터베이스는 테이블을 통해 자신을 노출하며 테이블과 행의 일관성을 유지하는 작업은 트리거를 통해 수행할 수 있습니다.일관성을 유지하는 또 다른 방법은 테이블에 대한 직접 액세스를 허용하지 않고 저장 프로시저와 뷰를 통해서만 액세스를 허용하는 것입니다.

트리거의 단점은 어떤 작업이든 트리거를 호출할 수 있다는 것입니다.이것은 또한 강점이기도 합니다. 누구도 무능함으로 인해 시스템의 무결성을 망치지 않을 것입니다.

이에 반해, 저장 프로시저와 뷰를 통해서만 데이터베이스에 대한 액세스를 허용하면 여전히 권한에 대한 백도어 액세스가 허용됩니다.충분한 권한을 가진 사용자는 데이터베이스 무결성을 손상시키지 않도록 신뢰되며, 다른 모든 사용자는 저장 프로시저를 사용합니다.

작업량을 줄이는 방법은 다음과 같습니다.데이터베이스는 외부 세계를 처리할 필요가 없을 때 놀라울 정도로 효율적입니다.프로세스 전환만으로도 성능이 얼마나 저하되는지 정말 놀라실 것입니다.이는 저장 프로시저의 또 다른 장점입니다.데이터베이스에 대한 수십 번의 호출(및 관련된 모든 왕복) 대신 하나가 있습니다.

하나의 저장된 프로세스에 여러 가지를 모아 두는 것은 괜찮습니다. 하지만 문제가 발생하면 어떻게 될까요?5개 단계가 있고 첫 번째 단계가 실패하면 다른 단계는 어떻게 되나요?해당 상황에 대처하려면 거기에 많은 논리를 추가해야 합니다.일단 그렇게 하기 시작하면 해당 시나리오에서 저장 프로시저의 이점을 잃게 됩니다.

비즈니스 논리는 어딘가로 가야 하며 데이터베이스 설계에는 묵시적인 도메인 규칙이 많이 포함되어 있습니다. 관계, 제약 조건 등은 예를 들어 사용자가 하나의 비밀번호만 가질 수 있다고 말함으로써 비즈니스 규칙을 성문화하려는 시도입니다.이러한 관계 등을 통해 비즈니스 규칙을 데이터베이스 서버에 적용하기 시작했다면 어디에서 선을 그어야 할까요?데이터베이스는 언제 데이터 무결성에 대한 책임을 포기하고 통화 앱과 데이터베이스 사용자가 데이터 무결성을 제대로 확보할 수 있다고 신뢰하기 시작합니까?이러한 규칙이 포함된 저장 프로시저는 DBA의 손에 많은 정치적 권한을 부여할 수 있습니다.이는 n계층 아키텍처에 몇 개의 계층이 존재할 것인지에 달려 있습니다.프레젠테이션, 비즈니스 및 데이터 계층이 있다면 비즈니스와 데이터의 구분은 어디에 있습니까?비즈니스 계층은 어떤 부가가치를 추가합니까?데이터베이스 서버에서 비즈니스 계층을 저장 프로시저로 실행하시겠습니까?

예, 트리거를 우회한다는 것은 "잘못하고 있다"는 의미라고 생각합니다.이 경우 트리거는 적합하지 않습니다.

enter image description here

저는 C#으로 웹과 Winforms 앱을 사용하고 있습니다. 싫어하다 열정으로 촉발합니다.해당 논리를 애플리케이션의 비즈니스 계층으로 이동하고 거기에 트리거 논리를 복제하는 것보다 트리거 사용을 정당화할 수 있는 상황을 본 적이 없습니다.

저는 DTS 유형의 작업이나 그와 유사한 작업을 수행하지 않으므로 거기에서 트리거를 사용하는 몇 가지 사용 사례가 있을 수 있습니다. 하지만 우리 팀의 누군가가 트리거를 사용하고 싶다고 말하면 주장을 잘 준비하는 것이 좋습니다. 나는 대기를 거부하고 내가 작업 중인 데이터베이스에 트리거를 추가하도록 허용하기 때문입니다.

내가 트리거를 좋아하지 않는 몇 가지 이유는 다음과 같습니다.

  • 그들은 논리를 데이터베이스로 옮깁니다.일단 그렇게 하기 시작하면 디버깅, 컴파일 시간 안전성, 논리 흐름을 잃어버리기 때문에 고통스러운 세상을 요구하게 됩니다.모두 내리막 길입니다.
  • 그들이 구현하는 논리는 누구에게도 쉽게 보이지 않습니다.
  • 모든 데이터베이스 엔진이 트리거를 지원하는 것은 아니므로 솔루션이 데이터베이스 엔진에 대한 종속성을 생성합니다.

나는 내 머리 꼭대기에서 더 많은 이유를 생각할 수 있다고 확신하지만 그것만으로도 트리거를 사용하지 않는 데 충분합니다.

"테이블의 행을 교차하는 무결성 제약 조건 검사를 수행하는 트리거를 설계하지 마십시오." -- 동의할 수 없습니다.질문에는 'SQL Server' 태그가 지정되어 있으며 SQL Server의 CHECK 제약 조건' 절에는 하위 쿼리를 포함할 수 없습니다.더 나쁜 점은 구현에서 CHECK가 단일 행만 포함하므로 함수 사용이 신뢰할 수 없다는 '하드 코딩된' 가정을 갖고 있는 것 같습니다.따라서 두 개 이상의 행을 합법적으로 포함하는 제약 조건이 필요한 경우(여기서 좋은 예는 동일한 엔터티에 대해 기간이 겹치는 것을 방지해야 하는 고전적인 '유효 시간' 시간 테이블의 순서화된 기본 키입니다.) 어떻게 할 수 있습니까? 트리거 없이 그런 일을 합니까?이는 데이터 무결성을 보장하는 기본 키이므로 DBMS가 아닌 다른 곳에서 이를 적용하는 것은 불가능합니다.CHECK 제약 조건이 하위 쿼리를 얻을 때까지는 특정 종류의 무결성 제약 조건에 대해 트리거를 사용하는 것의 대안이 보이지 않습니다.

트리거는 매우 도움이 될 수 있습니다.또한 매우 위험할 수도 있습니다.감사 데이터(작성자, 수정 날짜 등) 채우기와 같은 집안 정리 작업에 적합하며 일부 데이터베이스에서는 참조 무결성을 위해 사용될 수 있다고 생각합니다.

그러나 나는 여기에 많은 비즈니스 로직을 넣는 것을 별로 좋아하지 않습니다.이는 다음과 같은 이유로 지원에 문제를 일으킬 수 있습니다.

  • 연구할 추가 코드 계층입니다.
  • 때때로 OP가 배운 것처럼 데이터 수정을 수행해야 할 때 트리거는 데이터 변경이 문제를 해결하는 개발자나 DBA 또는 심지어 다른 사람이 아닌 항상 애플리케이션 지시어를 통해 이루어진다는 가정 하에 작업을 수행할 수 있습니다. 앱

무언가를 하기 위해 트리거를 우회해야 한다는 것은 당신이 뭔가 잘못하고 있다는 것을 의미할 수도 있고, 트리거가 뭔가 잘못하고 있다는 것을 의미할 수도 있습니다.

제가 트리거에 사용하고 싶은 일반적인 규칙은 트리거를 가능한 한 가볍고, 빠르고, 단순하고, 비침습적으로 유지하는 것입니다.

대량 데이터 가져오기를 수행할 때 트리거를 우회하는 경우가 있습니다.그런 상황에서는 그게 정당하다고 생각해요.

하지만 트리거를 매우 자주 우회하게 된다면 애초에 트리거를 어디에 두었는지 다시 한 번 살펴봐야 할 것입니다.

일반적으로 저는 "일부 시나리오에서는 목적을 달성합니다"에 투표하겠습니다.나는 성능에 미치는 영향에 대해 항상 긴장합니다.

저는 개인적으로 팬은 아닙니다.이를 사용하겠지만 작업을 트리거로 이동하여 제거할 수 있는 코드의 병목 현상을 발견한 경우에만 사용합니다.일반적으로 저는 단순함을 선호하며 일을 단순하게 유지하는 한 가지 방법은 논리를 한 곳에, 즉 애플리케이션에 유지하는 것입니다.나는 또한 접근이 매우 구획화되어 있는 직업에서 일한 적이 있습니다.이러한 환경에서는 더 많은 코드를 담을수록 가장 간단한 수정에도 더 많은 사람들이 참여해야 합니다.

저는 몇 주 전에 처음으로 트리거를 사용했습니다.프로덕션 서버를 SQL 2000에서 SQL 2005로 변경한 결과 드라이버가 NText 필드(대형 XML 문서 저장)와 다르게 동작하여 마지막 바이트가 삭제되는 것을 발견했습니다.데이터 끝에 여분의 더미 바이트(공백)를 추가하기 위한 임시 수정 사항으로 트리거를 사용하여 적절한 솔루션이 출시될 때까지 문제를 해결했습니다.

이 특별하고 임시적인 경우를 제외하고는 무슨 일이 일어나고 있는지 숨기기 때문에 피하고, 그들이 제공하는 기능은 숨겨진 마술이 아닌 개발자가 명시적으로 처리해야 한다고 말하고 싶습니다.

솔직히 유일성에 포함되지 않는 NULL을 가질 수 있는 고유 인덱스를 시뮬레이션하기 위해 트리거를 사용하는 유일한 경우입니다.

작업량을 줄이는 방법은 다음과 같습니다.데이터베이스는 외부 세계를 처리할 필요가 없을 때 놀라울 정도로 효율적입니다.프로세스 전환만으로도 성능이 얼마나 저하되는지 정말 놀라실 것입니다.이는 저장 프로시저의 또 다른 장점입니다.데이터베이스에 대한 수십 번의 호출(및 관련된 모든 왕복) 대신 하나가 있습니다.

이것은 약간 벗어난 주제이지만, 당신은 단지 하나의 잠재적인 긍정적 측면에서만 이것을 보고 있다는 것을 알아야 합니다.

하나의 저장된 프로세스에 여러 가지를 모아 두는 것은 괜찮습니다. 하지만 문제가 발생하면 어떻게 될까요?5개 단계가 있고 첫 번째 단계가 실패하면 다른 단계는 어떻게 되나요?해당 상황에 대처하려면 거기에 많은 논리를 추가해야 합니다.일단 그렇게 하기 시작하면 해당 시나리오에서 저장 프로시저의 이점을 잃게 됩니다.

총 팬,

하지만 이럴 때는 아껴서 사용해야 합니다.

  • 일관성을 유지해야 합니다(특히 차원 테이블이 웨어하우스에서 사용되고 팩트 테이블의 데이터를 적절한 차원과 연결해야 하는 경우).때로는 차원 테이블의 적절한 행을 계산하는 데 비용이 많이 들 수 있으므로 키를 팩트 테이블에 직접 기록하려고 합니다. "관계"를 유지하는 좋은 방법 중 하나는 트리거를 사용하는 것입니다.

  • 변경 사항을 기록해야 합니다. 예를 들어 감사 테이블에서 @@user가 변경한 내용과 변경 시기를 아는 것이 유용합니다.

SQL Server 2005와 같은 일부 RDBMS는 CREATE/ALTER/DROP 문에 대한 트리거도 제공합니다(따라서 누가 어떤 테이블을 생성했는지, 언제, 어떤 열을 삭제했는지 등을 알 수 있습니다).

솔직히 말해서, 이 세 가지 시나리오에서 트리거를 사용하면 왜 트리거를 "비활성화"해야 하는지 모르겠습니다.

일반적인 경험 법칙은 다음과 같습니다.트리거를 사용하지 마십시오.앞서 언급한 것처럼, 로직을 DB 계층 외부로 이동하면 쉽게 피할 수 있는 오버헤드와 복잡성이 추가됩니다.

또한 MS SQL Server에서는 트리거가 행당이 아닌 SQL 명령당 한 번 실행됩니다.예를 들어 다음 SQL 문은 트리거를 한 번만 실행합니다.

UPDATE tblUsers
SET Age = 11
WHERE State = 'NY'

나를 포함한 많은 사람들은 트리거가 모든 행에서 실행되는 것으로 생각했지만 사실은 그렇지 않았습니다.둘 이상의 행에서 데이터를 변경할 수 있는 위와 같은 SQL 문이 있는 경우 트리거의 영향을 받는 모든 레코드를 업데이트하기 위해 커서를 포함할 수 있습니다.이것이 어떻게 매우 빨리 복잡해질 수 있는지 알 수 있습니다.

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