以MySQL作为示例数据库来执行此操作(虽然我不限于此阶段的关系风格)和用于模型/数据库交互的Java风格语法。
我希望能够在用户编辑对象时允许对各个列值(及其相应类型)进行版本控制。这主要是为了减少频繁编辑复杂对象所需的存储量。
一个简单的例子可能是
- Food (Table)
- id (INT)
- name (VARCHAR(255))
- weight (DECIMAL)
所以我们可以在数据库中插入一个看似......的对象。
Food banana = new Food("Banana",0.3);
给我们
+----+--------+--------+
| id | name | weight |
+----+--------+--------+
| 1 | Banana | 0.3 |
+----+--------+--------+
如果我们想要更新我们可能使用的重量
banana.weight = 0.4;
banana.save();
+----+--------+--------+
| id | name | weight |
+----+--------+--------+
| 1 | Banana | 0.4 |
+----+--------+--------+
显然,这会覆盖数据。
我可以在此表中添加修订列,可以在保存项目时增加,并设置组合id / version的组合键,但这仍然意味着为每个修订版本存储此对象的所有属性
- Food (Table)
- id (INT)
- name (VARCHAR(255))
- weight (DECIMAL)
- revision (INT)
+----+--------+--------+----------+
| id | name | weight | revision |
+----+--------+--------+----------+
| 1 | Banana | 0.3 | 1 |
| 1 | Banana | 0.4 | 2 |
+----+--------+--------+----------+
但在这种情况下,我们将存储关于每个项目的每一条数据。如果用户对较大的对象进行少量修改,而文本字段甚至BLOB数据可能是对象的一部分,则这不是非常有效的。
我真正喜欢的是能够选择性地存储数据,因此权重可以单独保存在一个单独的数据库中,这样就可以引用表,行和列它与之相关。
然后可以将其与表的VIEW一起粉碎,这可以将各个列数据的任何后续版本强加到混合中以创建最新版本,但不需要为每个小版本存储所有数据。
+----+--------+--------+
| id | name | weight |
+----+--------+--------+
| 1 | Banana | 0.3 |
+----+--------+--------+
+-----+------------+-------------+-----------+-----------+----------+
| ID | TABLE_NAME | COLUMN_NAME | OBJECT_ID | BLOB_DATA | REVISION |
+-----+------------+-------------+-----------+-----------+----------+
| 456 | Food | weight | 1 | 0.4 | 2 |
+-----+------------+-------------+-----------+-----------+----------+
不确定将任何数据存储为blob的成功与否然后CAST回到原始的DTYPE可能是,但是我想在这里发明功能,为什么不坚持下去。
这种存储方法也相当危险,因为表名和列名完全可以改变,但希望这至少概括了我所想的那种行为。
答案 0 :(得分:1)
6NF中的表有一个CK(候选键)(在SQL中为PK),最多只有一个列。基本上6NF允许每个pre-6NF表的列更新时间/版本和值以无异常的方式记录。您可以通过删除非素数列来分解表,同时添加带有它的表以及旧的CK列。对于临时/版本控制应用程序,您进一步添加时间/版本列,新CK是旧的加上它。
添加一列时间/任何时间间隔(在SQL开始时间和结束时间列中)而不是时间到CK允许通过记录最长的不间断时间段或其他维度来进行数据压缩,通过该时间段,列具有相同的值。一个查询由原始CK加上您想要的值的时间。你不需要这个用于你的目的,但是标准化为6NF的初始过程和添加时间/任何列应该在时间教程中解释。
阅读temporal databases(同时处理"有效"时间和时间间隔的数据,但也"事务和#34;数据库更新的时间/版本)和6NF和它在它们中的作用。 (Snodgrass / TSQL2很糟糕,Date / Darwen / Lorentzos很好,SQL也有问题。)
您最终建议的表格是EAV的示例。这通常是一种反模式。它将数据库编码到一个或多个有效元数据的表中。但由于DBMS不知道你失去了很多功能。如果DDL足以管理具有您需要的列的表,则不会调用EAV。只需在每个数据库中声明适当的表。这实际上是一个数据库,因为您希望事务影响两者。从那个链接:
您正在使用DBMS反模式EAV。您是(trying to) build part of a DBMS into your program + database. DBMS已经存在来管理数据和元数据。使用它。
没有metatdata的类/表。 Just have attributes of movies be fields/columns of Movies.
人们需要使用EAV"因此每种实体类型都可以 扩展自定义字段"是错的。只需通过电话实现 更新元数据表有时而不是只更新常规 tables:DDL而不是DML。