Основным (и довольно важным) недостатком является то, что кажется, что ссылка, которую вы предоставляете, на самом деле не делает то, что вы думаете.
Она просто создает новый целочисленный тип, который может быть только положительным, он не дает вам никакой экономии места, которая могла бы возникнуть в результате использования поля без знака (что, кажется, является вашей главной целью).то есть максимальное значение их 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
.