47

まず、私はこの質問を認識しており、(GUIDを使用した)提案は私の状況には当てはまりません。

ユーザーが電話でこの情報を簡単に伝達できるように、単純なUIDが必要です。

こんにちは、注文1584に問題があります

とは対照的に

こんにちは、注文4daz33-d4gerz384867-8234878-14に問題があります

いくつかの異なる種類の「オブジェクト」があるため、これらを一意(データベース全体)にします...注文ID、配信ID、請求IDがあり、これらの間に1対1の関係がないため、 IDがどの種類のオブジェクトを参照しているかを推測する方法がありません。

データベース全体で一意のIDを使用すると、顧客がどのオブジェクトを参照しているかをすぐに知ることができます。私のユーザーは検索ツールにIDを入力するだけで、余分なクリックを保存して、探しているものをさらに絞り込むことができます。

私の現在のアイデアは、シード1、2、3などが異なり、増分値が100のID列を使用することです。

しかし、これはいくつかの疑問を提起します:

  • 最終的に100を超えるオブジェクトタイプを取得した場合はどうなりますか?確かに私は1000または10000を使用できましたが、うまくスケーリングしないものは「におい」

  • シードが「失われる」可能性はありますか(レプリケーション中、データベースの問題など)?

  • より一般的に、私が知っておくべき他の問題はありますか?

  • ID列として非整数(現在はbigintsを使用)を使用して、IDの前にオブジェクトタイプを表すものを付けることはできますか?(たとえば、varchar列)

  • ID列と、場合によってはオブジェクトタイプのみを含む「マスターテーブル」を使用して、新しいアイデアが必要なときにいつでも行を挿入できるようにすることをお勧めします。少しやり過ぎかもしれないと思いますし、挿入リクエストがすべて複雑になるのではないかと思います。さらに、データベースを見ないとオブジェクトタイプを判別できないという事実

  • 私の問題に対処する他の賢い方法はありますか?

4

11 に答える 11

56

すべてのテーブルで ID を使用しないのはなぜですか。ユーザーに表示するときはいつでも、タイプに 1 つの文字を追加するだけです。たとえば、O1234 は注文、D123213 は配達などですか? そうすれば、クレイジーなスキームを設計する必要はありません...

于 2009-04-06T13:50:10.977 に答える
13

ユーザー インターフェイスで処理します。ユーザーに報告するときに、ID 番号にプレフィックス文字 (複数可) を追加します。したがって、o472 は注文、b531 は請求書などになります。電話で「数字」を伝えるとき、人々は文字と数字を混在させることに非常に慣れており、単純な数字よりも正確です。

于 2009-04-06T13:53:55.007 に答える
12

自動インクリメント列を使用して一意の ID を生成できます。次に、この列の値を取得し、その前にエンティティ タイプを反映する固定識別子を追加する計算列を作成します。たとえば、OR1542 と DL1542 は、それぞれ注文 #1542 と配送 #1542 を表します。プレフィックスは必要に応じて拡張でき、同じ自動インクリメント値 (OR011542 と DL021542、プレフィックスは OR01 と DL02) を持つアイテムを区別できるようにフォーマットを調整できます。

于 2009-04-06T13:51:28.150 に答える
3

汎用ルートテーブルを定義して実装します。より良い名前がないため、それをエンティティと呼びます。エンティティテーブルには、少なくとも1つのID列が必要です。たとえば、すべてのオブジェクトに共通する他のフィールドや、この行が順序であることを示すメタデータを含めることもできます。

実際のOrder、Delivery ...テーブルには、エンティティテーブルへのFK参照があります。これにより、単一の一意のID列が得られます

私の意見ではシードを使用することは悪い考えであり、問​​題を引き起こす可能性があります。

編集

あなたがすでに言及した問題のいくつか。また、これはすべての新しいエンティティを追跡して正しく設定するのが面倒だと思います。2年後にシステムを更新する開発者を想像してみてください。

私がこの答えを書いた後、私はあなたがこれをする理由についてもっと考えました、そして私はマットがしたのと同じ結論に達しました。

于 2009-04-06T13:44:59.833 に答える
3

なぜbigintの単純なBase36表現ではないのですか? http://en.wikipedia.org/wiki/Base_36

于 2009-05-01T20:57:31.947 に答える
3

MS の意図的なプログラミング プロジェクトには、ランダムな ID から発音可能な名前を与える GUID-to-word システムがありました。

于 2009-04-16T02:44:03.977 に答える
1

これには高/低アルゴリズムを使用します。ただし、このオンラインの説明は見つかりません。それについてブログする必要があります。

私のデータベースには、カウンター フィールドを持つ ID テーブルがあります。これが高い部分です。私のアプリケーションには、0 から 99 までのカウンターがあります。これが低い部分です。生成されたキーは 100 * 高 + 低です。

キーを取得するには、次のようにします

initially high = -1
initially low = 0

method GetNewKey()
begin
  if high = -1 then
    high = GetNewHighFromDatabase

  newkey = 100 * high + low.
  Inc low
  If low = 100 then
    low = 0
    high = -1

  return newKey
end

実際のコードはロックなどでもっと複雑ですが、それが一般的な要点です。

auto inc キー、ジェネレーターなど、データベースから高い値を取得する方法は多数あります。最適な方法は、使用しているデータベースによって異なります。

このアルゴリズムは、毎回新しいキーを検索するというデータベース ヒットをほとんど回避しながら、単純なキーを提供します。テストでは、guid と同様のパフォーマンスがあり、auto inc キーを毎回取得するよりもはるかに優れたパフォーマンスを発揮することがわかりました。

于 2009-04-17T00:14:27.073 に答える
1

プロジェクトで同様の問題に直面しました。最初に行が 1 つしかない単純なテーブルを作成することで、この問題を解決しました。自動インクリメント ID として設定された BIGINT です。そして、デフォルト値を使用してトランザクション内で、そのテーブルに新しい行を挿入する sproc を作成しました。次にSCOPE_IDENTITY、 を変数に格納し、トランザクションをロールバックしてから、格納された を返しますSCOPE_IDENTITY

これにより、テーブルがいっぱいになることなく、データベース内で一意の ID が得られます。

ID が参照しているオブジェクトの種類を知りたい場合は、トランザクションのロールバックを失い、ID と共にオブジェクトの種類も保存します。そうすることで、Id が参照しているオブジェクトの種類を 1 つの選択 (または内部結合) だけで見つけることができます。

于 2009-04-16T18:15:20.307 に答える
0

UniqueObjectIDとサブタイプフィールドを使用してマスターテーブルを作成できます。サブテーブル(Orders、Usersなど)には、UniqueObjectへのFKがあります。INSTEAD OF INSERTトリガーは痛みを最小限に抑える必要があります。

于 2009-04-06T13:46:25.900 に答える
0

プロジェクトで同様の状況がありました。

私の解決策: デフォルトでは、ユーザーには GUID の最初の 7 文字しか表示されません。

衝突の可能性が非常に低い (2 億 6800 万分の 1) ほど十分にランダムであり、話したりタイピングしたりするのに効率的です。

もちろん、内部的には GUID 全体を使用しています。

于 2009-06-16T20:10:04.227 に答える
0

たぶん、itemType-year-week-orderNumberThisWeek バリアントですか?

o2009-22-93402

このような識別子は、いくつかのデータベース列の値で構成され、ソフトウェアによって識別子の形式に単純にフォーマットされます。

于 2009-04-16T09:51:24.700 に答える