260 likes | 419 Views
Relationelle databaser og XML. 11 trin til at mappe en relationel database til XML. Inspireret af www-106.ibm.com/developerworks/library/x-struct. Trinene. Udvælg de data, der skal mappes til XML Bestem rod-elementet Modeller indholdstabellerne som elementer
E N D
Relationelle databaser og XML • 11 trin til at mappe en relationel database til XML. • Inspireret af www-106.ibm.com/developerworks/library/x-struct
Trinene • Udvælg de data, der skal mappes til XML • Bestem rod-elementet • Modeller indholdstabellerne som elementer • Modeller de felter, der ikke er fremmednøgler • Tilføj id som nøgle til elementerne • Modeller opslagstabeller og fremmednøgler til disse • Modeller rodelementets indhold • Modeller relationer gennem understrukturer • Modeller relationer vha. nøgler • Tilføj manglende elementer til rod elementet • Fjern id'er der ikke er blevet refereret til
Trin 1: Vælg de data, der er nødvendige • Eksempel: Data til opgørelse af salg pr. kunde pr. måned • De tabeller, der er nødvendige erCustomer, MonthlyTotal og MonthlyCustomerTotal
Trin 2: Find rod-elementet • Elementet skal beskrive hvad dokumentet indeholder. • Rod-elementet kommer altså ikke (nødvendigvis) fra en del af databasen. • Her vælges at kalde det for SalesData. • Elementet kan også indeholde oplysninger, som f.eks status for dokumentet, eller hvornår det er opdateret • Her vælges at indføre en statusattribut, som kan være enten 'NewVersion', 'UpdatedVersion' eller CourtesyCopy
Trin 2: Schema <?xml version="1.0" encoding="iso-8859-1"?> <xs:schema targetNamespace=http://ah.dk/ns/salesdata/ xmlns=http://ah.dk/ns/salesdata/ xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:simpleType name="StatusType"> <xs:restriction base="xs:NMTOKEN"> <xs:enumeration value="NewVersion"/> <xs:enumeration value="UpdatedVersion"/> <xs:enumeration value="CourtesyCopy"/> </xs:restriction> </xs:simpleType> <xs:element name="SalesData"> <xs:complexType> <xs:attribute name="Status" type="StatusType"/> </xs:complexType> </xs:element> </xs:schema>
Trin 3: Modeller indholdstabeller • Alle tabeller, undtagen ShipMethod, er indholdstabeller. • Relationstabeller (for at undgå mange – til - mange relationer) modelleres som indholdstabeller • I første omgang puttes der ikke indhold i typen. • Og minOccur sættes til nu til 0, men kan blive ændret senere
Trin 3: Schema <xs:element name="SalesData"> <xs:complexType> <xs:sequence> <xs:element name="Invoice" minOccurs="0"></xs:element> <xs:element name="Customer" minOccurs="0"></xs:element> <xs:element name="Part" minOccurs="0"></xs:element> <xs:element name="MonthlyTotal" minOccurs="0"></xs:element> <xs:element name="MonthlyCustomerTotal" minOccurs="0"></xs:element> <xs:element name="MonthlyPartTotal" minOccurs="0"></xs:element> <xs:element name="LineItem" minOccurs="0"></xs:element> </xs:sequence> <xs:attribute name="Status" type="StatusType"/> </xs:complexType> </xs:element>
Trin 4: Modeller felter som ikke er fremmednøgler • De enkelte kolonner modelleres som attributter • Ved f.eks tekstblokke kan det være ide at bruge elementer istedet. • Det vælges at bruges AttributeGroup
Trin 4: Schema <xs:attributeGroup name="InvoiceAttributes"> <xs:attribute name="InvoiceId" type="xs:number" use="required"/> <xs:attribute name="InvoiceNumber" type="xs:number" use="required"/> <xs:attribute name="TrackingNumber" type="xs:number" use="required"/> <xs:attribute name="OrderDate" type="xs:date" use="required"/> <xs:attribute name="ShipDate" type="xs:date" use="required"/> </xs:attributeGroup> .... <xs:element name="SalesData"> <xs:complexType> <xs:sequence> <xs:element name="Invoice" minOccurs="0"> <xs:complexType> <xs:attributeGroup ref="InvoiceAttributes"/> </xs:complexType> </xs:element> ..... </xs:sequence>
Trin 5:Tilføj id som nøgle til elementerne • ID'et kaldes tabelnavnID, og tilføjes bare til attributgruppen • Samtidig defineres nøglen med <key> • Den defineres under <SalesData>, da den samme værdi godt kan forekomme hvis der er flere sæt af <SalesData>
Trin 5: Schema <xs:attributeGroup name="InvoiceAttributes"> <xs:attribute name="InvoiceId" type="xs:number" use="required"/> <xs:attribute name="InvoiceNumber" type="xs:number" use="required"/> <xs:attribute name="TrackingNumber" type="xs:number" use="required"/> <xs:attribute name="OrderDate" type="xs:date" use="required"/> <xs:attribute name="ShipDate" type="xs:date" use="required"/> </xs:attributeGroup> .... .... <xs:element name="SalesData"> <xs:complexType> ... </xs:complexType <xs:key name="InvoiceKey"> <xs:selector xpath="Invoice"/> <xs:field xpath="InvoiceID"/> </xs:key>
Håndtering af fremmednøgler • I en relationel database bliver referencer beskrevet vha. fremmednøgler • I XML kan fremmdnøgler mappes som: • en understruktur under tabelelementet (parent –child) • en reference (dvs. <keyref> hvis man bruger schema) • Brug af parent-child er mest XML-agtig. • Brug af referencer er mere fleksibel, men typisk vil referencer kun pege i en retning. • Traversering vha. referencer er som regel langsommere end gennem parent-child relationer • Min anbefaling: Brug kun referencer, når parent-child ikke er mulig. F.eks ved relationstabeller (mange – mange).
Navigation mellem tabeller (et eksempel) Ved et system til månedsrapportering kunne referencerne retning se således ud.
Trin 6: Modeller opslagstabeller og fremmednøgler til disse • Definer en attribut i den tabel, hvor fremmednøglen er (her Invoice) • Giv attributen det samme navn som opslagstabellen (ShipMethod), og gør den obligatorisk • Gør den til en enumeration liste med værdierne fra opslagstabellen.
Trin 6: Schema <xs:simpleType name="ShipMethodType"> <xs:restriction base="xs:NMTOKEN"> <xs:enumeration value="USPS"/> <xs:enumeration value="FedEx"/> <xs:enumeration value="UPS"/> </xs:restriction> </xs:simpleType> ...... <xs:attributeGroup name="InvoiceAttributes"> <xs:attribute name="InvoiceId" type="xs:number" use="required"/> <xs:attribute name="InvoiceNumber" type="xs:number" use="required"/> <xs:attribute name="TrackingNumber" type="xs:number" use="required"/> <xs:attribute name="OrderDate" type="xs:date" use="required"/> <xs:attribute name="ShipDate" type="xs:date" use="required"/> <xs:attribute name="ShipMethod" type="ShipMethodType" use="required"/> </xs:attributeGroup>.....
Trin 7: Modeller rodelementets indhold • Overvej hvilke elementer der skal være under rod elementet. • Og hvor ofte elementet kan forekomme • Men andre elementer kan komme til senere • F.eks kan vi her sige at det dokumentet skal bruges til oftest relateres til Invoice og MonthlyTotal, som begge kan forekomme flere gange i vilkårlig rækkefølge
Trin 8: Schema <xs:element name="SalesData"> <xs:complexType mixed="false"> <xs:sequence minOccurs="0" maxOccurs="unbounded"> <xs:element name="Invoice" minOccurs="0"> <xs:complexType> <xs:attributeGroup ref="InvoiceAttributes"/> </xs:complexType> </xs:element> <xs:element name="MonthlyTotal" minOccurs="0"> <xs:complexType> <xs:attributeGroup ref="MonthlyTotalAttributes"/> </xs:complexType> </xs:element> </xs:sequence> <xs:attribute name="Status" type="StatusType"/> </xs:complexType> • Alle elementer, undtagen Invoice og MonthlyTotal er nu (midlertidigt) fjernet fra SalesData
Trin 8: Modeller relationer gennem understrukturer • 1 – mange og 1 – 1 relationer, og hvis et child kun har en parent, kan modelleres gennem understrukturer. • MonthlyPartTotal og MonthlyCustomerTotal kan være børn til MonthlyTotal • LineItem kan være barn til Invoice
Trin 8: Schema <xs:element name="Invoice" minOccurs="0"> <xs:complexType> <xs:sequence maxOccurs="unbounded> <xs:element name="LineItem" maxOccurs="unbounded> <xs:complexType> <xs:attributeGroup ref="LineItemAttributes"/> </xs:complexType> </xs:element> </xs:sequence> <xs:attributeGroup ref="InvoiceAttributes"/> </xs:complexType> </xs:element> • Her er LineItem indført som en 1 – mange relation
Trin 9: Modeller relationer vha. nøgler • Mange – mange relationer og børn som ville få flere forældre (f.eks relationstabeller) kan ikke modelleres gennem understrukturer. • Her må vi bruge key referencer
Trin 9: Schema • Her er PartID fremmednøgle i MonthlyPartTotal <xs:element name="MonthlyPartTotal"> <xs:complexType> <xs:attributeGroup ref="MonthlyPartTotalAttributes"/> </xs:complexType> <xs:keyref name="PartIDRef" refer="PartKey"> <xs:selector xpath="Part"/> <xs:field xpath="PartID"/> </xs:keyref> </xs:element>
Trin 10: Tilføj manglende elementer til rod elementet • Customer og Part er pt. ikke en del af xml-træet. • De sættes derfor ind under SalesData (roden)
Trin 11: Fjern ubrugte ID keys • Det er kun PartID og CustomerID, der kom i brug. • Derfor fjernes de andre 5 ID'er
Eksempel på en valid xml-fil <?xml version="1.0"?> <n:SalesData xmlns:n="http://ah.dk/ns/salesdata/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://ah.dk/ns/salesdata/ D:\db2F04\SalesData.xsd" Status="NewVersion"> <Customer CustomerID="2" Name="BobSmith" Address="2AnyStreet" City="Anytown" State="AS" PostalCode="ANYCODE"/> <Invoice InvoiceNumber="1" TrackingNumber="1" OrderDate="1967-08-13" ShipDate="1967-08-13" ShipMethod="FedEx" CustomerID="2"> <LineItem Quantity="2" Price="5" PartID="2"/> </Invoice> <Part PartID="2" PartNumber="13" Name="Winkle" Color="Red" Size="10"/> <MonthlyTotal Month="January" Year="2000" VolumeShipped="2" PriceShipped="10"> <MonthlyCustomerTotal VolumeShipped="5" PriceShipped="25" CustomerID="2"/> <n:MonthlyPartTotal VolumeShipped="8" PriceShipped="40" PartID="2"/> </MonthlyTotal> </n:SalesData>