使用带时间戳的数据正确使用主键

时间:2012-01-05 16:08:17

标签: c# sql-server database

我有一张表,可以存储来自传感器集合的带时间戳记录,这些读数每天拍摄14400次。 (每6秒钟)。

共有4个传感器,它们共享主数据表。

目前架构如下:

id (int-PK)
time (DateTime)
sensor (int)
reading (int)

这非常有效,我将主键设置为自动增量。

然而,拥有这个主键似乎很愚蠢,因为我从不引用它 - 我会更好地使用时间和传感器的组合来充当复合键吗?

如果我确实使用了复合键,我假设每行的字节数也会减少?这是相关的,因为该表超过10米行,所以任何节省都是值得的。

这似乎是双赢的,但我想知道这种方法会产生什么后果。

4 个答案:

答案 0 :(得分:2)

应避免使用复合索引,尤其是复合主键。索引更宽,这对性能(和内存使用)不利。在我个人看来,拥有复合主键也是一种糟糕的设计,因为没有更独特的单一方式来引用你的行。

我的建议是坚持你现在的设计。

答案 1 :(得分:1)

目前您正在使用surrogate key。而且您正在评估转移到natural keys

使用代理键优于自然键,您可以在之前的链接中了解:

  1. 不变性
  2. 要求更改
  3. 性能
  4. 兼容性
  5. 均匀
  6. (来自维基百科)

    您可以在stackoverflow中查找有关surrogate v.s. natural keys的其他帖子。

    但每种设计都与其他设计不同。作为数据库分析师,您应该评估项目的最佳决策。

答案 2 :(得分:1)

坚持设计,我从来没有遇到过将日期时间放入PK的问题。当你的插入因重复而开始失败时,你会希望你没有这样做。

如果你想节省空间,请使用sensor列的小int(你只有4个不同的值)。可能是reading更小的东西,我怀疑传感器可以记录int可以存储的2万亿个不同的值,很可能你可以使用smallint或tiny int。

bigint   8 bytes, -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
int      4 Bytes              -2,147,483,648 to             2,147,483,647
smallint 2 Bytes                     -32,768 to                    32,767
tinyint  1 byte                            0 to                       255

答案 3 :(得分:0)

在10M行上使用组合主键(或唯一索引)可能会轻易占用通过删除int PK(以及更多)获得的任何存储空间。此外,引用此表中的行会变得更加困难。

我总是在任何表上保留一个int(或bigint,如果需要)PK。与其他数据相比,存储空间通常相对较小,并且可以轻松地链接/引用行总是到位,这样可以更轻松地对数据模型进行增强和更改。