views:

66

answers:

3

I read here some reasons to use constraints instead of triggers. But I have a doubt. How can be assure (using only constraints), the coherence between SUPERCLASS tables and SUBCLASSES tables?

Whit a trigger is only a matter of check when INS.. UPD...

Is there a way to define that kinda relation by using only constraints (I'm newbie at this), thanks!

+1  A: 

Databases are relational and constraints enforce relational dependencies pretty well, been doing so for some 30 years now. What is this super and sub class you talk about?

Update

Introducing the OO inheritance relationships in databases is actually quite problematic. To take your example, contract-employee and fulltime-employee. You can model this as 1) a single table with a discriminator field, as 2) two unrelated tables, or as 3) three tables (one with the common parts, one with contract specific info, one with fulltime specific info).

However if you approach the very same problem from a traditional normal form point of view, you may end up with a structure similar to 1) or 3), but never as 2). More often than not, you'll end up with something that looks like nothing you'd recommend from your OO design board.

The problem is that when this collision of requirements happens, today almost invariably the OO design will prevail. Often times, the relational model will not even be be on the table. Why I see this as a 'problem' is that most times databases far outlive their original application. All too often I see some design that can be traced back to a OO domain driven design session from an application long forgotten, and one can see in the database schema the places where, over time, the OO design was 'hammered' into place to fit what the relational engine underneath could support, scale and deliver. The tell sign for me is tables organized on a clustered index around a identity ID when no one ever is interrogating those tables for a specific ID.

Remus Rusanu
I'm talking about modeling (within my Relational Database, Inheritance Relationship). A contract-employee, a salary-employee all are employee. Ay relation like this one
Sheldon
Take my response with a big grain of salt. I am well aware of the inheritance relationships in table design, my point is that the relational concepts the vast majority of databases are (still) using today do not understand 'inheritance', they model keys, tuples and foreign keys.
Remus Rusanu
um ok. But, what about that keys.Is there a way to check (as constraint) that a certain key within table A, doesn't appear on table B?
Sheldon
+2  A: 

You can use constraints to ensure that every ContractEmployees row has a corresponding Employees row, and likewise for SalariedExployees. I don't know of a way to use constraints to enforce the opposite: making sure that for every Employees row, there is a row either in ContractEmployees or SalariedEmployees.

Backing up a bit... there are three main ways to model OO inheritance in a relational DB. The terminology is from Martin Fowler's Patterns of Enterprise Application Architecture:

  1. Single table inheritance: everything is just in one big table, with lots of optional columns that apply only to certain subclasses. Easy to do but not very elegant.

  2. Concrete table inheritance: one table for each concrete type. So if all employees are either salaried or contract, you'd have two tables: SalariedEmployees and ContractEmployees. I don't like this approach either, since it makes it harder to query all employees regardless of type.

  3. Class table inheritance: one table for the base class and one per subclass. So three tables: Employees, SalariedEmployeees, and ContractEmployees.

Here is an example of class table inheritance with constraints (code for MS SQL Server):

CREATE TABLE Employees 
(
  ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
  FirstName VARCHAR(100) NOT NULL DEFAULT '',
  LastName VARCHAR(100) NOT NULL DEFAULT ''
);

CREATE TABLE SalariedEmployees
(
  ID INT NOT NULL PRIMARY KEY REFERENCES Employees(ID),
  Salary DECIMAL(12,2) NOT NULL
);

CREATE TABLE ContractEmployees
(
  ID INT NOT NULL PRIMARY KEY REFERENCES Employees(ID),
  HourlyRate DECIMAL(12,2) NOT NULL
);

The "REFERENCES Employees(ID)" part on the two subclass tables defines a foreign key constraint. This ensures that there must be a row in Employees for every row in SalariedEmployees or ContractEmployees.

The ID column is what links everything together. In the subclass tables, the ID is both a primary key for that table, and a foreign key pointing at the base class table.

Richard Beier
Thank you very much!
Sheldon
+1  A: 

Here's how I'd model a contract vs salary employee setup:

EMPLOYEE_TYPE_CODE table

  • EMPLOYEE_TYPE_CODE, pk
  • DESCRIPTION

Examples:

EMPLOYEE_TYPE_CODE     DESCRIPTION
-----------------------------------
CONTRACT               Contractor
SALARY                 Salaried
WAGE_SLAVE             I can't be fired - slaves are sold

EMPLOYEES table

  • EMPLOYEE_ID, pk
  • EMPLOYEE_TYPE_CODE, foreign key to the EMPLOYEE_TYPE_CODE table
  • firstname, lastname, etc..

If you're wanting to store a hierarchical relationship, say between employee and manager (who by definition is also an employee):

EMPLOYEES table

  • EMPLOYEE_ID, pk
  • EMPLOYEE_TYPE_CODE, foreign key to the EMPLOYEE_TYPE_CODE table
  • MANAGER_ID

The MANAGER_ID would be filled with the employee_id of the employee who is their manager. This setup assumes that an employee could only have one manager. If you worked in a place like what you see in the movie "Office Space", you need a different setup to allow for an employee record to associate with 2+ managers:

MANAGE_EMPLOYEES_XREF table

  • MANAGER_EMPLOYEE_ID, pk, fk to EMPLOYEES table
  • EMPLOYEE_ID, pk, fk to EMPLOYEES table
OMG Ponies