Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2009.09.20;
Скачать: [xml.tar.bz2];

Вниз

Объясните тонконсти хранения чисел   Найти похожие ветки 

 
Zemen   (2008-11-21 17:08) [0]

Имеем СУБД Firebird 1.5. Вопрос касается в данном случае только этой системы.

Создаю таблицу:
CREATE TABLE CAR(SP SPEED NUMERIC(15,2));

Что значит 15 (разрядность) и точность (2). В книжке написано, разрядность общее число цифр в числе, а точность - число знаков после запятой. Точность задает формат отображения либо хранения чисел ?


 
Zemen   (2008-11-21 17:13) [1]

Вопрос возник по следующей причине. Есть таблица А, числовые колонки которой имеют тип NUMERIC(15,2). В результате расчетов в числовые колонки заносятся числовые значения, у которых количество знаков после запятой больше 2-х. При этом такое в базе они все эти знаки сохраняются!


 
Правильный$Вася   (2008-11-21 17:36) [2]

из справки по IB6
NUMERIC datatype
NUMERIC(x,y)
In the syntax above, InterBase stores exactly x digits. Of that number, exactly y digits are to the right of the decimal point. For example,
NUMERIC(5,2)
declares that a column of this type always holds numbers with exactly 5 digits, with exactly two digits to the right of the decimal point: ppp.ss


 
Правильный$Вася   (2008-11-21 17:40) [3]

The following table summarizes how InterBase stores NUMERIC and
DECIMAL datatypes based on precision and scale:
Datatype specified as… Datatype stored as…
NUMERIC     INTEGER
NUMERIC(4) SMALLINT
NUMERIC(9) INTEGER
NUMERIC(10) • DOUBLE PRECISION in dialect1
                  • INT64 in dialect 3
NUMERIC(4,2) SMALLINT
NUMERIC(9,3) INTEGER
NUMERIC(10,4) • DOUBLE PRECISION in dialect1
                    • INT64 in dialect 3


 
Anatoly Podgoretsky ©   (2008-11-21 19:04) [4]

> Zemen  (21.11.2008 17:08:00)  [0]

Есть два подхода к этому, когда точность (более правильно) это разрядность, а число знаков после запятой иногда почему то называется размер. Много путаницы внесли старые СУБД, типа dBase и FoxPro. Когда 15 означало не точность или число знаков, а число байт для хранения, а точность там называлось количесто знаков после запятой ( с точностью до Х знаков после запятой - наверно слышал такую фразу). Вот подобная запись означала в общем случае 13 знаков (из них две после запятой) + запятая + знак числа. В современных 15 это точность (precision - в твоей терминологии разрядность?) и 2 количество знаков после запятой, формат чисел BCD (не относится к обработке).


 
Anatoly Podgoretsky ©   (2008-11-21 19:05) [5]

> Zemen  (21.11.2008 17:13:01)  [1]

Для Numeric - тогда это ошибка данной СУБД


 
Anatoly Podgoretsky ©   (2008-11-21 19:06) [6]

> Правильный$Вася  (21.11.2008 17:36:02)  [2]

С ИБ надо быть поосторожнее, поскольку это зависит от уровня, на первом уровне это Float, на третьем BCD


 
Anatoly Podgoretsky ©   (2008-11-21 19:09) [7]

> Правильный$Вася  (21.11.2008 17:40:03)  [3]

Вот они эти особенности IB тот вообще 4 внутренних формата для NUMERIC.


 
Johnmen ©   (2008-11-21 19:26) [8]


> Anatoly Podgoretsky ©   (21.11.08 19:09) [7]

NUMERIC в ИБ это вообще не формат.


 
Anatoly Podgoretsky ©   (2008-11-21 20:40) [9]

> Johnmen  (21.11.2008 19:26:08)  [8]

Я могу и поправиться - это тип


 
Johnmen ©   (2008-11-21 21:07) [10]


> Anatoly Podgoretsky ©   (21.11.08 20:40) [9]

Псевдотип, если точнее...
:)


 
Anatoly Podgoretsky ©   (2008-11-21 23:45) [11]

> Johnmen  (21.11.2008 21:07:10)  [10]

Ну не буду спорить, но что бардак, так точно.


 
Loginov Dmitry ©   (2008-11-22 00:10) [12]

> Есть таблица А, числовые колонки которой имеют тип NUMERIC(15,
> 2). В результате расчетов в числовые колонки заносятся числовые
> значения, у которых количество знаков после запятой больше
> 2-х. При этом такое в базе они все эти знаки сохраняются!


Нет, в базе сохраняются именно 2 знака запятой. Более того, все число физически хранится в целочисленном формате (для 3-го (актуального сейчас) диалекта - см [3]). "Благодаря" этому, не так-то просто увеличить число знаков после запятой в процессе эксплуатации, так что если есть сомнения, лучше заранее брать с запасом ))


 
Zemen   (2008-11-24 12:51) [13]

Проше прощения за отсутствие, коллеги, был в отъезде.

Обсуждения ушли в сторону. То, что по разному хранит, это одно. Но такое поведение вообще нормально ? Причем обнаружил такую вещь. При с нуля таблицы по схеме: CREATE TABLE, INSERT, UPDATE такая ситуация не наблюдается. Если делаю UPDATE SET FFF = 0.12344124, то потом вижу значение FFF = 0.12. Получается, что все-таки СУБД округлила при обновлении под тип поля. Но в тоже самое время есть старая таблица с точно таким же типом поля. Попытка выполнить такой же запрос обновления, и в таблице сидят неокругленные значения с 8 знаками после запятой!


 
Правильный$Вася   (2008-11-24 12:57) [14]

ты так и не уточнил диалект
а это важно


 
Zemen   (2008-11-24 12:59) [15]

Диалект изначально третий, но перевод БД на третий диалект ситуацию не изменил.


 
Zemen   (2008-11-24 13:00) [16]

Сейчас попробую сделать демо-базу с двумя таблицами в качестве примера.


 
Виталий Панасенко   (2008-11-24 14:08) [17]


> Zemen   (24.11.08 12:59) [15]
>
> Диалект изначально третий, но перевод БД на третий диалект
> ситуацию не изменил.

А в старой - 1-й...


 
Zemen   (2008-11-24 14:29) [18]

Эврика! Диагноз поставлен, но адекватного решения похоже нет.

Никакой демо-базы делать не нужно. Рассматриваем только разрядность от 10 чисел. В диалекте 1 тип Numeric(15,2) хранится как DOUBLE PRECISION. При обновлении никакого округления не возникает, значение 0.12345678 хранится как есть. Диалект 3 тот же самый тип хранится как INT64. Значение 0.12345678 при обновлении округляется до 0.12.

Однако при переводе базы с первого диалекта на третий поведение не меняется. Это, конечно, удивило. Поля, созданные в первом диалекте, после перевода на третий ведут себя по старому, т.е. как DOUBLE PRECISION.  Смена типа через ALTER TYPE дает ошибку, т.к. СУБД не может конвертировать значения из DOUBLE PRECISION в INT64. Новые же поля ведут себя ожидаемо. Это - диагноз :).

Теперь решение. Переход на третий диалект без полной перетряски базы не поможет. По сути надо писать отдельную программу, которая для каждого числового поля будет переписывать данные. В настоящее время это исключено. Тогда придется, учитывая данную особенность, вносить изменения в программый код, т.е. плодить заплатки или боротся со следствием, а не причиной, что требует гораздо больше времени и сил. Такие, вот, пироги.

Не ошибся ли я в своих изыскания и есть ли другие пути решения ?


 
Правильный$Вася   (2008-11-24 15:23) [19]

выгрузить в скрипт, залить его в правильную?


 
Zemen   (2008-11-24 17:25) [20]


> выгрузить в скрипт, залить его в правильную?

Сейчас это фантастика. Дешевле будет заплатки лепить :)


 
Правильный$Вася   (2008-11-24 18:21) [21]

"никогда не хватает времени, чтобы что-то сделать правильно
зато чтобы переделать, причем N раз, время находится"
вольный перефраз из законов Мерфи


 
Johnmen ©   (2008-11-24 20:54) [22]


> Обсуждения ушли в сторону.

Чего тут обсуждать-то? Документацию лень открыть?



Страницы: 1 вся ветка

Форум: "Базы";
Текущий архив: 2009.09.20;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.005 c
3-1227533789
belmol
2008-11-24 16:36
2009.09.20
firebird и округление


15-1248204795
DVM
2009-07-21 23:33
2009.09.20
Расщепление байта на биты


2-1247658555
b/@.
2009-07-15 15:49
2009.09.20
Можно ли поместить на форме графикс поверх винконтрол ?


15-1248422799
GanibalLector
2009-07-24 12:06
2009.09.20
Win2003 ограничение запуска приложения


3-1227192412
bankir
2008-11-20 17:46
2009.09.20
SQL-запрос. Как наиболее правильно сделать.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский