Hello, you are not logged in.  Login or sign up
Community >> Blogs
Search Toad World Search

Do you have a topic that you'd like discussed?  We'd love to hear from you.  Send us your idea for a blog topic.

Super & Sub Type Option #1
 
Location: Blogs Bert Scalzo's Blog    
 Bert Friday, November 30, 2007 3:50 PM

When we create a super-and-sub type (a.k.a. Inheritance) entity relationship in a logical data model, it’s very clear what the business requirements being communicated are – that different subsets of attributes comprise the “cumulative entity” being modeled depending upon the business context.

So the Toad Data Modeler 3.0 logical diagram shown below relates that Entity1 always has the parent attributes of E1_Attribute1-4, and then depending upon the business context it will have either child attributes E2_Attributes 1-4 or E3_Attributes1-4. And we know that is exclusively true (i.e. only one or the other, and not both) due to the “X” in the super-and-sub type indicator.

So when it comes time to physically implement this logical data model for usage within a relational database, what are our choices? Well there are at least three alternatives, which I’ll cover over the next couple blogs separately – so that we only have to digest one way at a time.

Look below at Toad Data Modeler 3.0’s “Inheritance” definition dialog.

We’re going to choose the N-1 options, meaning that super and sub-types are implement by fully inheriting the parent into both sub-types, thus yielding the physical model shown here:

This is a very common choice for implementation. It keeps the coding pretty easy for the application developers. Plus it’s a pretty straight-forward and fairly easy to comprehend translation concept. However even though this is a very common implementation choice, nonetheless most data modeling tools will generate incorrect or incomplete DDL for this scenario. Most tools will properly generate the two tables with their proper primary and foreign keys all properly inherited and implemented. But they most often forget that to the business this is really just one business entity. And so having two tables with primary keys does NOT prevent one from loading the same key value to each table (which to the business is not allowed). But look at the trigger code Toad Data Modeler generates for this implementation – it specifically checks to verify and guarantee that the primary keys are unique across tables! That’s a very easy item to miss during physical modeling and the actual database construction. You usually don’t find out until the data is messed up!

/*
Created: 11/14/2007
Modified: 11/14/2007
Model: Physical Model
Database: Oracle 10g
*/

-- Create tables section ---------------------------------------------------------------------------

-- Table Entity2
CREATE TABLE "Entity2"(
  "E2_Attribute1" Integer NOT NULL,
  "E2_Attribute2" Integer NOT NULL,
  "E2_Attribute3" Integer,
  "E2_Attribute4" Integer,
  "E1_Attribute1" Integer NOT NULL,
  "E1_Attribute2" Integer,
  "E1_Attribute3" Integer,
  "E1_Attribute4" Integer
)
/

-- Add keys for table Entity2
ALTER TABLE "Entity2" ADD CONSTRAINT "Unique Identifier1" PRIMARY KEY ("E1_Attribute1")
/

-- Create triggers for table Entity2
CREATE TRIGGER "InheritanceEntity2"
  BEFORE INSERT
  ON "Entity2"
  for each row
declare numrows integer
begin
  select count(*) into numrows from Entity3  where E1_Attribute1 = :NEW.E1_Attribute1
  if (numrows > 0) then
    RAISE_APPLICATION_ERROR(-20003,'Exlusive Inheritance violation with entity Entity3');
  end if;
end;
/ 

-- Table Entity3
CREATE TABLE "Entity3"(
  "E3_Attribute1" Integer NOT NULL,
  "E3_Attribute2" Integer NOT NULL,
  "E3_Attribute3" Integer,
  "E3_Attribute4" Integer,
  "E1_Attribute1" Integer NOT NULL,
  "E1_Attribute2" Integer,
  "E1_Attribute3" Integer,
  "E1_Attribute4" Integer
)
/

-- Add keys for table Entity3
ALTER TABLE "Entity3" ADD CONSTRAINT "Unique Identifier1" PRIMARY KEY ("E1_Attribute1")
/

-- Create triggers for table Entity3
CREATE TRIGGER "InheritanceEntity3"
  BEFORE INSERT
  ON "Entity3"
  for each row
declare numrows integer
begin
  select count(*) into numrows from Entity2  where E1_Attribute1 = :NEW.E1_Attribute1
  if (numrows > 0) then
    RAISE_APPLICATION_ERROR(-20003,'Exlusive Inheritance violation with entity Entity2');
  end if;
end;
/

Copyright ©2007 Quest Software Inc.
Permalink |  Trackback

Comments (2)   Add Comment
By JCFlack on Monday, December 03, 2007 5:59 AM
I'm not crazy about that design. There are several things wrong with it. First, that SELECT in the triggers can really slow inserts down - why do you think uniqueness is usually enforced via a unique index? Second, it will help if the PKs are surrogate PKs created from an Oracle sequence - just use the same sequence for both PKs. Of course, generating from the sequence will make the keys unique MOST of the time, but won't guarantee it - hence you still need the trigger. In fact, you also need a BEFORE UPDATE trigger to make sure that you can't change the key, or can't change it so that it is no longer unique. Finally, what happens when you add a third table that inherits from the same parent? All the triggers have to be changed.

One possible workaround is a modification of the N tables design. Just have an index organized table with just the PK column(s). Have the BEFORE INSERT and BEFORE UPDATE triggers on all descendants try to INSERT or UPDATE the PK enforcement table.

But as long as you are doing a variation on N table design, might as well do it all the way. Or use the single table design. I like to use views to extract just the columns that belong to each descendant from the single table design. In an N table design, I use views to pre-join the descendant tables with the parent table, often with INSTEAD OF triggers to make it behave like an N-1 design.

By bscalzo on Monday, December 03, 2007 6:48 AM
Awesome feedback. I did not mean to imply that this option was preferable. There are three options and I was simply going to show each - with some pros and cons. I would then leave it up to each shop to decide which way to lean for their needs/desires. However some data modeling tools do not generate all the correct DDL as one would expect - so people need to know these issues so they can spot bad data modeling tool generated code. For example, ERwin does a subpar job when generating code for super and sub-types. We're striing with Toad data modeler to be more accurate.

BUT all that said, I always recommend an effective solution first - with efficiency where possible. I would never drop the triggers just because it might slow things down. Better slow and correct than otherwise. I can always buy hardware to improve performance. I cannot as easily fix a corrupt database (i.e. bad data). I've been an expert witness in many court cases. In cases where speed was poor but design was solid - 100% of the time there were no damages awarded. In cases where design was poor, regardless of performance, there was almost universally damages awarded.


Comment:
Add Comment   Cancel 
Search Blog Entries
 
Copyright 2008 by Quest Software  | Terms Of Use | Privacy Statement | Contact Us