If you are one of those folks who has never dealt with normalizing data for an RDBMS implementation, then count yourself among the lucky. Because I have, I can feel blessed to work with an object database (yeah, that’s what the marketing lit says, so I can roll with it) like Cache’ or any other MultiValued database tools.
A Party is a person or an organization. We don’t always care whether an organization or person is purchasing something, for example, so there are reasons to abstract these into the same entity in our data model. Take a look at what the RDBMS folks think is good form for an implementation of a Party
That’s six tables before getting to phone numbers, addresses and other demographic data about the party. Now, guess how many MultiValue files, specified by Cache’ classes, I made for pretty much this same data. Since I know I advertised this blog very narrowly, I think you guessed it on the nose. One. Uno.
While there is just one file for the data about each Party, whether it is an organization or a person, there are other related files, of course. There can be multiple Profiles (aligned with an e-mail address) or multiple Orgs (aligned with a URL home page).
How can we get away with such simplicity when the RDBMS folks have such complexities? Simple, we cheat. We, that being I, break the rules as taught to CS majors around the world. There are three or four rules I broke here on purpose, depending on how you count them. If there are others, then, well, oops, my bad.
First, I allow null values (yes null values not to be confused with nulls because I am using two-valued logic, see http://www.tincat-group.com/mewsings/2006/03/better-to-have-no-values.html) and violate “the key, the whole key, and nothing but the key” by putting First and Last name fields in the Party record. These have a value of “” in the case of an Org and have first and last names in them in the case of a person. So sue me.
To top that off, there is a full Name field in the Party record too, not to be confused with a Name column in a Party table (at least smile when you read that). And get this–when this is a person, that Name is derived from the First and Last names and then stored. Hah, redundant data, gotta love it.
Not only did I violate those arbitrary RDBMS rules that we continue to teach as if they were sent to Moses on tablets, I also violated an Agile development rule of thumb on that one. A possible future feature is to permit someone to have a first and last name that do not sum up to their full name. The full name could include a title, for example, or they might wish to use a nickname in one place or the other. If such a feature were to be implemented, the redundancy would go away, and having thought past my nose would have paid off. In the mean time, I can do a listing of all Parties with Names and see names for both people and organizations, which means this name field will come in handy in many places, I suspect, redundant or not.
That’s two or three, depending on whether you count the “” and functional dependency issue (only people have First names, not orgs) as one or two violations. The final one is more obvious, perhaps, in that I have a multi-valued list of phone numbers. I am using an MV database, after all. A list of phone numbers and types (an associated multivalue in MV terminology, an embedded child table) is sitting right there in the Party class. RDBMS data modelers don’t typically muddy the waters by showing phone numbers when showing a Party pattern, but I had to do a real implementation, not just pictures of one. Plus, there is no need with MV to have yet another class/table/file for phone numbers and types.
Additionally, if we ever need those Roles (so far I’ve kept them out), we can add ’em in, but when someone needs to select from organizations, they select through the Org record, which points to a Party. Most other foreign keys are to the Profile or Org records, not to Party, unless we don’t care if it is a person or an organization, which was a reason for pouring them together in the first place.
There has been no need so far to determine based on simply the Party record whether it is a person or an organization, but if we ever really needed to do so, I can tell them apart. The right way to do so would be to see if there were Org or Profile records associated with the Party record (there must be one or the other and cannot be both), but cheaters know, although the DBMS does not, that those First and Last names are required for people and always empty for Orgs. Yeah, I really do know how wrong that is, and yet…
Are you disgusted with me? Ah phooey. I’m having a bad day anyway, so what do I care? It was such a bad day that I thought maybe I could put a smile on both your face and mine if I invited you to my Party. It’s a small Party–just one room. You can see its class diagram by drawing a square on a piece of paper and writing Party in the header. Oh, and could you shake me up a vodka martini? That’s all I need now–one square and one triangle is all I need to be one Party girl.