Reason to use DECIMAL(31,0) - mysql

What is the reason that some people from Oracle background are using DECIMAL(31,0) for integers. In MySQL it is not efficient.

Oracle implements the "INTEGER" ANSI datatype as a synonym for NUMBER(38)
For more details see "Learn Oracle: Datatypes for SQL and PL/SQL, Numbers"
However, the following table should be used as a mapping between datatype in Oracle and MySQL:
"Oracle® Database SQL Developer Supplementary Information for MySQL Migrations"
Oracle and MySQL Compared > Data Types > Comparing Data Types
The main difference, as explained here and here is that Oracle NUMBER datatype is variable-length format while MySQL DECIMAL(n) datatype used to be represented as strings that require one byte per digit or sign character (before version 5.0.3)
(Oracle NUMBER Datatype) Internal Numeric Format
Oracle Database stores numeric data in
variable-length format. Each value is
stored in scientific notation, with 1
byte used to store the exponent and up
to 20 bytes to store the mantissa. The
resulting value is limited to 38
digits of precision. Oracle Database
does not store leading and trailing
zeros. For example, the number 412 is
stored in a format similar to 4.12 x
102, with 1 byte used to store the
exponent(2) and 2 bytes used to store
the three significant digits of the
mantissa(4,1,2). Negative numbers
include the sign in their length.
Taking this into account, the column
size in bytes for a particular numeric
data value NUMBER(p), where p is the
precision of a given value, can be
calculated using the following
formula:
ROUND((length(p)+s)/2))+1
where s equals zero if the number is
positive, and s equals 1 if the number
is negative.
Zero and positive and negative
infinity (only generated on import
from Oracle Database, Version 5) are
stored using unique representations.
Zero and negative infinity each
require 1 byte; positive infinity
requires 2 bytes.
and
(MySQL) DECIMAL Data Type Changes
The storage requirements for the
integer and fractional parts of each
value are determined separately. Each
multiple of nine digits requires four
bytes, and any remaining digits left
over require some fraction of four
bytes. [...]
For example, a DECIMAL(18,9) column
has nine digits on either side of the
decimal point, so the integer part and
the fractional part each require four
bytes. A DECIMAL(20,6) column has
fourteen integer digits and six
fractional digits. The integer digits
require four bytes for nine of the
digits and three bytes for the
remaining five digits. The six
fractional digits require three bytes.

Related

How many bytes does an unsigned DECIMAL(3,2) use in MySQL

I was wondering how many bytes an unsigned DECIMAL(3,2) uses in SQL. The documentation that I find online is not very clear, especially not when you have an unsigned DECIMAL.
The documentation seems pretty clear:
Values for DECIMAL columns are stored using a binary format that packs
nine decimal digits into 4 bytes. The storage requirements for the
integer and fractional parts of each value are determined separately.
Each multiple of nine digits requires 4 bytes, and any remaining
digits left over require some fraction of 4 bytes. The storage
required for remaining digits is given by the following table.
So, the integer part of DECIMAL(3, 2) has 1 digit and the fractional part has 2 digits. According to the table, 1-2 digits require one byte. Hence the total is two bytes.
The simple answer, which is usually correct or very close:
The storage requirement for DECIMAL(m,n) is m/2.
In your case 3/2 = 1.5 is very close. In this case, round up to get the correct "2".

Crypto Currency MySQL Datatypes ?

The infamous question about datatypes when storing money values in an SQL database.
However in these trying times, we now have currencies that have worth up to 18 decimal places (thank you ETH).
This now reraises the classic argument.
IDEAS
Option 1 BIGINT Use a big integer to save the real value, then store how many decimal places the currency has (simply dividing A by 10^B in translation)?
Option 2 Decimal(60,30) Store the datatype in a large decimal, which inevitibly will cost a large amount of space.
Option 3 VARCHAR(64) Store in a string. Which would have a performance impact.
I want to know peoples thoughts and what they are using if they are dealing with cryptocurrency values. As I am stumped with the best method for proceeding.
There's a clear best option out of the three you suggested (plus one from the comments).
BIGINT — uses just 8 bytes, but the largest BIGINT only has 19 decimal digits; if you divide by 1018, the largest value you can represent is 9.22, which isn't enough range.
DOUBLE — only has 15–17 decimal digits of precision; has all the known drawbacks of floating-point arithmetic.
VARCHAR — will use 20+ bytes if you're dealing with 18 decimal places; will require constant string↔int conversions; can't be sorted; can't be compared; can't be added in DB; many downsides.
DECIMAL(27,18) – if using MySQL, this will take 12 bytes (4 for each group of 9 digits). This is quite a reasonable storage size, and has enough range to support amounts as large as one billion or as small as one Wei. It can be sorted, compared, added, subtracted, etc. in the database without loss of precision.
I would use DECIMAL(27,18) (or DECIMAL(36,18) if you need to store truly huge values) to store cryptocurrency money values.

MySQL Decimal query efficiency for different number of digits

I am trying to implement a table with entry as Decimal data type using MySQL. In the link (http://dev.mysql.com/doc/refman/5.7/en/storage-requirements.html), it says that when I am using decimal to store a number that has 9 or less decimal digits, regardless of the number of digits being 7, 8 or 9, the storage space will be 4 bytes.
However, I am curious if any sql queries will take different amount of time if the decimal type number has different number of digits.
Since it take same 4 bytes, it should be same? Or would there be any difference?
The documentation says:
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.
It will depend on your CPU and your hardware configuration. Modern CPU's are smart enough and if you are not doing some really big calculations it should not affect the performance much. In case you are using it in a OLTP then it is not going to affect the performance very much. However in case of OLAP it might create some performance bottlenecks. But that is for something which involves really complex calculations.
Also just to add, prior to MySQL 5.0.3 decimal datatype was stored in format of string but later on with release of MySQL 5.1 and later the DECIMAL type is stored in a binary format so if we are not doing very complex calculations it should not affect the performance.

mysql DECIMAL storage requirements

I was reading the mysql manual and want to make sure I understanding something correctly.
If I have DECIMAL (15,8) would this mean 6 digital before the decimal and 8 after?
If I want to move from 15,2 to allow for 8 decimals after price, then should I move to 21,8 so I don't lose any precision?
From mysql documentation : http://dev.mysql.com/doc/refman/5.7/en/fixed-point-types.html
In a DECIMAL column declaration, the precision and scale can be (and usually is) specified; for example:
salary DECIMAL(5,2)
In this example, 5 is the precision and 2 is the scale. The precision represents the number of significant digits that are stored for values, and the scale represents the number of digits that can be stored following the decimal point.
Standard SQL requires that DECIMAL(5,2) be able to store any value with five digits and two decimals, so values that can be stored in the salary column range from -999.99 to 999.99.

MySQL can't handle large values even with DECIMAL

DECIMAL is supposed to be exact. It isn't. It rounds like crazy!
TABLE:
account_balance DECIMAL(18,4)
If I insert 43210987654321.9999
it rounds to 43210987654322.0000
If I insert 43210987654321.9876
it rounds to 43210987654321.9840
WHY? If I use numbers larger than 18 during table creation it is even worse.
EDIT:
I posted this clarification edit because some people do not know about the DECIMAL data type.
The DECIMAL data type is a FIXED POINT data type as opposed to a FLOATING POINT data type.
The reason it is used is:
(1) Store massive numbers that have decimal values with exact precision.
(2) Prevent rounding errors that can not be prevented when using floating point calculations. Thus any calculation on DECIMAL values should be exact... no rounding error.
POSTRESQL
http://www.postgresql.org/docs/8.1/static/datatype.html
numeric -- user-specified precision -- exact --no limit
The type numeric can store numbers with up to 1000 digits of precision and perform calculations exactly. It is especially recommended for storing monetary amounts and other quantities where exactness is required. However, arithmetic on numeric values is very slow compared to the integer types, or to the floating-point types described in the next section.
The types decimal and numeric are equivalent. Both types are part of the SQL standard.
MySQL
DECIMAL( , ) A DOUBLE stored as a string , allowing for a fixed decimal point.
http://www.htmlite.com/mysql003.php
MySQL DOC
Fixed-Point (Exact-Value) Types
The DECIMAL and NUMERIC types store exact numeric data values. These types are used when it is important to preserve exact precision, for example with monetary data. In MySQL, NUMERIC is implemented as DECIMAL, so the following remarks about DECIMAL apply equally to NUMERIC.
As of MySQL 5.0.3, DECIMAL values are stored in binary format. Previously, they were stored as strings, with one character used for each digit of the value.
http://dev.mysql.com/doc/refman/5.0/en/numeric-types.html
The maximum value of 65 for M means that calculations on DECIMAL values are accurate up to 65 digits. This limit of 65 digits of precision also applies to exact-value numeric literals, so the maximum range of such literals differs from before. (In older versions of MySQL, decimal values could have up to 254 digits. However, calculations were done using floating-point and thus were approximate, not exact.)
Calculations involving exact-value decimal numbers are accurate to 65 digits. This is fewer than the maximum number of digits permitted before MySQL 5.0.3 (254 digits), but the exact-value precision is greater. Calculations formerly were done with double-precision floating-point, which has a precision of 52 bits (about 15 decimal digits).
http://dev.mysql.com/doc/refman/5.1/en/precision-math-decimal-changes.html
I tested on my local mysql 5.1.36 and it does not round.
What version are you using.
Also, what are you using to insert. Are you sure it is mysql rounding and not the storage before inserting to mysql.