【问题标题】:How far to go with database constraints?数据库约束能走多远?
【发布时间】:2010-12-02 10:56:01
【问题描述】:

这个问题与another question I asked. 相关。在我的另一个问题中,我向人们询问了关于我可以构建数据库的 3 种不同方式的意见。我能想到的最简洁的方法是选项 2:

Location [Table]
- Id
- Name
- HasLogger
- LoggerRFID
- LoggerUpperLimit
- LoggerLowerLimit

Sensor [Table]
- Id [PK]
- LocationId [FK]
- UpperLimit
- LowerLimit

SensorReading [Table]
- Id [PK]
- SensorId [FK]
- Value

LoggerReading [Table]
- LocationId [FK]
- Value

Alert [Table]
- Id [PK]

AlertCorrectiveAction [Table]
- AlertId [FK]
- CorrectiveActionId [FK]
- ByUserId [FK]

AlertAcknowledgement [Table]
- AlertId [FK]
- ByUserId [FK]

SensorAlertReading [Table]
- AlertId [FK]
- SensorReadingId [FK]

LoggerAlertReading [Table]
 - AlertId [FK]
 - LoggerReadingId [FK]

现在这个选项的问题是它允许将来自多个传感器和多个位置的读数“链接”到单个警报。

为了解释为什么会出现这个问题,我将解释系统是如何工作的:

一个位置可以包含许多“实时传感器”,但只能包含 1 个记录器。出于这个原因,我将记录器属性放入位置表中(实际上是一对一的关系)。记录器收集读数,直到后来被收集,实时传感器立即通过网络传达读数,并且它们具有额外的属性,例如具有网络地址属性的网络从站..与记录器完全不同(我曾经尝试将记录器视为传感器,没有效果不好)。

当传感器或记录器超出范围(由读数指示)时,系统会生成警报。该警报仅针对该传感器,并被视为处于活动状态,直到该传感器(或记录器)的读数表明它已回到范围内。在此之前,将传感器进一步超出范围的读数“链接”到同一警报。

如您所见,单个警报实际上应该只有同一个传感器的读数链接到它,但是我上面的设计允许来自不同传感器和记录器的不同读数与同一个警报相关联 - 我是否应该对此感到困扰我没有以某种方式限制它?另一个问题是它允许警报在没有任何读数的情况下存在。

因此我的问题;一个人应该在多大程度上受到约束或弯曲设计以适应这些约束?我喜欢上面的设计,因为它很简单 - 警报可以有传感器读数和记录器读数,所以链接它们是一个简单的关系。

我不禁想我也错过了一个技巧 - 有没有更好的方法来做这个设计?我已经用它转了很多年,似乎总有一种妥协(除非我针对不同的阅读类型重复所有警报表)。

谢谢。

【问题讨论】:

    标签: database database-design constraints


    【解决方案1】:

    我应该为我没有以某种方式限制它而烦恼吗?

    是的。

    你犯了两个基本错误。

    1. 在所有移动的东西上粘贴Idiot 键。

      这阻碍了您将数据建模为作为数据(不是作为没有意义的行,而是具有人为强制唯一性的行)和公开标识符的能力;和依赖关系(例如,传感器依赖于位置)。您正在使用预先设置的 Row_Ids 对包含数据的电子表格进行建模。您需要将数据标准化为数据。

      这导致了您确定的问题,但也存在其他问题。

      如果您对数据进行建模,标识符将是清晰的,而索引和 FK 约束将阻止这一点。哪些数据是独立的;哪些数据属于(取决于)哪些其他数据;什么数据对其他数据有什么作用,以及这些操作的基础。

      那么(已解决的主要问题)您只剩下较小的限制来解决次要领域。

    2. 否则,您会陷入到处添加约束以尝试并获得您想要的东西,但永远无法达到目标。你知道你需要它们,所以你正在寻找它们。

    错误的地方。我们需要备份到 (1)。

    我已经回答了您的其他问题,并附上了▶Sensor Data Model◀。这并不能解决您在此处发现的缺陷。不过,我刚看到这个问题,明天我会更新 DM 并包含这些表和列。

    ▶Link to IDEF1X Notation◀ 适用于不熟悉关系数据库建模标准的任何人。

    问题

    1. 看起来您需要一个传感器参考表,即货架项目,以保存 UpperLimit 和 LowerLimit;而不是为每个位置重复它。或者它们是为每个位置设置、本地化的。

    2. 想想 Logger 的 SensorNo 为零。

    3. 为什么传感器没有 RFID?

    4. 在每个Location 处,Logger 是可选的,是 1::0-1 吗?,

    【讨论】:

    • 感谢您的回答 - 我也阅读了您的其他回答,并留下了关于无法看到模型的评论。我会等到我看到之前我完全回应。回答您的一个问题 (3) - 传感器没有 RFID(射频 ID),因为它们以不同的方式链接到系统。我将继续发表新评论。
    • 基本上它们是监控位置的两种方式;通过独立的电池供电数据记录器进行追溯,或通过网络系统实时进行。网络系统由网络监控单元和网络从站组成。网络从站通过电源信号连接到网络监控单元。每个网络从站都可以连接两个传感器(尽管这将很快)。一个位置可以有许多这样的传感器,以便实时监测空气、水、湿度等。
    • 通过电缆插入单个网络从站的传感器可以到达不同的位置,因此网络从站不受位置限制,因此它不是“包含”网络从站的位置,而是包含一个一组传感器。希望能澄清一点。
    • 是的,记录器是可选的; 1::0-1。
    • @Mark:谢谢,与了解他们的数据并真正想要一个好的数据库的人一起工作当然是一种乐趣。
    【解决方案2】:

    为什么没有:

    Alert [Table]
    - Id [PK]  
    - SensorReadingId [FK]  
    - LoggerReadingId [FK]  
    

    然后您填写 SensorReadingId 或 LoggerReadingId。我想你的结构是一个简化的结构,但通常一个没有其他东西的表然后一个 PK 是冗余的。

    【讨论】:

    • 我从来没有对 NULL 外键感到舒服。每当我阅读数据库理论时,都会说它们很糟糕而且设计也被破坏了,所以我一直在想,也许我只是遗漏了一些东西。
    • 此外,这不允许每个警报读取多个读数(除非您的意思是也要保留链接表,但这只能解决每个警报至少需要一个读数的问题)..
    • 马克,我真的不认为 null FK 有那么糟糕。 bytes.com/topic/sql-server/answers/81196-null-foreign-key
    • @iDevelop。空 FK 是可怕的,摆脱它们。这意味着您在建模过程中犯了基本错误,并且几乎总是意味着它没有标准化。无论如何,它们无法通过 DRI,因此除非您删除 DRI,否则您将无法使用它们;在这种情况下,你有一个数据堆,而不是一个数据库。
    • @iDevlop。我想它归结为松散的数据堆与紧凑的数据库;而且您似乎不了解数据库中实施的业务规则。如果客户行的 CategorId (FK) 未知,则不应插入;并且不会在数据库中。否则,您的连接失败,并且在整个数据堆中丢失了行。
    猜你喜欢
    • 2011-01-20
    • 2017-09-02
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-05
    • 2019-12-13
    相关资源
    最近更新 更多