4

[前标题:有没有办法强制基于标签的组织方法论的关系结构?]如何在基于标签的组织中定义结构?

我有一些实体,他们有一系列的属性。某些属性会影响实体可以具有的其他属性,许多属性会被组织为组,并且偶尔会要求实体具有来自某些组的某些数量的属性,或者可能包含来自某些组的某些属性。

有没有一种方法来使用数据库这些各种各样的标签 - 标签的关联度,如要求,编组,排除等模式,或者是这唯一可能与编程“业务规则”?理想情况下,我希望可能的标签及其关系易于配置,因此非常灵活。

我考虑过的方法之一是有标签和可能的关系,然后你得到一个标签标签应用关系排序表,但这似乎是一个相当脆弱的方法。

所以,这可能更严谨的方式,如果是的话,我将如何甚至开始着手呢?

回答

4

编辑:您对仅应用取决于其他属性中值的变量属性的描述是非关系非归一化设计。 RDBMS可能不是存储这类数据的最佳解决方案。对于需要这种灵活性的数据来​​说,RDF可能是一个很好的解决方案。

我刚才的答复,关于RDBMS的解​​决方案,下面是:与Entity-Attribute-Value设计


有人模型灵活的属性,但这往往是太非结构化和你结束了数据完整性问题的战斗。仅当您需要实际上无限数量的实体子类型时才使用它。

其他人使用Single Table Inheritance,您将所有子类型使用的所有属性列放入一个非常宽的表中,并在属性与子类型无关的行上将它们留空。但是这有局限性,因为表格可能变得太宽,而且你失去了强制使用任何属性的能力,因为它们必须都是可空的。

如果实体子类型数量较少,我建议为每组必需属性创建一个从属表。定义从属表的主键作为父表的外键,因此您可以获得一对一的关系。

CREATE TABLE Vehicles (
    vehicle_id INT PRIMARY KEY 
    ...attributes common to all vehicles... 
); 

CREATE TABLE Automobiles (
    vehicle_id INT PRIMARY KEY, 
    ...attributes specific to autos... 
    FOREIGN KEY (vehicle_id) REFERENCES Vehicles(vehicle_id) 
); 

您还可以通过在父表的主键中编码子类型来提供更多的数据完整性。这是为了确保Automobiles中的一排不能参考Vehicles中的摩托车。

CREATE TABLE Vehicles (
    vehicle_id INT, 
    vehicle_type VARCHAR(10), 
    ...attributes common to all vehicles... 
    PRIMARY KEY (vehicle_id, vehicle_type), 
    FOREIGN KEY (vehicle_type) REFERENCES VehicleTypes (vehicle_type) 
); 

CREATE TABLE Automobiles (
    vehicle_id INT, 
    vehicle_type VARCHAR(10) CHECK (vehicle_type = 'Automobile'), 
    ...attributes specific to autos... 
    FOREIGN KEY (vehicle_id, vehicle_type) 
    REFERENCES Vehicles(vehicle_id, vehicle_type) 
); 

当然,你需要创建一个新的从属表在每次定义一个新的子类时,但这样的设计确实给你更多的结构,以保持数据完整性,NOT NULL属性,等等。

您需要在应用程序逻辑中强制执行的唯一部分是确保在Vehicles的 ='Automobile'中为每行创建一行Automobiles

2

使用数据库来执行规则或在别处使用源代码没有区别。代码是数据。这就是深奥的Lisp答案。

你问的真正问题是这在关系数据库中还是在(我假设)Algol家族语言中更容易。你没有指定一个RDBMS,所以我将假设ANSI。这使得这很难。

顺便说一下,在Prolog中这很容易。但那不是在这里,也不在那里。

我会说使用检查约束的一切。这种方法所需要的心理转变是意识到你的UI将需要一种方法来定义这些标签关系。传统上,您可以从UI向数据库发出CRUD语句。相反,您需要向CRUD检查约束发出ALTER TABLE语句。

有两个问题的方法:

  • 这样的语句在大多数RDBMS的参数化。认为SQL注入。
  • 各种实现在对全ANSI检查约束的支持方面有所不同。如果子查询不受支持,则忘记它。

如果你可以用一个特定的RDBMS来澄清你的问题,那么我们可以给你一个更好的答案。