我一直在尝试创建一个应用程序,其中所有内容实际上都是具有一系列字段的对象。我已将其抽象为下表所示的级别:
- 对象模板
- 字段
- LinkObjectTemplateField
- 字段类型
每个ObjectTemplate都有一系列字段(多对多关系),可以在LinkObjectTemplateField中找到。 Field 链接到FieldType(多对一关系)。 Field 还有一个 ObjectTemplateID 字段 - 因此,假设我们有一个名为“Section”的对象模板,以及另一个名为“Question”的对象模板(如调查问卷)。部分将问题作为调查问卷设计者用来定义部分中出现的问题的字段。每个问题都会链接到一系列值(或者在 FieldType 为“文本”的情况下根本没有链接。
到目前为止,我们能够创建字段、字段类型和对象模板。然而我开始意识到,实际上所有这 3 个表都可以在上面的表中表示,而且我也可能会删除其中一个表(所以我只有 ObjectTemplate 和 LinkObjectTemplateField,其中 Field 本身就是一个 ObjectTemplate因此,ObjectTemplate 与其自身之间存在一个简单的链接(通过 LinkObjectTemplateField)。
我的目标是为所有对象类型提供一个表结构,无论是当前还是将来。我将有一个类,它拾取特定对象的所有字段以及基于对象模板所需的字段,并决定如何基于模板呈现字段。这似乎变得非常复杂,我一直发现自己很困惑。我还有一周的时间来做这件事,所以我的问题是:我应该继续做下去吗?有没有更好的技术来实现这一点,或者我的方法有什么缺陷?我是否应该坚持旧的结构(每个对象类型都有一个完整的表,其核心详细信息与大多数其他对象类型具有相同的字段 - 名称、描述、删除等)?
编辑
我再次审视了我的方法并得出以下结论:
- 每个对象类型(包括对象模板本身)都应在对象模板表中拥有自己的记录。
- 每个对象模板、字段和字段类型都应在对象表中拥有自己的行。
- 这样,例如Text、Dropdown等将是使用fieldtype对象模板的对象。这些 ID 将在编写表单的函数中使用 - 它们将被声明为常量并通过 MAIN::TEXT、MAIN::DROPDOWN 等引用。
最佳答案
您正在有效地尝试实现 EAV 的 o 形式,除非您确实需要它带来的灵 active ,否则被视为反模式。
这样"inner platform"通常是真品的劣质复制品。简而言之:
- 很难强制执行可用于“普通”表和字段的约束,包括数据类型、NULL 能力、CHECK、键和外键。
- 您不再有一个好的“目标”来设置权限或创建触发器。
- 很难将索引限制为特定“列”,或使其使用“ native ”类型。
- 重建“原始”对象很困难。通常,需要进行大量 JOINing,并且生成的对象不会表示为单行(这对客户端来说可能很尴尬)。索引和查询优化器无法再以最佳状态工作。
因此,除非您绝对必须能够更改数据结构而不更改数据库结构,否则只需使用DBMS已经通过“正常”提供的内容即可“表/列/约束...
My aim is to have one table structure for ALL object types, both as it currently stands and in the future.
嗯,您的 DBMS 中已经内置了该功能:它称为“数据字典”。是的,您可以通过 CREATE/ALTER/DROP 语句而不是 INSERT/UPDATE/DELETE 来更改它,但在逻辑级别上这是类似的事情。
Should I have stuck with the old structure (an entire table for each object type, with the same fields as most other object types for the core details - name, description, deleted etc.)?
可能。
顺便说一句,如果您有很多公共(public)字段(和/或约束),请考虑将它们放入公共(public)“基”表中,然后 "inheriting"其中的其他表。
关于php - 创建对象设计器的技术,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23480442/