HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-03-10
1 <p>Вот вы проектируете систему, в которой встречаются финансовые данные. Вы стоите перед выбором: в каком типе данных лучше хранить деньги?</p>
1 <p>Вот вы проектируете систему, в которой встречаются финансовые данные. Вы стоите перед выбором: в каком типе данных лучше хранить деньги?</p>
2 <p>Начну с конца - в каком типе точно НЕ хранить деньги? Конечно, это<strong>float</strong>. С одной стороны, вроде бы float подходит, так как денежные суммы обычно хранятся с целой и дробной частью: рубли с копейками. Например, эти наши любимые цены 9 руб. 75 копеек логично завести в поле "Цена" и записать как 9,75.</p>
2 <p>Начну с конца - в каком типе точно НЕ хранить деньги? Конечно, это<strong>float</strong>. С одной стороны, вроде бы float подходит, так как денежные суммы обычно хранятся с целой и дробной частью: рубли с копейками. Например, эти наши любимые цены 9 руб. 75 копеек логично завести в поле "Цена" и записать как 9,75.</p>
3 <p>НО! Только не используйте для этого типы данных, подобные<strong>float</strong>, потому что это тип приблизительных числовых данных для чисел с плавающей запятой, и при вычислениях он будет давать погрешность.</p>
3 <p>НО! Только не используйте для этого типы данных, подобные<strong>float</strong>, потому что это тип приблизительных числовых данных для чисел с плавающей запятой, и при вычислениях он будет давать погрешность.</p>
4 <p>Как<a>сказал</a><strong>Боб Мартин</strong>(Robert C. Martin): "В этом нет ничего смешного, я знавал людей, которых посадили в тюрьму за то, что они использовали тип<strong>float</strong>в БД для хранения денег".</p>
4 <p>Как<a>сказал</a><strong>Боб Мартин</strong>(Robert C. Martin): "В этом нет ничего смешного, я знавал людей, которых посадили в тюрьму за то, что они использовали тип<strong>float</strong>в БД для хранения денег".</p>
5 <h2>А что тогда подходит?</h2>
5 <h2>А что тогда подходит?</h2>
6 <p>Теперь, когда мы выяснили, что типы для чисел с плавающей запятой (да, да и<strong>double</strong>тоже) нам<strong>НЕ подходят</strong>, посмотрим, какие есть варианты:</p>
6 <p>Теперь, когда мы выяснили, что типы для чисел с плавающей запятой (да, да и<strong>double</strong>тоже) нам<strong>НЕ подходят</strong>, посмотрим, какие есть варианты:</p>
7 <p>●<strong>MONEY</strong>и<strong>SmallMoney</strong>(для небольших сумм). Соответственно, 8 и 4 байта. Это встроенные типы в<strong>SQL Server</strong>, и в общем это отличный выбор. Единственный минус в том, что это нестандартные типы данных (не ANSI), и они есть только в<strong>SQL Server</strong>. Это нужно учесть, если у вас есть хоть малейший шанс перехода с SQL Server на другую СУБД.</p>
7 <p>●<strong>MONEY</strong>и<strong>SmallMoney</strong>(для небольших сумм). Соответственно, 8 и 4 байта. Это встроенные типы в<strong>SQL Server</strong>, и в общем это отличный выбор. Единственный минус в том, что это нестандартные типы данных (не ANSI), и они есть только в<strong>SQL Server</strong>. Это нужно учесть, если у вас есть хоть малейший шанс перехода с SQL Server на другую СУБД.</p>
8 <p>● DECIMAL (19,4) Тип с фиксированной точностью, весит целых 9 байт. 4 - количество знаков, после запятой. Зачем 4, спросите вы? Ведь копейки, центы и прочие популярные валюты имеют только 2 знака? Да, хотя есть экзотические валюты, где дробная часть 3 знака. Кроме того, если у вас не просто хранятся деньги, а вы с ними производите какие-то вычисления с использованием умножения или, даже страшно представить, деления, у вас будет образовываться<strong>дробная часть</strong>. А на больших объемах эта дробная часть может быть кому-то и сложится в виллу, а может быть и нет… Поэтому лучше сделайте<strong>точность больше</strong>. В некоторых системах я видела до 8 знаков после запятой. При этом учтите, что округление должно быть одинаковое на все финансовые данные, которые выводятся из<strong>базы данных</strong>, так как бухгалтерия страшно нервничает, если у вас во внутренних документах для компании и для клиента указывается разное количество копеек.</p>
8 <p>● DECIMAL (19,4) Тип с фиксированной точностью, весит целых 9 байт. 4 - количество знаков, после запятой. Зачем 4, спросите вы? Ведь копейки, центы и прочие популярные валюты имеют только 2 знака? Да, хотя есть экзотические валюты, где дробная часть 3 знака. Кроме того, если у вас не просто хранятся деньги, а вы с ними производите какие-то вычисления с использованием умножения или, даже страшно представить, деления, у вас будет образовываться<strong>дробная часть</strong>. А на больших объемах эта дробная часть может быть кому-то и сложится в виллу, а может быть и нет… Поэтому лучше сделайте<strong>точность больше</strong>. В некоторых системах я видела до 8 знаков после запятой. При этом учтите, что округление должно быть одинаковое на все финансовые данные, которые выводятся из<strong>базы данных</strong>, так как бухгалтерия страшно нервничает, если у вас во внутренних документах для компании и для клиента указывается разное количество копеек.</p>
9 <p>● А есть ещё варианты? Да, есть! Вы можете использовать тип<strong>INT</strong>. При этом обычно все суммы в БД хранятся в копейках, а при отображении делятся на 100. Этот подход встречается не очень часто, но имеет место быть, и в тюрьму за него не сажают.</p>
9 <p>● А есть ещё варианты? Да, есть! Вы можете использовать тип<strong>INT</strong>. При этом обычно все суммы в БД хранятся в копейках, а при отображении делятся на 100. Этот подход встречается не очень часто, но имеет место быть, и в тюрьму за него не сажают.</p>
10 <p>Если вы всё же обнаружили у себя деньги в типе<strong>float</strong>, задумайтесь над<strong>рефакторингом</strong>. Даже если это кажется дорого, с ростом проекта проблемы будут только расти, и лучше это сделать прямо сейчас, не откладывая на потом.</p>
10 <p>Если вы всё же обнаружили у себя деньги в типе<strong>float</strong>, задумайтесь над<strong>рефакторингом</strong>. Даже если это кажется дорого, с ростом проекта проблемы будут только расти, и лучше это сделать прямо сейчас, не откладывая на потом.</p>
11 <p><em>А как вы храните деньги в БД? Пишите в комментариях!</em></p>
11 <p><em>А как вы храните деньги в БД? Пишите в комментариях!</em></p>
12  
12