← All writing

Keep DECIMAL values exact across the PHP boundary

MySQL 8.0+ / InnoDBSources checked 2026-09-14

A MySQL DECIMAL column stores an exact decimal value, but application code immediately casts it to float. The database choice alone cannot preserve exactness after that conversion.

Choose precision and scale from the domain

CREATE TABLE price_examples (
    id BIGINT UNSIGNED PRIMARY KEY,
    amount DECIMAL(12, 2) NOT NULL,
    currency CHAR(3) NOT NULL
);

The example allows ten digits before the decimal point and two after it. That is a sample constraint, not a universal money schema. Consider maximum values, required fractional precision, and currency rules.

Preserve the representation in application code

Database drivers commonly return DECIMAL as a string. Keep it as an exact decimal representation or convert through an appropriate money/decimal abstraction. Avoid a float cast just to satisfy a loosely designed DTO property.

Define rounding before storing values with more precision than the column accepts. Database SQL modes and conversion behavior should not silently decide invoice policy for you.

Test boundary values, excessive precision, negative amounts if supported, and a round trip through the API. Include the currency in comparisons and totals. A test that checks only number_format output may hide an earlier precision loss. Storage type, arithmetic, serialization, and business rounding all need to agree for exact amounts to remain exact throughout the workflow.

Reference

Official documentation.