我正在尝试为我已经开始的项目设计MySQL数据库,但我无法找到最佳方法。
它是一个OOP系统,包含不同类型的对象,所有这些对象都需要存储在数据库中。但是这些对象还需要保持父子关系。此外,我希望在系统投入生产后,可以灵活地轻松添加新数据类型。
据我所知,我有三个选项,一个是纯粹的关系,一个我认为是实体属性值(我没有正确理解EAV),最后一个是我想到的混合设计我自己,但我认为之前已经有过这样的想法并且有一个合适的名字。
关系设计将包含两个表,一个是大型表,其列允许存储任何类型的对象,另一个表用于维护第一个表中行的父子关系。
EAV设计将有两个表,一个是具有三列(实体ID,属性和值)的EAV表,第二个表将关联这些实体的父子关系。
混合设计将为每种类型的对象提供一个表,然后是父子关系表,它必须存储父,子的id以及这些id来自的表的某种标识符。
我确信此问题已经解决并解决了数百次之前我会很感激任何参考资料,所以我可以阅读解决方案。
答案 0 :(得分: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
);
我在这里描述了关于闭包表的更多信息:
答案 1 :(得分:0)
是的,您可以很好地使用EAV设计。它适用于我们创建的应用程序,但经过大约3年的改进。 您还可以使用通用表结构,并将任何特定表用于一组对象。或者只为每个对象创建一个通用表。 哪个Object是哪个Object是元数据存储库的一部分。 如果使用val_int,val_string类型的结构,除了存储值之外,您将具有Null列。您可以考虑使用MS SQL的稀疏矩阵功能。这些天磁盘大小有点便宜。因此,与传统结构相比,唯一的缺点是NxR行(比如对象的R属性)而不是N行。
除此之外,很少需要注意的是对象实例GUID,动态sql生成......