Database design 如何在基于标记的组织中定义结构?

Database design 如何在基于标记的组织中定义结构?,database-design,data-structures,tags,entity-relationship,entity-attribute-value,Database Design,Data Structures,Tags,Entity Relationship,Entity Attribute Value,[前标题:有没有办法在基于标签的组织方法上强制建立关系结构?] 我有一些实体,它们有一系列属性。某些属性影响实体可以具有的其他属性,许多属性被组织成组,有时实体需要具有特定组中的特定数量的属性,或者可能具有特定组中的一系列属性 是否有一种方法可以使用数据库对这些类型的标签之间的关系(如需求、分组、排除等)进行建模,还是只有通过编程的“业务规则”才能实现?理想情况下,我希望可能的标记及其关系能够轻松配置,因此具有高度灵活性 我考虑过的一种方法是使用标记和可能的关系,然后得到一个标记-标记-应用关系

[前标题:有没有办法在基于标签的组织方法上强制建立关系结构?]

我有一些实体,它们有一系列属性。某些属性影响实体可以具有的其他属性,许多属性被组织成组,有时实体需要具有特定组中的特定数量的属性,或者可能具有特定组中的一系列属性

是否有一种方法可以使用数据库对这些类型的标签之间的关系(如需求、分组、排除等)进行建模,还是只有通过编程的“业务规则”才能实现?理想情况下,我希望可能的标记及其关系能够轻松配置,因此具有高度灵活性

我考虑过的一种方法是使用标记和可能的关系,然后得到一个标记-标记-应用关系排序表,但这似乎是一种相当脆弱的方法


那么,这是否可能以更严格的方式实现呢?如果可能,我该如何着手呢?

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

我先前关于RDBMS解决方案的回答如下:


有些人使用设计为灵活的属性建模,但这通常过于非结构化,最终会遇到数据完整性问题。仅当您需要几乎无限数量的实体子类型时才使用此选项

其他人使用,将所有子类型使用的所有属性列放在一个非常宽的表中,并在属性与子类型无关的行上保留它们为空。但这是有限制的,因为表可能会增长得太宽,并且您无法将任何属性设置为强制属性,因为它们都必须为空

如果实体子类型的数量相对较少,我建议为每组必需的属性创建一个依赖表。将依赖表的主键定义为父表的外键,以便获得一对一关系

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)
);
您还可以通过在父表的主键中编码子类型来提供更多的数据完整性。这是为了确保
汽车
中的一行不能引用
车辆
中的摩托车

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)
);
当然,每次定义新的子类型时都需要创建一个新的依赖表,但这种设计确实为您提供了更多的结构来强制执行数据完整性,而不是空属性,等等


您需要在应用程序逻辑中强制执行的唯一部分是确保使用
车辆类型
=“Automobile”在
汽车中为
车辆中的每一行创建一行。

使用数据库强制执行规则与在其他地方使用源代码没有区别。代码就是数据。这就是深奥的口齿不清的答案

您要问的真正问题是,这在关系数据库中还是在(我假设)Algol家族语言中更容易实现。您没有指定RDBMS,因此我将假定为ANSI。这使得这很难

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

我想说的是对所有内容都使用检查约束。这种方法所需要的思想转变是认识到您的UI将需要一种定义这些标记关系的方法。传统上,您会从UI向DB发出CRUD语句。相反,您需要向CRUD检查约束发出ALTER TABLE语句

这种方法有两个问题:

  • 在大多数RDBMS中,这样的语句是不可参数化的。想想SQL注入
  • 实现对完整ANSI检查约束的支持各不相同。如果不支持子查询,请忽略它
如果您可以用特定的RDBMS来澄清您的问题,那么我们可以给您一个更好的答案