Let's say I have an app (a Monopoly game) with many users, where each user has a balance, and they make transactions between them.
I have a table with all the users (userID, name, email) and a table with all the transactions and the users who made them (user1, user 2, amount).
Now if I need to present a balance for each user, would it be better to keep the balance for each user in the users table and update it every time a transaction is made, or should I calculate it from the transactions table every time I wont to present it? Assume this game will have a lot of traffic, so what is a more reasonable approach for 10,000+ users and about 120,000+ transactions per week?
Having a new column balance in the user table is a redundancy beacause the value could be calculated with a query on the transactions table.
However one of the DB design process is the estimation of how many read and writes could happen on a particular table. If this estimation is high it's logic and permitted to simplify the result of some read or write and have a redundancy on the DB to afford the many reads requested by the web pages and display values with less processing time.
In your case the balance column update could be done with a trigger on the transactions table that calculate the balance for the two users involed.
Related
I'm creating a feature that has an option to create infinite bank account transactions by month, for example: A user buy something in 12x parcels, will be created 12 rows on database with relation with this purchase in a table called bank_account_transactions.
Now the problematic scenario: A user has a salary that increase the balance of bank account every month for the rest of his life, how can i store this in database?
I thought store data equivalent to 100 years (12*100=1200) but it is so slow because when the user update the value of his salary, will update 1200 rows in database.
How can I solve this in a performatic way? The project is developed with Nodejs and MongoDB.
I was wondering how people are securely storing money balances in a database. E.g how do you make sure that the database administrator does not modify balances or transactions? How do you make sure that the code that does a transaction not accidentally or intentionally by a rogue employee does not work correctly.
Banks, PayPal and any other apps that hold balances in USD or any other currency should have this problem
All the banking packages I've worked with store the balance with the account entity. Calculating it on the fly from movement history is unthinkable.
The right way is:
The movement table has an 'opening
balance' transaction for each and every account. You'll need
this in a few year's time when you
need to move old movements out of the
active movement table to a history
table.
The account entity has a balance
field
There is a trigger on the movement
table which updates the account
balances for the credited and debited accounts. Obviously, it has commitment
control. If you can't have a trigger, then there needs to be a unique module which writes movements under commitment control
You have a 'safety net' program you
can run offline, which re-calculates
all the balances and displays (and
optionally corrects) erroneous
balances. This is very useful for
testing.
Some systems store all movements as positive numbers, and express the credit/debit by inverting the from/to fields or with a flag. Personally, I prefer a credit field, a debit field and a signed amount, this makes reversals much easier to follow.
Notice that these methods applies both to cash and securities.
Securities transactions can be much trickier, especially for corporate actions, you will need to accommodate a single transaction that updates one or more buyer and seller cash balances, their security position balances and possibly the broker/depository.
From smirkingman answer on Database design: Calculating the Account Balance
I'm trying to build a database for banking I created a table for every account loan, deposit , checking account and also for payment methods checks, debit cards and cash.
My question is that how should I handle transactions between the tables knowing that the transactions are possible between all the tables?
For example customer can withdraw money using debit card, transfer money from checking account to loan or deposit money to checking using a check.
My first solution is to create one transaction table for all the transactions and the Cardinality (0...1 n ) so that only one type of payment and one account, so should I go with it or just create a transaction table for every relationship between two tables?
If "I created a table for every account, loan, deposit , checking account" means that you have more than four tables then you are doing something very very wrong. You should have one table for customers and one table for transactions. A transaction is money moving from one account to another account, so a simple transaction table would have the fields id, transaction date, credit account, debit account, amount. In accountancy, there are frequently transactions which involve several credit and debit accounts so these can't be maintained in the simple transaction scheme outlined above.
If you want to represent loans, then you'll probably need two more tables: one table contains the atomic details of all the loans (date given, account of the loanee, total amount, nominal interest rate, etc) and the other table contains the projected repayments of each loan.
There is no need for further tables representing deposits or checking accounts: these can be represented as accounts, with a type field designating which kind they are.
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.
Consider these two use cases.
Say a store gives out store credit for customers. Store credit come from refunds, discounts, overpaying amounts etc...
The customer decides how and when to
use this credit. E.g. Say customer A
have $50 dollars in store credit and
he decides to use $25 for invoice A
and $25 for invoice B... or decides
to have the store credit sitting
there against his account for future
purchases.
The customer and store must also
have a way to look up the total of
store credit.
What is the easiest and most straight forward way to cater for this in table structure?
I currently have tables:
Transaction (For journal and reporting purpose)
Customer
Credit
Used Credit
Invoice table will have other associations like invoice lines, receipt, receipt lines etc...
Is this the best way to do this? My concern is primarily regarding ease of reporting and transaction mechanics.
Alternatively I'm considering just saving all credit entry and used credit inside the transaction table.
Updated diagram for clarification and from inputs
Correct me if I'm wrong, but I believe you want something like this.
A Customer has CreditEntrys, and CreditEntrys have UsedCredites. There are also Transactions which include links to corresponding Invoice. And finally, a Transaction has links to many UsedCreditwhich were used during this transaction. If all CreditEntry was used at a time, then there will be one UsedCredit used with this Transaction, and this UsedCredit will correspond to the entire CreditEntry
The database schema would be quite straightforward here - relations through foreign keys. You would probably want to create an additional unique constraint to reflect ONE-TO-ONE relation between Transaction and Invoice
Oh, by the way, that service that you used for diagram creation is cool.
create 4 tables, 1 for customers then another for their credit and used credit and then another for transaction and invoice. You may join transaction and invoice since they may have similar data.