IMO, the balance sheet, income statement and cash flow tables can be the same. Here's my take on it:
-- Companies
CREATE TABLE company (
[id] int NOT NULL PRIMARY KEY,
[name] varchar(255) NOT NULL
);
-- "Balance sheet", "IFRS Income statement", etc
CREATE TABLE statement (
[id] int NOT NULL PRIMARY KEY,
[name] varchar(255) NOT NULL
);
--- "Tangible assets", "Outstanding stock", etc
CREATE TABLE statementRow (
[id] int NOT NULL PRIMARY KEY,
statementId int NOT NULL,
rowOrder int NOT NULL,
rowTitle varchar(255) NOT NULL,
rowDescription varchar(max) NULL,
rowProperties varchar(max) NULL,
FOREIGN KEY (statementId) REFERENCES statement ([id])
);
--- The facts
CREATE TABLE statementFact (
companyId int NOT NULL,
statementRowId int NOT NULL,
[date] date NOT NULL,
amount numeric NULL,
PRIMARY KEY ([date], statementRow),
FOREIGN KEY (companyId) REFERENCES company ([id]),
FOREIGN KEY (statementRowId) REFERENCES statementRow ([id])
);
Advantages of this model:
- You can have different types of balance sheets, income statements, etc, in order to cover future reporting needs
- The model defines the ordering of the rows for each statement (don't rely in an identity column for that, because you won't be able to insert rows later on)
- Using "date" instead of "year" allows you to publish statements more than once per year, i.e. per quarter or month, or even ad-hoc.
- The rowProperties field allows you to add information like if the row should be boldface, italics or other formatting properties.
- Optionally, you may want to move "companyId" from statementFact to "statement" if certain reports only apply to certain companies.