4

我正在使用 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 logtime,value from values where ID = 1不知道通道的数据类型。

但这是浪费内存,因为现在我将 int32 和布尔值存储为十进制。我是数据库编程的新手,我想知道是否有人知道更好的方法来做到这一点?

4

3 回答 3

6

您可以存储 3 个可以为空的单独字段。两个将具有 NULL 值,第三个将具有实际值(您甚至可以使用 CHECK 约束强制三个中的一个不为空)。NULL 值不占用空间。您可以添加一个计算值,将非空值公开为伪列。

或者,您可以使用sql_variant字段。sql_variant可以存储多种类型并保留类型元数据(类型、精度、比例)。

于 2011-04-20T02:17:59.390 回答
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)
)
于 2014-04-08T00:34:16.093 回答
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]
于 2011-04-25T21:40:28.207 回答