【问题标题】:Storing Time Zones on an SQL Server在 SQL Server 上存储时区
【发布时间】:2017-04-21 02:53:02
【问题描述】:

我正在开发一项全球调度服务,该服务使用不同时区的物理位置。 这些时区必须与每个位置一起保存在数据库中。 问题是,它们如何最好地存储?

我们目前使用自定义时区表,它将自定义整数 ID 映射到 Microsoft 时区字符串标识符。 我希望改为存储 IANA 时区标识符。 我们的数据库是一个 SQL Server,使用 Entity Framework 6 在 C# 中访问它。我们使用 NodaTime 处理时间。 解决方案必须与所有这些技术完美配合。

我看到了两种不同的方法:

  1. 只需将 IANA 标识符与每个位置一起存储为字符串即可。
  2. 将所有 IANA 标识符存储在单独的表中,并使用外键链接到该表。

第一个解决方案可能是最简单的,因为它很容易允许使用新的标识符并将数据紧密地结合在一起。 但是,它确实有使用大量空间的缺点。

第二种解决方案要求我们在每次需要时区时加入时区表 - 这很常见 - 但需要的空间很小。 如果需要,必须将新的时区标识符添加到该表中。 它还引入了这些神奇的整数 ID(使用的外键),它们可能会被误认为是众所周知的标识符(我们目前有这个问题,其中 ID 已移出数据库并进入用于代替数据库的代码内字典表)。

在我写这篇文章的时候,我想知道是否有可能为 SQL Server 创建一个自定义时区 UDT,其中时区可以作为字符串标识符保存和加载,但可以更有效地存储以用户隐藏的格式。

【问题讨论】:

  • 为什么不将所有内容存储为 UTC 并在客户端应用程序中处理本地化?
  • 这些位置可以是例如一家餐厅,该餐厅有当地的营业时间。这些营业时间基于餐厅的位置,而不是观众的位置。此外,我们进行调度,因此未来的时间必须以本地时间存储,以便可以根据给定位置的时区正确地将它们转换为分区时间。此外,其中一个客户端是 JS 前端,JS 在处理时区和夏令时方面是一团糟。
  • 在本地时间存储日期通常是一个坏主意,因为本地时间会随着夏令时等而变化。如果您以 UTC 存储所有内容并维护您的时区查找表,您可以准确地适应本地更改和只需转换为任何时区,无论是用户还是未来和过去的位置。尝试将其存储为本地比简单地尝试将其显示为本地更令人头疼。
  • 存储当地时间对于安排未来的活动是必要的,以防夏令时规则发生变化。如果规则发生变化,当地时间可能会有所不同。拜托,我知道如何处理时间。我在问我应该如何以最好的方式将物理位置的时区存储在数据库中。
  • @iamdave - Mikkel 在调度方面是正确的。 “UTC Always”不一定是真的——有很多极端情况。这在stackoverflow.com/questions/2532729/… 中有介绍

标签: c# sql-server timezone nodatime iana


【解决方案1】:

虽然这两种方法都行得通,但通常的做法是将 IANA 时区标识符存储为字符串。它们确实是唯一标识符,因此可以这样对待它们。 "America/Argentina/ComodRivadavia" 是目前最大的字符串,有 32 个字符 - 所以 varchar(32) 就足够了。不过,我通常使用 varchar(50) 只是为了未来安全。

您可以通过规范化查找表节省的几千字节存储空间通常不值得连接的性能影响,恕我直言。但是,就像任何权衡一样,您应该评估这两个选项,看看哪个更适合您的场景。使用查找表不一定错误

【讨论】:

  • 面向未来读者的快速更新:虽然 IANA 2017c 规定了 14 个字符的最大长度,但这适用于区域或链接名称的各个部分 - 而不是整个字符串。因此,这里的建议仍然适用。
猜你喜欢
  • 2010-12-22
  • 2016-10-21
  • 2010-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-04
  • 2011-10-22
相关资源
最近更新 更多