4

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

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

有没有办法使用数据库对这些标签到标签的关系进行建模,例如需求、分组、排除等,或者这只能通过编程的“业务规则”实现?理想情况下,我希望可能的标签及其关系易于配置,因此非常灵活。

我考虑的一种方法是拥有标签和可能的关系,然后你会得到一个标签-标签应用关系类型的表格,但这似乎是一种相当脆弱的方法。

那么,这是否可能以更严格的方式进行?如果可以,我将如何开始呢?

4

2 回答 2

4

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

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


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

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

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

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

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

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

于 2008-11-13T19:36:04.787 回答
2

使用数据库来执行您的规则或在其他地方使用源代码之间没有区别。代码就是数据。这就是深奥的 Lisp 答案。

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

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

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

这种方法有两个问题:

  • 这样的语句在大多数 RDBMS 中是不可参数化的。想想 SQL 注入。
  • 实现在对完整 ANSI 检查约束的支持方面有所不同。如果不支持子查询,请忘记它。

如果您可以使用特定的 RDBMS 来澄清您的问题,那么我们可以为您提供更好的答案。

于 2009-01-21T06:32:05.410 回答