Ich finde die Verwendung von hasOne
in Grails als besonders verwirrend. Zum Beispiel fragt diese Frage, was passiert, wenn eine TOONE Beziehung wie folgt erklärt:
class Person {
static hasOne = [address: Address]
}
Wie oben erwähnt, dies die person_id
Fremdschlüssel verursacht in der Adresstabelle angezeigt werden, was bedeutet, dass jede Adresse nur Punkt eine Person. Was ich seltsam finde, ist, dass obwohl der Code als "eine Person hat eine Adresse" geschrieben wurde, das tatsächliche Ergebnis ist, dass "eine Adresse eine Person hat".
Und in der Tat, nur wie oben definiert, gibt es nichts (auf der Datenbank-Ebene) verhindert mehr als ein Address-Datensatz auf die gleiche Person zeigen, was bedeutet, dass eine Person nicht wirklich eine Adresse haben muss .
Interessanterweise würden Sie die gleiche Datenbank Darstellung erhalten, wenn Sie die Adresse Klasse wie folgt erstellt:
class Address {
Person person
}
Die person_id
Fremdschlüssel in der Adresstabelle sein werden, so wie wie im vorherigen Beispiel, aber Natürlich können Sie nicht von der Person zur Adresse im Code gelangen, ohne diese Beziehung ebenfalls zu definieren.
Interessant ist auch, dass wenn Sie eine ToMany-Beziehung von Person zu Adresse in der Datenbank modellieren, Sie das gleiche Tabellenlayout verwenden würden. Sie würden den Primärschlüssel der Eltern (person_id) in die untergeordnete Tabelle einfügen. Aus einer Datenbankperspektive erzeugt die Verwendung von hasOne
die gleiche Struktur, die eine toMany-Beziehung erzeugen würde.
Natürlich erstellen wir nicht nur Datenbanktabellen, sondern erstellen auch Grails-Domänenklassen, denen ein gewisses Verhalten zugeordnet ist, sowie eine Erzwingung der Beziehungssemantik. In diesem speziellen Geschäftsbeispiel möchten Sie wahrscheinlich nicht den gleichen Address-Datensatz für mehrere Personen freigeben, sondern Sie möchten die Adresse nur separat speichern (möglicherweise für den Tag, an dem eine Person mehrere Adressen hat). Ich würde wahrscheinlich für diesen Ansatz stimmen:
class Person {
Address address
static constraints = {
address unique:true
}
}
Die address_id
Fremdschlüssel in der Tabelle Person sein werden, und die eindeutige Einschränkung erzwingt, dass keine zwei Personendatensätze an derselben Adresse zeigen.
Das macht Sinn, danke. Tut mir leid, ein bisschen von einem Gehirn furze von mir hier. Ich wurde in die Grals-Mechanismen eingewickelt und trat nicht zurück, um aus einer Datenbankperspektive darüber nachzudenken. –