0

2 つのまったく同じ構造のライブ データベースから取得したデータを含む読み取り専用データベースをすばやく実装する必要があります。

ライブ データベースは、実際には Dynamics 会計システムの企業データベースであるため、Dynamics 固有のアドバイスがあれば幸いですが、これは主に SQL に関する質問です。Great Plains が Microsoft に買収される前のかなり古いバージョンの Dynamics です。これは SQL Server 2000 上にあります。

Dynamics データにアクセスするレポートとアプリケーションがあります。これらのアプリは、1 つの会社のデータベースを参照するように設計されています。次に、別のものを追加する必要があります。これらのレポートとアプリのほとんどが結合されたデータを表示することは適切です。注文や請求書がどの会社に存在するかはあまり気にしません。少数のテーブルだけを見ます。

最も簡単な解決策は、結合されたデータを含むレポートのみのデータベースを作成することです。できれば、このデータベースを 1 日に数回変更して効率的に更新する方法が必要です。

私は開発者であり、データベースの専門家ではありませんが、私の計画は次のとおりです。

最初にライブ データベースと同じテーブル構造を持つ、必要なテーブルを含む結合レポート データベースを作成します。

すべての Dynamics テーブルには、DEX_ROW_ID と呼ばれる int ID 列があるようです。何に使用されるのかはわかりませんが(インデックスは作成されていません)、行を一意に識別するための明らかな一般的な方法のようです。レポート データベースでは、通常の int (ID ではありません) に変更します。すべてのデータベースの DEX_ROW_ID に一意のインデックスを作成します。

Dynamics にはタイムスタンプがないため、タイムスタンプ列をライブ データベースのテーブルに追加し、対応するバイナリ (8) 列をレポート データベースに追加します。私は、Dynamics が追加のインデックスと列によって動揺しないことを想定し、望んでいます。

int CompanyId 列をレポート データベース テーブルに追加し、一意のインデックスの末尾に追加します。それがなくても、ほとんどのデータは自然に一意になります。つまり、注文番号や請求書番号などは、2 つのライブ データベースで異なります。アプリケーションに若干の変更を加える必要があるかもしれませんが、新しいレポート データベースを指定する以外に多くのことを行う予定はありません。

レポート データベースが Reports と呼ばれ、ライブ データベースが Live1 と Live2 で、タイムスタンプ列が TS で、すべてのデータベースが同じサーバー上にあると仮定すると、MyTable と呼ばれる 1 つのテーブルの変更をコピーするための更新スクリプトを初めて試みます。 Live1 でレポート データベースに送信します。

USE Reports

CREATE TABLE #Changes
(
ReportId int,
LiveId int
)

/* Collect in a temp table the ids or rows which have been deleted or changed
in the live db L.DEX_ROW_ID will be null if the row has been deleted */

INSERT INTO #Changes
SELECT R.DEX_ROW_ID, L.DEX_ROW_ID
FROM MyTable R LEFT OUTER JOIN Live1.dbo.MyTable L ON L.DEX_ROW_ID = R.DEX_ROW_ID
WHERE R.CompanyId = 1 AND L.DEX_ROW_ID IS NULL OR L.TS <> R.TS

/* Delete rows that have been deleted or changed on the live db 
I wonder if using join syntax would run better than the subquery. */
DELETE FROM MyTable
WHERE CompanyId = 1 AND DEX_ROW_ID IN (SELECT ReportId FROM #Changes)

/* Recopy rows that have changed in the live db */
INSERT INTO MyTable
SELECT 1 AS CompanyId, * FROM Live1.dbo.MyTable L
WHERE L.DEX_ROW_ID IN (SELECT ReportId FROM #Changes WHERE LiveId IS NOT NULL)

/* Copy the rows that are new in the live db */
INSERT INTO MyTable
SELECT 1 AS CompanyId, * FROM Live1.dbo.MyTable
WHERE DEX_ROW_ID > (SELECT MAX(DEX_ROW_ID) FROM MyTable WHERE CompanyId = 1)

次に、Live2 db についても同じことを行います。レポートのすべてのテーブルに対して繰り返します。リテラルの代わりにパラメーター @CompanyId を使用する必要があることはわかっていますが、C# プログラムなどでこれらを動的に生成する可能性のあるライブ データベース名に対してはそれを行うことができません。

ここで行っていることについて、アドバイス、提案、または批評を探しています。私はそれがアトミックではないことを知っています。このスクリプトの実行中に、ライブ データベースで何かが発生する可能性があります。私たちはそれと一緒に暮らすことができると思います。稼働中のデータベースで何も起きていないときは、おそらく毎晩または毎週のいずれかで完全なコピーを作成します。

エレガンスや完璧さよりもパフォーマンスを優先する必要があります。一部の初期テストでは、最大のテーブルに対して約 30 秒で実行される TS 比較の最初のクエリが含まれているため、これが機能することを楽観視していますが、明らかな何かが欠けているかどうか、または表示されていないかどうかも知りたいです。木のための森。

レポート データベースのログ ファイルを扱いたくありません。これを単純な復旧モデルに設定して、ログを忘れることはできますか?

ありがとう

4

2 に答える 2

1

ここには未解決の問題がいくつかあると思います。

  1. これらのレポートをほぼリアルタイムにする必要がありますか? それとも、これは毎日の更新に対応できるこの種のレポートですか? ただし、最新のデータが必要だとします。

  2. データベースに直接クエリを実行し、その場でレポートごとにデータをマージすることを検討しましたか? リアルタイムのマージされたレプリケート データベースの設計、作成、およびサポートに費やされる労力を再現するには、多くのレポートを作成する必要があります。

  3. 本番データベースに対する単一のクエリでは、30 秒は (IMHO) 受け入れられません。これほど時間がかかるチューニング関連の理由はいくつも考えられますが、少なくとも、本格的な SQL Server 最適化のプロフェッショナルなリソース (人) が必要になることを意味します。また、これがレポートのクエリの問題である場合、クエリがレポート用に別のデータベースを維持することは良い兆候ではありません。

  4. 単一のデータベースに統合する必要がある場合は、それをミラーではなく OLAP データベースにするかどうかを検討する価値があるということを頭の片隅に置いておいてください。ミラーはより迅速かつ簡単になりますが、OLAP は長期的にははるかに柔軟で強力になります。最初から最後まで行ったほうがいいかもしれません。

于 2009-05-10T19:28:36.803 に答える
0

私がしたい最後のことは、カスタム更新スクリプトを書くことです。最初に次の防弾方法を試してください。

  1. 本番データベースがバックアップされることを期待しましょう。これらのバックアップを毎晩レポートサーバーに復元します。RESTOREコマンドを使用して復元を自動化できます。このコマンドは、ネットワークサーバー上のファイルを処理します。
  2. SQL Serverレプリケーションを使用して、ライブサーバーからバックエンドにデータをプッシュします。
  3. DTSパッケージを毎晩スケジュールして、本番データベース全体をインポートします。

これはブルートフォースのように見えるかもしれません。しかし、2000年代のデータベースをコピーしているので、今日のハードウェアではブルートフォースが問題になることはありません。追加の利点として、これらのメソッドは、開発者ではなくシステム管理者がサポートできます。

方法1には、バックアップ検証として機能するという追加の利点があります。:)

于 2009-05-10T19:14:28.107 に答える