1つ。 コンセプト
ネットワーク環境では、データベースアプリケーションはC/Sまたは多層構造パターンです。この環境では、データベースアプリケーションの開発では、ネットワークデータ送信の量を可能な限り削減し、並行性を可能な限り改善することを検討する必要があります。この目的に基づいて、一般的なプロセスは次のとおりです操作が完了し、データは適切な時間に一度にデータベースに送信されます。これにより、ネットワークトラフィックが大幅に減少し、データベースサーバーの負荷が削減され、並行性パフォーマンスが向上します。
これは非常に新しいテクノロジーではないと言われています。しかし、著者は、一部のプログラマーがこのテクノロジーの合理的な使用に注意を払わず、まだスタンドアロンアプリケーションのアイデアの下にとどまることを発見し、コンパイルされたプログラムの非効率性または潜在的なエラーをもたらします。したがって、このテクノロジーの適用の利点、原則、および方法を要約する必要があります(Delphiを例にとる)。
二。 長所と短所
キャッシュ付きのデータ更新テクノロジーには、次の利点があります。
(1)ネットワークトラフィックを最小限に抑え、データアクセス時間を短縮します。クライアントデータベースオペレーターの効率を向上させます。
(2)多くの繰り返し更新、変更、および削除操作をクライアントのバッファーで完了し、結果は最終的にサーバーにのみ送信されるため、データベースサーバーの負担を軽減します。
(3)トランザクション処理時間を効果的に短縮し、同時トランザクションのスループットを削減します。これにより、データベースの一貫性をより適切に保証できます。
その優位性を説明するための例を挙げることができます。データベースオペレーターはデータレコードをデータベースに挿入しますが、すぐにレコードが要件を満たしていないことがわかりますので、データを削除します。このプロセスでは、バッファーのないデータを更新するテクノロジーを使用する場合、サーバー側は1つの挿入操作と1つの削除操作を実行し、クライアントとサーバー側で2つの往復データ送信を実行し、そのようなデータがと一緒にあるために使用される場合他のデータベーステーブル。データの更新方法がキャッシュで採用されている場合、逆操作のこれらの2つのステップを、サーバー側にアクションなしでクライアントのデータバッファーで完了することができ、ネットワークデータの送信は生成されません。これは、バッファリングされたデータ更新テクノロジーの大きな利点を示しています。
キャッシュによるデータの更新の1つの欠点は、データがクライアントに保存されているため、データが他のユーザーによって変更された場合、損失や変更などの一貫性のない状況を引き起こすことです。データの変数を完全に考慮します。このテクノロジーの適用には、特定のスキルと特定の思考の変更が必要です。
三つ。 アプリケーションの原則
あらゆる技術の利点は、特定の環境に反映されています。
(1)C/sまたは多層データベースアプリケーションの機会。この場合、ネットワークトラフィックを効果的に削減できます。スタンドアロンの状況では、このテクノロジーは意味がありません。
(2)複数のテーブルのデータ更新の場合。たとえば、メインテーブル/詳細構造の更新では、2つのテーブルの追加と削除が互いに影響を与えた後、2つのテーブルのすべての更新を完了した後、トランザクションを定義して、完了した更新操作を送信できます。これにより、トランザクション時間が効果的に短縮され、データの一貫性が確保されます。
(3)サーバーの負荷容量が制限されている場合。現在、PCの速度の上昇と価格の低下により、クライアントとサーバーの機能の違いはますます小さくなり、サーバーのサービス機能は比較的減少しています。客観的には、ソフトウェアの観点からサーバーの負担を減らす必要がありますが、バッファリングされたデータの更新は、クライアントが更新タスクの一部を共有することにより、サーバーの負担を軽減します。
(4)データが同時に更新される可能性が比較的低い場合。データベース内の同じデータが同じ期間に複数のユーザーによって更新される可能性が高い場合、この状況はキャッシュされた更新には適していません。この場合、データのエラー上書きが簡単に生成され、データが矛盾するからです。
4。 Delphiの制御方法の概要
人気のあるデータベース開発ツールとして、Delphiには豊富なデータベース操作機能があります。 Delphiは、バッファリングされたデータアクセステクノロジーを包括的にサポートしています。一般に、Delphiは、TTABLEやTQueryなどのデータベーステーブルにアクセスするためのいくつかのデータセットコントロールを提供します。データセットのプロパティコントロールには、このアイテムをTrueに設定することを約束します。 、実際の提出されたメソッド(ApplyUpdates()など)が呼び出された場合にのみ、Delphiは実際の提出データを同時に反映しています。データベーステーブルが実際に更新されたときに更新されます(カスケード削除など)。これにより、データの提出の手順を自分で制御するための利便性があります。さらに、このモデルを通じて、トランザクションの長さを大幅に削減し、ネットワークトラフィックを削減し、アプリケーションの信頼性を高めます。以下に、このプログラミングモデルの使用方法を示す特定のアプリケーションモジュールを示します。
五。 Delphiプログラムの例
(1)アプリケーションの背景説明
製品注文処理のモジュールを作成しているとします。このモジュールには、3つのデータベーステーブルが含まれます。注文テーブルオーダー(注文ID、summoney、日付、顧客名コスマーなどのフィールドを使用)、注文詳細(注文詳細ID、注文ID、および製品番号CommondityID)、注文詳細(注文ID、注文ID、および製品番号COMMONDITYID、数量、単価、その他のフィールドなど)、在庫テーブルストレージ(製品番号CommondityID、既存の在庫、その他のフィールドを含む)。その中でも、注文リストと注文リストは1対多くの関係であり、注文番号は接続フィールドとして順序付けされています。注文が追加されるたびに、在庫テーブルを変更する必要があり、販売される対応する商品の量がインベントリから差し引かれます。
(2)プログラムフレームワークの説明
以下は、Delphiプログラムのフレームワークであり、キャッシュ更新のプログラミングモードを使用する方法を大まかに説明しています。読者は、このプログラムの機能を自分でさらに改善できます。
ユニットオーダー;
{ユニット名}
インタフェース
用途
{参照モジュール}
窓、メッセージ、sysutils、バリアント、クラス、グラフィック、コントロール、フォーム、
ダイアログ、グリッド、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(データセット:tdataset);
手順formcreate(sender:tobject);
プライベート
{プライベート宣言}
公共
{公開宣言}
終わり;
var
OrderForm:TORDERFORM;
実装
{$ r *.dfm}
{以下はメインプログラムフレームワークです}
手順TORDERFORM.FORMCREATE(SENDER:TOBJECT);
{メインテーブルのキャッシュ更新オプションと詳細なテーブルをTrueに設定}
始める
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の場合、file:// updateタイプが新しいレコードを挿入する場合は、対応するインベントリ額を更新します
temp_queryを使用してください
始める
近い;
sql.clear;
sql.Add( 'ストレージSET stocks = stocks-:humbor');
sql.add( 'commondityId =:commondityId');
parambyname( 'lument'):= tborder.fieldbyname( 'lument')。asfloat;
parambyname( 'commondityid'):= tbdetai.fieldbyname( 'commondityid')。asinteger;
execsql;ファイル:// inventoryを更新し、対応するインベントリ額を減算します。
終わり;
終わり;
手順TORDERFORM.TBDETAILAFTERPOST(データセット:TDATASET);
{詳細な表のレコードを変更して送信(投稿)した後、このプロセスでステートメントを実行します。
注意:この種の提出は、クライアントデータを対象としており、データベースに実際に反映されていません。
この例では、実装された関数は、メインテーブルの総量フィールドを計算することです}
始める
tborder.fieldbyname( 'money'):= 0;
tbdetailで
始める
初め;
EOFではありませんが
始める
tborder.fieldbyname( 'money'):= tborder.fieldbyname( 'money')+
fieldbyname( 'price')。asfloat*fieldbyname( 'lument');
file://メインテーブルの金額フィールドに詳細なテーブルの量を蓄積します
次;
終わり;
終わり;
終わり;
終わり。