Re: The Zen nature of a Delphi database application



On Sun, 18 Feb 2007 12:22:26 +0100, "Maarten Wiltink"
<maarten@xxxxxxxxxxxxxxxxxx> wrote:


What about storing polymorphic objects in a DB? That's another
bit of a snag for me. What used to be a single collectin of
polymoprhically-accessed objects is now a number of different
tables, since each subclass needs its own set of fields.

Give the class a virtual method and override it in each class that
needs different behaviour. Basic OO (sorry Bjřrge).

Right. I'm concerned with storage/retrieval. More on that below.

This is of course for storing. Retrieving might be a slightly
harder problem, what with probably needing to know all possible
descendent classes beforehand. Although registering classes isn't
particularly hard.

I do have classes that register themselves and factories that create them
based on some form of ID that a single class responds to. But for storage,
it immediately implies a "god class" that first loads a "metatable" with
class IDs of the actual data objects. So there are now at least two tables
which must be kept in sync: the metatable (classID, objectUID) and one or
more tables for the objects themselves.

To me, it also implies that objects shouldn't be in the business of
persisting themselves, because it would create an ugly assymetry: an object
can write all the pieces necessary to recreate it from storage, but
recreating the object happens in two stages (god class creates the object,
then the object loads its properties by itself). I'm leaning towards a more
symmetrical system, where objects are completely passive with regard to
storage.

In general I tend to stay away from giving methods such as
SaveToXxx/LoadFromXxx to classes, because whenever you need a new storage
format, you have to add a new pair of such methods to all persisted
classes. This quickly becomes hard to manage, and introduces implicit
coupling between unrelated objects: TFoo.SaveToZzz and TBar.SavetoZzz must
do the same exact thing even though they know nothing about each other.

There is nothing particularly hard about any of that; my doubts are more
along the lines of: is this indeed the only thing to do, or are there
better (more reliable or just simpler) arrangements that haven't occurred
to me.

There are three ways to store polymorphic objects in a relational
database that I'm aware of. You can have a single table with
optional fields for all possible cases, or a different table for
every possible case, or extension tables for all child classes,
that have a foreign key as their primary key. Only the second
option is safe in that it's impossible to construct records for
which you don't have a class available. The third corresponds
very nicely to classless prototype-based (ad-hoc, 'instant')
polymorphism.

What I am worried about - perhaps needlessly - is performance. I planned to
use your third method: one table with all that is common to all classes,
and one additional table per concrete class. This means that to read a
complete record I need a SELECT...WHERE query on the "concrete" table,
keyed on the object's UID. Assuming that objects are lazy-loaded and that
the table has an index on the UID field, will this cause a noticeable
delay? What about displaying a list of all records that way, say a thousand
of them?

marek


--
No ads, no nags freeware: http://www.tranglos.com



--
No ads, no nags freeware: http://www.tranglos.com
Skype: tranglos GG: 5967086

"For every bit belonging to me as good belongs to you."
.