2

我需要构建一个应用程序,其中有通用实体(比如文章、页面、节点),用户可以在其中添加自定义字段。

我已经看到了最流行的 php CMS(wp、drupal)用来实现这个目标的方法;它们都有包含最少字段(例如标题和正文)的表,然后将所有其他字段委托给其他表,例如:

table node
id | title | body

table field_foo
node_id | field_type | field_value

table field_bar
node_id | field_type | field_value
// and so on

这在完整的 mvc 环境中是非常合乎逻辑的;字段控制器分别处理每个字段。

但是谈到性能,加载单个节点将需要许多查询 - 或许多连接。

我采取了不同的方法(即使我的应用程序没有提供任何基本字段):对于每个字段,我在基本表上添加一个新列,它将存储一个原始值,然后为每个需要它的字段创建一个表(多个例如字段,或对其他实体的引用)和仅具有索引 entity_id |的关系表 field_id(该表实际上执行其他类型的工作,如跟踪版本和实体之间的关系类型)

因此,通过一个查询,我从一个实体中获取所有原始数据,然后字段控制器知道(在需要时)如何以及在何处加载该字段的实际值。

数据表中的列类型(table_entity_data)是字段数据的最佳猜测:对于文本是文本,对于十进制是十进制;仅对于多个字段(在该表之外具有它们的值)是数组(并且真正的 data_type 在 _field_foo_value.entity_value_ 列中)

假设实体结构不会经常改变,我试图规范化结构..

鉴于其他大型项目以非常不同的方式处理这个问题,我开始怀疑我的实现,并想知道我的hibryd结构会发生什么样的问题:

table entity
id

table entity_data
entity_id | field_foo_rav_value | field_bar_raw_value

table relations
entity_id | entity_field_id | field_id_value

table field_foo_value
field_value_id | entity_value

// lets say field_bar is a single text field, there no will be another table:
// entity_data.field_bar_raw_value contains the real value

有什么建议吗?

ps:我知道这个问题很笼统,如果不合适,请随时标记关闭。

4

1 回答 1

2

看起来你正在重新发明 EAV

http://www.google.com/search?q=entity+attribute+value+antipattern

缺点是你抛弃了关系数据库可以提供的所有类型安全和结构。

在理想的世界中,您可能想要以下之一:

  1. 允许建立一个合适的表
  2. 使用非关系数据库
于 2012-06-01T12:29:51.787 回答