您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

与时间属性有关的设计数据库

与时间属性有关的设计数据库

这是一个满足您指定要求的模型。

对于不熟悉关系建模标准的人,请 。

归一化为5NF; 没有重复的栏;没有更新异常,没有Null。

当产品的状态更改时,只需将具有当前DateTime的行插入ProductStatus中。无需触摸先前的行(这是正确的,并且保持真实)。无需解释报告工具(您的应用程序除外)的虚拟值。

DateTime是产品置于该状态的实际日期时间;如果您愿意,则使用“发件人”。“ To”很容易得出:它是产品的下一行(DateTime>“ From”)的DateTime;如果不存在,则该值为当前的DateTime(使用ISNULL)。

一个模型已经完成;(ProductId,DateTime)足以为主键提供唯一性。但是,由于您要求在某些查询条件下提高速度,因此我们可以在物理级别上增强模型,并提供:

索引(我们已经有了PK索引,因此我们将首先对其进行增强,然后再添加第二个索引)以支持涵盖的查询(基于{ProductId | DateTime | Status}的任何排列的查询都可以由索引提供,而无需转到数据行)。这会将Status :: ProductStatus关系从“非标识”(虚线)更改为“标识类型”(实线)。

选择PK安排的依据是,大多数查询都是基于Product?DateTime?Status的时间序列。

提供第二个索引以提高基于状态的查询速度。

在替代安排中,这是相反的;即,我们主要希望所有产品的当前状态。

在ProductStatus的所有格式中,辅助索引(不是PK)中的DateTime列为DESCending;最近是第一次。

我已提供您要求的讨论。当然,您需要尝试使用合理大小的数据集并做出自己的决定。如果这里有您不明白的地方,请询问,我会继续进行。

报告当前状态为2的所有产品

SELECT  ProductId,
        Description
    FROM  Product       p,
          ProductStatus ps
    WHERE p.ProductId = ps.ProductId  -- Join
    AND   StatusCode  = 2             -- Request
    AND   DateTime    = (             -- Current Status on the left ...
        SELECT MAX(DateTime)          -- Current Status row for outer Product
            FROM  ProductStatus ps_inner
            WHERE p.ProductId = ps_inner.ProductId
            )

ProductId 被索引,领导上校,双方

DateTime 在索引中,涵盖查询选项中的第二列

StatusCode 被索引,涵盖查询选项中的第三列

由于StatusCode索引中的数字是DESCending,因此只需要一次访存就可以满足内部查询

对于一个查询,同时需要这些行;它们靠得很近(由于分类索引);由于行尺寸短,几乎总是在同一页上。

这是普通的sql,是一个查询,它利用sql引擎的强大功能进行关系集处理。这是 ,没有更快的方法,而其他任何方法都会更慢。任何报告工具都只需单击几下,无需键入即可生成代码

DateTimeFrom和DateTimeTo等列是严重错误。让我们按重要性排序。

这是一个严重的标准化错误。“ DateTimeTo”很容易从下一行的单个DateTime派生;因此是多余的,重复的列。

鉴于该行很短,因此每次访问都需要 来读取表。

和 (或者换一种说法,只有一半多的行会适应任何给定的缓存空间)。

通过引入重复的列,您已经引入了发生错误的可能性(现在可以通过两种方式派生该值:从重复的DateTimeTo列或下一行的DateTimeFrom)。

这也是一个 。当您更新任何DateTimeFrom为Update时,必须获取前一行的DateTimeTo(因为关闭时没什么大不了的)和Updated(因为这是可以避免的附加动词,所以很重要)。

“ Shorter”和“编码快捷方式”无关紧要,sql是一种繁琐的数据操作语言,但是 sql就是我们所拥有的 (只需处理)。不能编写子查询的任何人实际上都不应进行编码。为简化次要编码“难点”而复制列的任何人实际上都不应为数据库建模。

请注意,如果保留了最高阶规则(归一化),则将消除整个较低阶问题集。

在编写简单的sql时遇到“困难”或“痛苦”的任何人都将无法执行其工作功能。通常,开发人员 考虑 集合 ,而关系数据库面向集合的模型

对于上面的查询,我们需要当前日期时间;由于ProductStatus是按时间顺序排列的一 产品状态,因此我们只需要属于该产品 的最新状态或MAX(DateTime)。

现在让我们从 集合的 角度来看一些所谓的“难点” 。有关每个产品处于特定状态的持续时间的报告:DateTimeFrom是一个可用列,并定义了水平截止线,一个 (我们可以排除较早的行);DateTimeTo是产品状态子 的最早 集合

SELECT ProductId, Description, [DateFrom] = DateTime, [DateTo] = ( SELECT MIN(DateTime) – earliest in subset FROM ProductStatus ps_inner WHERE p.ProductId = ps_inner.ProductId – our Product AND ps_inner.DateTime > ps.DateTime – defines subset, cutoff ) FROM Product p, ProductStatus ps WHERE p.ProductId = ps.ProductId AND StatusCode = 2 – Request

关于 获取下一行的 思考是面向行的, 而不是 面向集合的处理。使用面向集合的数据库时发生崩溃。让优化器为您做所有这些思考。检查您的SHOWPLAN,优化效果最佳。

不能以 集合的 方式思考,从而仅限于编写单级查询,对于以下情况而言,这不是合理的理由:在数据库中实现大量的复制和更新异常;浪费在线资源和磁盘空间;保证一半的性能。学习如何编写简单的sql查询获取容易获得的数据要便宜得多。

其他 2022/1/1 18:23:01 有555人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶