12

今朝、私たちが作成しているデータベースにあるアセットの ID をどのように保存すべきかについてミーティングを行いましたが、議論が少し熱くなったので、SO の専門家に相談することにしました。

私たちが持つべきだと私が信じているテーブル構造(短いバージョン)は次のようなものです:

例1)

  • AssetId - int(32) - 主キー
  • タイプ - 文字列

したがって、いくつかのサンプルデータは次のようになります。

==AssetId======Type===
  12345        "Manhole"
  155415       "Pit"

チームの別のメンバーは、次のような提案をしました。

例 2)

  • AssetId - 文字列 - 主キー
  • タイプ - 文字列

したがって、いくつかのサンプルデータは次のようになります。

==AssetId======Type===
  "MH12345"    "Manhole"
  "P155415"    "Pit"

タイプの短いバージョンを作成し、ID の前に追加して、データベースに保存します。これを行ういくつかの資産データベースを見てきましたが、実際にはこのアプローチはありませんでした。

ソートの理由で文字列を ID として使用するという考えは、私はあまり好きではありませんでした。とにかくアセットストアのようなものをすでに持っているのに、無駄な情報をただ保存しているようにも感じます。

どのようなアプローチをとりますか?なぜ?アプローチ 1 を 2 よりも使用する利点はありますか?

編集: はい、アプローチ 1 に AUTO_INCREMENT を使用します。

4

9 に答える 9

26

通常、経験則では、主キーに意味のある情報 (社会保障番号やバーコードなど) を使用しないでください。単純な自動インクリメント整数。データは一定に見えますが、ある時点で変化する可能性があります (新しい法律が制定され、すべての SSN が再計算されます)。

于 2009-02-03T06:36:08.313 に答える
7

これは、代理キーと自然キーの間の決定です。最初は代理 (または「技術的」) で、2 番目は自然キーです。

ほとんど常に代理キーを使用する必要があるという結論に達しました。自然キーを使用する場合、それらは変更される可能性があり、主キー/外部キーを更新することは一般的には良い考えではありません。

于 2009-02-03T06:31:46.920 に答える
4

私は前者を選びます。一意の ID の作成は SQL サーバーに任せる必要があり、それらが文字列の場合、スレッドセーフな方法でそれらを自動的に作成することはできません。私の理解では、あなたはそれをどうにかして自分で処理しなければなりませんか?

速度は別の要因です。int 値の処理は、常に文字列よりも高速です。私よりもはるかにSQLに精通した人が詳しく説明できる、インデックス作成に関する他のパフォーマンス上の利点があると思います;)

私の経験では、文字列 ID を持つことは失敗でした。

于 2009-02-03T06:22:35.237 に答える
3

さて、私はいくつかのポイントと提案をしたいと思います.

  • たとえば、列 Id と Desc を使用して、Type 用に別のテーブルを用意することを検討し、このテーブルで外部キー TypeId を作成します。物事を正常化するためにさらに一歩。しかし、それは望ましくないかもしれません。何らかの目的に役立つと思われる場合は実行してください

  • 後で UUID に移行することを考えている場合は、文字列にすることは理にかなっています。その場合、データ型を変更する必要はありません

【編集済】

ここでクレタスに同意します。この代理キーは、いくつかの実際のプロジェクトで有益であることが証明されました。彼らは変化を許します、そしてあなたは変化が唯一の不変であることをよく知っています。

于 2009-02-03T06:32:14.937 に答える
3

パフォーマンス上の理由から、数値の主キーを選択します。整数比較は文字列比較よりもはるかに安価であり、DB 内で占有するスペースも少なくなります。

于 2009-12-17T16:34:09.200 に答える
2

私は個人的に、最初のアプローチがはるかに優れていると信じています。これにより、データベース ソフトウェアは単純な整数比較を実行してキーを見つけて並べ替えることができるため、テーブル操作のパフォーマンスが向上します (SELECT、複雑な JOIN、キーによる INDEX ルックアップなど)。

もちろん、どちらの方法でも、ID を生成するためにある種の自動インクリメント メソッド (シーケンス、AUTO_INCREMENT、または同様のもの) を使用していると思います。プログラムのコードでそれらをビルドしないでください。

于 2009-02-03T06:22:47.997 に答える
1

私はあなたが言及した理由から例1を好み、例2を使用するために私が考えることができる唯一の議論は、既存のデータベース(かなり一般的)からの文字列IDを収容しようとしている場合ですが、そのシナリオでも、私は次のアプローチ。

==AssetId(PK)==Type========DeprecatedId====
  12345        "Manhole"   "MH64247"
  155415       "Pit"       "P6487246"
于 2009-02-03T07:46:39.793 に答える
0

例 2 の唯一の利点は、主キーだけで、このキーがどのテーブルのどの行に適用されるかを簡単に判断できることです。アイデアは素晴らしいですが、それが役立つかどうかは、ロギングとエラーメッセージの戦略によって異なります。おそらくパフォーマンス上の欠点があるため、使用する具体的な理由を挙げていただけない限り、使用しません。

(この利点は、グローバル シーケンスを使用して数値キーを生成するか、さまざまな数値範囲、最後の桁などを使用することによっても得られます。そうすれば、パフォーマンス上の欠点はありませんが、おそらくテーブルをそれほど簡単に見つけることはできません。 )

于 2009-12-17T16:30:04.263 に答える
0

資産に固有の自然識別子 (従業員 ID を持つ従業員など) が既にある場合は、それらを使用します。別の一意の識別子を作成しても意味がありません。

一方、自然な一意の ID がない場合は、予想されるテーブル サイズ (整数など) に対して十分な一意のキーを確保できる最短のものを使用します。必要なディスク容量が少なくなり、おそらく高速になります。さらに、後で文字列ベースのキーを使用する必要が生じた場合、それは単純な置換作業です。

  • 資産テーブルに文字列の主キーを追加します。
  • 参照テーブルに文字列外部キーを追加します。
  • 整数関係を使用して単純な UPDATE コマンドで文字列関係を更新します。
  • 文字列の外部キー制約を追加します。
  • 整数列の外部キー制約を削除します。
  • 整数列を完全に削除します。

これらの手順の一部は、特定の DBMS では問題になる可能性があり、整数の主キー列を削除するためにテーブルのアンロード/リロードが必要になる可能性がありますが、その戦略は基本的に必要なものです。

于 2009-02-03T06:31:50.290 に答える