php - 使用 codeigniter/php 的实体属性值模型

标签 php mysql codeigniter entity-attribute-value

所以我正在尝试创建一种方法来构建我的数据库,以便能够自定义表单。

我研究了 EAV 模式,这是我的数据库结构:

表格形式 - 表格编号 - 表格名称 - form_added_on - form_modified_at

表:form_fields - field_id - 表格编号 - 字段类型(TEXT、RADIO 等) - field_default_value - field_required

表格:表格数据 - data_id - field_id - 表格编号 - 字段值

所以现在我可以将任何自定义表单存储到数据库中,如果我想获取单个表单的值,我可以简单地通过“form_id”加入它..

问题:

我希望能够在所有表单中搜索特定字段值。

如何使用 EAV 模型做到这一点?

此外,我考虑过将自定义数据存储为序列化 (JSON) 对象,但后来我不确定如何查询该数据。

请注意,我将 Codeigniter 与 MYSQL 一起使用。因此,如果需要,对话可以使用 Codeigniter 库。

最佳答案

免责声明:我不知道 PHP 或 CodeIgniter,但我愿意断言它们都没有对 EAV 的任何内置支持。值得注意的是,我对 EAV 了解很多,所以我会从这个角度回答。

当您撰写有关搜索特定值的文章时,我假设您也指的是特定领域。因此,如上所述,将数据放在表单表(例如数据)之外的 XML CLOB 中并使用 MySQL's XML functions对其进行搜索。严重地。假设 XML 看起来像:

<data>
    <field id="[field_id]">value</field>
</data>

这样搜索:

SELECT f.form_id
FROM
  form f
WHERE 
  f.form_id = ?
  AND ExtractValue(data, '//field[@id="[field_id]"]') = ?

为什么?问题是针对 EAV 模型搜索多个标准具有挑战性。考虑这个例子:

SELECT f.form_id
FROM
  form f
    INNER JOIN form_fields f1 ON f1.form_id = f.form_id
    INNER JOIN form_fields f2 ON f2.form_id = f.form_id
WHERE 
  f.form_id = ?
  AND 
  (f1.field_id = ? AND f1.field_value = ?)
  AND 
  (f2.field_id = ? AND f2.field_value = ?)

这一切看起来都很好,现在将 AND 更改为 OR 一切都乱套了。

SELECT f.form_id
FROM
  form f
    INNER JOIN form_fields f1 ON f1.form_id = f.form_id
    INNER JOIN form_fields f2 ON f2.form_id = f.form_id
WHERE 
  f.form_id = ?
  OR 
  (f1.field_id = ? AND f1.field_value = ?)
  OR 
  (f2.field_id = ? AND f2.field_value = ?)

你看到问题了吗? FROM 子句中的 INNER JOIN 表示无论如何记录,无论 WHERE 子句返回数据。因此,EAV 要求在 WHERE 中使用 EXISTS,而不是 FROM 子句中的 JOIN + WHERE 子句:

SELECT f.form_id
FROM
  form f
WHERE 
  f.form_id = ?
  AND (
    EXISTS (
      SELECT f1.form_id FROM form_fields f1 
      WHERE f1.field_id = ? AND f1.field_value = ? AND f1.form_id = f.form_id
    )
    -- note OR search 
    EXISTS (
      SELECT f2.form_id FROM form_fields f2
      WHERE f2.field_id = ? AND f2.field_value = ? AND f2.form_id = f.form_id
    )
  )

有点丑吧?那和MySQL subquery performance is not good .添加搜索特定数据类型(例如日期和整数)的愿望,并且您正在转换或使用 form_field 表中的多个列(例如 field_date_value、field_int_value 等)。

所以 XML CLOB 意味着在查询时只考虑表以及多值属性的可能性(想到多选或复选框)。

关于php - 使用 codeigniter/php 的实体属性值模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4503358/

相关文章:

php - 将 MYSQL 脚本转换为 PDO

php - UTF-8贯穿始终

mysql - Jena SDB(一个关系数据库支持的 RDF 存储)如何处理 SPARQL 查询?

mysql - 根据距离优化用户数据库搜索

codeigniter - 从 codeigniter 调用存储过程

php - 序列化 PHP 字符串的结构

javascript - 当键与另一个数组匹配时更新关联数组中的值

mysql - 组合这两个 mySQL 查询

php - 更新到 Codeigniter 3 后找不到页面

codeigniter - 如何使用 CodeIgniter 从另一个模块加载模型