web-dev-qa-db-ja.com

Ok GUIDを外部キーとして使用しますか?

これが私の現在の状況です:

「MyTable」のように、ウェブサイトのフォームから送信されたデータを格納するテーブルがあります。テーブルは主キーとしてbigint(自動インクリメント)を使用します。これまでのところすべてが良好です。

さて、そのテーブルは、モバイルデバイスからアップロードされたレコードを格納できるようにするために必要です。しかし、携帯電話からアップロードされたレコードは、「MyTable」に保存される前に、まず検証される必要があります。したがって、ステージングテーブルが作成されます(「Temp_MyTable」など)。

つまり、これはフローです。

モバイルデバイス------>ステージングテーブル------>実際のテーブル

                    [GUID as PK]         [bigint as PK], [GUID as FK]

問題は、ステージングテーブルがGUIDを主キーとして使用していることです。理由は、複数のデバイスからアップロードされたレコードを参照する必要があるためです。ユーザーは変更後にレコードを再アップロードする場合があります。注: GUID hereは、モバイル(単純なJavaScript)によって生成されます。

したがって、ここで実際のテーブルのレコードをステージングテーブルに参照して戻したいです。この場合、「おそらく」外部キーが必要です。残念ながら、これはGUIDデータ型です。

そして、多くの記事を読んだ後、外部キーとしてGUID=を使用することは不利になるかもしれません-より多くのストレージまたはより遅いです。

知りたいのですが、Okを使用するにはGUIDを外部キーとして使用しますか?実際に「完全に正常」であると誰かが正当化できますか?それともより良いデザイン?

5
zeroflaw

UUID列を外部キーとして使用することは問題ありません。それが親レコードの唯一の候補キーである場合は、推奨/必須です。 FKは、参照されたテーブルで一意の値を参照する必要があります。これは通常、主キーを意味しますが、制約またはインデックスによって一意として定義された列(または列の組み合わせ)でも同様です。 alwaysも入力されている(つまり、null可能ではないと定義されている)必要があるという提案もあります。そうでない場合、参照されるテーブルのすべての行がFKから参照できるわけではありません。これは正しくありません。

参照されたテーブルの主キーがuniqueidentifier列である場合、そのテーブルに別の一意の値がない限り、それを外部キーターゲットとして使用する必要があります

外部キーとしてUUIDを推奨しない唯一の本当の理由はスペースです。このような値は、4(代替が32ビット整数であると想定)または8(bigintの場合)ではなく、16バイトを格納するのに使用されます。

特にPKがクラスタリングキーでもある場合(つまり、テーブルのクラスター化インデックスの唯一のメンバーまたは重要なメンバーが存在する場合)、主キーとしてUUIDを使用することには反対の議論があります。しかし、それは別の議論です。

6
David Spillett