approaches to design of database, which one? - database

I'm designing a database that will hold a list of transactions. There are two types of transactions, I'll name them credit (add to balance) and debit (take from balance).
Credit transactions most probably will have an expiry, after which this credit balance is no longer valid, and is lost.
Debit transactions must store from which credit transaction they come from.
There is always room for leniency with expiry dates. It does not need to be exact (till the rest of the day for example).
My friend and I have came up with two different solutions, but we can't decide on which to use, maybe some of you folks can help us out:
Solution 1:
3 tables: Debit, Credit, DebitFromCredit
Debit: id | time | amount | type | account_id (fk)
Credit: id | time | amount | expiry | amount_debited | accountId (fk)
DebitFromCredit: amount | debit_id (fk) | credit_id (fk)
In table Credit, amount_debited can be updated whenever a debit transaction occurs.
When a debit transaction occurs, DebitFromCredit holds information of which credit transaction(s) has this debit transaction been withdrawn.
There is a function getBalance(), that will get the balance according to expiry date, amount and amount_debited. So there is no physical storage of the balance; it is calculated every time.
There is also a chance to add a cron job that will check expired transactions and possibly add a Debit transaction with "expired" as a type.
Solution 2
3 tables: Transactions, CreditInfo, DebitInfo
Transactions: id | time | amount (+ or -) | account_id (fk)<br />
CreditInfo: trans_id (fk) | expiry | amount | remaining | isConsumed<br />
DebitInfo: trans_id (fk) | from_credit_id (fk) | amount<br />
Table Account adds a "balance" column, which will store the balance. (another possibility is to sum up the rows in transactions for this account).
Any transaction (credit or debit) is stored in table transactions, the sign of the amount differentiates between them.
On credit, a row is added to creditInfo.
On debit one or more rows are added to DebitInfo (to handle debiting from multiple credits, if needed). Also, Credit info row updates the column "remaining".
A cron job works on CreditInfo table, and whenever an expired row is found, it adds a debit record with the expired amount.
Debate
Solution 1 offers distinction between the two tables, and getting data is pretty simple for each. Also, as there is not a real need for a cron job (except if to add expired data as a debit), getBalance() gets the correct current balance. Requires some kind of join to get data for reporting. No redundant data.
Solution 2 holds both transactions in one table, with + and - for amounts, and no updates are occurring to this table; only inserts. Credit Info is being updated on expiry (cron job) or debiting. Single table query to get data for reporting. Some redundancy.
Choice?
Which solution do you think is better? Should the balance be stored physically or should it be calculated (considering that it might be updated with cron jobs)? Which one would be faster?
Also, if you guys have a better suggestion, we'd love to hear it as well.

Which solution do you think is better?
Solution 2. A transaction table with just inserts is easier for financial auditing.
Should the balance be stored physically or should it be calculated (considering that it might be updated with cron jobs)?
The balance should be stored physically. It's much faster than calculating the balance by reading all of the transaction rows every time you need it.

I am IT student that has passed a course called databases, pardon my inexperience.
I made this using MySQL workbench can send you model via email to you do not lose time recreating the model from picture.
This schema was made in 10 minutes. Its holding transactions for a common shop.
Schema explanation
I have a person who can have multiple phones and addresses.
Person makes transactions when he is making a transaction,
You input card name e.g. american express,
card type credit or debit (MySQL workbench does not have domains or constrains as power-designer as far as i know so i left field type as varchar) should have limited input of string debit or credit,
Card expiry date e.g. 8/12,
Card number e.g. 1111111111
Amount for which to decrease e.g. 20.0
time-stamp of transaction
program enters it when entering data
And link it to person that has made the transsaction
via person_idperson field.
e.g.
1
While id 1 in table person has name John Smith
What all this offers:
transaction is uniquely using a card. Credit or Debit cant be both cant be none.
Speed less table joins more speed for system has.
What program requires:
Continuous comparion of fields variable exactTimestamp is less then variable cardExpiery when entering a transaction.
Constant entering of card details.
Whats system does not have
Saving amount that is used in the special field, however that can be accomplished with Sql query
Saving amount that remains, I find that a personal information, What I mean is you come to the shop and shopkeeper asks me how much money do you still have?
system does not tie person to the card explicitly.
The person must be present and use the card with card details, and keeping anonymity of the person. (Its should be a query complex enough not to type by hand by an amateur e.g. shopkeeper) , if i want to know which card person used last time i get his last transaction and extract card fields.
I hope you think of this just as a proposition.

Related

How do I persist sales price in an orders details table?

I'm writing a simple transactional database to practice my T-SQL skills.
If I sell an umbrella in my sales.orderdetails table and it's getting the current retailprice of that umbrella from the items table and putting it in the invoice, how do I keep from having incorrect historical report data 6 months from now when I jack up the retail price of the umbrella by $10?
How do i store that umbrella sold price in the orderdetails table so it's unaffected by any changes in the items table in the future?
I know you can use an SCD for a datawarehouse for this kind of issue but was wondering how to do it in an OLTP system. Computed persisted column? Can't seem to get that to work in the object explorer when I try to enter the items.retailprice as the computed value for the salesorderdetails.cost column.
The way I have seen this done in the past, without using a technique like SCD, was to have the order detail have the price that was charged and then use a foreign key to another table, possibly products or productprices, that contains the current price.
In a full-on transactional system, you'd want the order detail row to record full retail (MSRP, or what have you), current price (in case you had the item posted at a discount that day), and price charged (in case the customer used a promo/coupon code to reduce the price themselves). Unless you log all three, you're at the mercy of whatever the price changes to tomorrow or next week or next year, which makes for bad analytics.
You probably also want to capture current cost of goods, too, since that's subject to change over time, especially in an average costing scenario. Otherwise, margin calculations will be suspect.
But then, yes, a foreign key or keys to any other descriptive tables for those less ephemeral characteristics of the product.

Change Data Capture and SQL Server Analysis Services

I'm designing a database application where data is going to change over time. I want to persist historical data and allow my users to analyze it using SQL Server Analysis Services, but I'm struggling to come up with a database schema that allows this. I've come up with a handful of schemas that could track the changes (including relying on CDC) but then I can't figure out how to turn that schema into a working BISM within SSAS. I've also been able to create a schema that translates nicely in to a BISM but then it doesn't have the historical capabilities I'm looking for. Are there any established best practices for doing this sort of thing?
Here's an example of what I'm trying to do:
I have a fact table called Sales which contains monthly sales figures. I also have a regular dimension table called Customers which allows users to look at sales figures broken down by customer. There is a many-to-many relationship between customers and sales representatives so I can make a reference dimension called Responsibility that refers to the customer dimension and a Sales Representative reference dimension that refers to the Responsibility dimension. I now have the Sales facts linked to Sales Representatives by the chain of reference dimensions Sales -> Customer -> Responsibility -> Sales Representative which allows me to see sales figures broken down by sales rep. The problem is that the Sales facts aren't the only things that change over time. I also want to be able to maintain a history of which Sales Representative was Responsible for a Customer at the time of a particular Sales fact. I also want to know where the Sale Representative's office was located at the time of a particular sales fact, which may be different than his current location. I might also what to know the size of a customer's organization at the time of a particular Sales fact, also which might be different than it is currently. I have no idea how to model this in an BISM-friendly way.
You mentioned that you currently have a fact table which contains monthly sales figures. So one record per customer per month. So each record in this fact table is actually an aggregation of individual sales "transactions" that occurred during the month for the corresponding dimensions.
So in a given month, there could be 5 individual sales transactions for $10 each for customer 123...and each individual sales transaction could be handled by a different Sales Rep (A, B, C, D, E). In the fact table you describe there would be a single record for $50 for customer 123...but how do we model the SalesReps (A-B-C-D-E)?
Based on your goals...
to be able to maintain a history of which Sales Representative was Responsible for a Customer at the time of a particular Sales fact
to know where the Sale Representative's office was located at the time of a particular sales fact
to know the size of a customer's organization at the time of a particular Sales fact
...I think it would be easier to model at a lower granularity...specifcally a sales-transaction fact table which has a grain of 1 record per sales transaction. Each sales transaction would have a single customer and single sales rep.
FactSales
DateKey (date of the sale)
CustomerKey (customer involved in the sale)
SalesRepKey (sales rep involved in the sale)
SalesAmount (amount of the sale)
Now for the historical change tracking...any dimension with attributes for which you want to track historical changes will need to be modeled as a "Slowly Changing Dimension" and will therefore require the use of "Surrogate Keys". So for example, in your customer dimension, Customer ID will not be the primary key...instead it will simply be the business key...and you will use an arbitrary integer as the primary key...this arbitrary key is referred to as a surrogate key.
Here's how I'd model the data for your dimensions...
DimCustomer
CustomerKey (surrogate key, probably generated via IDENTITY function)
CustomerID (business key, what you will find in your source systems)
CustomerName
Location (attribute we wish to track historically)
-- the following columns are necessary to keep track of history
BeginDate
EndDate
CurrentRecord
DimSalesRep
SalesRepKey (surrogate key)
SalesRepID (business key)
SalesRepName
OfficeLocation (attribute we wish to track historically)
-- the following columns are necessary to keep track of historical changes
BeginDate
EndDate
CurrentRecord
FactSales
DateKey (this is your link to a date dimension)
CustomerKey (this is your link to DimCustomer)
SalesRepKey (this is your link to DimSalesRep)
SalesAmount
What this does is allow you to have multiple records for the same customer.
Ex. CustomerID 123 moves from NC to GA on 3/5/2012...
CustomerKey | CustomerID | CustomerName | Location | BeginDate | EndDate | CurrentRecord
1 | 123 | Ted Stevens | North Carolina | 01-01-1900 | 03-05-2012 | 0
2 | 123 | Ted Stevens | Georgia | 03-05-2012 | 01-01-2999 | 1
The same applies with SalesReps or any other dimension in which you want to track the historical changes for some of the attributes.
So when you slice the sales transaction fact table by CustomerID, CustomerName (or any other non-historicaly-tracked attribute) you should see a single record with the facts aggregated across all transactions for the customer. And if you instead decide to analyze the sales transactions by CustomerName and Location (the historically tracked attribute), you will see a separate record for each "version" of the customer location corresponding to the sales amount while the customer was in that location.
By the way, if you have some time and are interested in learning more, I highly recommend the Kimball bible "The Data Warehouse Toolkit"...which should provide a solid foundation on dimensional modeling scenarios.
The established best practices way of doing what you want is a dimensional model with slowly changing dimensions. Sales reps are frequently used to describe the usefulness of SCDs. For example, sales managers with bonuses tied to the performance of their teams don't want their totals to go down if a rep transfers to a new territory. SCDs are perfect for tracking this sort of thing (and the situations you describe) and allow you to see what things looked like at any point historically.
Spend some time on Ralph Kimball's website to get started. The first 3 articles I'd recommend you read are Slowly Changing Dimensions, Slowly Changing Dimensions Part 2, and The 10 Essential Rules of Dimensional Modeling.
Here are a few things to focus on in order to be successful:
You are not designing a 3NF transactional database. Get comfortable with denormalization.
Make sure you understand what grain means and explicitly define the grain of your database.
Do not use natural keys as keys, and do not bake any intelligence into your surrogate keys (with the exception of your time keys).
The goals of your application should be query speed and ease of understanding and navigation.
Understand type 1 and type 2 slowly changing dimensions and know where to use them.
Make sure you have a sponsor on the business side with the power to "break ties". You will find different people in the organization with different definitions of the same thing, and you need an enforcer with the power to make decisions. To see what I mean, ask 5 different people in your organization to define "customer" or "gross profit". You'll be lucky to get 2 people to define either the same way.
Don't try to wing it. Read the The Data Warehouse Lifecycle Toolkit and embrace the ideas, even if they seem strange at first. They work.
OLAP is powerful and can be life changing if implemented skillfully. It can be an absolute nightmare if it isn't.
Have fun!

Bank transactions table - can this be done better?

I am wondering what is the best way to make bank transaction table.
I know that user can have many accounts so I add AccountID instead of UserID, but how do I name the other, foreign account. And how do I know if it is incoming or outgoing transaction. I have an example here but I think it can be done better so I ask for your advice.
In my example I store all transactions in one table and add bool isOutgoing. So if it is set to true than I know that user sent money to ForeignAccount if it's false then I know that ForeignAccount sent money to user.
My example
Please note that this is not for real bank, of course. I am just trying things out and figuring best practices.
My opinion:
make the ID not null, Identity(1,1) and primary key
UserAccountID is fine. Dont forget to create the FK to the Accounts table;
You could make the foreignAccount a integer as well if every transaction is between 2 accounts and both accounts are internal to the organization
Do not create Nvarchar fields unless necessary (the occupy twice as much space) and don't create it 1024. If you need more than 900 chars, use varchar(max), because if the column is less than 900 you can still create an index on it
create the datetime columns as default getdate(), unless you can create transactions on a different date that the actual date;
Amount should be numeric, not integer
usually, i think, you would see a column to reflect DEBIT, or CREDIT to the account, not outgoing.
there are probably several tables something like these:
ACCOUNT
-------
account_id
account_no
account_type
OWNER
-------
owner_id
name
other_info
ACCOUNT_OWNER
--------------
account_id
owner_id
TRANSACTION
------------
transaction_id
account_id
transaction_type
amount
transaction_date
here you would get 2 records for transactions - one showing a debit, and one for a credit
if you really wanted, you could link these two transactions in another table
TRANSACTION_LINK
----------------
transaction_id1
transaction_id2
I'd agree with the comment about the isOutgoing flag - its far too easy for an insert/update to incorrectly set this (although the name of the column is clear, as a column it could be overlooked and therefore set to a default value).
Another approach for a transaction table could be along the lines of:
TransactionID (unique key)
OwnerID
FromAccount
ToAccount
TransactionDate
Amount
Alternatively you can have a "LocalAccount" and a "ForeignAccount" and the sign of the Amount field represents the direction.
If you are doing transactions involving multiple currencies then the following columns would be required/considered
Currency
AmountInBaseCcy
FxRate
If involving multiple currencies then you either want to have an fx rate per ccy combination/to a common ccy on a date or store it per transaction - that depends on how it would be calculated
I think what you are looking for is how to handle a many-tomany relationship (accounts can have multiple owners, owners can have mulitple accounts)
You do this through a joining table. So you have account with all the details needed for an account, you have user for all teh details needed for a user and then you have account USer which contains just the ids from both the other two tables.

database design: accounts with multi currency

In your accounting software how would you design your accounts database for COA
Design 1) 1 account can hold 1 currency only
Design 2) 1 account can hold multi currency, just filter the transaction by CurrencyId (USD, GBP etc..)
Design 1) 1 account can hold 1 currency only
ACCOUNT
Id
AccountNumber
CurrencyCode
...
TRANSACTION
Id
AccountId
Amount
...
Design 2) 1 account can hold multi currency
ACCOUNT
Id
AccountNumber
...
TRANSACTION
Id
AccountId
Amount
CurrencyCode
....
In the first place, I wouldn't design accounting software. I'd buy it. Accounting is one of the fields where you need domain experts (that is, accountants) helping to develop the software.
In the second place, if you're required to accept multiple currencies, then you have to store the type of currency along with the value. In a system like that, a debit of 30 is meaningless. Only debits of 30 USD or 30 EUR are meaningful.
But storage is the simplest part of your problem. How are you going to add up transactions involving multiple currencies? There's more than one way to do that, there's probably more than one "right" answer, and your accountants will probably come to blows over which way is the "right" way.
You could use existing services as a guide - e.g., Paypal.
In Paypal, for each account you have to nominate the base currency for that account. Then, any transactions are converted to that currency before being applied to the account. The original amount, its currency, and the conversion rate applied at the time, could also be stored alongside, but for doing calculations you'd use the base currency.
As a general safety rule, always go for the more flexible design. In this interconnected world, it is almost certain that there will be transactions in all kind of currencies (except maybe the local car boot sale, although I am not sure about it). So, store the currency code in the transaction table.

Accounting and Database design, storing debit and credit amount

QUESTION: In the case below should I have stored all my amount as positives decimal amounts then flag the amount as either being a "Debit" or "Credit" rather than storing debits as negative amount and credits as positive amount?
In my database design, I store "debit" as negative amount, and credit as positive amount.
Now in reporting sometimes the results come out wrong because if you do this
TotalAmount = Amount-Fee, and if withdraw amount is $100, and fee is $1.
You would end up with -$100-$1 = -$101, which is the incorrect result!.
Using one column for everything and then using negative numbers for either debits or credits doesn't work, as you've discovered. Accounting values are not scalars -- they are vectors which contain an enum (debit or credit) and a fixed-point decimal number (which can be positive or negative).
Any accounting transaction must contain an equal number of debits and credits. If it doesn't, it's not a valid transaction.
Likewise, an account balance is also that same sort of vector. At any instant in time, the total debits and the total credits across all the accounts in an accounting system must be equal to each other, or else something broke.
Another way of looking at this is to think of an accounting value as a complex number, where debits are real and credits are imaginary. This means that 4 debits + 3 credits = 4 + 3i. This makes it obvious that you can't simplify that any further by collapsing the imaginary term into a negative real term -- it's not the same number line axis. It would be the same as claiming that 4 + 3i = 4 - 3. Not valid math.
If a database could store complex numbers natively, then complex numbers would actually be a good way of storing accounting data, would probably clear up a lot of the confusion that programmers usually have about accounting, and would lead to all sorts of interesting properties. For instance, a balanced transaction would always have a phase angle of 45 degrees, as would a balanced set of accounts. But most databases need you to decompose the complex number into its real and imaginary terms before storage, and store those terms in different columns -- in the accounting world, the names of those two columns are "debits" and "credits", respectively.
P.S.: I'm aware that some folks do use negative for credits and positive for debits, but this takes great care to do right, and is fragile. You have to keep track of the normal balance of any account every time you touch it -- for instance, since an asset account has a debit normal balance, then you can use a positive number to increase it. But a liability account has a negative normal balance, so an increase in that account's value is a negative number. You can't sum those two values together at any time -- they aren't the same thing. A debit is something you have, while a credit is something you owe. Putting both in the same column in a database table smells bad.
As accounting is all based on journal entries, it might be best for your data model to follow from that. This would mean having two columns in your table, one for debit and one for credit. You then leave it up to the application to determine what should be considered a "positive" value and what should be considered "negative". (The question always arises - positive from whose point of view? When you transfer money between bank accounts, it a "negative" for one account but a "positive" for the other.)
It's a while since I worked on this kind of thing, but I seem to remember that it is possible for the debit AND credit columns to contain both positive AND negative values. Accountants have a different way of thinking about numbers than us programmers, so when writing software for them, it can simplify things if you try to work with their conventions.
I work with the Sage Timberline accounting system and it saves debits as positive amounts and credits as negative amounts. In all reports, including the Trial Balance, you do debits + credits. Then you do negative debits for debit reversals and positive credits for credit reversals. Works fine
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.
You can use the ABS function within sql server to get the absolute value. This would allow you to treat negative numbers as positive ones.
eg:
select ABS(-100)
returns 100, not -100.
Here is a transaction detail schema from a great book called "The Data Model Resource Book". This schema meets all the recording requirements without using two columns.
PK TransactionID - int
PK TransactionDetailSequenceID - smallint
Amount decimal
CreditDebitFlag char(1)
Simple and effective, and it doesn't use extraneous columns as other answers here suggest. One column to store all the numeric value data and still gives you the ability to track asset and liability accounts properly.
Though there is already an accepted answer which is very too the point of the question but I also want to share my opinion because it may help others in decide specially when they are designing their database!
Overall both have their own cons and pros and matter can be easily ended by using abs() as in accepted answer! But the problem comes when you talk across teams where different people may have different mind and believe me saving (-ve) values caused more confusions actually, specially if they are directly reading values from database!
I am not against of saving -ve values in database when debit in most cases but saving +ve leads to less confusions actually, even as database programmer, because we always have a column of telling (is it Debit or Credit) and who ever is going to write code can easily convert it at App Level.
Only exception comes with using sum(value) at database level but in reality this is least used scenario because in accounting mostly we are showing running balances and at app level we could use (+) or (-ve).
The point I want to raise is that the database can be used a Company perspective or Customer perspective and now companies have Data Analysts who think from both perspective and once we save just +ve numbers it becomes easier to remember because we already have a flag to know what value is what!

Resources