早上好,
我有一个从事科学研究的客户。当前数据库 (Azure postgres) 设计为 3NF,但发生的事务很少。有几条“管道”会将新数据添加到表中,科学家可能会更新某些数据或“丢弃”某些数据作为错误数据,但总体而言,事务方面发生的事务很少。
然而,他们的工作确实有“报告”的一面,而这正是科学家们一天中大部分时间都在做的事情。查看数据(遗传学方面),看看这些突变是否以前出现过,或者起始和终止标记是什么等等。
例如,他们的一个“报告”或数据分析网页调用了一个视图。该视图需要 4 多分钟才能运行。当我查看该视图时,它基本上收集了来自不同 3NF 表的所有数据,并将其展平为 1NF 然后显示。
以下是我的想法/问题:
3NF 和 1NF 表可以存在于同一个数据库和同一个模式中吗?我知道你确实可以这样做,但这样做明智吗/有问题吗?像这样混合搭配是一种“反模式”吗?
1a. 如果您这样做了,您会修改管道以将新传入的数据直接放入 1NF 表中吗?还是您仍让管道插入到 3NF,然后使用触发器或 ETL 过程等来更新 1NF 表?
1b 这里的想法是,如果一个表存在于 1NF 中,那么我们可以从该表进行扫描,而不是当前在长期运行的视图中的所有连接、cte、子查询等。
我是否应该将整个操作迁移到 1NF,同时理解其中的少数交易会变慢,但其他所有交易(sp、vw、fx 等)的 90% 会变得更简单、更快。
2a. 如果我确实将所有内容迁移到 1NF,您是否仍会拥有“暂存”表,管道会将新传入的数据写入其中,然后 ETL 过程会将新数据加载到 1NF 表中?
总的来说,我想制定一个长期解决方案。当然,我可以及时缩短这个 4 分钟的视图,但从长远来看,我们应该考虑什么,尤其是当数据量持续增长时。(仅去年一年就增长了 20%)。
短暂性脑缺血发作
您所描述的是基本的数据仓库架构,其中您既有规范化的交易数据,也有为易于使用和快速查询性能而建模的加载表。
在 Lakehouse 架构中,这个想法通常被称为“Medalion 架构”:https://learn.microsoft.com/en-us/azure/databricks/lakehouse/medallion
但无论您使用 Lakehouse 还是数据库,设计都是相同的。解决方案的消费层通常使用维度建模来建模,这通常比生成宽的非规范化表更有用、更高效。
您的问题是通用问题的典型例子:
谁知道呢?这完全取决于为什么“A”没有按你期望的方式工作。
如果“A”因为其中一个简单的可修复的问题而无法工作,那么您可能应该只修复该问题;
相反,如果“A”由于其中存在根本无法修复的问题而无法工作,那么您可以尝试“B”——只要您明白“B”可能会更糟,因此改用“B”会浪费您的时间,而改回“A”甚至可能会浪费更多时间!
因此,在进行任何更改之前,您应该明确确定当前查询速度缓慢的原因。
我猜是以下一项或多项:
您的数据库没有正确规范化;
表没有适当的主键,和/或没有适当的索引;
您的查询写得不够高效。
假设你的查询运行速度出乎意料地慢:
选择最简单、最慢的查询。(例如,选择一个运行速度比您认为的慢 50 倍的 10 行查询,而不是运行速度比您认为的慢 5% 的 1,000 行查询。)
找出查询运行缓慢的原因。如有必要,请咨询更有经验的人。在知道原因之前不要继续!
然后进行相应的操作。
高血压