Stevan Little wrote:
On May 29, 2010, at 11:20 PM, Darren Duncan wrote:
2. Besides the ability to introspect or perform powerful searches on your objects using SQL/etc, I see another big advantage of using database storage without serialization as portability. You can have applications written in different programming languages sharing the same database and the same objects, because they don't contain Perl-specific data formats.

KiokuDB mostly uses JSON and JSPON as the storage format, which is not Perl specific. The serialization format we store in is dependent on the Moose class definition, so in that way it is not terribly portable.

An advantage of not using serialization like JSON, but rather storing each object attribute as a database member attribute, is that the DBMS itself can then most easily be defined to enforce the consistency of your objects, so someone accessing the database by some way other than KiokuDB, or using a buggy version of KiokuDB, is less likely to be able to corrupt the data. As for how to get the database to do that, one general answer is CHECK constraints, though that is a fallback to where terser/simpler kinds of constraints don't do the job.

A relational database can map to an object structure of any language fairly easily. Add attributes/columns for mutually heterogeneous data, like when you would add object attributes, and add tuples/rows for mutually homogeneous data, like when you would use arrays or sets.

And then you get the impedance mismatch. You are ignoring inheritance, which is not really possible in a relational model.

I wasn't ignoring inheritance, but rather was just being terse by giving examples rather than every relevant detail.

As for inheritance, a relational model can handle that just fine.

You also have several options for how to lay it out, depending on what you're going for.

One option in the general case is to have a distinct database relvar/table per each instantiatable class, which has one attribute/column per class attribute, plus an extra attribute/column to hold an ID value for the object. When a class composes a role or inherits from a class, the attributes defined in the others plus those defined directly in the first class would each have a corresponding attribute in the relvar/table attribute/column, so that each attribute of the object of that class has a place to be stored. And so, when multiple classes compose the same attributes, their corresponding relvars/tables all have common-named/typed attributes/columns corresponding to said.

Another option in the general case is to also have a database relvar/table for each role or non-instantiatable class as well, which is then the only one having the attributes/columns that the corresponding declares, and then the relvars/tables mentioned in the previous paragraph then wouldn't have these but instead would have matching ID values to relate records in them to ones in the others.

Generally speaking, with the exception perhaps of Moose classes where every single object can have different names or kinds etc of attributes, rather than those being class-defined, I would think the best design is for the database to have exactly the same granularity of component data as the Moose objects do. Just where each object can have different attributes, then the database could probably be designed like a key-value store, but that's less ideal.

One should think about the database schema like they think about their code. It is just as reasonable to change the schema as it is to change what classes you have or what attributes they have. The schema *is* code, and the data it holds is like objects of classes. No more, and no less.

Remember, objects are graphs not sets of tuples.

And graphs can be represented as sets of tuples, such as where tuples have 2 attributes that name connected graph nodes. For that matter, objects only *represent* graphs themselves.

Now, all that I've had to say here isn't meant to diminish that the JSON serialization approach is useful and probably a best fit for many usage scenarios.

But at the same time, relational databases are very powerful and their strengths, of ensuring that data is consistent and making it easier to search, should be utilized, where it makes sense to do so. Using a relational database, without exploiting the features that make them uniquely powerful, is like wasting the tools you have.

Perhaps a reasonable analogy is people who use Perl 5 but write their Perl code as if they were using Perl 4, and were faking references rather than using real references, structures, and objects. Sometimes I think of that when I hear of people just dumping objects as a serialized string in a relational database.

-- Darren Duncan

Reply via email to