24

私たちが作成している資産システムの番号付けシステムを考え出そうとしていますが、オフィスでこのトピックについていくつかの白熱した議論があったので、SOの専門家に尋ねることにしました。

以下のデータベース設計を検討すると、より良いオプションがあります。

代替テキスト

例1:自動代理キーの使用。

=================   ==================
Road_Number(PK)     Segment_Number(PK)
=================   ==================
 1                   1

例2:プログラムで生成されたPKを使用する

=================   ==================
Road_Number(PK)     Segment_Number(PK)
=================   ==================
 "RD00000001WCK"     "00000001.1"

(これは、道路の最初のセグメントである00000001.1ことを意味します。これは、新しいセグメントを追加するたびに増加します。例)00000001.2

例3:両方のビットを使用する(新しい列を追加する)

=======================    ==========================
ID(PK) Road_Number(UK)     ID(PK)  Segment_Number(UK)
=======================    ==========================
 1     "RD00000001WCK"       1       "00000001.1"

ほんの少しの背景情報ですが、レポートやその他のドキュメントでとRoad Numberを使用するので、それらは一意である必要があります。 Segment Number

私はいつも物事をシンプルに保つのが好きだったので、例1を好みますが、レポート/ドキュメントで主キーを公開するべきではないことを読んでいます。だから今、私は例3の線に沿ってもっと考えています。

また、資産番号の生成方法を変更することにした場合、主キーに対してカスケード更新を行う必要がないため、例3にも傾いています。

私たちは何をすべきだと思いますか?

ありがとう。

編集:素晴らしい答えをありがとうみんな、私を大いに助けてくれました。

4

13 に答える 13

65

これは実際には、サロゲート (技術的または合成とも呼ばれる) と自然な主キーの対比についての議論であり、広く取り上げられてきた主題です。これについては、AppDevelopers が作成したデータベース開発の間違い で説明しました。

自然キーは、(表向きは) 一意である外部的に意味のあるデータに基づくキーです。一般的な例としては、製品コード、2 文字の州コード (米国)、社会保障番号などがあります。サロゲートまたは技術的な主キーは、システムの外ではまったく意味を持たないものです。それらは純粋にエンティティを識別するために考案されたもので、通常は自動インクリメント フィールド (SQL Server、MySQL など) またはシーケンス (最も顕著なのは Oracle) です。

私の意見では、常に 代理キーを使用する必要があります。この問題は、次の質問で発生しました。

自動採番フィールドが最適です。キーがデータベース外で意味を持つ場合 (資産番号など)、それらは変更される可能性が高く、キーの変更には問題があります。それらのインデックスを関連するテーブルに使用するだけです。

于 2009-04-05T01:51:37.047 に答える
7

個人的には、シンプルに保ち、自動インクリメントされた主キーを使用します。プログラムでの表示に関してもっと「読みやすい」ものが必要な場合は、おそらく他のアイデアの1つですが、それは主キーフィールドに不要な複雑さを追加しているだけだと思います。

于 2009-04-01T22:57:10.867 に答える
7

私はまた、「主キーを意味のあるデータとして使用しない」という陣営にも非常に強く属しています。私がその方針に違反するたびに、それは涙で終わりました. 遅かれ早かれ、意味のあるデータを変更する必要があり、それが主キーを変更する必要がある場合、それは苦痛になる可能性があります。主キーはおそらく外部キー制約で使用され、単純なデータ変更を行うためだけにすべてを整理しようとして何年も費やすことができます.

私はこれまでに作成したすべてのテーブルの主キーに常に GUID/UUID を使用していますが、それは単に個人的な好みのシリアルなどでも良いことです。

于 2009-04-01T23:31:51.080 に答える
3

ここで覚えておくべき重要なことは、データベース/デザインの各テーブルに複数のキーがある可能性があることです。これらは候補キーです。 候補キーについては、ウィキペディアのエントリを参照してください

定義上、すべての候補キーは同じように作成されます。これらはそれぞれ、問題のテーブルの一意の識別子です。

次に、主キーとして機能する候補キーのプールから最適な候補を選択するのがあなたの仕事です。主キーは、リレーショナル制約を確立するために他のテーブルによって使用されますが、候補キーを使用してテーブルをクエリし続けることができます。

主キーは他の構造によって参照され、したがって結合操作で使用されるため、主キーの選択基準は、私にとって(重要度の高い順に)次のように要約されます。

  • 不変/安定-主キーの値は変更しないでください。その場合、更新の異常を導入するリスクがあります
  • ヌルではない-ほとんどのDBMSプラットフォームでは、主キー属性がヌルでないことが必要です。
  • シンプル-物理ストレージとパフォーマンスのシンプルなデータ型と値。ここでは整数値が適切に機能します。これは、ほとんどの代理/自動生成キーに最適なデータ型です。

候補キーを特定したら、上記の基準を使用して主キーを選択できます。基準を満たす「自然な」候補キーがない場合は、他の回答に記載されているように、基準を満たす代理キーを作成して使用できます。

于 2009-04-10T14:55:47.357 に答える
1

使用しないポリシーに従ってください。

あなたが遭遇する可能性のあるいくつかの問題:

複数のホストからキーを生成する必要があります。

誰かが一緒に使用するために連続した番号を予約したいと思うでしょう。

人々はそれをどれほど意味のあるものにしたいと思うでしょうか?戦争はこれをめぐって争われており、あなたはすでに最初の小競り合いにいます。「それはすでに意味があり、さらに2桁追加すれば...」つまり、拡張可能な(すべき)デザインスタイルを確立していることになります。

2つを連結している場合は、クエリオプティマイザを台無しにする可能性のあるタイプキャストを実行しています。

道路を再分類し、境界を再定義する(つまり、道路を移動する)必要があります。これは、主キーを変更し、リンクを失う可能性があることを意味します。

これにはすべて回避策がありますが、これは回避策が急増して制御不能になるような問題です。そして、「シンプル」を超えるのに2、3回以上かかることはありません。

于 2009-04-01T23:09:53.783 に答える
0

サロゲートキーを使用しますが、レポートが改善される場合は、サロゲートキーをより「読みやすい」値に「フォーマット」する計算列が必要になる場合があります。計算された列は、たとえば表示目的で、代理キーから例2を生成できます。

代理キールートが進むべき道だと思います。私がそれに対して行う唯一の例外は、主キーが外部キー参照で構成されている可能性がある結合テーブルです。このような場合でも、代理の主キーを持つ方が便利であることがわかりました。

于 2009-04-10T13:42:26.457 に答える
0

すべてのデザイン要素が単一の目的を持つべきであるということに同意していただければ幸いです。

質問は、PKの目的は何だと思いますか?テーブル内の一意のレコードを識別する場合は、代理キーが問題なく優先されます。これはシンプルでまっすぐです。

オプション3の新しい列に関する限り、パフォーマンスを大幅に低下させることなく、これらを計算できるかどうかを確認する必要があります(RDBMSで計算する場合よりも簡単に変更できるように、モデルレイヤーで計算するのが最善です)。他の要素。たとえば、セグメント番号と道路番号を対応するテーブルに保存し、それらを使用して「00000001.1」を生成できます。これにより、資産番号をその場で変更できます。

于 2009-04-11T21:08:14.707 に答える
0

ここで多くの人がすでに言っているように、あなたは本当にオプション#3を使うべきだと思います。適切なビジネスキーがある場合でも、代理PK(整数またはGUID)を使用することをお勧めします。サロゲートは、メンテナンスの頭痛の種を減らします(あなた自身がすでに述べたように)。

そうは言っても、考慮したいことは、データベースが次のとおりであるかどうかです。

  1. データの保守とトランザクション処理(つまり、作成/更新/削除操作)に焦点を当てています
  2. 分析とレポート(クエリなど)を対象

言い換えると、ユーザーは、アクティブなデータを維持したり、主に静的なデータをクエリして回答を見つけたりすることに関心がありますか?

ビジネス用語をよく理解している技術的なビジネスユーザー(レポートデザイナーなど)に公開される分析およびレポートDB(データウェアハウス/マートなど)の構築に重点を置いている場合は、ナチュラルの使用を検討することをお勧めします意味のあるビジネス価値に基づくキー。これらは、複雑な結合の必要性を排除することでクエリの複雑さを軽減し、ユーザーがデータベース構造と戦うのではなく、タスクに集中できるようにします。

それ以外の場合は、すべてのベースをある程度カバーする必要がある完全なCRUDDBに焦点を当てている可能性があります。これはほとんどの状況です。その場合は、オプション#3を選択してください。将来的にはいつでもクエリ可能性を最適化できますが、保守性のために後付けするのは難しいでしょう。

于 2009-04-10T17:36:36.567 に答える
0

もう 1 つ留意すべき点は、このシステムに大量のデータをインポートしている場合、Road_Number思ったほど独自のものではなく、問題を修正するための運用上の障害があることに気付くかもしれないということです (道路標識の再塗装、など)。

于 2009-04-01T23:28:32.070 に答える
0

自然キーはビジネス ユーザーにとって大きな意味を持つかもしれませんが、それらのキーが神聖であり、変更されるべきではないという合意がない場合、「製品コードが含まれるデータベースを維持する際に、おそらく頭を悩ませることになるでしょう。同社が買収した新しい製品ラインに対応するために変更される予定です。」データの RI を保護する必要があり、自動インクリメント付きの主キーとして整数を使用するのが最善の方法です。char 列よりも整数のインデックス作成とトラバースを行う場合のパフォーマンスも向上します。

主キーとしては適切ではありませんが、自然キーはユーザーの使用に非常に適しており、インデックスを介して一意にすることができます。それらは、すべての関係者が理解しやすくするコンテキストをデータにもたらします。また、データをリロードする必要が生じた場合、自然キーはルックアップがまだ有効であることを確認するのに役立ちます。

于 2009-04-10T10:16:41.960 に答える
0

まず、オプション 2 は絶対に最悪のオプションです。インデックスとして、それはstringであり、それが遅くなります。また、ビジネス ルールに基づいて生成されますが、これは変更される可能性があり、かなり大きな問題を引き起こす可能性があります。

個人的には、私は常に別の主キー列を使用しています。私は常にGUIDを使用しています。一部の開発者は、ハード ドライブの容量の理由から、GUID よりも単純な INT を好みます。ただし、2 つのデータベースをマージする必要がある状況が発生した場合、GUID が衝突することはほとんどありません (一方、INT は衝突することが保証されています)。

主キーは、ユーザーに決して見せてはなりません。ユーザーが読めるようにすることは問題ではありません。主キーは、外部キーとのリンクに使用する必要がありますこれが彼らの目的です。値は機械可読である必要があり、一度作成されると変更されることはありません。

于 2009-04-12T00:59:58.693 に答える