我正在使用MSSQL server 2005设计一个数据库来存储来自不同设备的日志值。 值的数据类型可以是boolean,int-32或64 bit-double
将会有一个名为channels
的查找表:
ID(PK) | int32
device_name | varchar(32)
将有一个名为values
的表来存储该值。所以boolean和int-32,double值将被转换为DECIMAL数据类型。
ID(foreign key to ID@channels) | int32
logtime | DATETIME
value | DECIMAL
我这样做的原因是最终用户可以在一个表上使用简单的select语句选择数据,例如
select logtime,value from values where ID = 1
,但不知道频道的数据类型。
但这是浪费内存,因为现在我将int32和boolean存储到Decimal。我是数据库编程的新手,我想知道是否有人知道更好的方法吗?
答案 0 :(得分:4)
您可以存储3个可以为空的单个字段。两个将具有NULL值,第三个将具有实际值(您甚至可以使用CHECK约束强制执行三个中的一个不是-NULL)。 NULL值不占用空间。您可以添加一个将非null值公开为伪列的计算值。
或者,您可以使用sql_variant
字段。 sql_variant
可以存储多种类型并保留类型元数据(类型,精度,比例)。
答案 1 :(得分:2)
这是一个CHECK约束的例子,它确保三个IS NOT NULL中的一个
ALTER TABLE MyTable WITH CHECK
ADD CONSTRAINT CK_MyTable_ColumNulls CHECK(
(CASE
WHEN col1 IS NOT NULL
THEN 1
WHEN col2 IS NOT NULL
THEN 2
WHEN col3 IS NOT NULL
THEN 3
ELSE
500
END)
=
(CASE
WHEN col3 IS NOT NULL
THEN 3
WHEN col2 IS NOT NULL
THEN 2
WHEN col1 IS NOT NULL
THEN 1
ELSE
600
END)
)
答案 2 :(得分:0)
通过使用3个可空的单个字段,我创建了一个名为 mixedNumericView 的视图, 使用CASE选择正确的列。我假设使用CASE这种方式很便宜,对吗?有没有替代方法呢?日志频率可以达到每分钟,我想确保这是选择数据的最佳方式。
SELECT [ID], [logtime]
,'value' =
CASE
WHEN [intValue] is not NULL THEN [intValue]
WHEN [bitValue] is not NULL THEN [bitValue]
WHEN [floatValue] is not NULL THEN [floatValue]
ELSE NULL
END
FROM [dbo].[mixedNumericView]