SQL Server 2008 - целочисленные типы данных без знака - PullRequest
8 голосов
/ 01 сентября 2011

Я использую SQL SERVER 2008, у меня есть несколько полей INT, SMALLINT в моих различных таблицах, и я знаю, что все они будут 0 или больше 0, то есть я могу принять их без знака.

Isесть простой способ создания / использования типов данных без знака ИЛИ мне придется создать тип-> Создать правило-> Использовать созданный тип;как указано в следующей статье?

http://www.julian -kuiters.id.au / article.php / sqlserver2005-unsigned-integer

Если это единственный способиспользовать Unsigned в SQL, есть ли недостатки / недостатки в его использовании?

Ответы [ 3 ]

11 голосов
/ 01 сентября 2011

Основным (и довольно важным) недостатком является то, что кажется, что ссылка, которую вы предоставляете, на самом деле не делает то, что вы думаете.

Она просто создает новый целочисленный тип, который может быть только положительным, он не дает вам никакой экономии места, которая могла бы возникнуть в результате использования поля без знака (что, кажется, является вашей главной целью).то есть максимальное значение их unsignedSmallint будет таким же, как максимальное значение для smallint, поэтому вы все равно будете тратить эти дополнительные биты (но тем более, что вы не можете вставить отрицательные значения).

То есть их unsignedInt не позволят значения выше 2 ^ 31-1.

Я понимаю и понимаю, что в 100 миллионов строк экономия от использования int32 против int64 наодин столбец составляет около 380 МБ.Возможно, лучший способ сделать это - обработать сохраненное значение после его прочтения, в идеале в представлении и только когда-либо читать из этого представления, а затем при вставке добавить -2 ^ 31 к значению... Но проблема в том, что синтаксический анализ для int32 происходит до вставки, поэтому триггеры INSTEAD OF не будут работать .. (Я не знаю ни одного способа создания триггера INSTEAD OF, который принимает типы, отличающиеся от типа владельцатаблица)

Вместо этого единственный вариант в этом отношении - использовать хранимые процедуры для set значения, затем вы можете использовать представление или сохраненный процесс для получения значения:

create table foo
(fooA int)
GO

CREATE VIEW [bar]
AS
SELECT CAST(fooA AS BIGINT) + 2147483647 AS fooA
FROM foo
GO

CREATE PROCEDURE set_foo
    @fooA bigint
AS
BEGIN
    SET NOCOUNT ON;

    -- Insert statements for procedure here
    IF @fooA < 4294967296 AND @fooA >= 0
        INSERT INTO foo VALUES (@fooA - 2147483647)
    --ELSE
        -- throw some message here
END
GO

Это можно проверить с помощью:

exec set_foo 123
exec set_foo 555
select * FROM bar
select * FROM foo
exec set_foo 0
exec set_foo 2147483648
exec set_foo 4147483648
select * FROM bar
select * FROM foo

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

Если у вас есть случай, когда вы увидите значительное улучшение от этого (например, почти каждый столбец в таблице вдвое больше, чем big, как и должно быть в противном случае), тогда вышеуказанные усилия могут быть оправданы, в противном случае я бы просто остался с bigint.

3 голосов
/ 11 июня 2014

Чтобы преобразовать подписанный smallint в число без знака, попробуйте это:

CAST(yourSignedSmallInt AS int) & 0xffff

Чтобы преобразовать подписанное int в число без знака, попробуйте

CAST(yourSignedInt AS bigint) & 0xffffffff

например, если ваше поле таблицы x является smallint и вы хотите вернуть значение unsigned, тогда попробуйте

SELECT (CAST(x AS int) & 0xffff) FROM ... WHERE ....
2 голосов
/ 03 апреля 2013

Соответствующее решение зависит от проблемы, которую вы пытаетесь решить.Если это поле идентификаторов, и ваша цель состоит в том, чтобы удвоить количество строк, которое может содержать ваша таблица, не сохраняя 4 дополнительных байта, в каждой строке для использования bigint, то просто заполняйте поле как -2 147 483 648, а не как 1. Если вам нужнохранить значения больше 2,147 миллиарда, а затем использовать больший тип данных.

...