Hallo,
Eigentlich möchte ich mit der Angabe von unique oder key sagen, dass die PersonID eindeutig sein soll, so dass man eindeutig sagen kann: Duffy Duck hat die PersonID 1 und nicht, dass plötzlich auch Daisy Duck die PersonID 1 hat.
Dazu (d.h. wenn du nichts anderes erreichen möchtest) reicht unique und brauchst weder key noch keyref. [1]
Unter Bestellung soll nur eine Art Verbindung zur eigentlichen PersonID hergestellt werden -> also keyref (dachte ich jedenfalls). Dabei ist es egal, ob diese dort mehrmals auftritt. Eine Person kann ja auch mehrere Bestellungen auslösen.
[2] Das sagt mir aber, dass du deine Personen _nicht_ in <Bestellung> verwaltest, d.h. dass die Liste der möglichen Personen woanderes steht und du in <Bestellung> auf diese Liste referenzieren willst: d.h. du hast
- eine Liste der Personen, in der du sicherstellst, dass keine zwei Personen dieselbe PersonID haben (kannst mit unique oder key machen)
- eine Liste der Bestellungen, in der du sicherstellen willst, dass die Person die die Bestellung aufgegeben hat, tatsächlich eine Person aus der Liste der Personen ist (machst du mit keyref) und weil du bereits in der Liste der Personen die Eindeutigkeitsbeschränkung definiert hast, kannst du eben aus Bestellung/Person darauf referenzieren.
Nur: ich kenne die Struktur deines XMLs nicht, aber was ich bisher gesehen habe, legt nache, dass du eben keine Liste der möglichen Personen hast [3], sondern nur eine Liste von Bestellungen und dazu reicht wiederum --> [1].
Ein <xs:selector xpath=".//Person"/> in diesem Konstrukt würde dagegen bedeuteten, dass in Bestellungen jede Person, die über ihre PersonID identifiziert wird, eindeutig bestimmt sein sollte. D.h. es dürfen keine zwei Kunden mit derselben PersonID innerhalb von Bestellungen auftreten.
Achso, das ist damit gemeint. D.h. wenn ich die PersonID zwar mit key in Person angebe (oder sonstwo), diese in Bestellungen mit keyref referenziere, mache ich durch Angabe von .//Person diese eindeutig? D.h. es können nicht wie oben beschrieben 2 Personen die gleiche PersonID haben?
Ich glaube, dass dir noch immer nicht so ganz klar ist, was key-keyref macht.
Lese nochmal [2] durch und vergleich es mit deinem XML siehe --> [3].
Wie gesagt: wenn es dir nur um die Eindeutigkeit einer Person geht, reicht unique (dort kannst du auch mehrere Felder angeben).
Schau dir das Beispiel unter http://www.edition-w3c.de/TR/2001/REC-xmlschema-0-20010502/#K5 an (ignoriere mal die Namensräume einfach, der Text unter das Schemabeispiel ist leider als Erklärung sehr irreführend und kaum brauchbar, weil dort im gegensatz zum englischen Original nicht auf das Beispiel Bezug genommen wird. Wenn du kannst, solltest du dazu das englische Original durchlesen).
Dort wird mit:
<unique name="EindBeschr1">
<selector xpath="a:Kundenkonto/a:Kunde"/>
<field xpath="a:Name"/>
<field xpath="a:Vornamen"/>
<field xpath="a:Geburtsdatum"/>
</unique>
sichergestellt, dass im <KundenAufstellung> jede Kunde nur einmal vorkommen darf. Der selector "Kundenkonto/Kunde" wählt eine Menge von Elementen aus, und um die ausgewählte Elementen zu identifizieren, werden die Elemente Name, Vorname, Geburtsdatum (innerhalt der ausgewählten Elemente) herangezogen.
Das alles hat aber nichts mit keys und keyrefs zu tun.
du kannst dann dort oder unter http://www.edition-w3c.de/TR/2001/REC-xmlschema-1-20010502/#element-keyref die Beispiele für die Verwendung von key und key-ref anschauen. Das zweite Bsp. ist zuerst mal sicher kompilzierter, aber auch sehr anschaulich dafür wie key-keyref genutzt werden kann (man muss halt immer das XML dazudenken ;-))
Das ist also die eine Sache. Damit hättest du die Eindeutigkeit von Person sichergestellt.
<xs:key name="PersonID">
<xs:selector xpath="Person"/>
<xs:field xpath="@PersonID"/>
</xs:key>
Dieser key zeigt auf das Attribut PersonID in Person, richtig?
Ja (auch wenn es jetzt nicht gut ist, dass du den Code aus dem Kontext genommen hast!)
Damit ist jetzt sichergestellt, dass jede Person einen eindeutigen Schlüssel PersonID hat?
Ja.
<xs:keyref name="PersonID2" refer="PersonID">
<xs:selector xpath="Bestellungen/Bestellung/Person"/>
<xs:field xpath="@PersonID"/>
</xs:keyref>
Dieser keyref zeigt auf das Element Person in Bestellungen/Bestellung, richtig?
Ja. (wobei das wort "zeigen" hier falsch ist, aber ich weiss was du damit meinst)
D.h. es muss ein Element Person unter Bestellung existieren?
Ja.
Kann ein keyref auch auf ein Attribut zeigen oder ist mit dieser XPath-Angabe gleich beides gemeint?
Nain. Ein <selector> darf nicht auf ein Attrubut zeigen, das darf nur ein <field>.
Ich möchte doch nur wie in meinen Datenbanken sagen: Person hat einen eindeutigen Schlüssel PersonID, der in Bestellung als Fremdschlüssel auftaucht, um referenzieren zu können, wer die Bestellung denn überhaupt ausgelöst hat.
Da sind wir wieder ganz bei [2] und somit müssen in deinem XML 1) und 2) vorhanden sein.
Grüße
Thomas