规范化 - 消除传递依赖

时间:2015-01-27 11:44:10

标签: sql sql-server

我正在创建一个将在代码中执行的规则引擎,但我在为其定义正确规范化的数据库结构时遇到问题:

  • 有可以从中派生规则的模板
  • 每个模板将定义一组可供规则使用的字段
  • 每条规则都会定义一组可以根据字段进行测试的条件

例如,我可能有一个模板'Bicycle',其中包含“Wheel Size”和“Number of gears”字段。

然后,我可以针对该模板创建一些规则,例如:

  • '儿童自行车':轮尺寸= 14“
  • '山地自行车':车轮尺寸= 26“,齿轮数= 27
  • '城市自行车':轮尺寸= 26“,齿轮数= 3

这是我到目前为止的数据库设计的简化版本:

Database diagram

以及相关的SQL:

CREATE TABLE RuleTemplate(
    Id INT IDENTITY(1,1) PRIMARY KEY,
    Name NVARCHAR(100) NOT NULL
)

CREATE TABLE Field(
    Id INT IDENTITY(1,1) PRIMARY KEY,
    RuleTemplateId INT NOT NULL FOREIGN KEY REFERENCES RuleTemplate(Id),
    Name NVARCHAR(100) NOT NULL
)

CREATE TABLE [Rule](
    Id INT IDENTITY(1,1) PRIMARY KEY,
    RuleTemplateId INT NOT NULL FOREIGN KEY REFERENCES RuleTemplate(Id),
    Name NVARCHAR(100) NOT NULL
)

CREATE TABLE Condition(
    Id INT IDENTITY(1,1) PRIMARY KEY,
    RuleId INT NOT NULL FOREIGN KEY REFERENCES [Rule](Id),
    FieldId INT NOT NULL FOREIGN KEY REFERENCES Field(Id),
    ComparisonValue NVARCHAR (100) NOT NULL
)

此设计容易受到异常的影响,因为规则可能包含引用来自与规则不同的模板中的字段的条件。

任何人都可以建议一个可以克服这个弱点的桌面设计吗?

2 个答案:

答案 0 :(得分:1)

我认为同一个Field可以参与多个模板,因此Field和RuleTemplate实际上是M:M。

接下来,您无法执行规则,例如“条件”应仅指向属于“规则”模板的字段'以声明方式,并保持此架构规范化。但你可以使用触发器来控制这样的规则。如果你看到很多这样奇怪的问题,通常意味着我们可能会为主题领域选择更好的基础实体。

这并不意味着无法使用此架构。不,它已经标准化并且足以在应用中使用。但应在应用程序端检查数据完整性。处理这样的计划是很自然的方式。 GUI不应该在规则设计器中显示错误的列。

new schema

关于另一组实体。从逻辑上讲,每条规则都是表达式。表达是一种树状结构。不幸的是,关系模式不适合这样的信息。在此过程中,您将遇到很多困难,例如,ComparisionValue列的类型对于不同的字段应该是不同的。解决方案可以是存储表达式的XML。它是表达式的更好选择,类型安全且更灵活。

答案 1 :(得分:-1)

不要只想拥有结构

模板 - >字段 - >规则 - >条件

这将确保规则与正确的字段相关联,并且正确的字段与模板

相关联