Wols Lists wrote: > On 13/12/10 22:44, Darren Duncan wrote: >> I am also very interested in these subjects. >> >> I believe that the relational model can accurately model anything in >> the real world, and that this can be implemented in efficient ways, >> with physical structure taking hints from logical structure. > > But can you STORE it?
Yes. Anything that a computer can represent, a computer can store. > A challenge I throw out - please STORE a list in the relational model. > Oh - I'll just add a couple of sensible constraints. (1) as seen by the > application, there mustn't be any duplicate data (I believe the > relational model says you mustn't duplicate data, yes?). And (2) - again > as seen by the application - you mustn't mix data and metadata in the > same table. Worded a bit differently, don't get your cardinal and > ordinal numbers mixed up :-) Okay, I'll take this up. I will model an array of elements, where each element has arbitrary/possibly-user-defined type Foo, in terms of a relation. I also argue that the array index is necessary in any model or implementation, relational or not; the user explicitly cares about this because they want an order associated with a list of Foo that isn't intrinsic to the Foo values themselves. Sure, the language can provide syntax for operations such that users don't actually have to use the index numbers, but they still have to be there, and users have explicitly said they must by declaring their list is ordered. And indexes must exist somehow; every implementation of an array must have some way of referring to and finding an element regardless of language. >> Also, that you can model any data structure simply over tuples and >> relations, including arrays and bags, and likewise implement such >> tuples and relations with physical arrays behind the scenes. > > Again, you use the word *model*. Isn't this pushing all this complexity > back out into the app - where it DOESN'T belong? No. All the complexity is stored and enforced by the database, right where it belongs, and not with the app. Since the format I describe of using a binary relation to represent an array is canonical for Muldis D, it has related shorthands, and by using those, users don't see the index numbers which conceptually exist. Muldis D short-hand for declaring the array type: material Foo_Array ::= array_of.Foo Muldis D longer-hand for same: material Foo_Array ::= relation-type { over tuple-type { attr index : subset-type of Int where { topic >= 0 } attr value : Foo } primary-key { index } where { #topic > max(topic{value}) } } One way to declare a database relvar of that type: relvar list_of_foo : nlx.lib.Foo_Array Or Foo_Array can be the declared type of a lexical variable, or a function parameter, or another relation attribute, or whatever. Here is a SQL analogy: CREATE TABLE "list_of_foo" ( "index" INTEGER CHECK "index" >= 0, "value" FOO, PRIMARY KEY ("index") ); CONSTRAINT CHECK (SELECT COUNT(*) FROM "list_of_foo") > (SELECT MAX("index") FROM "list_of_foo"); Now a relational DBMS can see the above definition and realize that it means a simple ordered array, and so can implement and store it as such physically if it chooses to; but the implementation choice is left to the DBMS. For an example of assigning to said array variable, lets assume for simplicity that Foo is actually just Text (if not, then replace the string literal for a Foo value literal) ... In Muldis D, the short-hand: list_of_foo := ['cherry', 'apple', 'orange'] Muldis D longer-hand for the same: list_of_foo := %:[index, value]:{ [0, 'cherry'], [1, 'apple'], [2, 'orange'], } And the SQL analogy (assume within a transaction): SET CONSTRAINTS ALL DEFERRED; TRUNCATE "list_of_foo"; INSERT INTO "list_of_foo" ("index", "value") VALUES (0, 'cherry'), (1, 'apple'), (2, 'orange') ); SET CONSTRAINTS ALL IMMEDIATE; You will see that in all the short-hands, there is no array index metadata to be seen. The DBMS API for the application can map these arrays-as-relations to its native arrays fairly simply. >> Ordered lists and bags can be logically binary relations with >> index+value or value+count attributes. (That is also the canonical >> way to do it in Muldis D.) > > I think this is what I said above you mustn't do - mixing up your > ordinals and cardinals? (And mixing your data and metadata.) The index is an ordinal, the count is a cardinal and both are just data. Lots of actual user data is the same. If we're storing a count of apples, or quantity of grain, in our inventory, that count is a cardinal number. If we're listing the starting lineup for ball players, their order to go out is an ordinal number. If you want the DBMS to enforce that they are not mixed up, as you could do with plain integers, you can declare wrapper types to keep things separate; for example: scalar-type OrdinalInt { attr where_on_line : Int } scalar-type CardinalInt { attr how_much : Int } ... and then use those instead of Int; the DBMS will not allow any of those 3 to be substituted for the other, being strongly typed. >> It is perfectly valid to nest tuples and relations inside each other >> (these *are* valid 1NF), and so likewise you can have record field >> values that are sets or arrays or tables or whatever. > > Which is where Pick scores, this is easy to do and flows naturally from > the data model. But it does it the other way round - the logical > structure takes hints from the real-world-physical structure (and the > database designer makes sure the physical database structure mimics the > real-world physical structure). > > Cheers, > Wol -- Darren Duncan _______________________________________________ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users