> While working on the money module today i realized that the data
> structure choices are far from trivial.
>
The data structures are ALWAYS "far from trivial". That's why there
is a discipline called Data Analysis that needs to be done parallel to
the Functional Analysis and the data structure should be designed just
as flexibly as the functional structure.
> First of all, i started by storing transaction :id as
>
> :year/:month/:day/:tab/transaction/:id
>
> and the balance for participant :peer as
>
> :year/:month/:day/:tab/balance/:peer
>
> Later i realized that tabs can probably be kept separate from each
> other, so that it would be more efficient to put :tab at the front. So
> I changed that.
> Luckily we don't have an installed base here yet,
Only the Big Bang had no installed base and even it may have been a
pinched off bubble of the Multiverse. Luckily, you are working on
something that a lot of folks have spent enormous time making right
because money is at the core of their day job. Perhaps you could look
at some of the existing money systems for guidance on how it has best
been done. Surely there is accessible documentation somewhere. Stand
on those shoulders, not in the wilderness.
> because i can only imagine having to write migration code every time
> we change something like this.
Try thinking of the smallest units of data that can stand alone or be
combined with other isolated data to report a fact. You'll run into
fewer needs to restructure something that is built dynamically as
needed. While you eventually won't want to accumulate all
transactions to establish a current balance, because it will
eventually take too long, you should know what is statically accurate
versus what is derived.
> so my first note to self and tip to
> other module authors, make sure you get the data organization right
> the first time. :)
Let this be your lesson, you never know everything at the beginning of
your design process. So, nothing is ever "Right the First Time."
Design for maintenance.
> Later on i realized that if you add a transaction, then you have to
> update the balance for that day and all subsequent days. There is
> basically no good way to do that (we don't have any locking or
> transactions).
But this scenario is one of the drivers of the invention of locking.
Be careful, here be bugs waiting to happen.
> So then i thought of something that actually eliminates
> the need for a solution, by changing the problem.
Again, be careful. You can't eliminate all problems by wishing they
didn't exist. Often a new algorithm is exactly what you need, but
don't eliminate required functionality to achieve simplified design.
It'll just come back to you as a harder to implement requirement.
> Let's just prohibit random access to past data.
Define "past data" carefully. Does it mean data about the past that
you didn't have at the time? Or the data that you entered some time
in the past?
> only the current day
> can be edited.
Only what you have now can be entered correctly?
> and only past days have a balance calculated.
A provisional balance?
> This
> slightly influences the functionality, but i think it's an acceptable
> interpretation that history can't be changed,
You certainly can't go back and change what you knew then, but you can
add recently acquired information now. The question seems to be, how
does one add it?
> so you get a sort of
> temporally incremental data design. anyway, that's my second tip that
> can probably be useful for other modules too, so i thought i would
> share it. :)
>
>
> Cheers!
> Michiel
It's good to see someone who is willing to "Talk out loud" about his
analysis. Bugs are much easier to eliminate at this stage than later
and sharing with co-workers is a way to eliminate the bats in the
belfry that may prevent clear vision of the requirements.
Keep thinking. Carefully.