使用一个用于热力学模拟的软件(在C ++中),我需要在不同温度下存储流体属性。这些数据点用于构建简单的插值函数,以便在我们没有完整实验数据的温度下评估属性值。
流体简单地通过其名称和浓度(%)(后者通常无关紧要)来识别。如果您感到好奇,有四个属性值得关注:质量密度,动态粘度,比热容和导热系数。对于任何其他意图和目的,这些只是4个数字属性,称为A,B,C和D.
因此,特定流体的功能如下所示:(A,B,C,D) = f(T)
,其中T是温度。
目前,它是一个SQLite3数据库,流体表如下所示:
+----+-------+---------------+
| id | name | concentration |
+====+=======+===============+
| 1 | Water | 100 |
+----+-------+---------------+
| 2 | ..... | ... |
还有属性表:
+----------+-------------+---------+-----------+--------------+----------+
| fluid_id | temperature | density | viscosity | conductivity | capacity |
+==========+=============+=========+===========+==============+==========+
| 2 | 373.15 | 1045.48 | 0.412 | 1.415 | 0.845 |
| 3 | 273.15 | 1105.0 | 2.113 | 0.4688 | 0.849 |
| 3 | 283.15 | | 1.678 | 0.4859 | 0.8503 |
| 3 | 293.15 | 1098.0 | 1.353 | 0.5015 | 0.5833 |
| 3 | 303.15 | | 1.08 | 0.5164 | |
| 3 | 313.15 | 1090.0 | 0.893 | 0.532 | 0.8561 |
| 3 | 323.15 | | 0.748 | 0.5432 | |
| 3 | 333.15 | 1080.0 | 0.644 | 0.5543 | 0.8577 |
| 3 | 343.15 | | 0.563 | 0.564 | |
| 3 | 353.15 | 1068.0 | 0.499 | 0.5722 | 0.8612 |
| 3 | 363.15 | | 0.44 | 0.5796 | |
| 3 | 373.15 | 1054.0 | 0.39 | 0.5856 | |
+----------+-------------+---------+-----------+--------------+----------+
手动插入数据进行测试是可以的。这也是以后流体编辑器GUI的直观显示。
然而,在代码中,插值是针对每个属性单独进行的。此外,由于我不能使用NULL值,因此并非所有温度(行)都与所有属性相关。为了使事情符合代码的观点,我创建了四个相同的视图 - 每个属性一个。例如:
+----+-----------+---------------+-------------+-------+
| id | name | concentration | temperature | value |
+====+===========+===============+=============+=======+
| 2 | Sea Water | 22 | 373.15 | 0.412 |
| 3 | Sea Water | 14 | 273.15 | 2.113 |
| 3 | Sea Water | 14 | 283.15 | 1.678 |
| 3 | Sea Water | 14 | 293.15 | 1.353 |
| 3 | Sea Water | 14 | 303.15 | 1.08 |
| 3 | Sea Water | 14 | 313.15 | 0.893 |
| 3 | Sea Water | 14 | 323.15 | 0.748 |
| 3 | Sea Water | 14 | 333.15 | 0.644 |
| 3 | Sea Water | 14 | 343.15 | 0.563 |
| 3 | Sea Water | 14 | 353.15 | 0.499 |
| 3 | Sea Water | 14 | 363.15 | 0.44 |
| 3 | Sea Water | 14 | 373.15 | 0.39 |
+----+-----------+---------------+-------------+-------+
现在,随着我逐渐从原型设计转向构建合适的软件,我试图思考这些方法中的任何一种是否符合ORM的观点。它是每个属性的模型(如我的视图)还是所有属性的单个模型(如当前使用的表)。 第三种选择可能是保持数据库不变,并在视图之上构建模型(而不是实际表格),但这不是ORM的方式。
我甚至考虑将此数据集移动到NoSQL解决方案(例如MongoDb),但我无法想出克服双重视角问题的方法。
我承认这里既没有运行时间也没有空间性能问题,无论如何,要存储和处理的数据量可以忽略不计。一小时内可能只有两个查询,每个查询将特定流体的数据集加载到应用程序的内存中并在那里处理它(基于评估的插值和计算)。 如果您认为我对此过于紧张,我会接受它。
否则,我想听听您的想法并考虑您可能提供的任何不同方法。我错过了什么吗?那些拆分桌子的钥匙(流体和温度)的冗余会产生什么影响呢?此外,对于那些确实设置了约束的人来说,这可能是有意义的。
答案 0 :(得分:1)
每个表都带有NULL表示"缺少" ("未知"或"不适用")值对应于一个模式,该模式删除了NULLable列并引入了另一个表,其中包含原始的一些(超级)键,并且只保留该列中的非NULL行在它。
Nulls支持更容易人类同时读取这些单独的相同(超级)密钥表。但是它们使包括meaning of a table在内的所有其他内容复杂化(行进入或停留的标准/谓词),因此基本设计和查询组成。通常我们会尽快删除任何未粘贴到键上的NULL,以便在最终输出中显示它。 (例如,经常使用OUTER JOIN来引入然后删除NULL以表示无NULL的EXCEPT / MINUS。)我们使用单独的表'表示具有NULL的表的含义以及使用它的查询的含义中的含义。我们从组合的NULLed视图中提取单独的表,基本上用于任何处理。
直接的关系解决方案是单独的表。 SQL传统适用于一个表。其他SQL理由是通过组合表来减少JOIN。但这只是最终的人类可读输出!要处理一个表,您必须提取单独的视图。
PS
Re"分裂表格的密钥(流体和温度)的冗余将导致":没有" redundancy"具有相同(子)值在列,表或数据库中出现多次。当两个基表或行进行相同的断言时,会发生冗余。替换为标准/谓词的行给出一个陈述/命题;一个当前行断言它,一个缺席行断言不是它;一个表(命题)断言其当前和不存在的行的连接。断言。 (并且数据库(命题)断言其表格和命题的结合。)此外,冗余不一定是坏的;在时间,空间和复杂性之间总是存在工程权衡。
PPS
ORM具有视图:延迟或延迟查询评估。由于您以后可以在另一个中使用此类查询,因此它就像一个视图。它是ORM查询语言中查询的命名表示,而不是DBMS查询语言。可以想象,这可以用于更新命令(如果可能)以及查询。这取决于DBMS / ORM。但是,视图更新基本上是一种方便,因为它总是可以用组成表的更新来表达。