我的 F# 应用程序有一个非常好的 F# 模型,充分利用了 F# 类型系统(联合、记录、元组和原始类型)。我试图找出将这些数据类型保存到 SQL-Server DB 的最佳方法。
让我们做以下假设:
我要坚持的中心实体是一个有区别的联合,
Task
称为表实现起来很繁琐我希望每周多次不断地改进这些模型,CI 将在提交后立即将我的应用程序部署到生产环境中。同样,使用常规表格会使
ALTER TABLE
语句减慢我的开发和部署速度,并增加相当多的认知超载,任何新开发人员在此系统上都会发现具有挑战性在模型进化时,我应该能够轻松地使用后台进程在线升级我的旧模型,或者从数据库中获取,停机时间接近于 0
我应该能够以任意深度查询这些模型,而且我已经有将近一百万行要处理,而且还会继续增长。查询应该很快,最多百毫秒级
我需要使用 SQL Server,因为这个应用程序是更大系统的一小部分,我希望任何数据库操作都参与任何正在进行的数据库事务
序列化为Task
JSON
这是我的第一次尝试——使用 SQL Server 2016 的新 JSON 函数将所有内容存储为 JSON,识别可查询值,将它们存储在索引表中。SQL Server 中的 JSON 函数非常快,但是对这些查询进行索引需要我使用持久+计算+索引列或索引视图。
痛点:
很难进化模型,特别是如果我想进化所有类型 X 的实例,对于不同的联合情况,它可能出现在不同的深度。没有标准化的语言来说明这些演变
JSON 不区分十进制/浮点数/数字,这有时很难处理,我需要自定义格式化程序。小问题,没什么大不了的。
查询语言在任意深度上都有些原始,并且这些查询没有索引,因此新查询几乎总是需要我创建一个计算列或更改我的索引视图。
将新的索引列添加到索引视图不是 ONLINE 操作,会导致停机,并且在 CI 中很难自动化
在同一个表中使用 PERSISTED COLUMNS 有时会导致 SQL Server 在搜索/选择时没有真正使用这些,而是从头开始重新计算值(因为它在其查询计划器中不能很好地准确计算此操作的成本)
序列化为Task
XML
这是我目前的实现。
我编写了自己的自定义 XML 序列化程序,使我可以很容易地使用 XQuery 和 SQL Server 的 xml 数据类型列查询数据库
使用极其强大的 XSLT,模型演变轻而易举
问题:
- 即使添加了所有可能的 XML 索引,查询也很慢——大约需要 5 秒(在 Azure P6 SQL 实例中)
- 再加上对不同持久模型版本的稍微不同的查询,这使得它变得更加昂贵
- 非索引 XML 函数非常慢,构建索引表/持久列需要很长时间,所以我不能真正使用它。
我对我的 XML 解决方案非常满意——我只需要一种方法来加快我的 XML 查询,我认为此时我已经达到了 SQL Server 所能提供的极限。
是否还有其他我错过的方法是 F# 社区试图能够持久化非常丰富的 F# 数据模型?