views:

85

answers:

5

[noob warning!] I need to store some data in some tables where it is like the equivalent of an array of pointers to polymorphic objects. E.g. (pseudo C++)

struct MyData { string name; }
struct MyDataA : MyData { int a,b,c; }
struct MyDataB : MyData { string s; }
MyData * data[100];

I don't really know what google search to enter! How would you store info like this in an SQL database?

My random thoughts:

  • I could have one table with a column that is the struct identifier and then have redundant columns, but this seems wasteful.
  • I can have one table for each struct type. These would have a foreign key back to the master array table. But, how do I point to the struct tables?
+1  A: 

One possibility is an XML field to store the data, this allows searching and retrieving whilst also being relatively easy to serialise. (the question says SQL, but doesn't specify a specfic vendor database, so XML may not work for every DB solution.)

Edit : I'm going to caveat this because it's not entirely clear what needs to be stored / retrieved / purpose etc, so XML may be entirely inappropriate - I'm throwing it out there as a thought provoker instead.

Andrew
I have a "real time" stream of data that I want to filter into a database. Database is SQLite (ADO). XML would be too slow (marshalling) and create massive (GB) files. XML was where the source data came from.
Nick
+3  A: 

This is a complex topic. To get an idea of the strategies involved, I suggest reading the Hibernate docs on this topic:

http://docs.jboss.org/hibernate/stable/core/reference/en/html/inheritance.html

Even if you're not using Hibernate, the relational mapping concepts are still relevant. Note that Hibernate does not dictate any one strategy, because no one approach is better than the others.

skaffman
+2  A: 

I do the "table-per-sublcass" style from the Hibernate docs.

You make a Person table with all the things you know about a person, plus the PersonID. Then you make a Customer table, with only the data that's unique to a Customer (account balance, etc). Put the PersonID in the Customer table. A WebsiteUser might have a CustomerID in it, and so on down the chain.

One-to-one relationships mapping the IS-A inheritance relationships.

Chris McCall
A: 

Here's your google search:

http://www.google.com/search?q=object+relational+modeling&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:official&client=firefox-a

Doug
Why the downvote? he asked for a google search
Doug
+1 Thanks Doug. I'm a noob to database design so any useful pointers are appreciated.
Nick
+1  A: 

There's really two major ways to solve this:

  • table-per-type
  • table-per-hierarchy

Either of them has its pros and cons.

Table-per-type gives you more tables (one per type), which only store the "delta" from the immediate super class. Worst case, you need to join together a number of tables to finally get all the data together for a single instance of a type. Pros: since you only store what's really relevant for that type into a separate table, you can do this like set NOT NULL restrictions etc. on the database table.

Table-per-hierarchy gives you less tables, but each table represents an entire hierarchy, so it will contains potentially lots of columns which aren't filled (in the rows representating base class types). Also, on the extra columns that make up the derived classes, you cannot set things like NOT NULL restrictions - all those extra columns must be nullable, since they really don't exist in the base classes, so you loose some degree of safety here.

See for yourself - there are two really good articles on how to do this (in Entity Framework, but the principles apply to any database and any data mapping technology):

Hope this helps and gives you some inputs!

Marc

marc_s
Thanks, that helps model the data. Now, how do I do a query when I have table per type and multiple types. Do I have to join all the tables with the "base" and query each type?
Nick
How do you plan to access your data? Both the Entity Framework, as well as more capable ORM such as NHibernate will support this "out of the box" - you just ask for a "thing", and you get the right "thing" back from the OR-mapper.
marc_s
If you need to access it from straight SQL, you'd have to somehow know (or figure out) what type you need and do several queries or a joined query to get your data. OR: you could create a view for each type that would encapsulate this JOIN (or these several JOINS) and then you can simply select from that view and get all your e.g. students or all your business students etc.
marc_s