문제

나는 최근에 엄청난 "Enterprisey"응용 프로그램으로 회사에서 일하기 시작했습니다. 마지막으로 데이터베이스를 설계했지만 여기에는 전체 데이터베이스 아키텍처 부서가 있습니다.

데이터베이스의 낯선 것 중 하나는 사용자가보고 싶은 날짜 범위를 제공하는 대신 시작 및 종료 날짜와 함께 (글로벌 임시) 테이블 "TMP_PARM_RANG"과 가입하는 많은 견해가 있다는 것입니다. 기본 앱이 요청을 처리하기 시작할 때마다 첫 번째 일은 가장 먼저해야합니다. "DELETE FROM TMP_PARM_RANG; "그런 다음 삽입.

이것은 기괴한 일을하는 방식처럼 보이고 안전하지는 않지만 다른 사람들은 모두 괜찮아 보입니다. 이것은 정상입니까, 아니면 내 불안감이 유효합니까?

업데이트 나는 그들이 트랜잭션과 클라이언트 당 자물쇠를 사용한다고 언급해야하므로 대부분의 동시성 문제로부터 보호됩니다. 또한, 수백 가지의 견해가 아니라면 말 그대로 수십 명이 있습니다. TMP_PARM_RANG.

도움이 되었습니까?

해결책

이것을 올바르게 이해합니까?

다음과 같은 견해가 있습니다.

SELECT * FROM some_table, tmp_parm_rang
  WHERE some_table.date_column BETWEEN tmp_parm_rang.start_date AND tmp_parm_rang.end_date;

그런 다음 일부 프론트 엔드에서 사용자는 날짜 범위를 입력하고 응용 프로그램은 다음을 수행합니다.

  1. TMP_PARM_RANG에서 기존 행을 모두 삭제합니다
  2. 사용자의 값으로 TMP_PARM_RANG에 새 행을 삽입합니다.
  3. 보기에서 모든 행을 선택합니다

TMP_PARM_RANG의 변경 사항이 커밋되었거나 롤백되는지 궁금합니다. 그렇다면 언제입니까? 임시 테이블입니까 아니면 일반 테이블입니까? 기본적으로 이러한 질문에 대한 답변에 따라 여러 사용자가 병렬로 실행할 수있는 프로세스가 안전하지 않을 수 있습니다. 이 경우에 이미 그것을 발견하고 해결했을 것이라는 희망이지만 누가 알 수 있습니까?

스레드 안전 방식으로 수행 되더라도 간단한 쿼리 작업을 위해 데이터베이스를 변경하는 것은 많은 의미가 없습니다. 이러한 삭제 및 인서트는 완전히 불필요한 REDO/UNDO (또는 동등한 것이 아닌 데이터베이스에있는 것)를 생성합니다.

동일한 목표를 달성하는 간단하고 일반적인 방법은이 쿼리를 실행하여 사용자의 입력을 쿼리 매개 변수에 바인딩하는 것입니다.

SELECT * FROM some_table WHERE some_table.date_column BETWEEN ? AND ?;

다른 팁

데이터베이스가 Oracle 인 경우 글로벌 임시 테이블 일 수 있습니다. 모든 세션에서는 자체 버전의 테이블을보고 삽입/삭제는 다른 사용자에게 영향을 미치지 않습니다.

이 테이블에 대한 비즈니스 이유가 있어야합니다. 나는 실제로 파벌이있는 견해였던 날짜 하드 코드가있는 견해를 보았고 날짜를 파티 닝 필드로 사용하고있었습니다. 나는 또한 일광 절약 시간을 다룰 때와 같은 테이블에 참여하는 것을 보았습니다. 그리고이 것들 중 어느 것도 삭제하고 테이블에 삽입하지 않을 것입니다 ... 그건 홀수입니다.

따라서 파견해야 할 더 깊은 이유가 있거나 당시에는 좋은 생각처럼 보였지만 왜 그런 식으로 그렇게 한 이유는 부족의 지식으로 사라졌습니다.

개인적으로, 나는 그것이 꽤 이상한 일이 될 것이라고 생각합니다. 그리고 과정을 동시에 호출하는 두 가지 방법은 매우 흥미로울 수 있습니다.

일반적으로 날짜 범위는보기에서 필터로 수행되며 다른 테이블에 저장된 외부 값으로 구동되지 않습니다.

내가 볼 수있는 유일한 정당화는 다단계 프로세스가있는 경우 한 번에 한 번만 실행되었으며 여러 저장 절차에서 여러 작업에 날짜가 필요합니다.

나는 그것이 여러 범위를 지원할 수 있다고 생각합니다. 예를 들어, 2008 년 1 월 1 일과 1/1/2009와 2006 년 1 월 1 일과 1/1/2007 사이의 모든 날짜를 반환하여 2006 데이터를 2008 데이터와 비교할 수 있습니다. 하나의 바운드 매개 변수로 그렇게 할 수 없었습니다. 또한 Oracle이 어떻게 쿼리 플랜 캐시를 보는지 모르겠지만 아마도 그것과 관련이 있습니까? 날짜 열이보기의 일부로 확인되면 서버는 항상 날짜를 확인할 수있는 계획을 캐시 할 수 있습니다.

여기에 약간의 추측을 버리고 있습니다 :)

또한, 당신은 다음을 썼습니다.

나는 그들이 트랜잭션과 클라이언트 당 자물쇠를 사용한다고 언급해야하므로 대부분의 동시성 문제로부터 보호됩니다.

동시성으로 인한 데이터 일관성 문제를 방지 할 수 있지만 동시성으로 인한 성능 문제와 관련하여 아프다.

또한 기본 키의 다음 고유 값을 생성하기 위해 응용 프로그램에 하나를 추가합니까?

공유 된 국가의 개념은이 사람들을 피하거나 공유 된 국가의 이유가 우리를 피하는 것으로 보인다.

그것은 나에게 꽤 이상한 알고리즘처럼 들립니다. 동시성을 어떻게 처리하는지 궁금합니다. 거래에 싸여 있습니까?

누군가가 Where 절을 작성하는 방법을 확신하지 못한 것처럼 들립니다.

보기는 아마도 임시 테이블로 사용됩니다. SQL Server에서는이 목적으로 테이블 변수 또는 임시 테이블 (# / ##)을 사용할 수 있습니다. 전문가가보기를 권장하지는 않지만, 작업중인 테이블이 서로를 참조하지 않기 때문에 SSRS 프로젝트를 위해 많은 것을 만들었습니다 (FK가 없어도). 데이터베이스 디자인에서 결함이 있어야합니다. 그래서 뷰를 많이 사용하는 이유입니다.

여기에서 의견을 사용하는 글로벌 임시 테이블 GTT 접근 방식을 사용하면 다중 사용자 시스템과 관련 하여이 방법이 확실히 안전하므로 문제가 없습니다. 이것이 Oracle이라면 시스템이 적절한 수준의 동적 샘플링을 사용하여 GTT가 적절하게 결합되거나 GTT에 대한 통계를 공급하기 위해 DBMS_STATS에 대한 호출이 이루어집니다.

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