5

我正在处理本机作为有理数提供的数据。我有一个漂亮的通用 C# 类,它可以在 C# 中精美地表示此数据,并允许转换为许多其他形式。不幸的是,当我转身想将它存储在 SQL 中时,我想到了几个解决方案,但没有一个是非常令人满意的。

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

  1. 就像一个小数/浮点数,即0.66666667各种精度和精确度的值=。 优点:这使我可以查询数据,例如找到 < 1 的值。 缺点:它失去了准确性,当我在 UI 中显示这个简单的值时,它很难看。

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

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

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

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

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

4

5 回答 5

8

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

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

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

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

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

于 2009-12-19T19:02:31.923 回答
6

我可能会选择选项#4,但对第三列使用计算列以避免同步/干燥问题(也意味着您实际上只存储 2 列,避免“三个字段”问题)。

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

CREATE TABLE dbo.Whatever(
   Numerator INT NOT NULL,
   Denominator INT NOT NULL,
   Value AS (Numerator / Denominator) PERSISTED
)

(请注意,您可能需要进行一些类型转换和验证分母不为零等)。

此外,SQL 2005 添加了一个 PERSISTED 计算列,该列将在查询时摆脱计算。

于 2009-12-19T18:57:04.167 回答
2

您需要多少精度?

语言,C# 或其他语言,将在精度的给定位置四舍五入 2/3。如果您正在处理的任何事情都可以使用科学记数法 10 的十进制值,那么请在 db.xml 中相应地设置精度。

如果精度确实是一个问题,那么将分子和分母分开。这将确保您始终可以访问所需的任何精度,并且您可以使用计算列来表示快速过滤的值:

numerator INT,
denominator INT,
result AS CASE WHEN denominator > 0 THEN numerator / denominator ELSE NULL END
于 2009-12-19T19:03:51.623 回答
0

我已经尝试过使用 SQL Server 2008 中的几何数据类型来存储和操作有理数。基本上,我假设分子进入 X 槽,分母进入虚构几何点的 Y 槽。

这对我的需求有好处,但对你的需求可能没用。这将取决于您的优先事项(性能、代码可读性等)。我个人发现用于几何数据操作的 T-SQL 很难写和读。

于 2009-12-19T18:57:47.957 回答
0

你在看多少精度?double/float 提供了不错的精度(在我看来)。我很确定科学/天文数据需要比这更高的精度。我知道像 matlab 和 mathematica 这样的库很擅长这些。我发现您可以将mathematica 与您的.net 程序一起使用。链接在这里

编辑:添加更多链接和引号

“当 Mathematica 对有理数进行运算时,无论需要多少位数,它都会给出准确的结果”从 这里开始

另一个很好的读物,但我猜你必须实现它

于 2009-12-19T19:00:25.517 回答