Let's say you have a notes table. The note can be about a particular account, orderline or order.
- Notes that are about the account do not apply to any specific orderline or order.
- Notes that are about the orderline also apply to the parent order and the account that is attached to the order.
- Notes that are on the order also apply to the attached account but not the orderline.
NOTES table
[Id] [int] IDENTITY(1,1) NOT NULL
[NoteTypeId] [smallint] NOT NULL
[AccountId] [int] NULL
[OrderId] [int] NULL
[OrderLineId] [int] NULL,
[Note] [varchar](300) NOT NULL
The idea is that if I view a client I can see all notes that are in someway related. Initially I created a notes table for each of the above and union-ed them in a view. The problem here comes with editing/deleting a record. Notes can be edited/deleted on the particular item or in a generic notes view of the account or order. This method made that more difficult.
Then I switched to the Single Table Inheritance pattern. My notes table has nullable values for AccountId, OrderId and OrderLineId. I also added the NoteTypeId to identify the record explicitly. Much easier to manage update/delete scenarios.
I have some problems & questions still with this approach.
- Integrity - Although complex constraints can be set in SQL and/or in code, most DBAs would not like the STI approach.
- The idea of bunch of nulls is debated (although I believe performance in SQL 2008 has improved based on the storage of null values)
- A table in a RDBMS does not have to represent an object in code. Normalization in a table doesn't say that the table has to be a unique object. I believe the two previous sentences to be true, what say you?
Discussed some here. http://stackoverflow.com/questions/1034925/is-an-overuse-of-nullable-columns-in-a-database-a-code-smell/1035385#1035385 I'd have to say I agree with Ian but I'd like some opposite views as well.