Database design 在数据库结构中保存具有计算列的用户定义视图

Database design 在数据库结构中保存具有计算列的用户定义视图,database-design,Database Design,我从数据库表格中组织的各种传感器采集数据 我让用户能够创建自己的数据视图,添加列,每个传感器一列,按数据分组,如下所示 View #1 +---------------------+------+----+-----+ | datetime | v1 | v2 | v3 | +---------------------+------+----+-----+ | 2010-09-13 00:05:00 | 40.9 | 1 | 0.3 | | 2010-09-13

我从数据库表格中组织的各种传感器采集数据

我让用户能够创建自己的数据视图,添加列,每个传感器一列,按数据分组,如下所示

 View #1
+---------------------+------+----+-----+
|      datetime       |  v1  | v2 |  v3 |
+---------------------+------+----+-----+
| 2010-09-13 00:05:00 | 40.9 |  1 | 0.3 |
| 2010-09-13 00:10:00 | 41.0 |  2 | 0.3 |
| 2010-09-13 00:15:00 | 41.1 |  4 | 0.3 |
+---------------------+------+----+-----+
为了存储这种视图,我使用了两个表:视图和视图选项

views
    id
    name

view_opts
    id
    id_view
    id_sensor
    ord #for column ordering
现在我必须更进一步:添加更多列,不是直接来自传感器数据,而是作为其他列的计算,如下所示:

 View #1
+---------------------+------+----+-----------+-----+
|      datetime       |  v1  | v2 | (v1+v2)/2 |  v3 |
+---------------------+------+----+-----------+-----+
| 2010-09-13 00:05:00 | 40.9 |  1 |   20.95   | 0.3 |
| 2010-09-13 00:10:00 | 41.0 |  2 |   21.5    | 0.3 |
| 2010-09-13 00:15:00 | 41.1 |  4 |   22.55   | 0.3 |
+---------------------+------+----+-----------+-----+
如果这在SQL中不难实现(我将旧的SELECT封装在一个新的SELECT中进行计算),那么我必须以某种方式扩展存储视图的方式

我想在几个方面,都有一些赞成和反对

有什么好主意吗

================

编辑:

我的想法之一是添加一个文本字段来查看选项,让用户以类似SQL的语法添加自己的计算:

(v1+v2)/2
如果传感器外键在视图_opt中为空,则在查询中使用文本,如:

SELECT v1, v2, (v1+v2)/2, v3 FROM (
    SELECT v1, v2, v3 FROM ...
)
view_opts
id
id_view
isCalc bit --contains 0 for Sensor and 1 for Calc (not strictly necessary)
id_sensor --nullable
id_viewcalc --nullable
ord #for column ordering
当然,我应该分析
(v1+v2)/2
部分的语法错误、注入(不太可能,此功能仅适用于对损坏自己的数据不感兴趣的可信管理用户)

===============

加:

以下是我数据库中关键表的som DDL(我修剪了一些不需要的字段和表):

简要说明:我有
ctrl\u单元
以类似csv的文件通过网络发送数据,每个
ctrl\u单元
都有许多
传感器
,单个
传感器
被标识为
id\u-id\u-meas

这不是我找到的解决方案,而是通过网络发送数据的真正方法

每次采集都是csv中的一行,带有日期时间和许多传感器测量值,如
id\u-meas,value
(简化版:可以说每个传感器在采集中发送更多测量值,如
id\u-meas,id\u-elab,value
,其中
id\u-elab
根据传感器类型具有不同的含义)

通过这种方式,传感器的数据(结果列)由其控制单元id(存储在父采集中)和测量类型id(存储在单个数据中)标识。
我使用来提取数据。

为了能够保留查询中的顺序,并允许计算列显示在正确的位置,您确实需要在view_opts表中使用某些内容作为占位符。比如说:

SELECT v1, v2, (v1+v2)/2, v3 FROM (
    SELECT v1, v2, v3 FROM ...
)
view_opts
id
id_view
isCalc bit --contains 0 for Sensor and 1 for Calc (not strictly necessary)
id_sensor --nullable
id_viewcalc --nullable
ord #for column ordering
可为空的列应表示可以维护fk关系

然后为calcs提供一个额外的表(以避免滥发视图选项表):


然后,您可以选择使用一组预定义的Calc,并将其与所需的列一起引用,或者允许使用一组完全可配置的Calc(我建议使用第一个,因为第二个可能会导致糟糕的UI)。

如果用户可以创建视图,为什么不干脆
将创建视图授予用户\角色
。他们可以自己计算。然后,它们将拥有SQL视图的全部功能。你或我能想到的任何东西都是:

  • 其中的一小部分,以及

  • 需要额外的表和维护

实施 考虑到你必须实现它,那么

最好的方法仍然是尽可能少地使用应用程序代码,并尽可能多地使用SQL和SQL工具。解析输入请求和构建查询是非常困难的,您不希望每次他们提出新请求时都要改变这一点

你所拥有的是相当硬的编码和脆弱的;它们似乎是只做一件事的汇总表。而是在数据库中构建向量。与中一样,维度事实结构是数据仓库中常见的做法,而不是汇总表。如果您发布一些DDL(3或4个关键表被用作源,用于您问题中的“视图”),我可以提供更具体的说明

当然,如果您的数据库不是一个数据库,这将阻止数据库和SQL的基本功能。有一半的时间,这些归档系统只需要重新实现,从非数据库提供普通功能并维护它们的成本远远超过重新实现的成本

在另一半的时间里,可以通过实现几个SQL视图来克服非数据库的缺陷,每个视图都提供了标准化表的功能。但这需要仔细分析,在决定是否可能之前,这在这里是不可能的。然后,可以在视图上构建向量或维度,就像在实际数据库中的表上一样

每个向量或维度都是一个标量子查询,填充单个列。外部查询定义结果集(网格)的结构。子查询填充单元格


最后,在你的应用程序中,它现在可以是一个更简单的解析器,给定输入数据,它可以获取一个或两个向量,或者一个向量除以另一个向量,等等。构建SELECT语句,然后执行。

这是我认为的解决方案之一,有一些优点,也有很多缺点,我只是不能预先定义一组计算……你的用户是什么样的专业水平?通用专业知识库很低用户不了解SQL,此外,我并不是从头开始,添加列的所有UI部分都已准备就绪并正常工作,基本用户需要进行相当复杂的查询,才能将同一表中的数据显示在按DateTimeline分组的多个列中。但是,自己编写这一切是一项艰巨的任务,本质上是重复SQL的功能。你想过简单的报告工具吗?这是一个数据库,对吧,用户可以访问数据。只需几百美元,他们就可以拥有无限的视图、向量、简单或中等的计算。复制现成的软件是一项艰苦的工作。但如果你真的必须自己写,有一个更有效的方法