1

データベースをクリーンアップしようとしており、テーブルに外部キー制約を配置するかどうかについて議論している最中です。あるテーブルの主キーのスキーマを変更すると、他のテーブルの外部キーのスキーマに影響を与える場合、それらを使用することは非常に説得力のある議論になります。しかし、これは事実ですか?

たとえば、主キーidを持つ USER テーブルがあり、 blogger_id がidに関連付けられた外部キーである別のテーブル BLOGGERS があるします。idが最初は SMALLINT として宣言されているとしますが、サインアップするユーザーの大群があり、id に使用できる範囲を増やす必要があります。idを INT に変更すると、BLOGGER テーブルのblogger_idも自動的に INT に変更されますか?

私の主な質問への回答に関係なく、そのフィールドに配置できるデータを制限する以外に、外部キー制約を正式に宣言する説得力のある理由を知っている人はいますか? ありがとう!

4

1 に答える 1

1

親テーブルのデータ型を変更しても、MySQL は子テーブルのデータ型を変更しません。

Usersテーブルの INT 値が最大に達したコンサルティング顧客の 1 人を助ける必要がありました。しかし、ご想像のとおり、 を参照する他の 30 のテーブルがありましたUsersALTER TABLEテーブルの主キーのデータ型を変更する前に、他の 30 個のテーブルのそれぞれを変更する必要がありましUsersた。これは、新しいユーザー ID が子テーブルによって参照されないと機能しないためです。

外部キーに関する質問については、はい、データの整合性を確保するために外部キーをお勧めします。私が分析したすべてのデータベースで、外部キーなしで実行しようとしたところ、子テーブルに多くの孤立した行があり、それらを自動的に検出する方法がありませんでした。

とはいえ、孤立したデータを避けるためにアプリケーションコードで「正しいことをする」と仮定して、サイトが外部キーを放棄することは驚くほど一般的です。

外部キーに対する反論の 1 つは、外部キーの存在によって予期しないロックが発生する場合があるということです。子行を UPDATE すると、トランザクションの間、その行がロックされることが予想されます。ただし、外部キーがある場合は、外部キーによって参照されるテーブルの親行ロックされます。

例: 親テーブルShoppingCartと子テーブルがあるとしますLineItems。で行の数量を UPDATE すると、LineItemsトランザクションはその行に対して排他ロック (X ロック) を作成します。ただし、 の親行に共有ロック (S ロック) も作成しShoppingCartます。たとえば、その行を参照している行の 1 つで作業を進めているときに、依存している行を DELETE したくないのは理にかなっています。

これは共有ロックであるため、複数のトランザクションが同時にこの種のロックを持つことができますが、1 つ以上のクライアントが暗黙的な共有ロックを保持しているときに親行を直接更新する必要がある場合は、ブロックされます。

于 2013-11-07T18:59:04.923 に答える