4

我正在创建用于监控应用程序功能状态的数据库。逻辑如下:

每个应用程序都有自己的特定功能列表,我正在监控这些功能。每个功能只属于一个应用程序。有一个具有应用程序外键的功能表

每个应用程序都在一台或多台机器上运行。每台机器都可以运行一个或多个应用程序。这是MTM连接,所以有ApplicationInstance表连接Applications with Machines。

实际监控是查询ApplicationInstance。如果有问题,有关它的信息将转到 AppInstanceError 表,该表包含 ApplicationInstance 的外键。如果查询成功,我们会得到每个功能的状态列表。所以我们有一个功能状态表,其中包含应用程序实例和功能的外键。

我认为这是一种糟糕的设计——为什么我们要多次引用应用程序?什么保证两者都指向同一个应用程序?或者有什么办法可以确保这一点?

所以我的修复建议是将功能状态与机器和功能的外键连接起来。但是在这种情况下,他们定义了 ApplicationInstance 那么每对都有 ApplicationInstance 的保证是什么?他们不应该以某种方式连接吗?在现实世界中存在连接并且是显而易见的,那么数据库中没有它可以吗?

是否有解决这个问题的“正确方法”,或者确保连接从数据设计中不可见?

为了更清楚,我准备了我现在拥有的数据库设计: 数据库设计

唯一缺少的是从功能状态到机器的连接。我看到了两种建立这种联系的方法:

  1. 将外键添加到 ApplicationInstance - 那么我的疑问是:
    • 如何确保功能中的 ApplicationId 与 ApplicationInstance 中的相同?
    • 真的需要这种数据复制吗?
  2. 将外键添加到机器 - 和疑问:
    • 每个功能状态记录都会有一个适当的 ApplicationInstance 记录吗?
    • 如果 ApplicationInstance 和 FunctionalityStatus 之间有明显的联系(在第一个疑问中提到)我们不能在数据库中看到它吗?
    • 再次数据冗余,因为所有 ApplicationInstance 记录都(或应该)在 FunctionalityStatus 表中可见

或者,也许整个设计都搞砸了,我应该找出完全不同的东西?

4

3 回答 3

1

你的设计对我来说似乎很好。我会选择选项 1,从FunctionalStatusto添加一个外键ApplicationInstance

如果你想确保FunctionalStatusApplicationStatus引用相同的应用程序,你可以添加一个新列FunctionalStatus.ApplicationId,并将外键FunctionalStatusApplicationStatus包含ApplicationId。同样对于外键 from FunctionalStatusto Functionality

换句话说,像

CREATE TABLE application
    ( application_id          INT PRIMARY KEY
    /* Other columns omitted */
    );
CREATE TABLE application_instance
    ( application_instance_id INT PRIMARY KEY
    , application_id          INT REFERENCES application(application_id)
    , machine_id              INT REFERENCES machine(machine_id)
    /* Other columns omitted */
    );
CREATE TABLE functionality
    ( functionality_id        INT PRIMARY KEY
    , application_id          INT REFERENCES application(application_id)
    /* Other columns omitted */
    );
CREATE TABLE functionality_status
    ( functionality_status_id INT PRIMARY KEY
    , application_id          INT REFERENCES application(application_id)
    , functionality_id        INT /* Part of composite foreign key, see below */
    , application_instance_id INT /* Part of composite foreign key, see below */
    /* Other columns omitted */
    FOREIGN KEY (functionality_id, application_id) 
      REFERENCES functionality(functionality_id, application_id)
    FOREIGN KEY (application_instance_id, application_id) 
      REFERENCES application_instance(application_instance_id, application_id)
    );
于 2010-02-23T05:25:34.187 回答
0

您可能遇到的最大问题是,同一台机器上同一应用程序的两个不同实例总是可能具有相同的实例 ID。不能同时使用,实例 ID 会随着时间的推移而重复使用,并且您的应用再次获得相同 ID 的可能性很小。

当我做这种事情时,我会在每个应用程序启动时为其分配一个 GUID,这样就不可能有两个具有相同 GUID 的应用程序,然后我将该 GUID 用于关系。您甚至不需要在关系中包含机器信息,因为每台机器都不会生成与任何其他机器相同的 GUID。

回答完这个问题后我意识到我真的没有回答你真正的问题。如果您想查看某些功能是否以某种方式工作,最好将其与机器和应用程序相关联一错。

拥有三张表,一张用于机器,一张用于应用程序,一张用于功能将是最好的数据库设计。根据您正在执行的操作,软件可能会更轻松、更快速地为您正在使用的每组功能复制所有应用程序和机器信息,尤其是在有关机器和应用程序的信息无论如何都只是一个字段的情况下。如果可以提供帮助,您真的不想减慢记录此信息的功能,因此您希望快速完成。

于 2010-02-22T17:22:57.030 回答
0

如果是我,我会这样做:

  1. 创建 5 个表,Machine、Application、Functionity、ApplicationPool 和 Log。
  2. 在功能中放置一个 FK 列,即功能存在的应用程序的 ID。
  3. ApplicationPool 将有一个机器 ID 列、一个应用程序 ID 列、作为 GUID 或种子身份的主键、一个应用程序实例 ID,即您的 ApplicationName + PK。如果可以的话,这就是我将您的应用程序命名为您的机器的名称。
  4. 最后,我会制作 Log 表并给出一个引用 ApplicationPool PK 的 FK Column。然后,每次您记录某些内容时,您都可以将其添加到 Log 表中,并且您有关该应用程序的所有信息都将单独存储。

如果这不是关闭,请告诉我,因为我可能误解了您要查找的内容。

于 2010-02-22T19:33:47.213 回答