hasOne
Grailsでの使用は特に紛らわしいと思います。たとえば、この質問では、toOne関係が次のように宣言されたときに何が起こるかを尋ねます。
class Person {
static hasOne = [address: Address]
}
上記のように、これによりperson_id
外部キーがアドレステーブルに表示されます。つまり、各アドレスは1人の個人のみを指すことができます。奇妙なことに、コードは「1人の住所が1人」と書かれていても、実際の結果は「1人の住所が1人」ということです。
実際、上記のように定義されているだけで、(データベースレベルで)複数のAddressレコードが同じPersonを指すことを妨げるものはありません。つまり、Personが実際に1つのAddressを持つ必要はありません。
興味深いことに、次のようにAddressクラスを作成した場合、同じデータベース表現が得られます。
class Address {
Person person
}
前のperson_id
例と同じように、外部キーはAddressテーブルにありますが、明らかに、何らかの方法でその関係を定義しない限り、コード内のPersonからAddressに到達することはできません。
また、データベース内の個人から住所へのtoMany関係をモデル化する場合は、同じテーブルレイアウトを使用することも興味深いことです。親の主キー(person_id)を子テーブルに配置します。データベースの観点からすると、を使用hasOne
すると、toMany関係が作成するのと同じ構造が作成されます。
もちろん、データベーステーブルを作成するだけでなく、いくつかの動作が関連付けられたGrailsドメインクラスを作成し、関係セマンティクスを強制します。この特定のビジネス例では、同じ住所レコードを複数の人と共有するのではなく、住所を個別に保存するだけです(人が複数の住所を持っている日の準備をする場合もあります)。私はおそらくこのアプローチに投票するでしょう:
class Person {
Address address
static constraints = {
address unique:true
}
}
外部キーはaddress_id
Personテーブルにあり、一意の制約により、2つのPersonレコードが同じアドレスを指していることはありません。