好吧,老实说,我找不到更好的标题了。
我最近来到了一个新的工作场所,有人要求我帮助处理数据库。我想尝试解释一个概念,但我不确定如何最好地表达它,也许这个概念已经有了更好的解释和名称。我不把自己标榜为 DB 专家,所以我想向他们展示一些比我自己的观点更正式的东西,无论我一生中设计了多少好的 DB。
我发现最有趣的一件事(但不是很好)是他们似乎是根据问题的逻辑而不是根据“这是一个数据库,它应该包含数据”来设计数据库,因此,例如要知道某个元素是否属于某个类别,查询将以这种方式进行(伪代码):
SELECT Column1, Column2...ColumnN
FROM Invoices [LIST OF JOIN]
WHERE
Invoces.Field1 IN
(TableA WHERE TableA.Field NOT IN
(TableB WHERE TableB.Field IN ((TableC WHERE) OR (TableD WHERE)))
OR Invoces.Field1 NOT IN
(TableB WHERE TableB.Field IN ((TableC WHERE) AND (TableD WHERE))
OR TableB.Field IN
(TableC WHERE TableC.Field IN (TableC WHERE))
OR TableB.Field NOT IN
(TableC WHERE TableC.Field NOT IN (TableD WHERE))
依此类推其他二十个左右的条件。不,我不是在开玩笑。
发生这种情况是因为他们没有说“这是一张发票,它的类别是发票本身的一个属性”,而是一直说“这张发票是由那个用户在那天插入的,他本可以插入它进入某个部门或根本没有,如果是部门,那么该部门可能是某个结构的一部分……”等等。这甚至不是参照完整性的问题,在这种情况下根本没有 FKs ...
另一个实际示例是文档的最后编辑日期:它不是作为属性存储,而是通过一个函数计算得出,该函数按照以下方式进行:
如果那个文档与另一个文档相关,那么如果另一个文档是这种,那么如果第一个文档也与这个其他文档相关,那么最后编辑的日期就是管理员打印每日约会日历的日期”。 .
显然,每个 if 也有一堆其他的。而且,这不是因为存在某种依赖关系,只是因为存储了很多东西来反映它们的逻辑。
在某种程度上,我很想说“一次写入,多次读取”,意思是“一次写入该属性,然后根据需要多次免费读取它”,因为我们的写入频率很低,并且读取频率非常高,显然所有读取都必须每次都重新计算所有内容。但我有一种感觉,一定有一些原则表明你应该设计数据库来保存数据......
这取决于
数据库的目的是以
valid data
安全的方式为跨多个应用程序的多个用户存储数据。一些逻辑将集中在该
valid data
语句的部分。这些将是你的constraints
和data types
。数据库中的其他代码部分将集中在该
multiple applications
部分。例如,aVIEW
将隐藏一些复杂的逻辑以确保所有应用程序以相同的方式查看数据。一个应用程序可以是基于 Web 的应用程序,另一个应用程序可以是第 3 方报告生成器。联机事务处理
在 OLTP 系统中,复杂的
SELECT
语句和last modified date
逻辑没有多大意义。如果假设这是一个 OLTP 系统,您应该尝试改变一些东西,以便它们遵循正常的关系数据库实践。
数据仓库
您的伪代码
SELECT
语句和date of last edit
逻辑的复杂性在数据仓库 [DW] 环境中非常有意义。但是,它们可能是ETL/ELT 过程的一部分,用于将数据具体化为非规范化表,以便更快地生成报告。和
TABLES
和旨在解决一组非常具体的业务问题VIEWS
。MATERIALIZED VIEWS
根据我的经验,这些对象被用作各种业务报告的来源。在某些情况下,每个报告创建一个表/视图来解决业务需求。没有
FKs
?这对于 DW 来说可能是正常的。TRUNCATE
表中的数据可以用 刷新INSERT...SELECT
。在这种情况下,aForeign Key
弊大于利。当我阅读评论时,它表明您的公司需要转向更正式的 OLTP 分层设计。祝你好运。