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

Reply via email to