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

每个应用程序都有我要监视的特定功能列表。每种功能仅属于一个应用程序。有一个功能表,该表具有应用程序的外键

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

实际的监视与查询ApplicationInstance有关。如果存在问题,则有关此问题的信息将转到AppInstanceError表,该表将持有ApplicationInstance的外键。如果查询成功,我们将获得每个功能的状态列表。因此,我们有一个FunctionalityStatus表,其中包含ApplicationInstance和Functionality的外键。

我认为这是一种错误的设计-为什么我们要多次引用Application?什么保证两者将指向同一应用程序?还是有什么方法可以确保这一点?

因此,我的修复建议是将FunctionityStatus与带有外键的Machines&Functionality连接。但是在这种情况下,它们定义了ApplicationInstance,那么对每对具有ApplicationInstance的保证是什么?他们不应该以某种方式连接吗?在现实世界中存在连接并且很明显,所以可以不在数据库中连接吗?

是否有“适当的方法”来解决此问题,或确保从数据设计中看不到连接?

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

唯一缺少的是从FunctionalityStatus到Machine的连接。通过这种方式,我看到两种方法:

  • 将外键添加到ApplicationInstance-那么我的疑问是:
  • 如何确保功能性的ApplicationId与应用程序实例的ApplicationId相同?
  • 是否真的需要重复数据?
  • 向机器添加外键-以及疑问:
  • 每个FunctionityStatus记录是否都有适当的ApplicationInstance记录?
  • 如果ApplicationInstance和FunctionalityStatus之间存在明显的联系(首先提到的是问题),我们怎么在数据库中看不到呢?
  • 再次是数据冗余,因为所有ApplicationInstance记录在(或应该)在FunctionalityStatus表
  • 中可见

    还是整个设计搞砸了,我应该完全找出其他东西吗?

    最佳答案

    您的设计对我来说似乎很好。我会选择选项1,将FunctionalStatus中的外键添加到ApplicationInstance中。

    如果要确保FunctionalStatusApplicationStatus引用同一应用程序,则可以添加新列FunctionalStatus.ApplicationId,并使从FunctionalStatusApplicationStatus的外键包含ApplicationId。同样,对于从FunctionalStatusFunctionality的外键。

    换句话说,类似

    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)
        );
    

    09-07 01:26