Search code examples
mysqldata-storage

What is the Storage Requirement for Decimal(2,1)?


It says in MySQL 5.6 manual that:

Values for DECIMAL (and NUMERIC) columns are represented using a binary format that packs nine decimal (base 10) digits into four bytes. Storage for the integer and fractional parts of each value are determined separately. Each multiple of nine digits requires four bytes, and the “leftover” digits require some fraction of four bytes. The storage required for excess digits is given by the following table:

+----------------------------------+
|Leftover Digits | Number of Bytes |
+----------------------------------+
|       0        |        0        |
+----------------------------------+
|       1        |        1        |
+----------------------------------+
|       2        |        1        |
+----------------------------------+
|       3        |        2        |
+----------------------------------+
|       4        |        2        |
+----------------------------------+
|       5        |        3        |
+----------------------------------+
|       6        |        3        |
+----------------------------------+
|       7        |        4        |
+----------------------------------+
|       8        |        4        |
+----------------------------------+

My question is, if the digits are less than nine on each side of the decimal, would it still use up 4 bytes or will they be considered as "leftovers"?


Solution

  • I did some measurements using MyISAM table to get the answer by comparing the file size of the table dec.MYD after adding some columns to six rows of data. Here is what I get:

    Original:
    -rw-rw----. 1 mysql mysql   54 Dec 17 18:49 dec.MYD
    
    Add one column of DECIMAL(2,1):
    -rw-rw----. 1 mysql mysql   66 Dec 17 18:51 dec.MYD
    
    Further add one column of DECIMAL(4,1):
    -rw-rw----. 1 mysql mysql   84 Dec 17 18:51 dec.MYD
    

    The Conclusion:

    DECIMAL(2,1) requires (66-54)/6 = 2 bytes in total
    DECIMAL(4,1) requires (84-66)/6 = 3 bytes in total
    

    Note that testing is not so straight forward as the first column seems to be always 7 bytes regardless of whether it is DECIMAL(2,1) or INT. You need to add more columns to reproduce the above result.