I am building a warehouse for a billing system that bills a number of services/utilities on the same invoice, as such I am having real trouble conforming to a recognised design method for the warehouse. I think I still very much have an OLTP hat on.
As an example a single invoice could be produced containing charges for electricity, gas and mobile phones.
All three components of the bill, themselves have two components, fixed charges, and usage based charges. Even simplified to just a mobile phone it still means to store the level of detail required for the business I need 2 fact tables:
FactMobileFixedCharge
FactMobileCalls
Each of these go onto a single invoice, in addition to this there are transactions at an invoice level too, so I now need a further fact table:
FactInvoiceTransaction
The basic schema for this simple example is as follows:
All the reading I have done approaches the InvoiceLineItem
example to resolve the issue of an invoice appearing like a fact and a dimension, where the facts of the invoice are essentially propogated to the child table, causing some redundancy but conforming to standard practises.
In the production billing system itself there are 15 tables that contain items that appear on an invoice, a summary table that contains invoice level charges and a summary of the charges in the other 15 tables by category, and the invoice table itself.
I don't feel that my scenario matches this though, because the invoice has a number of different things that also need to be reported on (Invoicing address, marketing material on invoice, payment method, invoice format, email, online or paper billing, balance brought forward, payments since the last invoice etc). While this is acceptable redundancy if I had one or two tables it seems like a lot for 15 fact tables.
In addition to being a lot of redundancy when there are multiple tables, I would also still need to link FactMobileCall
and FactMobileCharge
to get records for the same invoice, and I don't beleive a degenerate dimension is a good way to link the two.
Basically this all points towards Invoice
being a dimension, especially as there are no measurements on an invoice level, however it still feels like it should be a fact as there will only ever be new records on each import.
Which leads to my questions:
- Am I correct in thinking that an Invoice in this scenario should be considered a fact?
- If so is it acceptable to have further facts referencing this fact, or is there a better way to approach this?
- I can't believe I am the only person who has encountered a situation where the
InvoiceLineItem
examples don't really seem to fit. Is there a recognised way of dealing with this?
For further information, my warehouse schema currently looks likes this (where I have conceded to Invoice being a fact like dimension):