Database design best practice - database

Suppose a user is able to
(1) use money to buy something (Money leaves wallet)
(2) sell something to earn money (Money enters wallet)
and I want to keep track of the transactions and ensure that they are accurate. And I have thought of two methods
(A) Keep track using three disjoint table
buys <userid, amount>
sells <userid, amount>
transaction <transactionid, userid, amount, type>
i.e.
insert <u1, 90> into buys trigger insert <t1, u1, 90, 'buy'>
for example
(B) Have buys and sells store transactionid from transaction table
buys <userid, transactionid>
sells <userid, transactionid>
transaction <transactionid, amount>
i.e.
insert <t1, 90> into transaction and insert <u1, t1> into buys
My questions will be what are the pros and cons to method (A) and (B) and what are the alternative methods/best practices out there?

You can do it like this:
user table: (userid, name, ...)
transaction table: (transactionid, amount, date, ...)
link user and transaction table, (transactionid, buyerid, sellerid).
buyerid and sellerid are foreing keys of user.userid.
This way, you can get buyer and seller form one single query, and not two tables. If you need to keep track of offered price and paid price, they are just extra fields in the transaction table.
So any data on the transaction goes in the transaction table, any data related to the involded users goes into the link table.
I see entities (users, transactions) as separate tables, and actions as link tables between entities.

Related

Double Entry System

System has many users belongs to a company. Admin user of the company can entry customers and each customer may have invoices with payment amount. The customer invoice amount need to be paid and should be inserted in double entry system in transaction master table.
Data Models are followings:
User
Company
Customer
Invoice
Transaction Master
My initial approach will be:
Company will have a one to many relationship with users
in invoice table, the details will be saved.
My questions are:
Do I need to create any relationship between customers and invoices tables?
How the transaction master table will be created? (double entry system refers to have debit and credit accounts, that's all my knowledge)
Yes, you need to create a relationship between customers and invoices table. Every invoice will have one customer. Every customer will have none, one, or many invoices. You will need a unique identifier to be stored in each file.
Transaction file is a much deeper subject. I assume you mean Ledger Transactions. Generally you will group a transaction with one or more debit entries matched with one or more credit entries with an associated reference number which will point to the invoice transaction. You would group references in a batch, usually called a session, and assign a session number at batch posting time which would have the post date.
These are the basic minimum answers to a very vague question on a potentially complex subject, but hopefully it will help get you started in the right direction for further research.

SQL Server Database Design - Seperate Table for Sale and Purchase

I am building a new business application for my personal business which has close to ~100 transactions of sale and purchase per day. I am thinking of having Separate tables to record the sale and purchase with another linked table for Items that were sold and a seperate linked table with items that were purchased.
Example:
**SaleTable**
InvoiceNo
TotalAmt
**SaleTableDetail**
LinkedInvNo
ProductID
Quantity
Amount
etc.,
would this design be better or would it be more efficient to have one transactiontable with a column stating sale or purchase?
-From an App/Database/Query/Reporting Perspective
An invoice is not the same as a sales order. An invoice is a request for payment. A sales order is an agreement to sell products to a party at a price on a date.
A sales order is almost exactly the same as a purchase order, except you are the customer, and a sales order line item can reference a purchase order line item. You can put them in separate tables, but you should probably use Table Inheritance (CTI, extending from an abstract Order). Putting them in the same table with a "type" column is called Single Table Inheritance and is nice and simple.
Don't store totals in your operational db. You can put them in your analytic db though (warehouse).
You are starting small, thats a quick way to do. But, I am sure, very shortly you will run into differences between sale and purchase transactions, some fields will describe only a sale and some fields that will be applicable only for purchases.
In due course, you may want to keep track of modifications or a modification audit. Then you start having multiple rows for the same transaction with fields indicating obsoletion or you have to move history records to another table.
Also, consider the code-style-overhead in all your queries, you got to mention the Transaction Type as sale or purchase for simple queries.
It would be better to design your database with a model that maps business reality closest. At the highest level, everything may abstract to a "transaction", with date, amount and some kind of tag to indicate amount is paid or received against what context. That shouldn't mean we can have a table with Tag, Date, Amount, PayOrReceive to handle all the diverse transactions.

database design & relations for tourism web app

I'm currently developing a web app on a travel & tourism website. What I'm willing to do is to allow the user to register himself to be able to book a tour for himself and/or family members. The 'family members' need not to register themselves. And the user should be able to cancel any member/himself from the booking. The tables I've designed so far are:
users
id,
name,
password,
email,
phone,
level (to distinguish between user & admin),
dob (date of birth),
status (active or blocked)
tours
id,
title,
short_desc,
start_date,
end_date,
max_passenger_capacity,
fees,
published (boolean),
long_desc
passengers (for additional passengers who are not registered)
id (PK),
user_id (FK from users),
name,
age,
sex,
status
wallets (where users can deposit money and pay from)
id (PK),
user_id (FK from users),
date_time,
narration,
ref_no,
withdraw (float),
deposit (float)
Now I intend to create an invoice table (id, date, user_id etc.), invoice_items table (id, invoice_id, etc. with reference to who is booking which tour for whom), passengers_booked table (id, tour_id, passenger_id etc. to keep track of which passenger is opting which tour).
The user should be able to cancel all the members from a tour or any member from the tour. In the later case an invoice should be raised quoting any refund and the other members should stay opted for the tour.
And how should manage the condition when the user is opting a tour for himself? And how to manage such invoice_items so that he can cancel himself?
I'm totally lost. Please help.
A few thoughts on users and invoices structures to hopefully get you back on track. You'll probably need to clarify your question regarding other aspects (e.g. refunds).
To cope with users optionally being passengers, you could create a common people table, the people_id being a FK in both passengers and users. Hopefully, this should help keep your subsequent queries simpler and ease the processes whereby users become passengers, and possibly where passengers become registered users too. For example:
people: id (PK), name, dob, sex
users: id (PK), people_id, password, email, phone, level, status
passengers: id (PK), people_id (FK from people), status (as a passenger)
Notes:
Would people.name be better as multiple fields (forename and surname)?
You might consider email and phone better as fields on people rather than users (balancing redundancy against potential marketing)?
Use dob consistently, rather than age (as this will require maintaining).
You might think about how you keep entries on the people table unique to help prevent duplicates being added for the same person.
With respect to Invoices and Refunds section, I'm not entirely sure what is required from the fragment you posted. Consider the following:
invoice: id (PK), invoice_date, user_id, tour_id, invoice_amount
passengers_booked: id (PK), tour_id, passenger_id
wallets: id (PK), user_id (FK from users), transaction_date_time, narration, invoice_no NULL (FK to invoice), ref_no, transaction_amount (float)
Notes:
I'm not sure what your intention was for invoice_detail, as you know who's booking for whom by joining invoice and passengers_booked on tour_id.
Refunds would be handled by posting any refund amount to the relevant wallet record.
I've combined withdrawal and deposit into a single transaction_amount field to remove redundancy and ease the processing when, for example, calculating balances. The types can be distinguished using +ve and -ve values. [Although you may have accounting standards that mandate separate fields.]
I've added invoice_no to wallet to track payments and refunds relating to a particular trip (but may be NULL for deposits/withdrawals). Similarly, ref_no may then be used when deposits/withdrawals into the wallet are received. [n.b. You might consider combining invoice_no and ref_no.]
Example
User U is booking for a tour T for himself and his family members A,
B, C & D. And he also made the payment. Lets assume cost for tour T is
$1000/passenger. So he made a payment of $5000.
The users table has a record for user U.
The tours table has a record for tour T.
The people table has 5 records for U, A, B, C, D.
The passengers table has 5 records.
The passengers_booked table has 5 records for tour T.
The invoice table has a record dated e.g. '1 Jan' for $5000 for tour T.
The wallet has a deposit record for $5000.
The wallet also has a payment of -$5000 against our invoice.
Now he wishes to cancel the booking of B. And for that he will be refunded (suppose)
$900 after cancellation charge.
The B record is removed from passengers_booked (but can be left on passengers for future use).
The invoice table is updated with revised date e.g. '8 Jan' and amount $4100.
The wallet table has a refund made to it against that invoice for $900.
Thus we use a single invoice which only holds the latest position.
You can check the latest invoice amount against the sum of wallet entries for that invoice, to see whether there is an amount outstanding or due for refund.
n.b. There are other ways to model this, e.g. use invoice as the summary as above but have multiple invoice_detail records to capture the detail on passenger changes. Depending on why you're doing this and how sophisticated it needs to be will determine which route is better for you.

banking database design issue

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.

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.

Resources