I've used most of the approaches you describe, albeit it without always
knowing their formal names.  Some are better supported than RDBO than
others.  I'll try to handicap the field for you.

> 1. Table per class (aka "union mapping" aka "filtered mapping")
> a single table with pkey corresponding to the base class, and
> a table for each subclass table sharing the same pkey.
> the "base class" table has a discriminant column in addition to
> its pkey value.
> pro: optimal storage, and can use "NOT NULL" appropriately
> con: foreign key to a base class is a little awkward
> con: query requires a join to get all columns

RDBO is not a good fit for this system, although it kind of depends on what
proportion of the fields are common.  Although it'd be possible to aggregate
RDBO objects appropriately within each subclass (e.g., a Vendor class would
"be a" Contact but "have a" VendorDetails RDBO object), you'd lose one level
of indirection in the Manager.  IOW, the Manager can auto-join, at most,
three levels deep in a single query.  By putting the details in another
table, you're using up one level just to get what would normally be the top
level fields.  (Of course, you could always write your own, better
manager...)

Another way to attack the problem is to make views that represent the
different types.  For example, a "vendors" view that combines all contacts
where type = vendor plus all the associated vendor_details columns into a
single virtual table.  Then have the Vendor RDBO class front that view.  If
the view is updatable, it should work.

> 2. "Table per instantiable class" (aka "horizontal mapping")
> a table for each instantiable subclass. each table has all columns,
> including pkey and all inherited columns. There may not be anything
> to ensure pkey uniqueness across these multiple tables.
> pro: query by class is easy
> con: following a foreign key to a base class (can go to any subclass) is
> awkward

RDBO supports this, since it's just a simple one-table-per class
relationship.

> 3. "Table per hierarchy"
> a single table that a union of all columns from all subclasses.
> it has a pkey and a discriminant column.
> pro: following foreign key is easy, to any class in hierarchy
> con: wastes some storage, and can't use "NOT NULL" for leaf columns
> con: query requires hooking to filter rows and columns by discriminant

I've done this in the past, but the technique I used may be a bit too hack-y
for your tastes.  What I did was make a custom mutator method for the
discriminant column, then I re-blessed the object into the appropriate
subclass based on the value of the column.  I actually had native support
for this technique in an early version of RDBO, but removed it because it
seemed too sketchy.

That said, this technique actually worked very well on a large project I
worked on.  It has the advantage of being transparent to the Manager and
(mostly) to users of the class.  IME, most databases perform pretty well
using the "one big table with some null fields" arrangement.  Database
constraints can ensure data integrity (e.g., making sure a Toy product can't
have an ISBN and a Book product can't have a subtitles field) while the
"magic re-blessing" ensures that the appropriate derived methods are
available in your objects.

> Any how, I can't find any documentation about any of this
> with Rose::*. (That isn't unusual; so far as I can determine,
> not a single one of the jillion perl OR solutions has anything
> documented about this so basic OR design issue.)
> 
> Are there some docs I'm missing?

I'm working on a tutorial that'll run through the basics up to medium-level
usage (in CVS now, about half done).  After I'm done, I'm considering an
"advanced techniques" document

For now, the documentation stand-in for all of this inheritance stuff is the
statement in the main documentation that says an RDBO class represents a
single table.  Anything more complex than that has not really been nailed
down yet.

In particular, I'm currently trying to sort out metadata inheritance.  For
example, imagine the "table per hierarchy" system implemented without
re-blessing.  I'd have a Product base class where I'd define all the common
columns.  Then I want to have a Book subclass where I simply define all the
book-specific columns.

The trouble is, the Book class gets its very own (blank) metadata object by
default.  So, what to do?  My choices seem to be:

* Make a copy of the Product metadata object, then add columns to it.

* "Transparently inherit" the Product metadata object, then add columns on
top of it.

The second option strikes me as needlessly complex, since I doubt the
metadata will ever change at runtime.  So why not just copy the base class
metadata and then build on it?  But even that is hard to "DWIM."  It'd have
to be explicit:

    package Book;
    use base 'Product';
    Book->meta(Product->meta->clone);
    Book->add_columns(...);
    Book->initialize;

I don't think that's too bad, but I'm open to suggestions.

I'd kind of like to add the "magic re-blessing" technique to this
arrangement, too, since it allows the Manager to get_products() and return a
heterogeneous list of all the different kind of product subclasses.  (As
opposed to being limited to a get_books() method, a get_toys() method, etc.)

Basically, these are two ways to create classes to front a single "table per
hierarchy" table.  One sticks all the columns into the base class and then
re-blesses at load time into an appropriate subclass that adds only
behavior, not metadata.  The other puts the common columns into the base
class and the common columns plus the more specific columns into the
subclasses (by either cloning the base class metadata or "transparently
inheriting it," whatever that means).

Anyway, like I said, I'm open to suggestions in this area.  While I don't
want to make RDBO needlessly complex, I'd like to do as much as possible to
help users support the various inheritence techniques.

-John




-------------------------------------------------------
SF.Net email is sponsored by:
Tame your development challenges with Apache's Geronimo App Server. Download
it for free - -and be entered to win a 42" plasma tv or your very own
Sony(tm)PSP.  Click here to play: http://sourceforge.net/geronimo.php
_______________________________________________
Rose-db-object mailing list
Rose-db-object@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rose-db-object

Reply via email to