简体   繁体   English

SQL Server:最佳的存储时间方式(无日期)

[英]SQL Server: Most optimal way of storing time (without date)

Here's one more or less for perfection's sake. 为了完美,这里或多或少是一个。

Microsoft SQL Server only contains the field type datetime for storing dates and times. Microsoft SQL Server仅包含用于存储日期和时间的字段类型datetime

But let's say that I want to store a list of business hours, where the date is completely irrelevant. 但是,让我们说我想存储一个营业时间列表,其中日期完全无关紧要。 Currently I'm using the datetime type and then simply displaying the time-portion of the data. 目前我正在使用datetime类型,然后只显示数据的时间部分。 But I have two problems with this. 但我有两个问题。

  1. It seems awkwardly inefficient. 这似乎效率低下。
  2. It may confuse future developers to see a full-blown date coming along with the time, which they may not know whether is used anywhere or not. 它可能会让未来的开发人员感到困惑,因为他们可能不知道是否在任何地方使用了这个时间。

And so it begs the question; 所以它引出了一个问题; in the absence of a specific time field (like in MySQL), what is the most optimal way of storing only a particular time of day, from 00:00 to 23:59? 在没有特定time字段的情况下(如在MySQL中),从00:00到23:59只存储一天中特定时间的最佳方式是什么?

UPDATE : It's SQL Server 2005. (Also I'd just be interested in knowing what to do in general when there is no time type.) 更新 :它是SQL Server 2005.(另外,我只是想知道在没有time类型的情况下一般该做什么。)

For SQL Server 2005 or older... 对于SQL Server 2005或更早版本...

If you only want to know to the minute, you can store it as an int in the range of 1-1440 . 如果您只想了解分钟,可以将其存储为1-1440范围内的1-1440 1 is 00:01 and 1440 is 0:00 . 1是00:01和14400:00

It would be easy do display as a time again if you like: 如果您愿意,可以轻松再次显示:

SELECT CAST((605 / 60) as varchar) + ':' + RIGHT('0' + CAST((605 % 60) as varchar), 2)

An additional advantage of this is that if you use a smallint data type you are saving 1-3 bytes per record from the built-in TIME datatype. 另一个优点是,如果使用smallint数据类型,则从内置TIME数据类型中为每条记录保存1-3个字节。

TIME uses 3-5 bytes per row and smallint is 2 bytes per row. TIME每行使用3-5个字节, smallint每行2个字节。

The extra bytes are for seconds and fractional seconds I believe. 我相信额外的字节是秒和小数秒。

EDIT 编辑

It's more complicated with seconds but still doable I should think... 它会更复杂的秒,但仍然可行,我应该想...

1-86400 range (seconds per day) 1-86400范围(每天秒数)

DECLARE @i INT
SET @i = 3661

SELECT RIGHT('0' + CAST((@i / 3600) as varchar),2) --hours
+ ':' + RIGHT('0' + CAST((@i % 3600)/60 as varchar), 2) -- minutes
+ ':' + RIGHT('0' + CAST((@i % 3600)%60 as varchar), 2) -- seconds

SQL Server 2008 has a TIME datatype: SQL Server 2008具有TIME数据类型:

http://www.sql-server-performance.com/2007/datetime-2008/ http://www.sql-server-performance.com/2007/datetime-2008/

DECLARE @dt as TIME
SET @dt = getdate()
PRINT @dt

Upgrade to SQL 2008? 升级到SQL 2008?

Personally I would not consider the points raised as sufficient enough to move away from using DATETIME or SMALLDATETIME. 就个人而言,我不会认为提出的点数足以让我们不再使用DATETIME或SMALLDATETIME。

  • An INT uses 4 bytes, as does a SMALLDATETIME INT使用4个字节,SMALLDATETIME也是如此
  • People make mistakes with SMALLINT that cause implicit type conversions (increasing cpu load) 人们使用SMALLINT导致错误导致隐式类型转换(增加cpu负载)
  • Disk Space is cheap, you need a lot of bytes to add up to anythign significant 磁盘空间很便宜,你需要很多字节才能加起来
  • Code such as WHERE minutes < 720 is less understandable than WHERE time < '12:00' 诸如WHERE minutes < 720代码比WHERE time < '12:00'更难理解
  • Display issues (such as conversion of DATETIME to hh:mm) is often best place in the client 显示问题(例如将DATETIME转换为hh:mm)通常是客户端中的最佳位置
  • Using DATETIME allows future flexibility, such moving to seconds instead of minutes 使用DATETIME可以实现未来的灵活性,例如移动到秒而不是几分钟

That said, I have used INTEGER fields to hold number of seconds, such as when they're predominantly used for calculating average durations, etc. 也就是说,我使用INTEGER字段来保持秒数,例如当它们主要用于计算平均持续时间等时。

My single biggest consideration in choosing the type is how the value will be used; 我在选择类型时最大的考虑因素是如何使用该值; to ensure legible code and performant execution plans. 确保清晰的代码和高性能的执行计划。

SQL 2008 fixed this problem as others have noted but in 2005: SQL 2008解决了这个问题,正如其他人已经注意到的那样,

Do you need to perform any date math on the times? 你需要在时间上执行任何日期数学吗? If not, you can store it as a string. 如果没有,您可以将其存储为字符串。

If you need to perform date math, a datetime with the day set to zero along with a descriptive column name shouldn't stump any future devs (and thanks for keeping us in mind). 如果您需要执行日期数学运算,将日期设置为零的日期时间以及描述性列名称不应该留下任何未来的开发人员(并且感谢您记住我们)。

And yes, datetime is clunky for time only storage but it functions just fine. 是的,datetime对于仅限时间存储而言非常笨重,但它的功能很好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM