Database design 替代在SQLAlchemy中使用数组

Database design 替代在SQLAlchemy中使用数组,database-design,sqlalchemy,Database Design,Sqlalchemy,我们使用sqlalchemy创建了一个数据库,其中包括以下表格: users alarms alarm_history +---------+-----------+ +----------+------------+ +----------+-----------+------------+ | user_id | user_name | | alarm_id | alarm_name |

我们使用sqlalchemy创建了一个数据库,其中包括以下表格:

users                      alarms                       alarm_history
+---------+-----------+    +----------+------------+    +----------+-----------+------------+
| user_id | user_name |    | alarm_id | alarm_name |    | alarm_id | timestamp | alarm_data |
+---------+-----------+    +----------+------------+    +----------+-----------+------------+
可能值得指出的是,这些表中有许多其他数据,这是一个缩写版本,报警id由外键关联。还有许多其他具有关系的表

报警表类似于待监控报警的主列表,历史记录表只是从外部监控服务接收到的报警数据的历史更改列表,用户表是自解释的

我们需要能够做的是有一个默认的报警列表,用户根据他们所属的组订阅,但也能够选择订阅或取消订阅哪个报警。这必须是动态可管理的–他们可以随时通过API进行更改

我应该如何在数据库中存储这些配置?这样做的想法是在用户表中有一个“subscription”列,该列指向需要用于确定用户需要监控的警报集的配置

我考虑在alarms表中添加一个subscriptions列,它只是一个订阅ID的数组/列表,但SQL不存储数组或列表。 我还想过要有一个配置表,详细说明每个配置的名称以及它所关心的报警,但您遇到了同样的问题——在没有阵列/列表的情况下,如何告诉它引用了哪些报警? 我还想过每次有人创建一个新配置时都要生成一个新表,但reading告诉我这是一个非常糟糕的主意,我甚至不知道如何做这样的事情。 我还考虑过使用in方法解析数据库查询中的一个列表,但是当列表长度超过900个元素时会出现内存错误,因此需要批处理请求。另外,它不是真正的关系,所以速度很慢。
关于如何解决这个问题,有什么建议吗?

在RDBMS中很少使用数组。原因很明显:关系数据库系统已经在表中存储了关系,那么为什么要添加只表示1:n关系的数组,而不具有外键一致性和快速索引查找的数据库优势呢

你说某个用户属于某个组,甚至是某个组,这一点还不清楚。所以我希望有一张分组表。如果用户属于一个组,您将向用户表中添加一个组id。如果一个用户可以属于多个组,您将添加一个用户组桥接表

组具有默认报警。由于一个组可以有多个默认报警,并且一个报警可能是多个组的默认报警,因此您将有一个m:n关系,这意味着一个桥接表组\ U报警

用户最终决定订阅哪些警报。另一个m:n关系,另一个桥接表:user\u报警

到目前为止,对于数据库结构来说,这已经足够简单了

现在进入逻辑:您希望在默认情况下订阅报警。这意味着在将组分配给用户时,将默认报警分配给用户。这可以通过将报警从组报警复制到用户报警的触发器或应用程序来完成。触发器会自动且无声地执行此操作。应用程序也可以静默地执行此操作,或者它可以提供一个复选框列表,因此可以显式地完成订阅/取消订阅

当一个警报作为默认值添加到一个组中时,我想您不希望发生任何事情。我想这只会影响新的用户/组关联。还是要将此警报添加到用户警报?如果是这样的话,触发也可能是合适的


我不懂炼金术。它是一种ORM,ORM倾向于尝试将RDBMS提供的关系网转换为树结构,这必然会导致妥协,包括对数据的访问不太方便,速度较慢。突然之间,您不得不使用一种编程语言来查询数据,而不是访问4GL查询语言。因此,虽然上述结构是合适的数据库,但我不知道在SQLAlchemy中使用它会有什么感觉。

一位同事建议添加一个额外的表current_alarms,它是每个报警的最新信息。当接收到新的报警数据时,它会在报警历史记录表中追加一个新行,但随后会覆盖当前报警表中任何更改的数据。然后可以查询整个表,并快速处理结果,以删除服务器端或客户端上不需要的数据。然后会有一个带有ID和报警字符串表示的configs表,该表在登录时发送给用户。另一个方法是简单地在报警历史表上运行一个查询,该表按日期降序排序,只要求唯一的报警ID,因此它应该返回每个报警中的一个,然后对返回的结果运行额外的过滤器。这两种方法都不能很好地处理总共有100k个警报的可能性,而用户A只关心其中的20k个警报和我们
er B关心一个不相交的30k。谢谢@Thorsten。没错,用户属于某个组,该组有一组默认报警。我已经有一个用户组表没有显示,并且用户已经通过组id与组相关。我只是不知道用户报警表如何存储用户订阅的报警。除非我误解了术语“桥接表”?因此,如果我理解正确,表面上看起来是数据的不受控制的复制,它被压缩到另一个表中,可能创建一个非常大的表,可以扩展到n_报警x m_报警订阅列表,实际上是明智而优雅的解决方案,而且速度很快。这显然是一个解决方案,即使它看起来很难看,但它肯定能完成任务,并允许超快速查询。