0

基本的に、状況は次のようになります(簡略化された擬似コード)。

私は2つのテーブルの人と国を持っています。

人物テーブル:

KEY INT ID, STRING NAME, STRING COUNTRY

カントリーテーブル:

KEY INT ID, STRING COUNTRY_NAME

クライアントは、カントリーテーブルの内容を制御できるため、リストに郡を追加および削除できます。この国の値は、人物を作成するときにドロップダウンリストに表示されます。人が作成されると、国の文字列の値が人の行の国の列に挿入されます。

私にとって、Personは国への外部キー参照を持つ必要があることは理にかなっていますが、クライアントが国テーブルに表示される内容を制御できるため、使用済みの国を削除することはできないため、それらは別々のテーブルとして保持されます(参照整合性とすべて)。これは私の同僚がこの場合外部キーを使用しないようにした議論ですが、この問題にはもっと良い解決策があるはずだと思います。それで、私の同僚は正しいですか、それとももっと良い解決策がありますか?

クライアントはcountryテーブルの値を追加および削除できますが、countryテーブルから値が削除された場合、その値を使用した作成者はその値を保持する必要があります。

4

3 に答える 3

1

FOREIGN KEY参照されたテーブルのレコードが削除されたときに何をするかをオプションとして指定できます:(ON DELETE ([RESTRICT | CASCADE | SET NULL | NO ACTION])これらはMySQLで使用可能なオプションです)。

一般に、外部キーを使用する必要があります。たとえば、人が国を参照した場合、なぜその国を削除できるのでしょうか。外部キーがない場合は、参照を手動で確認する必要があります。

あなたの例では、国のIDフィールドも参照として使用しています。国の名前を変更することができ、IDを参照するすべての人がこの情報を取得します(もちろん、参加する必要があります)。

この更新の別の解決策はON UPDATE CASCADE、元の外部キーにオプションを指定することです。これCountryにより、国の名前を変更するときに、対応する人物のすべてのフィールドが更新されます。

于 2011-11-14T14:22:29.567 に答える
1

isactive列を作成すると、履歴レコードのデータに最初に選択された郡(または更新された値。以下を参照)が表示され、ドロップダウンリストを調整してアクティブな国のみを表示できます。いかなる状況でも、外部キー制約を削除しないでください。これは、データの整合性の問題のレシピです。

nullのアイデアへの設定も、一般的に悪いものです。その人がいる国に関するデータを失いたくありません。

国が変更される可能性がある場合(新しい国が追加されるのではなく)、カスケード更新を使用できますが、この場合は代理キー(変更しないでください)を使用することをお勧めします。その後、名前が変更されると、何百万もの子レコードを更新しなくても、どこにでも反映されます。

于 2011-11-14T14:26:22.370 に答える
0

データベースは、外部キーによって参照されているレコードの削除を処理するようにすでに設計されています。

それでも外部キーを使用し、それをどのように動作させるかを指定する必要がありますon delete。(人によって)まだ参照されているレコード(国)を削除できるようにする場合は、次を使用します。

foreign key country_id references countries(id)
    on delete set null;

参照されている国が消えないように外部キーが必要な場合は、on delete句を省略して、まだ参照されている国を削除しようとすると失敗します。これは通常、望ましい動作です。データベースを無効な状態にしようとすると失敗するはずです。

関連するレコードの外部キーがに設定されているnullか、参照されているレコードの削除が防止されているかに関係なく、外部キーは参照整合性を強制および維持します。それが彼らの仕事であり、彼らはそれがかなり得意です。

于 2011-11-14T14:12:53.020 に答える