在数据库表中使用汇总列是常见的还是好的形式?

时间:2017-04-19 19:51:45

标签: sql-server database-design

我需要来自数据库人员的一些建议。如果我有这个数据库表:

EVENT
Id
Name
StartDateTime
EndDateTime
DurationInSeconds  <---

可以在表格中包含一个汇总列,其中包含事件的持续时间(以秒为单位)(StartDateTime和EndDateTime之间的秒数):

firewall-cmd --permanent --remove-service=ssh2

我知道这需要额外的存储空间,但随着表格变得非常大(数千万行),在运行时计算这段时间会变得非常昂贵。

我想遵循“最佳做法”,但也不希望因为没有“廉价”格式(性能明智)而使数据无法使用。

你会做什么?

如果重要,我正在使用SQL Server 2014。

2 个答案:

答案 0 :(得分:3)

以下是包含样本信息的计算列的示例。

create table MyEvents
(
    ID int
    , Name varchar(20)
    , StartDateTime datetime
    , EndDateTime datetime
    , DurationInSeconds as datediff(second, StartDateTime, EndDateTime) PERSISTED
)


insert MyEvents
select 1
    , 'Event 1'
    , getdate()
    , dateadd(minute, 3, getdate())

select * 
from MyEvents

答案 1 :(得分:1)

在数据库设计方面,术语“最佳实践”被过度使用。问题在于,对于许多人来说,“最佳实践”相当于“做聪明人做的事”,而不是学习聪明人学到的东西。

对于任何重大设计问题,将会有多个令人满意的设计,尽管有些设计会比其他设计更令人满意。在你的情况下,它不会是一场灾难。在更大的方案中,存储空间和处理时间的差异将很小。最好的方法取决于您对数据的使用,正如几条评论所指出的那样。

以下是需要注意的几件事。

如果将持续时间存储为单独的列,则存在一些粗心的更新程序将更改事件的结束时间,并忘记相应更改持续时间的风险。这不太可能在编程良好的应用程序中发生,但如果您偶尔通过交互式SQL进行修正,则驾驶舱错误可能会引入这种不一致。

如果您在检索时计算持续时间,并且如果许多不同的程序员对此计算进行编码,那么您将面临其中一个人不知道如何计算两个时间戳之间的差异的风险。

可能最好的折衷方案是计算列。但是,最好是存储开始时间和持续时间,并将结束时间作为计算值。同样,这取决于您对数据的处理方式。