0

我正在尝试为我已经开始的项目设计一个 MySQL 数据库,但我无法找到最好的方法。

它是一个 OOP 系统,包含不同类型的对象,所有这些对象都需要存储在数据库中。但是这些对象也需要彼此保持父子关系。我还希望在系统投入生产后能够灵活地轻松添加新数据类型。

据我所见,我有三个选项,一个是纯关系,一个我认为是实体属性值(我不太理解 EAV),最后一个是我自己想到的混合设计,但是我认为之前已经考虑过并且有一个正确的名称。

关系设计将由两个表组成,一个带有列的大表允许它存储任何类型的对象,另一个表用于维护第一个表中行的父子关系。

EAV 设计将有两个表,一个是具有三列(实体 id、属性和值)的 EAV 表,然后第二个表将关联这些实体的父子关系。

混合设计对于每种类型的对象都有一个表,然后是一个父子关系表,该表必须存储父子关系的 id 以及这些 id 来自的表的某种标识符。

我确信这个问题之前已经解决和解决了数百次,我将不胜感激任何参考,以便我可以阅读有关解决方案的信息。

4

2 回答 2

1

这是唯一真正的关系设计:

CREATE TABLE Objects (
  object_id INT AUTO_INCREMENT PRIMARY KEY,
  parent_object_id INT,
  -- also attribute columns common to all object types
  FOREIGN KEY (parent_object_id) REFRENCES Objects (object_id)
);

CREATE TABLE RedObjects (
  object_id INT PRIMARY KEY,
  -- attribute columns for red objects
  FOREIGN KEY (object_id) REFRENCES Objects (object_id)
);

CREATE TABLE BlueObjects (
  object_id INT PRIMARY KEY,
  -- attribute columns for blue objects
  FOREIGN KEY (object_id) REFRENCES Objects (object_id)
);

CREATE TABLE YellowObjects (
  object_id INT PRIMARY KEY,
  -- attribute columns for yellow objects
  FOREIGN KEY (object_id) REFRENCES Objects (object_id)
);

但是 MySQL 不支持递归查询,因此如果您需要执行复杂的查询以获取整个树,例如,您将需要使用另一种方法来存储关系。我建议封闭表设计:

CREATE TABLE Paths (
  ancestor_id INT,
  descendant_id INT,
  length INT DEFAULT 0,
  PRIMARY KEY (ancestor_id, descendant_id),
  FOREIGN KEY (ancestor_id) REFRENCES Objects (object_id),
  FOREIGN KEY (descendant_id) REFRENCES Objects (object_id)
  -- this may need additional indexes to support different queries
);

我在这里描述了更多关于闭包表的信息:

于 2013-06-01T16:40:00.503 回答
0

是的,您可以很好地使用 EAV 设计。它适用于我们创建的应用程序,尽管经过了大约 3 年的改进。您还可以使用通用表结构并将任何特定表用于一组对象。或者只为每个对象创建一个通用表。哪个对象的哪个表是元数据存储库的一部分。如果您使用 val_int、val_string 类型的结构,您将拥有 Null 列,但存储值的位置除外。您可以考虑使用 MS SQL 的稀疏矩阵特性。这些天磁盘大小有点便宜。因此,与传统结构相比,您唯一的缺点是 NxR 行(例如对象的 R 属性)而不是 N 行。

除此之外,需要注意的几件事是对象实例 GUID、动态 sql 生成......

于 2013-06-01T16:24:54.310 回答