use*_*055 8 sql sql-server-2008 sqldatatypes unsigned-integer
我正在使用SQL SERVER 2008,我在各种表中都有一些INT,SMALLINT字段,而且我知道它们都是0或大于0,即我可以将它们取无符号.
是否有一种创建/使用无符号数据类型的简单方法,或者我必须创建类型 - >生成规则 - >使用创建类型; 如下文所述?
http://www.julian-kuiters.id.au/article.php/sqlserver2005-unsigned-integer
如果这是在SQL中使用Unsigned的唯一方法,那么使用它有什么缺点/缺点吗?
Sep*_*eph 11
主要(而且相当关键)的缺点是,您提供的链接似乎实际上并不像您认为的那样.
它只是创建一个只能为正的新整数类型,它不会为您提供任何空间节省,否则将导致使用无符号字段(这似乎是您的主要目标).也就是说,它们的最大值unsignedSmallint将与最大值相同smallint,因此您仍然会浪费那些额外的位(但更多因为您不能插入负值).
也就是说他们unsignedInt不允许超过2 ^ 31-1的值.
我理解并意识到,在1亿行中,在单个列上使用int32 vs int64可节省大约380MB.也许你这样做的最好方法是处理这是为了在你读取它之后抵消你的存储值,理想情况是在视图中并且只从该视图中读取,然后在执行插入时将-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
Run Code Online (Sandbox Code Playgroud)
这可以使用以下方法测试:
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
Run Code Online (Sandbox Code Playgroud)
您将看到值是无符号返回的,但是返回的值是int64而不是unsigned32,因此您的应用程序需要将它们视为仍然是int64.
如果你有一个情况下,你会看到这样显著的改善(表等几乎每一列的两倍大,因为它否则必须),那么上述的努力,可能必要的,否则,我只想留在bigint代替.
| 归档时间: |
|
| 查看次数: |
33106 次 |
| 最近记录: |