2011-11-14 5 views
1

defaultUrlとというエンティティへの参照を持つPageエンティティは、それぞれpageへの参照を持ちます。巡回外字キーを使用した削除

これは周期的なので、一度ページとURLを追加すると、相互に参照するものは削除できません。

私はそれを修正する2つの方法を見ることができますが、それを行う "教義"の方法の確信がありません。

  1. 私はのいずれかを実行する方法を見つけ出すことができなかった関係の一つだけインデックスではなく、外部キー制約
  2. 削除、外部キー制約のチェックをオフにし

を作りますこれら...あなたは知っていますか?

ありがとうございます!

答えて

2

これを設定する方法は次のとおりです。前述のように、少なくとも1つの外部キーをNULL値に設定する必要があります。

また、onDeleteカスケードをSET NULLに設定することも検討してください。そうすれば、レコードを削除する前にキーをNULLに更新する必要がなくなります。

あなたのschema.ymlのは、次のようになります。

Url: 
    columns: 
    page_id: { type: integer, notnull: true } 
    relations: 
    Page: { local: page_id, foreign: id } 

Page: 
    columns: 
    default_url_id: { type: integer, notnull: false } # ALLOWS NULL foreign key here 
    relations: 
    DefaultUrl: { class: Url, local: default_url_id, foreign: id, onDelete: SET NULL } 
+0

Bam!これは素晴らしい仕事...ありがとう!私は実際に削除する前に片側をヌルにすると思っていなかったので、私はそれをどうにかしていた。しかし、 'onDelete:SET NULL'がキーでした。今私は理解し、それは動作します! –

+0

@ nick-langうれしいわよ! – ybull

1

外部キーを作成するときは、常に1つをヌル可能にするか、1つの外部キー定義を省略します。

これにより、サイクルが中断されます。

最も単純なケース(SQL構文が、SAMPE原理が適用されます):

CREATE TABLE Employee (
    EmployeeId INTEGER NOT NULL IDENTITY(1,1) 
    ManagerId INTEGER NOT NULL 
    --... 
    PRIMARY KEY EmployeeId NONCLUSTERED 
) 

または、次のように:

CREATE TABLE Employee (
    EmployeeId INTEGER NOT NULL IDENTITY(1,1) 
    ManagerId INTEGER NULL 
    --... 
    PRIMARY KEY EmployeeId NONCLUSTERED 
    FOREIGN KEY FK_Manager REFRENCES Employee(EmployeeId) 
) 

私が好む、次のように

CREATE TABLE Employee (
    EmployeeId INTEGER NOT NULL IDENTITY(1,1) 
    ManagerId INTEGER NOT NULL 
    --... 
    PRIMARY KEY EmployeeId NONCLUSTERED 
    FOREIGN KEY FK_Manager REFRENCES Employee(EmployeeId) 
) 

がループを分けることができます外部キーを宣言するとき、常にダイアグラムをトレースし、サイクルがないことを確認する。私はすべてのサイクルが壊れるまで、最も危険でないキーは省略します。これにより、すべての表を一括エクスポートしてから別のデータベースに一括インポートすることができます。

編集:私はあなたが本エキスパートにこの質問をするときに、削除中に外部キーをオフにするような答えを得ることがわかります。これは2つの理由で間違っています。まず、通常のトランザクション操作でスキーマ定義が変更されるべきではありません。第2に、コードの残りの部分は外部キーがそこに存在することを期待しているため、アプリケーションコードでそれを処理しません。スキーマの変更には、トランザクション間の出血やテーブル全体のロックが厄介な癖があります。

+0

おかげジョシュアを。私はあなたが言っていることを完全に得ています...しかし、これはドクトリンでどのように行われているのか分かりますか? –

+0

doctrineは外部キーを宣言するのを "忘れる"ことはできませんか? – Joshua

+0

はい、私は完全にあなたの編集ステートメントに同意します。私はむしろ外来のキーを忘れることで問題を解決するだろう...私はちょうどその上のどこにもドキュメンテーションを見つけることができないと思うし、それを把握することはできません。ああ、私は今のところそれを残す必要があります。ありがとう! –

関連する問題