2

文字列を主キーとして使用する従来のデータベースがあります。そのレガシー データベースの上にオブジェクトを実装して、いくつかのビジネス ロジックをより適切に実装し、より多くの機能をユーザーに提供したいと考えています。

テーブルの主キーに文字列を使用するのは悪いことだと読んだことがあります。なぜだろう?大文字と小文字の区別の問題のためですか?文字セット?

...これがNHibernateにとって特に悪いのはなぜですか?

...そしてそれをフォローアップ...文字列が悪い主キーになる場合、データベースの主キーをintやGUIDなどに置き換える価値はありますか? (関連するテーブルは約 25 ~ 30 しかありません)

4

3 に答える 3

5

わかりました、私はこれを突き刺します。私はデータベースの専門家ではなく、NHibernate ではなく Hibernate (Java) の経験がありますが、いくつか注意点があります。

文字列としての主キーの問題は、データベースでそれらを表すために使用される SQL データ型に関係していると思います。主キーは挿入やクエリなどで常に使用されるため、データベース エンジンは主キーの比較に多くの時間を費やさなければなりません。数値を使用している場合、これらは単純にバイトとして保存され、コンピューターはこれをすばやく処理するのが得意です。文字列の使用を開始するとすぐに、これらの操作 (主に比較) のコストが大幅に上昇します。データベース エンジンがキーを比較するために非常に巧妙な戦略を使用している場合でも、バイトを文字列ではなくバイトとして比較する方が常に高速です。

ただし、最新のハードウェアでは、これは以前よりもはるかに問題が少なくなり、インデックスを使用すると問題はほとんどなくなります。

これが Hibernate (および NHibernate) で本当に悪い理由についてはよくわかりませんが、私の経験では、私のアプリケーションにはオブジェクトの複雑なグラフがあり、多くの場合、リストまたはセットとして、他の永続化されたオブジェクトへの参照を持っているためです。これらはすべて、他のオブジェクトの ID を使用して保存されます。また、カスケード保存やフェッチなどのルールが適用されているため、これは主キーが常に使用されていることを意味します。Hibernate - 私はとても気に入っています - は、言われたことを正確に実行する傾向があり、時には人々 (特に私!) は、本当にばかげたことをするように指示します。その結果、一見単純な更新やクエリでさえ、非常に複雑な SQL を生成することになります。

つまり、要約すると、主キーとしての文字列は、単純な操作のコストがかかるため悪いものであり、Hibernate を使用するとこれが拡大する可能性があります。ただし、実際には、最新のデータベース エンジンには、パフォーマンス ヒットがそれほど悪くならないようにするための巧妙な戦略がたくさんあります。(Postgres - およびおそらく他の - デフォルトでは、主キーのインデックスを作成します)

フォローアップのために - キーを交換する必要がありますか? まあ、それはアプリケーションのパフォーマンスに依存します。パフォーマンスが重要な場合、大規模で非常に集中的なアプリケーションの場合は良い考えかもしれませんが、それ以外の場合は、すべてのテーブルを変更するのに時間を費やさなければならないという欠点があり、おそらく最小限のメリットしかありません. NHibernate で使用している戦略を改良すると、より良い結果が得られることが期待できます (つまり、戦略をフェッチするときや、保存をカスケードするときなど)。

于 2009-02-26T03:50:31.780 に答える
0

文字列や文字を使用すると、システムが非常に複雑になります。次の質問を検討してください。

  • 大文字と小文字の区別を処理する方法。
  • パディングの扱い方。NHibernate を使用すると短い文字列を挿入でき、データベースは黙ってパディングを追加しますが、永続化されたエンティティには反映されません。メモリ内 ID を使用してエンティティを再度取得しようとすると、null が返されます。
  • エンコーディングの問題を処理する方法。C# は Unicode 文字列を使用しますが、データベースは使用しない可能性があります。変換がどのように処理されるか教えていただけますか? 私はそうは思わない。
  • 合成整数キーは、ほとんどのデータベースで余計な手間をかけずに自動生成できます。文字列を使用すると、おそらく「手動で」作成します。(DDD の意味で) Factory の背後にそれらを隠蔽しない限り、結果のコードはドメイン モデルを混乱させます。

andy Kが言及したパフォーマンスのオーバーヘッドは、インデックス作成により減少する可能性がありますが、それでも多くの場合、メモリ内で ID 比較 (ハッシュマップ?) を実行し、DB の最適化は適用されません。

文字列の主キーがあり、外部キーがまったくないレガシーデータベースを使用したプロジェクトに取り組んでいます。レガシ アプリはそのすべての小さな側面に依存しているため、古いスキーマに触れることは許可されていません。NHibernate は後者を非常に適切に処理するため、文字列の主キーは外部キーの欠落よりも一貫性を損なうと感じています。

于 2010-12-06T17:32:46.227 に答える