2017-03-02 2 views
1

CQRS에 대한 실제 경험이 없으며 이것이이 질문의 기초입니다.CQRS 및 이벤트 소싱과 관계형 데이터베이스 디자인

배경 : 새로운 핵심 요구 사항이 관리자를 허용하고 어디는 시스템을 구축하고이 "재생"사용자 작업 (관리자가 특정 시점에 시스템에 일어난 모든 행동을 단계별로 할 수있게하려면) . 이것에 대한주의 사항은 회사가 이미 변경되지 않은 현재 SQL db로부터 생성 된 보고서를 가지고 있기 (적어도이 새로운 요구 사항과 병행하지 않음) 레코드 저장소가 SQL이 될 것입니다. SQL의 변경 데이터 캡처에 액세스 할 수 없으므로 트리거가있는 많은 기록 테이블을 만들면 유지 관리가 매우 어려워 지므로 가능한 경우이를 피하고 싶습니다. 마지막으로 SQL (변경/추가 필드 변경)을 변경하는 버전 관리주기를 거치는 잠재적 인 (현재는 아닙니다) 많은 데이터 진입 점이 있으므로 SQL에서 변경 내용 추적을 구현하려고하면 이전 버전의 데이터 (악몽)를 처리하는 테이블을 유지 관리해야합니다.

잠재적 인 솔루션 내가되는 NoSQL이 (푸른 DocumentDB)는 데이터 저장을 처리 (기록) 다음 명령 핸들러 관련 데이터와 현재의 SQL (푸른 SQL)을 업데이트 처리하도록 사용하는 방법에 대해 생각하고 조회 할 (읽기) . 그렇게하면 감사 추적이 생성되고 "재생"이라는 아이디어가 제공되는 현재 백엔드 기능을 방해하지 않으면 서 처리 될 수 있습니다.

이 접근법은 요구 사항을 처리하고주의 사항을 만족시킵니다. 나는이 "재생"기능이 필요한 부분만을 위해 전체 앱에 CQRS를 사용하지 않을 것입니다. 나는 Client를 따라 실패 점을 완화해야 함을 안다. -> DocumentDB에 쓰기 -> 성공/실패로 사용자 응답 -> 성공시 SQL에 쓰기 - DocumentDB 경로에 쓰기. 초보자 CQRS 눈은 이유를 볼 수 없다. 왜 이것이 이것을 처리하는 좋은 방법이 아닌지.

모든 조언을 주시면 감사하겠습니다.

+1

[변경 피드] (https://docs.microsoft.com/en-us/azure/documentdb/documentdb-change-feed)를 사용하여 변경 사항을 수신하고 SQL 데이터베이스에 적용 할 수 없습니까? –

+0

변경 피드는 정확히 내가 실제로 찾고있는 것 같습니다. Dogu의 대답은 내 문제를 해결할 아키텍처를보다 철저하게 다룬다 고 생각합니다. ChangeFeed를 "메시지 대기열"로 사용하고 해당 대기열을 모니터링하고 그에 따라 트랜잭션을 처리하는 작업자 역할을 사용합니다. – JakeHova

답변

0

생각해 볼 수있는 잠재적 인 방법 중 하나는 고유 한 ID가 있고 처리해야 할 작업을 나타내는 트랜잭션 개체를 만드는 것입니다. 이 경우 트랜잭션은 db를 문서화하거나 SQL db에 객체를 쓰는 객체를 작성합니다. 그것은 쓰여질 메모리 객체와 대상 db (doc db, sql 등) 연결 매개 변수를 포함 할 수 있습니다.

일단 거래를 정의하면 적절한 CQRS에 대한 작업 흐름을 조정해야합니다. 클라이언트가 doc db에 직접 작성하고이 호출의 결과를 기다리는 대신 클라이언트가 고유 한 ID (날짜 시간 틱 수 또는 증분 트랜잭션 ID와 같은 값일 수 있음)로 트랜잭션을 작성한 다음이 트랜잭션을 작성하게하십시오 하늘 대기열 또는 서비스 버스와 같은 메시지 대기열에 저장됩니다. 큐에 트랜잭션을 작성하면 그 시점에서 성공한 사용자가 리턴됩니다. 이 대기열에서 트랜잭션 메시지를 읽고 처리하여 작업자 역할을 작성하고, 객체를 doc db에 씁니다. 이는 doc db에서 동일한 엔티티를 겹쳐 쓰지 않고 해당 엔티티에 대한 고유 증분 ID가있는 트랜잭션을 doc db에 씁니다. 당신은 또한 그 afaik를 위해 하늘색 테이블 스토리지를 사용할 수 있습니다.

doc db 트랜잭션을 성공적으로 업데이트 한 후에는 동일한 작업자 역할이이 트랜잭션을 SQL db의 엔티티를 업데이트하는 고유 한 작업자 롤 세트에 의해 처리되는 다른 메시지 대기열에 기록 할 수 있습니다. 중간에 문제가 발생하면 오류 테이블을 유지하고 해당 오류 테이블의 오류를 쿼리하여 나중에 다시 시도하십시오.

+0

이것은 나에게 흥미 롭습니다. 내가 설명하는 아키텍처 레이아웃 (대기열 데이터 저장소를 피드) 좋아해. DocumentDB에 직접 쓰는 것 (언급 한 트랜잭션 객체로)과 트랜잭션 자체를 처리하기 위해 DocumentDB의 ChangeFeed 큐 (@Matias가 제안한 것)를 모니터링하는 것과는 대조적으로 DocumentDB에 작성하기 전에 메시지 대기열에 쓰는 이유가 있습니까? – JakeHova

+0

확실한 대기열은 작업자 역할별로 메시지 처리를 확장 할 수있는 선반 기능을 제공하며 메시지 가시성 등과 같은 기능을 통해 클라이언트 코드가 처리 할 필요가없는 메시지를 안전하게 처리 할 수 ​​있습니다. 물론 작업 단위 내에서 작업하는 경우에는 계산이 많지 않지만 데이터베이스에 엔티티를 작성하면 대기열에로드하는 이점이 미미하다고 말할 수 있습니다. –

0

이 기사에서는 CQRS pattern을 설명하고 CQRS 구현 예를 제공합니다.

NoSQL (Azure DocumentDB)을 사용하여 데이터 저장소 (쓰기)를 처리 한 다음 쿼리 처리 할 관련 데이터가있는 현재 SQL (Azure SQL)을 명령 처리기가 처리하도록 할 생각입니다.

사용자가 레코드를 업데이트하기 위해 작업을 작성하면 관리자 감사 사용자 작업 전에 항상 삽입 작업을 수행 할 수 있습니다. 예를 들어 사용자가 레코드를 업데이트하려는 경우 레코드를 직접 업데이트하지 않고 관리자가 현재 작업을 감사할지 여부를 나타내는 속성을 업데이트 엔티티에 삽입 할 수 있습니다. age 필드를 업데이트하는 문서

{ 
    "version1_data": { 
    "data": { 
     "id": "1", 
     "name": "jack", 
     "age": 28 
    }, 
    "isaudit": true 
    } 
} 

에서

원본 데이터, 우리는 대신 직접 원본 데이터를 업데이트의 업데이트 된 정보와 개체를 삽입 할 수 있습니다.

{ 
    "version1_data": { 
    "data": { 
     "id": "1", 
     "name": "jack", 
     "age": 28 
    }, 
    "isaudit": true 
    }, 
    "version2_data": { 
    "data": { 
     "id": "1", 
     "name": "jack", 
     "age": 29 
    }, 
    "isaudit": false 
    } 
} 

그런 다음 관리자가 현재 문서를 검사하여 사용자 작업을 감사하고 업데이트가 SQL 데이터베이스에 쓸 수 있는지 확인할 수 있습니다.

관련 문제