7

レポート用に SQL Server 2008 で新しいデータベースを構築しています。さまざまな種類のレポートに含まれるこのデータに関連する多くの一般的なビジネス ルールがあります。現在、これらのルールは、レガシー言語のより大きな手続き型プログラムに組み込まれていますが、これを SQL に移行しようとしています。SASでのレポート、C#でのレポートなど、このデータからレポートを実装する際の柔軟性を狙っています。

現在の私のアプローチは、これらの一般的なルール (通常は非常に単純なロジック) を分割し、個々の SQL UDF にカプセル化することです。パフォーマンスは問題ではありません。これらのルールを使用して、一種のレポート「スナップショット」で静的フィールドにデータを入力したいだけです。これを使用して、任意の方法でレポートを作成できます。

各ルールが何をしているかを理解する (そしてルール自体を維持する) 限り、このモジュラー アプローチは気に入っていますが、メンテナンスも悪夢になるのではないかと少し心配になり始めています。他のルールに依存するルールもありますが、そこから逃れることはできません。;)

データベースでのこのモジュラー アプローチのためのより良いアプローチはありますか? 私は正しい方向に進んでいますか、それともアプリケーション開発の考え方が多すぎますか?

4

5 に答える 5

2

ある時点で、UDF を大量に使用すると、結果セットの各行に対して UDF が実行され、オプティマイザーのロジックが不明瞭になり、インデックスの使用が難しくなるため、パフォーマンスの問題が発生し始めます (つまり、パフォーマンスがどのように改善されないのかがよくわかりません)。問題はありますが、要件を最もよく知っているのはあなたです)。特定の機能については、それらは優れています。ただし、控えめに使用してください。

于 2010-01-28T22:16:30.927 に答える
2

データベース側にロジックを保持することは、ほとんどの場合正しいことです。

質問で述べたように、ほとんどのビジネス ルールには非常に単純なロジックが含まれますが、通常は膨大な量のデータを処理します。

データベース エンジンはそのロジックを実装するのに適しています。なぜなら、データベース エンジンはデータI/Oを最小限に抑え、データベースはほとんどのデータ変換をはるかに効率的に実行するからです。

しばらく前に、このトピックについて非常に主観的なブログ投稿を書きました。

補足: aUDFはストアド プロシージャと同じではありません。

AUDFは、クエリ内で callable によって設計された関数であるため、可能な操作の非常に限られたサブセットしか実行できません。

ストアド プロシージャを使用すると、さらに多くのことができます。

アップデート:

あなたが示した例では、「派生フィールド」を計算するロジックを変更するなどUDF、フィールドを計算するのは問題ありません。

しかし、(念のため) パフォーマンスが問題になる場合 (そして、私が信じているように、これは考えられるよりもはるかに早い時期です)、セットベースの操作でデータを変換する方が、s を使用するよりもはるかに効率的である可能性がありますUDF

UDFこの場合、 s (レコードベース) の更新に制限するのではなく、より効率的なクエリを含む結果セットを返すビュー、ストアド プロシージャ、またはテーブル値関数を作成することができます。

1 つの例: クエリに「ユーザー スコア」のようなものがあり、変更される可能性があると感じ、それをUDF

SELECT  user_id, fn_getUserScore(user_id)
FROM    users

最初は、これはテーブル内の単純なフィールドです。

CREATE FUNCTION fn_getUserScore(@user_id INT) RETURNS INT
AS
BEGIN
        DECLARE @ret INT
        SELECT  user_score
        INTO    @ret
        FROM    users
        WHERE   user_id = @user_id
        RETURN @ret
END

、次に、他のテーブルのデータを使用して計算することを決定します。

CREATE FUNCTION fn_getUserScore(@user_id INT) RETURNS INT
AS
BEGIN
        DECLARE @ret INT
        SELECT  SUM(vote)
        INTO    @ret
        FROM    user_votes
        WHERE   user_id = @user_id
        RETURN @ret
END

これにより、どちらの場合でも、エンジンは最も効率の悪いNESTED LOOPSアルゴリズムを使用することになります。

しかし、ビューを作成し、基になるクエリを次のように書き直した場合:

SELECT  user_id, user_score
FROM    users

SELECT  user_id, SUM(vote) AS user_score
FROM    users u
LEFT JOIN
        user_votes uv
ON uv.user_id = u.user_id

、これにより、結果セットの構造を維持し、ロジックをプレゼンテーションから分離しながら、エンジンに最適化のためのより広いスペースを与えることができます。

于 2010-01-28T22:17:29.657 に答える
1

あなたは正しい軌道に乗っていると思います.SQLプロシージャはますます複雑になるにつれて急速に手に負えなくなり、共有され、繰り返されるロジックの部分をUDFにカプセル化することは、これに対処するための完全に適切なソリューションです.

読みやすさを向上させるために、その 1 つのプロシージャでのみ使用される sql プロシージャのロジックを適切な名前の UDF にカプセル化することもよくあります。

UDF に関するこの MSDN の記事を見てください。おそらく、UDF の使用法についてさらにいくつかのアイデアが得られるでしょうか?

UDF を頻繁に使用する場合は、パフォーマンスに関するさまざまな考慮事項に注意する必要があります。たとえば、スカラー UDF とテーブル UDF のパフォーマンス、CLR UDF の利点などです。

于 2010-01-28T22:17:06.753 に答える
1

SQL はセット ベースであり、モジュラー アプローチを適用すると本質的にパフォーマンスが低下します。
関数、ストアド プロシージャ、および/またはビュー - それらはすべて、基になるロジックを抽象化します。同じテーブルを利用する 2 つ (またはそれ以上) の関数などを使用すると、パフォーマンスの問題が発生します。これは、1 つのクエリを使用できた場合に、2 つのクエリが同じテーブルになることを意味します。

複数の関数の使用は、データ モデルが非常に「柔軟」になるように作成されたことを示しています。私にとって、それは疑わしいデータ型と全体的な列/テーブル定義を意味します。データベースには何でも保存できるため、関数などの必要があります。つまり、データが正しくない可能性が非常に高くなります。事後に既存の悪いデータと戦うよりも、常に良い/有効なデータを取得することに力を入れたいと思います。

データベースは、このロジックを格納する場所です。アプリケーション コードよりも高速であり、最も重要なことは、メンテナンスを最小限に抑えるために集中化されていることです。

于 2010-01-28T22:24:21.550 に答える
0

レポート用のデータ ウェアハウスの構築に関心がある場合は、ツールとユーザーが同様に生成できる単純なステートメントでレポート SQL が構成されるように、ETL の Transform 部分にできるだけ多くのデータを入れてみてください。

SSIS は、この種のことのために SQL サーバーに付属している非常に有能な ETL ツールです。

于 2010-01-28T22:17:17.927 に答える