主要(而且相当关键)的缺点是你提供的链接似乎并不能做你想做的事情。它只是创建了一个新的整数类型,只能为正数,不提供使用无符号字段所带来的任何节省空间的好处(这似乎是你的主要目标)。也就是说,他们的unsignedSmallint的最大值与smallint的最大值相同,因此你仍然会浪费那些额外的位(但更多的是因为你不能插入负值)。
换句话说,他们的unsignedInt将不允许超过2^31-1的值。
我理解并欣赏,使用int32与int64在单个列上处理100百万行的存储值的节省约为380MB。也许你最好的方法是,在读取存储的值后,在视图内进行偏移,并且始终只从该视图中读取,在进行插入操作时,将该值添加-2^31。但问题在于,在插入之前会发生int32的解析,因此INSTEAD OF触发器将不起作用。(我不知道有没有办法使接受与拥有表不同类型的INSTEAD OF触发器)
因此,在这方面,你的唯一选择是使用存储过程来设置该值,然后可以使用视图或存储过程来获取该值:
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;
IF @fooA < 4294967296 AND @fooA >= 0
INSERT INTO foo VALUES (@fooA - 2147483647)
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。
如果你有一个情况,在这种情况下从中获得了显着的提升(例如表中几乎每一列都比本来需要的大小大两倍),那么上述努力可能是值得的,否则我建议仍然使用bigint
。
rules
。现在你也可以创建CLR UDTs。 - Martin Smith