通用数据库架构

时间:2011-03-25 14:23:42

标签: mysql

您能否对以下设计发表评论。 我是否通过这种设计让自己毁灭?我一直在设计系统,因为全新的要求无法在设计中被破解,所以现在我正在寻找具有最灵活系统的长期解决方案。

通过这种设计,我可以动态地创建如下所示的复杂性和设计我现在意识到实现不会是直接的,所以在我花费数天时间之前我想得到一些真正的输入。

这是一种常见的禁忌还是常见? 任何输入将不胜感激。   schema

instance
    firstname   bob
    lastname    gates
    scoreone    20
    scoretwo    90
    scorethree  
        scorethreePart1 30
        scoreThreePart2 32


    CREATE DATABASE uni;
use uni;

CREATE TABLE instance (
ID                          INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
ParentID                    INT DEFAULT NULL,
FOREIGN KEY         (ParentID) REFERENCES instance(ID) ON DELETE CASCADE
) ENGINE=InnoDB;

CREATE TABLE keyval_connector (
ID                          INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
ParentID                    INT NOT NULL,
TextKey                     VARCHAR(255) NOT NULL,
Note                        TEXT DEFAULT NULL,
UNIQUE(ParentID, TextKey),
FOREIGN KEY         (ParentID) REFERENCES instance(ID) ON DELETE CASCADE
) ENGINE=InnoDB;
CREATE TABLE keyval_int (
ID                          INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
ParentID                    INT NOT NULL,
Value                       INT DEFAULT NULL,
UNIQUE(Value),
FOREIGN KEY         (ParentID) REFERENCES keyval_connector(ID) ON DELETE CASCADE
) ENGINE=InnoDB;

CREATE TABLE keyval_varchar (
ID                          INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
ParentID                    INT NOT NULL,
Value                       VARCHAR(255) DEFAULT NULL,
UNIQUE(Value),
FOREIGN KEY         (ParentID) REFERENCES keyval_connector(ID) ON DELETE CASCADE
) ENGINE=InnoDB;

CREATE TABLE keyval_double (
ID                          INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
ParentID                    INT NOT NULL,
Value                       DOUBLE DEFAULT NULL,
UNIQUE(Value),
FOREIGN KEY         (ParentID) REFERENCES keyval_connector(ID) ON DELETE CASCADE
) ENGINE=InnoDB;

CREATE TABLE keyval_datettime (
ID                          INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
ParentID                    INT NOT NULL,
Value                       DATETIME DEFAULT NULL,
UNIQUE(Value),
FOREIGN KEY         (ParentID) REFERENCES keyval_connector(ID) ON DELETE CASCADE
) ENGINE=InnoDB;

6 个答案:

答案 0 :(得分:3)

看起来你正准备Entity-Attribute-Value (EAV) Model,它在某些情况下有用。在不知道您的要求的具体情况的情况下,很难说这是否是一个有效的用例。

答案 1 :(得分:3)

如果我了解您的架构,您正在做的是构建一个名称/值存储系统,其中包含您尝试支持的数据类型的特定表(日期,数字等)。

这是一种完全有效的方法 - 但它带来了与解决方案一样多的问题。例如,您无法以干净的方式真正建模数据库模式的“关系”部分。使用即使是中等复杂的逻辑创建查询也很棘手 - 想象一下用一些AND,OR和IN编写内容。 MIN,MAX等聚合函数很难做到。

另一个问题是,您的工作方式与业内其他方面不同 - 这使得很难将新开发人员带入团队,或使用标准工具/框架,如对象/关系映射工具,E / R图等。

答案 2 :(得分:1)

如果没有您告诉我们这样的数据库架构应该支持哪些应用程序,我们无法真正发表评论。但是,一般而言,数据库模式应该至少在一定程度上反映一个或多个特定域的应用程序和数据。

然而,为了避免将来重构而插入一层以上对我来说听起来并不是很吸引人,至少对于正在开发的代码现在没有明确的优势,为您的数据引入更合适的存储模型。

实际上,我只能看到一大堆索引(由PRIMARY KEYUNIQUE约束所暗示)和外键,这是优秀的方式让任何数据库服务器瘫痪......

答案 3 :(得分:1)

似乎可以存储单个键值对。但是你怎么搜索,比如“名字是弗雷德或罗杰,并且在游戏中得分至少为23”,而不必在同一张桌子上进行一系列重复的别名连接?

您基本上忽略了关系数据库的要点和目的,并将其纯粹用作键值存储。为此,你可以选择其中一个NoSQL数据库。

答案 4 :(得分:1)

正如Joe所说,看起来你正在创建一个EAV模型。我认为这对稀疏数据最有效。因此,尝试将所有实体(名字,姓氏等)共有的内容保存在单个表中,然后将EAV模型用于更稀疏的数据或更可能随时间变化的属性。 / p>

答案 5 :(得分:1)

虽然我可以同情你为什么沿着这些方向思考,但你可能正在为自己的痛苦世界做好准备。关系数据库用于结构化数据,旨在有效地操作它。

您是否查看了XML数据库

http://www.ibm.com/developerworks/library/x-comparexmldb/

我不推荐任何特定的数据库,因为我对它们知之甚少