OK, I'm a bit late to the party but there some interesting answers here and I thought I should add my take.
To answer the question: Should you store values as positive amounts and flag as debit or credit ?
The short answer: You don't need to add the flag, because any system automatically applies the flag 'debit' or 'credit' when you save the number in it's correct signed form. It's the '-' sign. Should you store values in one of two columns, debit or credit, instead ? Definitely not ! Why save an empty field to every transaction in the system ? A single column with the correct signed value is much easier to manage.
The longer answer to the question title: Accounting and Database Design, storing debit and credit amount.
It's perfectly straightforward and robust as long as you understand double entry book keeping. When you post a journal to the nominal ledger, you offer the user a debit field and a credit field for each line in the journal. In your application you permit only one of the fields to have a value (per line) and it must be a positive, unsigned value. When you write the transaction, if you have a debit you just write it as is. If you have a value in the credit field, you reverse it and write it as a negative number. The database sees only a single signed value in a single column, per line (record). As any accountant will tell you a journal entry must balance so the database records for the journal transaction lines will add up to zero. Application code must ensure that a journal has to be balanced.
Now consider a purchase invoice that the user adds to the system. Let's say we have this (unlikely) invoice for the Widget Company:
£500 for steel bar
£100 for a box of envelopes
£10000 for a lathe
£2120 purchase tax
£12720 invoice total
The application writes a single record to the documents table. It has one-to-many links to the transaction table. For the three-line invoice, 5 transaction lines are written by the application.
£500 linked to Cost of Sales, a p&l general ledger account. Debit balance = expense when in the p&l
£100 linked to Stationery, a p&l general ledger account. Debit balance = expense when in the p&l
£10000 linked to Machinery, a balance sheet general ledger account. Debit balance = asset when in the bs.
£2120 linked to Input Tax Reclaimable, a bs gl account. Debit balance = asset, we are owed money by the tax man
-£12720 linked to Creditors Control, a bs gl account. Credit balance = liability, we owe this to the supplier
£0.00 total value of 5 records written to the transaction table.
Now consider a sales invoice that the user adds:
£250 for premium widgets
£250 for standard widgets
£100 sales tax
£600 invoice total
Again a single record is written to the documents table. For the two-line invoice, 4 transaction lines are written. Because this is a sales invoice, the application must reverse the values behind the scenes. Sales invoice lines are book keeping credits but the user doesn't expect to have to add them as negative values.
£250- linked to Premium Widget Sales, a p&l gl account. Credit balance = income/profit when in the p&l
£250- linked to Standard Widget sales, a p&l gl account. Credit balance = income/profit when in the p&l
£100- linked to Output Tax Payable, a bs gl account. Credit balance = liability when in the BS. We owe this money to the tax man.
£600 linked to Debtors Control, a bs gl account. Debit balance = asset, we are owed this by the customer.
£0.00 total value of 4 records written to the transaction table.
It's perfectly ok to add negative lines to the sales invoice if you want to give credit for something returned. They just get reversed with all the other lines before writing the transactions. More usually you would issue a credit note, which would have the lines written as debits to sales income, reducing the value of sales in the p&l.
If the system is doing stock control, quantities are written into the transaction lines, and they are linked to the Product table.
The bank entries often catch non-book keepers out. They say, we put money in our bank so we credited the account. Think of the bank as a person external to the business. When you hand over your money for safe keeping, s/he becomes a debtor, and must hand your money back on demand. So receipts into the bank are recorded as debits and payments out are recorded as credits. When we receive payment from the customer we write two transaction lines:
£600 linked to Bank Account, a bs gl account. Debit balance = increases the value of the asset, we have more money.
£600- linked to Debtors Control, a bs gl account. Credit balance = reduces the value of the asset, we are owed less money.
£0.00 total value of 2 records written to the transaction table.
If you follow this through you'll see that Debtors Control has £600 written to it when the sales invoice is raised, and £600- written to it when the payment is received. Net balance = £0.00 which is what our customer now owes.
So with the right design, relationships and indexes all the reporting is done from the combination of documents and transactions.
And that's it. Any time you sum the transaction table it should always return zero. There's no need to maintain two columns. The application needs to do two things, it needs to be coded so that it applies the correct signing to the various transaction types, and it needs to present the transaction in one of two columns according to whether it is >0 or <0. So you can have your trial balance, your customer and supplier ledgers, bank and cash accounts, and general ledger all nicely formatted into debit and credit columns.
Building a system where both sides of the double entry are recorded in one transaction is appealing. If a single transaction fails, it doesn't unbalance the accounts. You would still have just one column for the value, signed. You would record two gl foreign keys to each transaction, one for the value of what you've recorded, which could be a positive or negative value to represent debit or credit, and another gl foreign key to record the account that you are posting the opposing ('double entry') value to. You might also need to record the gl fk for two tax control accounts as well, one for the output tax control account and one for the input tax control account. So you might end up linking your transaction line to four gl accounts instead of just one (plus the links for the customer, supplier and product tables which applies to both methods). The control accounts would have a very high volume of transactions linked to them. A 10-line invoice would have 10 transactions linked to it instead of just one per document. You would have to calculate the tax element for each invoice line individually instead of as a total for the document (you might do this anyway). Finally you would have to have a special arrangement for a journal entry document which might include 10 lines as debits all offset by one line as a credit, so the single-transaction approach doesn't work here.