За съхранение не цели числа в MySQL - Публикации

В MySQL, има много видове номера за съхранение на данни като числа и числа с плаваща запетая.
Помислете за съществуващите формати:

За число използва: TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT. Тези видове се използват за съхранение и да се цели числа от 1 до 8 байта памет, съответно.

За плаващ се използват номерата на точките: FLOAT, двойно. Основният недостатък на плаваща запетая (или реален брой) - на принципа на тяхното представяне и съхранение. Тези номера се съхраняват като степен на две. Тъй като не всички десетични числа са точно представяне на двоичен фракция, съхранение резултатите са закръглени. Дори елементарни математически операции са възможни несъответствия. Още подробности за това могат да бъдат прочетени на Хабре

При съхранение на важни данни (например, по банкова сметка) е важно във всеки символ дори последната цифра след десетичната точка, така че използването на плаваща запетая невъзможно.
Избягвайте съхранение и извличане на данни могат да бъдат проблеми с помощта на тип: десетични, числено.

За версия 5.03, тези видове, съхранявани като низове, използван един поредица от букви, цифри за всеки номер (ако е необходимо да се харчат допълнително по един знак знак номер и десетична запетая) също е възможно загуба на точност поради неправилно прилагане на аритметиката като номера.

От 5.03 в MySQL нова библиотека за аритметични фиксирана запетая и различен подход към съхраняване на такива номера. Сега, неразделна част и част след десетичната запетая се съхраняват като две отделни числа. консумация процент пространство може да се основава на следната таблица:

Изчислението е много проста: например, че трябва да се запази десетични (10,2) - цялата страна има 8 цифри и е 4 байта, частта след точката - 2 цифри и отнема 1 байт. Общо на депозита ще бъдат изразходвани 5 байта.

В по-ранни версии на MySQL, десетична запетая и числените типове държат по различен начин. SQL-стандарт изисква точността на NUMERIC (M, D) има точно M цифри. стандарт изисква точност не по-малко от цифрите на M за десетичен (M, D), но позволява повече. Това означава, че ако искате да запазите броя 1.00005 в десетичен (6,4) и цифрови (6,4), а след това при 1.0000 ще запази стандартна цифрова и десетични може да спаси 1.00005. Това поведение на голям брой математически операции може да даде една малка грешка.

Последните версии на MySQL десетична запетая и числови, и двата вида са с точност точно M цифри.

За да се извари всички по-горе, помислете два примера (Версия на сървъра: 5.0.77 Gentoo Linux).

Създайте таблица тест с 4 полета от различни типове. Ние ще направим едни и същи данни и да видим как ще се държи в MySQL

Нагледен пример за това защо не трябва да се доверите на важните данни с плаваща точка номер. Но не мисля, че двойното - панацея. FLOAT и DOUBLE - същия принцип на съхранение. И двата вида са еднакво не точни, просто ДВОЙНИ неточности настъпват, когато голям брой знаци.

Проблеми могат да възникнат дори и в по-тежките случаи. Да предположим, че ние съхраняваме данни за баланса на клиента до цента:

Ако аз не съм убеден, можете да се откажете от оборотни средства. подготви за проблеми при търсенето.

Проблемът с това търсене:

Ако имате съществува необходимост в полето за търсене на плувка - използвайте границата, за да се търси.

Въпросът остава отворен. Тъй като данните се съхраняват?
Да предположим, че нашата задача е да се запази броя с два знака след десетичната запетая. Това може да стане по следните начини:

1. FLOAT - изкован точността, не забравяйте за проблемите на намиране и все още се използва. Обхватът на съхранените номера е много голям: [-3,402823466E + 38. -1,175494351E-38] 0 и [1,175494351E-38. 3,402823466E + 38]. Той заема 4 байта.

3. десетичен (X, 2) - точния брой с десетична точка. В зависимост от желания брой знаци, до степен, промяна X. Например, ние трябва да съхраните номера на 10 млн. След инициализация поле ще има форма десетични (9,2), поле - 5 заемат байта и складови числа в интервала [-9,999,999.99. 9,999,999.99].

4. INT - магазин незабавно в "Пени", както и всички трансформации, които участват в съхранени процедури, тригери, PHP или друг език за програмиране. С този подход, можем да поддържаме числата в интервала: [-21,474,836.48. 21474836,47], или чрез използване на неозначено [0. 42949672,95]. Ако изведнъж се нуждаете от по-голям диапазон, винаги можете да използвате 8-байт BIGINT.

1. За съхранение на важни данни, които не могат да се използват видове плувка и двойни;

2. Най-добрият начин да се съхранява - десетична. В краен случай - INT или BIGINT (особено ако са използвани ORM или DAO за достъп до данни и всички операции за превод на цяла част и обратно ще бъдат прозрачни);

4. Ако използвате версия на MySQL преди 5.0.3. настоятелно се препоръчва да преминат към нещо по-свежа;