如何最好地表示SQL Server中的有理数?

mck*_*mey 5 sql sql-server rational-numbers

我正在使用原生作为有理数提供的数据.我有一个灵活的通用C#类,它在C#中精美地表示这些数据,并允许转换为许多其他形式.不幸的是,当我转身并希望将其存储在SQL中时,我有几个解决方案,但没有一个是非常令人满意的.

这是一个例子.我有2/3new Rational<int>(2, 3)在C#中轻松处理的原始值.我想到的用于将其存储在数据库中的选项如下:

  1. 就像一个十进制/浮点,即值= 0.66666667各种精度和精确度. 优点:这允许我查询数据,例如查找值<1. 缺点:它具有精确性的损失,当我在UI中显示这个简单的值时它很难看.

  2. 存储为两个精确的整数字段,例如,分子= 2,分母= 3各种精度和精确度. 优点:这使我能够精确地表示原始值,并在以后以最简单的形式显示它. 缺点:我现在有两个字段来表示这个值,查询现在很复杂/效率低,因为每个查询都必须执行算术,例如find numerator/denominator <1.

  3. 序列化为字符串数据,即"2/3".我将能够知道最大字符串长度并且有一个varchar可以容纳这个. 优点:我回到了一个领域,但有一个确切的代表. 缺点:查询几乎被破坏并支付序列化成本.

  4. #1和#2的组合. 优点:轻松/高效地查询值范围,在UI中具有精确值. 缺点: 三个字段(!?!)保存一个数据,必须保持多个表示同步才能打破DRY

  5. #1和#3的组合. 优点:轻松/高效地查询值范围,在UI中具有精确值. 缺点:回到两个字段来保存一个数据,必须保持多个表示同步,这会破坏DRY,并且必须支付额外的序列化成本.

有没有人有另一个开箱即用的解决方案比这些更好?还有其他我不考虑的事情吗?有没有一种相对简单的方法在SQL中做到这一点,我只是没有意识到?

Mic*_*tta 8

如果您使用的是SQL Server 2005或2008,则可以选择定义自己的CLR数据类型:

从SQL Server 2005开始,您可以使用用户定义类型(UDT)来扩展服务器的标量类型系统,从而在SQL Server数据库中存储CLR对象.UDT可以包含多个元素,并且可以具有行为,将它们与由单个SQL Server系统数据类型组成的传统别名数据类型区分开来.

由于UDT是整个系统访问的,因此它们对复杂数据类型的使用可能会对性能产生负面影响.复杂数据通常使用传统的行和表进行最佳建模.SQL Server中的UDT非常适合以下内容:

  • 日期,时间,货币和扩展数字类型
  • 地理空间应用
  • 编码或加密数据

如果你能忍受这些限制,我无法想象一种更好的方法来映射你已经在自定义类中捕获的数据.


Chr*_*fer 6

我可能会使用选项#4,但是使用第3列的计算列来避免同步/干扰问题(也意味着您实际上只存储了2列,避免了"三个字段"问题).

在SQL Server中,计算列的定义如下:

CREATE TABLE dbo.Whatever(
   Numerator INT NOT NULL,
   Denominator INT NOT NULL,
   Value AS (Numerator / Denominator) PERSISTED
)
Run Code Online (Sandbox Code Playgroud)

(注意你可能需要做一些类型转换和验证Denominator不为零等).

此外,SQL 2005添加了一个PERSISTED计算列,可以在查询时删除计算.