Тип данных SQL Server, называемый деньгами, является типом двоичной с фиксированной точкой или десятичной с фиксированной точкой?

Я расширяю аналогичный вопрос под названием Является ли тип данных SQL Server «ДЕНЬГИ» десятичным с плавающей запятой или двоичным с плавающей запятой?

Принятый ответ сообщил нам, что тип данных «деньги» является типом данных с фиксированной точкой, а не с плавающей точкой, но не сказал, был ли он двоичным с фиксированной точкой или десятичной с фиксированной точкой.

Я предполагаю, что это десятичная фиксированная точка, но я нигде не могу найти этому подтверждения.

Документация сообщает нам диапазон и размер, но не базовую реализацию.


person samHumeniuk    schedule 11.02.2020    source источник
comment
Я никогда не слышал о binary-fixed-point. Пожалуйста, укажите, что это должно быть. Двоичный - это единица с основанием, а не десять. Несмотря на то, что это тот же номер.   -  person Nick.McDermaid    schedule 11.02.2020
comment
В Следует ли выбирать типы данных MONEY или DECIMAL (x, y) в SQL Server? (TL; DR: не использовать ДЕНЬГИ), пользователь Анон сообщает нам, что за кулисами деньги / smallmoney - это просто bigint / int Десятичная точка в текстовое изображение денег - наглядная ерунда ...   -  person Andrew Morton    schedule 11.02.2020
comment
Это не совпадение, что наименьшее и наибольшее значения точно соответствуют значениям BIGINT с вставленной десятичной точкой, потому что в основном это то, что есть (а SMALLMONEY - это INT с вставленной десятичной точкой). Поскольку коэффициент масштабирования представляет собой степень 10, он квалифицируется как десятичный тип с фиксированной точкой. Как говорится в связанных ответах, MONEY следует использовать с осторожностью именно из-за его фиксированной точности (DECIMAL вычисления будут варьировать свою точность по мере необходимости).   -  person Jeroen Mostert    schedule 11.02.2020
comment
Эта ссылка может вам помочь? w3computing.com/sqlserver2012/data-types-sql-components   -  person Mohamad    schedule 11.02.2020
comment
@samHumeniuk. . . Интересный. Я предполагал, что он хранит то же значение, что и decimals. Но с учетом ограничений на значения это может показаться другим внутренним форматом. Чтобы ответить на этот вопрос, вам, возможно, придется погрузиться во внутреннее устройство SQL Server.   -  person Gordon Linoff    schedule 11.02.2020
comment
@ Nick.McDermaid, Привет, Ник, спасибо за комментарий. Я сам не очень горяч в этой теме. Я руководствовался тем, что wikipedia говорит в абзаце «Двоичные и десятичные». Таким образом, число с фиксированной точкой, имеющее масштабный коэффициент, равный степени 10, является десятичной фиксированной точкой. Число с фиксированной точкой, имеющее коэффициент масштабирования, равный степени 2, является двоичным фиксированным числом.   -  person samHumeniuk    schedule 11.02.2020


Ответы (1)


Не уверен, почему вы заботитесь о базовой реализации, но вы можете CAST money значение типа данных binary(8), чтобы увидеть биты значения:

DECLARE @money money;;

--same as min 64-bit signed integer (2's compliment) with 4 decimal places assumed
SET @money = -922337203685477.5808;
SELECT CAST(@money AS binary(8)); --0x8000000000000000

--same as max 64-bit signed integer with 4 decimal places assumed
SET @money = 922337203685477.5807
SELECT CAST(@money AS binary(8)); --0x7FFFFFFFFFFFFFFF

Таким образом, деньги выглядят как 64-битное целое число со знаком с 4 десятичными знаками. Точность / масштаб не включены в значение с money (и это smallmoney двоюродный брат).

person Dan Guzman    schedule 11.02.2020
comment
Замечание по этому поводу - хотя преобразование в binary действительно говорит вам кое-что о том, как представлены значения, это не полная история. Это бывает для MONEY, но не для DECIMAL - преобразование этих типов в BINARY включает байты для точности и масштабирования и дополняет значение для выравнивания, ни одно из которых не является частью представления при сохранении на странице данных. Масштаб и точность являются частью метаданных набора строк, а не значением. (DECIMAL по-прежнему занимает больше места по другим причинам, в первую очередь из-за отдельного байта знака и нефиксированного двоичного масштабного коэффициента). - person Jeroen Mostert; 11.02.2020
comment
@JeroenMostert, верно, формат в памяти и на диске меняется вместе с уродством с порядком байтов. Не говоря уже о структуре при прохождении TDS по проводу. - person Dan Guzman; 11.02.2020
comment
Ага. Я хочу сказать, что ваше последнее предложение на самом деле неверно - точность / масштаб не включены в значение, поэтому это не причина, по которой money занимает меньше места. (Я предполагаю, что вы не говорили о хранении отдельных значений в памяти, поскольку это почти никогда не актуально - это вступает в игру только тогда, когда движок декодирует страницы данных, а затем временно.) - person Jeroen Mostert; 11.02.2020
comment
@JeroenMostert, разве я не говорил, что точность / масштаб не включены в денежную ценность? - person Dan Guzman; 11.02.2020
comment
Извините, мне нужно быть более ясным. Вы говорите, в отличие от decimal, точность / масштаб не включаются в значение, подразумевая, что для decimal точность / масштаб включены в значение, и это объясняет разницу в хранении. Это не. Наименьший тип decimal, охватывающий money (decimal(19, 4)), занимает 9 байтов памяти, в отличие от 8 байтов money, 1 для байта знака и 8 для значения. Точность и масштаб - это всего лишь метаданные. - person Jeroen Mostert; 11.02.2020
comment
@JeroenMostert, я вижу, откуда вы. Я удалил часть десятичного хранения из своего ответа, которая была собственной десятичной структурой для BCP. - person Dan Guzman; 11.02.2020