5

有理数としてネイティブに提供されるデータを扱っています。このデータを C# で美しく表現し、他の多くの形式に変換できる洗練されたジェネリック C# クラスがあります。残念ながら、振り返ってこれを SQL に保存したい場合、いくつかの解決策を念頭に置いていますが、どれも満足のいくものではありません。

ここに例があります。C# で簡単に処理できる生の値2/3があります。new Rational<int>(2, 3)これをデータベースに保存するために考えたオプションは次のとおりです。

  1. 10 進数/浮動小数点、つまり0.66666667さまざまな精度と正確さの値 = と同じです。 長所:これにより、データのクエリが可能になります。たとえば、値 < 1 を検索できます。 短所:正確さが失われ、この単純な値を UI に表示しようとすると見苦しくなります。

  2. 2分子 = 、分母 =3など、さまざまな精度と正確 さの2 つの正確な整数フィールドとして格納します。長所:これにより、元の値を正確に表現し、後で最も単純な形式で表示することができます。 短所:この値を表す 2 つのフィールドがあり、すべてのクエリで算術演算を実行する必要があるため、クエリが複雑になり、効率が低下します。たとえば、分子/分母 < 1 を検索します。

  3. 文字列データとしてシリアル化します"2/3"。最大文字列長を知ることができ、これを保持できる varchar を持つことができます。 長所: 1 つのフィールドに戻ってきましたが、正確な表現があります。 短所:クエリはほとんど機能せず、シリアル化のコストがかかります。

  4. 1号と2号の組み合わせ。 長所:値の範囲を簡単かつ効率的にクエリし、UI に正確な値を表示します。 短所: 1 つのデータを保持するための 3 つのフィールド (!?!) は、DRY を壊す複数の表現を同期させなければなりませ

  5. 1号と3号の組み合わせ。 長所:値の範囲を簡単かつ効率的にクエリし、UI に正確な値を表示します。 短所: 1 つのデータを保持するために 2 つのフィールドに戻り、複数の表現を同期して維持する必要があるため、DRY が壊れ、追加のシリアル化コストを支払う必要があります。

これらよりも優れた別のすぐに使えるソリューションを持っている人はいますか? 他に考慮していないことはありますか?私が知らないSQLでこれを行う比較的簡単な方法はありますか?

4

5 に答える 5

8

SQL Server 2005 または 2008 を使用している場合は、独自の CLR データ型を定義するオプションがあります。

SQL Server 2005 以降では、ユーザー定義型 (UDT) を使用してサーバーのスカラー型システムを拡張し、SQL Server データベースに CLR オブジェクトを格納できるようになりました。UDT には複数の要素を含めることができ、単一の SQL Server システム データ型で構成される従来のエイリアス データ型とは異なる動作を持つことができます。

UDT はシステム全体からアクセスされるため、複雑なデータ型に UDT を使用すると、パフォーマンスに悪影響を及ぼす可能性があります。複雑なデータは、通常、従来の行とテーブルを使用してモデル化するのが最適です。SQL Server の UDT は、次の場合に適しています。

  • 日付、時刻、通貨、および拡張数値型
  • 地理空間アプリケーション
  • エンコードまたは暗号化されたデータ

制限を受け入れることができるなら、カスタム クラスで既にキャプチャしているデータをマッピングするより良い方法は想像できません。

于 2009-12-19T19:02:31.923 に答える
6

おそらくオプション #4 を使用しますが、同期/DRY の問題を回避するために 3 番目の列に計算列を使用します (また、実際には 2 つの列のみを保存し、「3 つのフィールド」の問題を回避することも意味します)。

SQL サーバーでは、計算列は次のように定義されます。

CREATE TABLE dbo.Whatever(
   Numerator INT NOT NULL,
   Denominator INT NOT NULL,
   Value AS (Numerator / Denominator) PERSISTED
)

(分母がゼロでないことなどの型変換と検証を行う必要があるかもしれないことに注意してください)。

また、SQL 2005 では、クエリ時に計算を削除する PERSISTED 計算列が追加されました。

于 2009-12-19T18:57:04.167 に答える
2

どのくらいの精度が必要ですか?

C# などの言語は、精度の特定の位置で 2/3 を丸めます。あなたが取り組んでいるものは何でも、10の科学的表記法などの10進値を使用することが許容される場合は、それに応じてdbで精度を設定してください。

精度が本当に重要な場合は、分子と分母を分けてください。これにより、必要な精度に常にアクセスできるようになり、計算列を使用して値を表すことができ、迅速なフィルタリングが可能になります。

numerator INT,
denominator INT,
result AS CASE WHEN denominator > 0 THEN numerator / denominator ELSE NULL END
于 2009-12-19T19:03:51.623 に答える
0

SQL Server 2008 でジオメトリ データ型を使用して、有理数を格納および操作する方法を少し試しました。基本的に、架空のジオメトリ ポイントの X スロットに分子が入り、Y スロットに分母が入ると仮定します。

これは私のニーズには合っていましたが、あなたにとっては役に立たないかもしれません. それはあなたの優先事項(パフォーマンス、コードの読みやすさなど)によって異なります。個人的には、ジオメトリ データ操作用の T-SQL は読み書きが難しいことがわかりました。

于 2009-12-19T18:57:47.957 に答える
0

どのくらいの精度を見ていますか?double/float はまともな精度を提供します (私の意見では)。科学的/天文学的データには、それよりもはるかに高い精度が必要であると確信しています。私は、matlab や mathematica などのライブラリがこれらに優れていることを知っています。.net プログラムで mathematica を使用できることがわかりました。ここにリンクがあります

編集:リンクと引用をさらに追加する

ここから「Mathematica が有理数を操作する場合、必要な桁数に関係なく正確な結果が得られます」

別の良い読み物ですが、実装する必要があると思います

于 2009-12-19T19:00:25.517 に答える