Table 带有自定义字段

Table with custom fields

我们目前在 CRM 中工作,我们的 table 之一需要有多个字段,该字段应存储通过 API 发送的自定义数据,客户可能需要许多这样的字段.

最初,我们有如下内容:

Entity
id, -specific fields to the entity-, customField1, customField2, customField3

但后来被告知只有3个字段不够,要求至少100个字段。

考虑到这一点,我陷入了困境,我应该使用类似 EAV 的结构,还是只将字段添加到 table(customField1,...,customField100)?

类似于 EAV 的结构类似于:

Entity
id

EntityCustomField
id, entityId, fieldValue

这里的主要问题是查询,它变得更复杂(而且很慢?)。

更多信息:

有人遇到过类似问题并找到了解决方案,或者对所提出的任何可能解决方案有经验吗?

如果您正在使用 RDBMS 并且不想切换,处理此类用例的唯一选择是使用 @JoinColumn@OneToMany 映射来持久化自定义字段的实体而不是存储直接。

如果您使用任何 ORM,读取和写入都可以得到高效处理,查询也很容易。

(我不熟悉 doctrine2 )

只是一个想法:

为什么不用 table 来保存字段值:

CREATE TABLE field_values_table (
    id int(11) NOT NULL AUTO_INCREMENT
    ,field_value_1 varchar(100) NOT NULL DEFAULT ''
    ,field_value_2 varchar(100) NOT NULL DEFAULT ''
    ,field_value_3 varchar(100) NOT NULL DEFAULT ''
    ,field_value_n varchar(100) NOT NULL DEFAULT ''
    ,PRIMARY KEY (id)
);

和另一个 table 来保存相应的字段名称:

CREATE TABLE field_names_table
(
    id int(11) NOT NULL AUTO_INCREMENT
    ,field_name_1 varchar(100) NOT NULL DEFAULT ''
    ,field_name_2 varchar(100) NOT NULL DEFAULT ''
    ,field_name_3 varchar(100) NOT NULL DEFAULT ''
    ,field_name_n varchar(100) NOT NULL DEFAULT ''
    ,PRIMARY KEY (id)
);

或者

  • 考虑以上两个table之间的一对一关系,id为公共字段
  • 或者有另一个 table 作为上述两个 tables
  • 之间的关系 table

说:

CREATE TABLE field_name_value_relation (
    id int(11) NOT NULL AUTO_INCREMENT
    ,field_names_table_row_id int(11) NOT NULL DEFAULT '0'
    ,field_values_table_row_id int(11) NOT NULL DEFAULT '0'
    ,PRIMARY KEY (id)
);

因此,如果您要搜索一个名为 country 且值为 New Zealand 的字段(您可能无法单独通过 SQL 查询完全实现它,但是)一个非常高的级别 SQL 查询可以是:

SELECT
    *
FROM
    field_names_table
    LEFT OUTER JOIN field_name_value_relation
        ON field_name_value_relation.field_names_table_row_id = field_names_table.id
    LEFT OUTER JOIN field_values_table
        ON field_values_table.id = field_name_value_relation.field_values_table_row_id
WHERE
        field_name_n = 'country'
    AND field_value_n = 'New Zealand'

这不是那么简单,因为您不知道 country 字段名称可能在 field_names_table 中的所有列。

无论如何,我希望这能给你一些想法来完成你的要求。

您尝试使用 EAV 创建的结构类型可以用许多不同的方式建模。

我的第一个选择是为每个需要存储的数据类型创建一个 table,例如 'integer'、'text' 和 'datetime'。

'customfields_text' table 的架构将是:

object_id、field_name、text_value

Primary Key = object_id + field_name
Index at text_value

相同的架构也适用于 'customfields_integer' 和 'customfields_datetime'。

查询时,您将能够:

SELECT * FROM objects o JOIN customfields_integer ci ON o.id = ci.object_id WHERE ci.field_name = 'my_custom_attribute'