2016-03-24 2 views
0

Я миграции базы данных MySQL на PostgreSQL и я столкнулся с тривиальной задачейPostgreSQL, конвертировать беззнаковое число (от MySQL) подписанному (например, 65535 -32768 для SMALLINT)

база данных хранит столбец hash_something, который является unsigned integer на MySQL, этот хэш представляет собой 32-битный шумовой хэш v3

Проблема в том, что теперь я не могу найти способ преобразования этих чисел в подписанную версию.

Конечно обходной путь будет использовать BIGINT, так что он подходит, но это займет бы гораздо больше места и замедлить запросы (как у нас есть сотни миллионов подряда)

Так есть ли способ в MySQL или Postgresql, чтобы сделать преобразование, поскольку мне все равно, что это «оптимизированные типы для хранения 32 бит»?

+0

Что происходит, когда вы не конвертировать? – wvdz

+0

@wvdz PostgreSQL жалуется, что значение вне диапазона (я экспортировал данные как CSV из MySQL и реимпортировал его PostgreSQL) –

ответ

1

я закончил, создавая эту функцию в MySQL стороне

CREATE FUNCTION convert_unsigned_to_signed_preserving_bits_32(
    x BIGINT UNSIGNED 
) 
RETURNS BIGINT SIGNED 
DETERMINISTIC 
RETURN 
    CASE 
     WHEN x < POW(2,31) THEN x 
     ELSE x - POW(2,32) 
    END 
; 

так что теперь я могу сделать

mysql> select convert_unsigned_to_signed_preserving_bits_32(4294967295) as signed ; 
+--------+ 
| signed | 
+--------+ 
|  -1 | 
+--------+ 
1 row in set (0.00 sec) 
+0

@muistooshort для char (8) нет, потому что хэш должен быть быстрым, следовательно почему я не хочу преобразовывать их обратно и для строки hexa, для бит (n) или bytea, я не проверяю, функция C, которую я использую, возвращает мне int32, поэтому мне было удобно. Мой вариант использования заключается в том, что я использую этот хеш в индексах для того, чтобы делать «где» на них, и у меня есть 4 столбца, подобные этому с составным индексом, поэтому я наивно (без какого-либо сарказма), думая, что он может быть матовым, чтобы быть int вместо bigint ? –

+0

Разве ваше приложение не нуждается в модификации, чтобы сделать аналогичную манипуляцию? Всякий раз, когда 32-битное значение без знака сравнивается со значениями, хранящимися в столбце? Итак, вместо 'WHERE signed_col = 4294967295', его нужно было бы изменить, чтобы сделать' WHERE signed_col = -1'? – spencer7593

+0

@ spencer7593, да, но мой код все равно будет изменен, поскольку я перехожу от mysql к postgresql, поэтому использование int32 вместо uint32 действительно небольшое изменение по сравнению с переключателем базы данных :) –