① SPASQL Example · ② SPASQL-MySQL · ③ SPASQL XTech Paper · ③ XTech Slides · ⑤ SPASQL CVS Tree
Eric Prud'hommeaux, RDF Data Access Working Group team contact
http://www.w3.org/2006/Talks/0518-SPASQL/
http://tinyurl.com/opxwl
XML: query element/attribute structure.
<Person name="Sue"><knows><Person name="Bob">...</Person></name></Person>
<Person id="p7"><name>Sue</name>...</Person>
<Person id="p23"><name>Bob</name>...</Person>
<knows who="p7" whom="p23"/>
<knows who="p7" whom="..."/>
SQL: tuples of attributes
SPARQL: query relationships between objects.
XQuery: query element/attribute structure.
let $pairs := //knows let $n1 := Person/@name[@id=$pairs/@who] let $n2 := Person/@name[@id=$pairs/@whom]
SQL: query attributes of objects
FROM knows JOIN Persons as who ON knows.who=who.id JOIN Persons as whom ON knows.whom=whom.id
SPARQL: query relationships between objects.
WHERE { ?who <foaf:knows> ?whom . ?who <foaf:name> ?n1 . ?whom <foaf:name> ?n2 }
subjects | predicates | object |
---|---|---|
order7 | product | product23 |
order7 | shipDate | 20050508 |
product23 | product-name | "Mystifier" |
subjects | object |
---|---|
order7 | 20050508 |
subjects | object |
---|---|
product23 | "Mystifier" |
Most of the data used in computer automation.
New example use case: OrderTracking.
id | customer | product | orderDate | shippingAddress |
---|---|---|---|---|
2186 | 518 | 7385 | 2006-05-01 01:08:30 | NULL |
2186 | 208 | 2922 | 2006-05-01 18:34:38 | NULL |
2187 | 518 | 7439 | 2006-05-01 01:05:30 | NULL |
Term: Graph
All 3 data models represent graphs:
<order prodct="#p23">...<Product id="p23" name="mystifier">
SQL graph shape comes from table aliases:
... WHERE o.orderDate < "20060501" AND o.shipDate = "20060508"
SPARQL graph shape (mostly) comes from variable.
... WHERE { ?o <orderDate> ?od . ?o <shipDate> "20060508" FILTER (?od < "20060501") }
Term: restrict
SQL restricts cross joins on attribute values.
... FROM Orders AS o JOIN Products AS p ON o.product=p.id
SPARQL has links in the data model that it queries.
... WHERE { ?o <Orders.products> ?p }
Term: tuple
Term: predicate
{ ?o <Orders.product> ?p }
{ ?o <Orders.product> ?p ?o <Orders.shipDate> ?ship }
{ ?t <Orders.product> ?p OPTIONAL { ?t <Orders.shipDate> ?ship } }
SPARQL UNION corresponds to an SQL subselected UNION
WHERE { { ?x <TableA.field> ?y } UNION { ?x <TableB.field> ?y } }
JOIN ( SELECT TableA.field AS foo FROM ... WHERE ...
UNION
SELECT TableB.field [AS foo] FROM ... WHERE ... ) AS U0 ON U0.foo=...
SELECT ?part ?descr ?given ?family ?posn ?rma ?billCity ?billState ?shipCity ?shipState WHERE { { ?order <Orders.product> ?prod . ?order <Orders.customer> ?cust . OPTIONAL { ?order <Orders.shippingAddress> ?shipAddr . ?shipAddr <Addresses.city> ?shipCity . ?shipAddr <Addresses.state> ?shipState } } UNION { ?order <Returns.product> ?prod . ?order <Returns.customer> ?cust . ?order <Returns.rma> ?rma } ?prod <Products.partNo> ?part . ?prod <Products.description> ?descr . { ?cust <Customers.id> ?num . ?cust <Customers.givenName> ?given . ?cust <Customers.familyName> ?family . ?cust <Customers.billingAddress> ?addr } UNION { ?cust <Employees.id> ?num . ?cust <Employees.givenName> ?given . ?cust <Employees.familyName> ?family . ?cust <Employees.position> ?posn } ?cust <Employees.homeAddress> ?addr . ?addr <Addresses.city> ?billCity . ?addr <Addresses.state> ?billState }
This SQL approximates the previous SPARQL query:
SELECT Products_0.partNo AS part, Products_0.description AS descr, U1.given, U1.family, U1.posn,U0.rma, Addresses_1.city AS billCity, Addresses_1.state AS billState, U0.shipCity, U0.shipState FROM ( SELECT Orders_0.customer AS cust, Orders_0.product AS prod, NULL AS rma, IF(Addresses_0.city IS NULL OR Addresses_0.state IS NULL, NULL, Addresses_0.city) AS shipCity, IF(Addresses_0.city IS NULL OR Addresses_0.state IS NULL, NULL, Addresses_0.state) AS shipState FROM Orders AS Orders_0 LEFT OUTER JOIN Addresses AS Addresses_0 ON Orders_0.shippingAddress=Addresses_0.id WHERE Orders_0.customer IS NOT NULL AND Orders_0.product IS NOT NULL UNION ALL SELECT Returns_0.customer AS cust, Returns_0.product AS prod, Returns_0.RMAnumber AS rma, NULL AS shipCity, NULL AS shipState FROM Returns AS Returns_0 WHERE Returns_0.customer IS NOT NULL AND Returns_0.product IS NOT NULL AND Returns_0.RMAnumber IS NOT NULL ) AS U0 INNER JOIN Products AS Products_0 ON U0.prod=Products_0.id INNER JOIN ( SELECT Customers_0.id AS num, Customers_0.givenName AS given, Customers_0.familyName AS family, NULL AS posn, Customers_0.billingAddress AS addr FROM Customers AS Customers_0 WHERE Customers_0.id IS NOT NULL AND Customers_0.givenName IS NOT NULL AND Customers_0.familyName IS NOT NULL AND Customers_0.billingAddress IS NOT NULL UNION ALL SELECT Employees_0.id AS num, Employees_0.givenName AS given, Employees_0.familyName AS family, Employees_0.position AS posn, Employees_0.homeAddress AS addr FROM Employees AS Employees_0 WHERE Employees_0.id IS NOT NULL AND Employees_0.givenName IS NOT NULL AND Employees_0.familyName IS NOT NULL AND Employees_0.position IS NOT NULL AND Employees_0.homeAddress IS NOT NULL ) AS U1 ON U1.num=U0.cust INNER JOIN Addresses AS Addresses_1 ON U1.addr=Addresses_1.id WHERE Products_0.partNo IS NOT NULL AND Products_0.description IS NOT NULL AND Addresses_1.city IS NOT NULL AND Addresses_1.state IS NOT NULL;
$query1 = "SELECT id FROM Orders WHERE Orders.shipDate = '20060501'"; mysql_query($query1); ... $query2 = "SPARQL: SELECT ?o WHERE { ?o <Orders.product> '20060501' }"; mysql_query($query2);
Term: materialized
Subselects materialized, at least in theory.
FROM (...) AS U0 INNER JOIN ( SELECT ... FROM Customers AS Customers_0 WHERE ... UNION ALL SELECT ... FROM Employees AS Employees_0 WHERE ... ) AS U1 ON U1.num=U0.cust
more details in the XTech talk
http://www.w3.org/2005/05/22-SPARQL-MySQL/XTech#features
SPASQL in MySQL project page
http://www.w3.org/2005/05/22-SPARQL-MySQL/
$#&@!!!