하나. 개념
네트워크 환경에서 데이터베이스 응용 프로그램은 C/S 또는 다층 구조 패턴입니다. 이 환경에서 데이터베이스 응용 프로그램의 개발은 가능한 한 많은 네트워크 데이터 전송량을 줄이고 가능한 한 동시성을 향상시키는 것을 고려해야합니다. 이러한 목적에 따라 캐시 된 데이터 업데이트 기술은 다음과 같습니다. 응용 프로그램은 데이터베이스에서 클라이언트 버퍼로 데이터를 추출하고 새 데이터를 완료합니다 작업이 완료되고 데이터는 적절한 시간에 한 번에 데이터베이스에 제출되어 네트워크 트래픽을 크게 줄이고 데이터베이스 서버의로드를 줄이며 동시성 성능을 향상시킵니다.
이것은 매우 새로운 기술이 아니라고 말해야합니다.이 기술은 Delphi와 같은 이전 버전의 데이터베이스 프론트 엔드 개발 도구에서 지원되었습니다. 그러나 저자는 일부 프로그래머 가이 기술의 합리적 사용에주의를 기울이지 않고 여전히 독립형 응용 프로그램에 대한 아이디어를 유지하여 컴파일 된 프로그램에서 비 효율성 또는 잠재적 오류를 초래한다는 것을 발견했습니다. 따라서이 기술의 적용의 장점, 원칙 및 방법을 요약해야합니다 (델파이를 예로 들어).
둘. 장단점
캐시가있는 데이터 업데이트 기술에는 다음과 같은 장점이 있습니다.
(1) 네트워크 트래픽을 최소화하고 데이터 액세스 시간을 줄입니다. 클라이언트 데이터베이스 운영자의 효율성을 향상시킵니다.
(2) 많은 반복 업데이트, 수정 및 삭제 작업이 클라이언트 버퍼에서 완료 될 수 있고 결과는 결국 서버에만 제출되므로 데이터베이스 서버의 부담을 줄입니다.
(3) 거래 처리 시간을 효과적으로 줄이고 동시 거래의 처리량을 줄입니다. 이것은 데이터베이스의 일관성을 더 잘 보장 할 수 있습니다.
데이터베이스 연산자는 데이터베이스에 데이터 레코드를 데이터베이스에 삽입하지만 레코드가 요구 사항을 충족시키지 못한다는 것을 즉시 발견하므로 데이터를 삭제합니다. 이 프로세스에서 버퍼가없는 데이터 업데이트 기술이 사용되는 경우 서버 측은 하나의 삽입 작업과 하나의 삭제 작업을 수행하고 클라이언트 및 서버 측에서 2 개의 왕복 데이터 전송을 수행하고 그러한 데이터가 사용하는 데 사용되는 경우 다른 데이터베이스 테이블. 계단식 관계가 있으며 계단식 업데이트, 삭제, 복구 및 기타 데이터 작업도 고려해야합니다. 데이터 업데이트 방법이 캐시와 함께 채택되면,이 두 단계의 역 작업은 서버 측에 대한 작업없이 클라이언트의 데이터 버퍼에서 완료 될 수 있으며, 네트워크 데이터 전송 및 캐스케이드 업데이트는 작동하지 않습니다. 이것은 완충 데이터 업데이트 기술의 큰 장점을 보여줍니다.
캐시와의 데이터 업데이트의 한 가지 단점은 데이터가 클라이언트에 저장되므로 다른 사용자가 데이터를 변경하면 동시성 제어 및 수정과 같은 일관되지 않은 상황을 일으킨다는 것입니다. 데이터의 불일치가 발생할 수 있습니다. 이 기술을 적용하려면 특정 기술과 특정 사고 변화가 필요합니다.
삼. 응용 프로그램 원칙
모든 기술의 장점은 특정 환경에 반영됩니다.
(1) C/S 또는 다층 데이터베이스 응용 프로그램 경우. 이 경우 네트워크 트래픽을 효과적으로 줄일 수 있습니다. 독립형 상황 에서이 기술은 의미가 없습니다.
(2) 여러 테이블의 데이터 업데이트의 경우. 예를 들어, 메인 테이블/세부 구조의 업데이트에서 두 테이블의 추가 및 삭제는 종종 두 테이블의 모든 업데이트를 완료 한 후에는 완료 된 업데이트 작업을 제출하도록 정의 할 수 있습니다. 이렇게하면 거래 시간이 효과적으로 단축되고 데이터 일관성이 향상됩니다.
(3) 서버로드 용량이 제한된 경우. 오늘날 PC 속도가 증가하고 가격이 감소함에 따라 클라이언트 및 서버의 기능 차이가 점점 작아지고 서버의 서비스 기능이 상대적으로 줄어 듭니다. 객관적으로, 소프트웨어 관점에서 서버의 부담을 줄여야하는 반면, 버퍼링 된 데이터 업데이트는 클라이언트의 업데이트 작업의 일부를 공유하여 서버의 부담을 줄입니다.
(4) 데이터가 동시에 업데이트 될 확률이 상대적으로 낮은 경우. 같은 기간에 여러 사용자가 데이터베이스의 동일한 데이터를 업데이트 할 가능성이있는 경우,이 상황은 캐시 된 업데이트에 적합하지 않습니다.이 경우 데이터의 오류 덮어 쓰기가 쉽게 생성되어 데이터가 불일치되기 때문에 데이터의 오류가 발생합니다.
네. 델파이의 제어 방법에 대한 개요
인기있는 데이터베이스 개발 도구로서 Delphi에는 풍부한 데이터베이스 조작 기능이 있습니다. Delphi는 완충 데이터 액세스 기술에 대한 포괄적 인 지원을 제공합니다. 일반적으로 Delphi는 TTABLE 및 TQUERY와 같은 데이터베이스 테이블에 액세스하기위한 여러 데이터 세트 컨트롤을 제공합니다. Delphi는 데이터 세트의 속성 컨트롤에 CachedUpdate 옵션이 완비 된 양식으로 데이터 세트에 액세스 할 것을 약속합니다. 즉, 데이터 세트에 대한 업데이트 작업은 데이터베이스 서버에 즉시 반영되지 않습니다. Delphi는 실제 제출 된 메소드 (예 : ApplyUpDates) 등을 호출 할 때만 데이터베이스에 대한 데이터 세트는 updateEcord () 메소드를 사용하여 필요를 정의하는 데 사용됩니다. 데이터베이스 테이블이 실제로 업데이트 될 때 업데이트됩니다 (예 : 계단식 삭제 등). 이것은 우리가 데이터 제출 단계를 직접 제어 할 수있는 편의를 제공하면 프로그래밍이 더 어려워 지지만 어떤 경우에는 유연성이 필요합니다. 또한이 모델을 통해 트랜잭션 길이를 크게 줄이고 네트워크 트래픽을 줄이며 응용 프로그램의 신뢰성을 높입니다. 아래에서는이 프로그래밍 모델을 사용하는 방법을 설명하기 위해 특정 응용 프로그램 모듈을 제공합니다.
다섯. 델파이 프로그램 예
(1) 응용 프로그램 배경 설명
제품 주문 처리를위한 모듈을 만든다고 가정합니다. 이 모듈에는 세 가지 데이터베이스 테이블이 포함됩니다. 주문 테이블 주문 (주문 ID, 금액 Summoney, 날짜 날짜, 고객 이름 Costomer 등과 같은 필드 포함), 주문 세부 사항 (주문 세부 ID, 주문 ID 및 제품 번호 commondityId), 주문 세부 사항 (주문 ID, 주문 ID 및 제품 번호 CommondityId, 수량 금액, 단가 가격 및 기타 필드), 재고 테이블 스토리지 (제품 번호 CommondityId, 기존 주식 및 기타 필드 포함). 그중에서도 주문 및 주문 목록은 일대일 관계이며 주문 번호 OrderID는 연결 필드입니다. 주문이 추가 될 때마다 인벤토리 테이블을 수정하고 판매 된 상품의 수량이 재고에서 빼야합니다.
(2) 프로그램 프레임 워크 설명
다음은 델파이 프로그램의 프레임 워크로, 캐시 업데이트의 프로그래밍 모드를 사용하는 방법을 대략 설명합니다. 독자들은이 프로그램의 기능을 스스로 향상시킬 수 있습니다.
단위 순서;
{단위 이름}
인터페이스
용도
{참조 모듈}
창, 메시지, 시스템, 변형, 클래스, 그래픽, 컨트롤, 양식,
대화, 그리드, dbgrids, extctrls, dbctrls, Toolwin, Actnman, Actnctrls,
Actnmenus, db, dbtables;
유형
{선언 된 변수, 추가 제어 및 정의 된 방법 및 절차}}
torderform = class (tform)
tborder : ttable;
tbdetail : ttable;
Orderdb : tdatabase;
ActionMainMenubar1 : TactionMainMenubar;
dbnavigator1 : tdbnavigator;
DBGRID1 : TDBGRID;
절차 tborderafterpost (데이터 세트 : tdataset);
절차 tbdetailNewRecord (데이터 세트 : tdataset);
절차 tbdetailupdaterecord (데이터 세트 : tdataset;
updatekind : tupdatekind;
절차 tbdetailAfterpost (dataSet : tdataset);
프로 시저 Formcreate (sender : tobject);
사적인
{개인 선언}
공공의
{공개 선언}
끝;
var
Orderform : Torderform;
구현
{$ r *.dfm}
{다음은 주요 프로그램 프레임 워크입니다}
프로 시저 TORDERFORM.FORMCREATE (Sender : Tobject);
{메인 테이블 및 세부 테이블의 캐시 업데이트 옵션 설정}}
시작하다
tborder.CachedUpdates : = true;
tbdetail.cachedupdates : = true;
끝;
프로 시저 TORDERFORM.TBORDERAFTERPOST (데이터 세트 : TDATASET);
{주문 테이블의 업데이트를 제출 한 후이 프로세스의 내용을 실행하면 실제 제출 된 트랜잭션이 메인 테이블과 자세한 테이블을 구현합니다.
참고 : 데이터 세트의 CachedUpdates 속성이 사실 인 경우
그런 다음 사후 조치는 클라이언트 버퍼의 커밋 조치 일뿐입니다.
실제로 실제 데이터베이스에 제출하는 대신. 진정한 커밋을 달성하기 위해
ApplyUpdates 문이 필요합니다. }
시작하다
orderdb.startTransaction; // 업데이트 트랜잭션이 실행을 시작합니다
노력하다
tborder.ApplyUpdates; // 메인 테이블에 대한 실제 업데이트하십시오
tbdetail.applyUpdates; // 세부 목록에 대한 실제 업데이트
제외하고
Orderdb.rollback; // 사고가 발생하면 거래를 롤백하고 프로세스를 종료하십시오.
출구;
끝;
Orderdb.commit; // 사고가 발생하지 않으면 거래 커밋을 완료하십시오
tborder.commitupdates; // tborder 테이블의 클라이언트 버퍼를 지우십시오
tbdetail.commitupdates; // tbdetail 테이블의 클라이언트 버퍼를 지우십시오
끝;
프로 시저 torderform.tbdetailNewRecord (데이터 세트 : tdataset);
{자세한 목록이 추가되면 완료된 작업. }
시작하다
tbdetail.fieldByName ( 'OrderId'). Asinteger : = tborder.fieldByName ( 'OrderId'). Asinteger;
파일 : // 메인 테이블의 OrderId 필드를 세부 테이블의 OrderId 필드에 할당합니다.
끝;
프로 시저 torderform.tbdetailupdaterecord (데이터 세트 : tdataset;
updatekind : tupdatekind;
{데이터베이스 테이블이 실제로 업데이트되면 동시에 수행 해야하는 작업은 OnupDatereCord 이벤트에서 정의됩니다.
이 경우 세부 목록 및 인벤토리 테이블의 계단식 업데이트 작업이 수행됩니다.
주의 :이 프로세스에서 수행되는 작업은 데이터베이스가 실제로 업데이트 될 때 수행되는 작업입니다.
클라이언트의 캐시 데이터를 업데이트 할 때 수행되는 작업 대신}
var temp_query : tquery;
시작하다
updateKind = ukInsert 인 경우 파일 : // 업데이트 유형이 새 레코드를 삽입하는 경우 해당 인벤토리 금액을 업데이트하십시오.
temp_query와 함께
시작하다
닫다;
sql.clear;
sql.add ( '업데이트 스토리지 세트 주식 = 주식-: 금액');
sql.add ( 'commondityid = : commondityid');
parambyName ( 'aUND') : = tBORDER.FIELDBYNAME ( 'aUND'). ASFLOAT;
ParambyName ( 'commondityId') : = tbdetai.fieldByName ( 'commondityId'). Asinteger;
execsql; 파일 : // SQL 문을 실행하여 인벤토리를 업데이트하고 해당 재고 금액을 빼십시오.
끝;
끝;
프로 시저 torderform.tbdetailafterpost (데이터 세트 : tdataset);
{자세한 표에서 레코드를 수정하고 (게시) 제출 한 후이 과정에서 진술을 실행하십시오.
주의 : 이러한 종류의 제출은 클라이언트 데이터를 대상으로하며 실제로 데이터베이스에 반영되지 않습니다.
이 예에서 구현 된 기능은 주 테이블의 총 금액 필드를 계산하는 것입니다.
시작하다
tborder.fieldByName ( 'Money') : = 0;
tbdetail과 함께
시작하다
첫 번째;
EOF는 아닙니다
시작하다
tborder.fieldByName ( 'Money') : = tborder.fieldByName ( 'Money')+
FieldByName ( 'price'). Asfloat*FieldByName ( 'aMber');
파일 : // 상세 테이블의 양을 메인 테이블의 금액 필드로 축적합니다.
다음;
끝;
끝;
끝;
끝.