主キーは不変である必要がありますか?


26

StackOverflowの上の最近の問題は、主キーの不変性についての議論を引き起こしました。主キーは不変でなければならないというのは一種のルールだと思っていました。いつか主キーが更新される可能性がある場合は、代理キーを使用する必要があると考えました。ただし、これはSQL標準には含まれておらず、一部のRDBMSの「カスケード更新」機能により、主キーを変更できます。

だから私の質問は次のとおりです。変更される可能性がある主キーを持つことは依然として悪い習慣ですか?可変の主キーを持つことの短所がある場合、それは何ですか?

回答:


25

主キーが外部キーにリンクされている場合、またはデータベースの外部で識別子として使用されている場合(たとえば、アイテムのページを指すURLで)、主キーが不変である必要があります。

一方、変更可能な情報が含まれている場合は、変更可能なキーのみが必要です。レコードにキーとして使用できる単純で不変の識別子がない場合は、常に代理キーを使用します。


7
「主キーが外部キーにリンクされている場合、主キーが不変である必要がある」のなぜですか?OPが述べたように、ほとんどのRDBMSには「カスケード」更新機能があります。
タナトス

1
@Thanatosのほとんど(実際に私が遭遇したすべて)のrdbmsでは、変更可能な主キーは許可されませんが、カスケード更新が行われます。一般に受け入れられているdbaの知恵では、主キーには情報が含まれず、一意のレコード識別子のみである必要があります(タイムスタンプやそれから延期されたレコード範囲などでさえありません)。
ジュウェンティング

5
@jwenting:同じことを話しているのですか?「ほとんどのrdbmsでは可変主キーが許可されません」には何が含まれますか?MySQLとPostgreSQLはどちらも可変の主キーを許可し、カスケード更新を尊重します。標準SQLがそうすべきだと思います。また、「一般に受け入れられているdbaの知恵」とは?代理キーに反対する多くのDBAと、自然キーに反対する多くのDBAに会いました。
タナトス

2
@Thanatos 「すべてのテーブルに代理がなければならない」を支持する議論は書誌的参照を欠いており、「一般に認められたdbaの知恵」を引用しているが、本を引用することはない。正規の本では、次の場合にサロゲートを使用する必要があると書かれています。そのため、適合する場合は自然で、適合しない場合は代理となります。
Tulainsコルドバ

4
@ user61852:なに?
グッフ

15

主キーがなければならないの一意性を判断するために必要なものは何でもタプルで構成すること。データを変更できるかどうかは関係ありません。レコードの一意性のみが重要です。これがデータベースの概念設計です。

実装の領域に移動するとき、最も安全なことは、単に代理キーを使用することです。


15

はい、私の意見では、主キーは不変でなければなりません。

明らかな候補キーがあったとしても、私は常に代理キーを使用します。いくつかの機会で、私はこれをやったことがないが、ほとんどいつも後悔している。そして、キーがどんなに不変だと思っても、データ入力エラーから保護することはできません。それは、主キーであるためにその情報を編集できないことをユーザーに伝えることは悲しいことではありません。


データ入力エラーに関する良い点
ティムグッドマン

richeym、あなたはキーが不変であってはならない理由を主張しているようです:ユーザーはそれらを変更したいかもしれません。
nvogel

4
@dportas-私のポイントは、PKが不変であることを好むため、テーブルデータ(電子メール、ユーザー名など)から派生できる明らかなキーがあると考えても、常に代理キーを使用することです。
richeym

2

主キーが変更されると、データベースとユーザーの間のキャッシュメカニズムの有効性が失われます。


2

何故なの?列を削除したいのですか?

要件が3つの列を一意にする必要があるからといって、それが主キーである必要があるわけではありません。このルールは永遠に続くと思うかもしれません(会議中、ピンヘッド部門のマネージャーがそれは決して変わらないと誓ったことを覚えていますか?解雇されたばかりです)。

私が実装したすべてのカスケード更新に対して支払いを受けるわけではなく、自分でコーディングした場合のボーナスもありません。

コンピューターはキーの意味を必要としません。私見、キーはコンピューター用であり、人々がデータの残りを台無しにします。


1
「キーはコンピューター用です。人々に残りのデータを台無しにさせてください。」+1、いいね。

2

値が変化する可能性のあるキーを持つことは悪い習慣ではありません。

適切なキーのプロパティには、安定性が含まれます。不変性は理想的ですが、前提条件ではありません。不変性のために人工キーを導入するのは悪い習慣です。

国際標準図書番号(ISBN)の例を取り上げます。それは非常に安定していますが、不変ではありません:いつか本の出版社は間違いを犯します-そして恐怖!-ISBN番号が重複する可能性があります。これは、ISBNがコンピューター化されたデータベースの候補キーとして受け入れられるべきではないということですか?もちろん違います。ISBNの利点の1つは、世界中のすべてのユーザーの問題を解決する信頼できるソースがあることです。

ISBNには、無意味な自動インクリメント整数キーに欠ける他の適切なキーの特性があります。 DBMS(ISBNは固定幅でチェックサムを含む)などを参照して検証されます。


3
ISBNは固定幅ですが、そうでない場合は除きます(ISBN-10とISBN-13を参照)。
CVn

それでは、重複するISBNを処理することをどのようにお勧めしますか?私が知っているすべてのRDBMSで、フィールドを主キーとして使用するには、フィールドにUNIQUE制約が必要です。
ワイルドカード

1

不変になる可能性のあるものはすべてあるはずです。これは、正確性を保証するのに役立ち、アプリケーションをマルチスレッド化するときに役立ちます。


1

はい、主キーは非ヌルで一意であることに加えて、不変でなければなりません。ただし、主キーの不変性を強制するデータベースをまだ見つけていないので、本当に必要な場合は、先に進んで値を変更できます。


0

すでにいくつかのコメントが言っているように、1つの解決策は新しい主キーを使用することです

たとえば(@onedaywhenの例に従って)、書籍のリストを格納するテーブルBooksが存在し、ISBNを主キーとして決定するために「使用」したとします。ただし、一部の著者は、間違ったISBNを入力するというミスを犯したため、ISBNの変更を要求しました。これには次のタスクが含まれていました。

  • テーブルBooksに新しいレジストリを作成します
  • 古いISBNから新しいISBNへのすべての参照をポイントします。(*)
  • 最後に、テーブルBooksから古いレジストリを削除します。

(*)外部キーを使用するデータベースモデルのすべての参照を見つけるのは簡単ですが、一部のモデルにはそれがありません。

Table Books
ISBN  is the primary key
NAME is a simple field.
etc.

として変更します

Table Books
InternalBookId as the primary key
ISBN as a simple field or an indexed field.
NAME is a simple field.
etc.

新しいInternalBookIdが自動数値である場合もあります。

それについての短所:

  • より多くのスペース/リソースを使用する新しいフィールドが追加されます。

  • モデル全体を書き換える必要があります。

  • 新しいモデルは自己説明的ではありません。

プロ

  • 「主キー」を変更できます。
  • 「主キー」をドロップまたはリファクタリングすることもできます。たとえば、BooksをISBN-13に変更して、古い列を削除して新しい列を作成することができます。

新しいテーブル:

Table Books
InternalBookId as the primary key
ISBN13 is a new field.
NAME is a simple field.
etc.
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.