Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

zaster's avatar

Storing currency(money) in the database

I have decided to proceed with decimal (Not Integer) when it comes to storing currency in the database and decided not to store the amount in the database($amount = $qty * $rate)

Reason to use decimal instead of integer / biginteger

In my case i need 4 decimal points. So something like

decimal('rate', 13, 4) 

should work for me

If i am to use integer / biginteger , i will need to have accessors and mutators too. In that case using decimal is better (Please Correct me if i am wrong)

Reason to NOT store amount in the database

E.g.

Qty : 1000000 Rate : 3.832472 Amount : 3832472

If amount is calculated before storing in the database , the value be 3832472

If amouns is stored in the database it will store 3832400

Therefore i have decided to NOT store(which i belive the best practice) the amount in the database (Please correct me if i am wrong)

0 likes
13 replies
jlrdw's avatar

Many here use int, but I have had no problems with decimal. Just learn how to round as needed and format for display as needed. Of course only a final answer is rounded as needed.

And yes you can calculate when needed.

I'd say practice both techniques and see how it goes.

1 like
zaster's avatar

I have used both ways and decimal seems the best becuase,

  1. No need of using accessors and mutators (performance improvement, i think + ease of use when currency is stored in a pivot table)
  2. Looks good in the database (Becuase it represents the exact value. E.g. - $23.45 will be represented as 23.45 Not 2345)
Tray2's avatar

It doesn't really matter if you store it as an int or as a decimal as long as you don't store it as a float.

I prefer storing it as int instead of decimal, but that is just a preference.

1 like
zaster's avatar

In my case I will have to go with BigInteger since i need 4 decimal points

And use of accessors and mutators seems to be required for both the methods

Snapey's avatar

I will have to go with BigInteger since i need 4 decimal points

Are you sure you know what you mean? Integers (of any size) do not have decimal places.

DO NOT store as decimal fractions, your maths will always be off resulting in differences when working with percentages for discounts and VAT

zaster's avatar

@snapey

What i meant was to store as an BigInteger

Something like this

E.g. - Qty : 10,000 Rate : $3.838 Total : $38,838

    public function getBillItemRateAttribute($rate)
    {
        return $rate / 10000;
    }

    public function setBillItemRateAttribute($value)
    {
        $this->attributes['rate'] = $value * 10000;
    }

In this case 38380 will be stored in the database under the rate field

I think this approach should be ok

Now my issue is dealing with pivot tables

E.g.

Invoice Class


    public function subJobs()
    {
        return $this->belongsToMany('App\Models\SubJob', 'invoice_subjob', 'invoice_id', 'subjob_id')
        ->withPivot('id', 'invoice_id', 'subjob_id', 'qty', 'rate', 'description')
        ->withTimestamps();
    }

SubJob Class

   public function invoices()
    {
        return $this->belongsToMany('App\Models\Invoice', 'invoice_subjob')
        ->withPivot('id', 'invoice_id', 'subjob_id', 'name', 'qty', 'rate', 'description')
        ->withTimestamps();
    }

invoice_subjob is the pivot table

Then when i need to do something like this

@foreach ($invoice->subJobs as $subJob)
                        <tr>
                            <td class="px-6 py-2 text-sm text-center text-gray-500 border-2 border-gray-200 whitespace-nowrap">
                                {{ $subJob->name }}
                            </td>
                            <td class="px-6 py-2 text-sm text-center text-gray-500 border-2 border-gray-200 whitespace-nowrap">
                                {{ $subJob->pivot->description }}</b>
                            </td>
                            <td class="px-6 py-2 text-sm text-center text-gray-500 border-2 border-gray-200 whitespace-nowrap">
                                {{ $subJob->pivot->qty }}
                            </td>
                            <td class="px-6 py-2 text-sm text-center text-gray-500 border-2 border-gray-200 whitespace-nowrap">
                                {{ $subJob->pivot->rate }}
                            </td>
                            <td class="px-6 py-2 text-sm text-center text-gray-500 border-2 border-gray-200 whitespace-nowrap">
                                {{ ($subJob->pivot->qty * $subJob->pivot->rate) }}
                            </td>
                            <td class="px-6 py-2 text-sm text-center text-gray-500 border-2 border-gray-200 whitespace-nowrap">
                            </td>
                        </tr>
                     @endforeach

How can i apply the accessor to

  {{ $subJob->pivot->rate }}

Something like this is required

    public function getRateAttribute($rate)
    {
        return $rate / 10000;
    }
Snapey's avatar

your maths is off

E.g. - Qty : 10,000 Rate : $3.838 Total : $38,838

store in database 38838000

Snapey's avatar

pivot table = new question

but sounds like you need a pivot model

zaster's avatar

@snapey I am storing only the rate in the database

Qty : 10000 Rate : 3.838

38380 will be stored in the database

So this approach is ok right ?

I will create another question for the pivot table issue

zaster's avatar

@Snapey

I wanted to give the user to insert a rate with 4 decimal places

Initially i wanted to store it using decimal('rate', 13, 4) and now have decided to go ahead with using BigInteger

with this approach

   public function getBillItemRateAttribute($rate)
    {
        return $rate / 10000;
    }

    public function setBillItemRateAttribute($value)
    {
        $this->attributes['rate'] = $value * 10000;
    }

Is my approach ok ?

Please or to participate in this conversation.