数据库EAV模型,根据搜索记录列表

发布于 2024-09-01 09:00:59 字数 554 浏览 8 评论 0原文

我正在构建一个动态应用程序。 我有三个表:(EAV模型样式)

  1. 项目(ItemId,ItemName)
  2. 字段(FieldId,FieldName)
  3. 字段值(ItemID,FieldId,Value)

您能告诉我如何编写单个查询以从FieldId的所有项目中获取开始20条记录吗? =4 等于 TRUE。

预期结果:

Columns =>  ItemID | Name  | Field1 | Field2 |  Field3  
Each Row=>  ItemId | ItemName| Value1 | Value2 | Value3

重要问题:

  1. 每一项的字段数未知,
  2. 我需要一个字段来编写一个查询。
  3. 查询将在 100K 条记录上运行,因此性能值得关注。
  4. 我正在使用 MySQL 5.0,因此需要 MYSQL 的解决方案

如果上述查询根本不可能,我是否应该对表进行非规范化?有什么建议吗?

I am building a dynamic application.
I have three tables : ( EAV model style)

  1. Items ( ItemId, ItemName)
  2. Fields (FieldId, FieldName)
  3. Field Values ( ItemID, FieldId, Value)

Can you tell me how to write SINGLE query to get starting 20 records from ALL items where FieldId=4 is equal to TRUE.

Expected Result :

Columns =>  ItemID | Name  | Field1 | Field2 |  Field3  
Each Row=>  ItemId | ItemName| Value1 | Value2 | Value3

Important concerns :

  1. Number of fields per item are not known
  2. I need one to write ONE query.
  3. Query will be running on 100K records, so performance is concern.
  4. I am using MySQL 5.0, so need solution for MYSQL

Should I denormalize the tables if above query is not possible at all ? Any advice ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

善良天后 2024-09-08 09:00:59

EAV 设计是非规范化的。也就是说,它是一种非关系型设计。没有任何规范化规则会引导您使用 EAV 设计。

SQL 要求您在编写查询时知道列,并且结果集的每一行都具有相同的列。使用 EAV,如果您不知道每个项目有多少字段,唯一的解决方案是将它们作为行而不是列取回。

SELECT i.ItemID, i.ItemName, f.FieldName, v.Value
FROM Items i
JOIN FieldsValues v4 ON (v4.ItemID, v4.FieldID, v4.Value) = (i.ItemID, 4, TRUE)
JOIN FieldsValues v ON i.ItemID = v.ItemID
JOIN Fields f ON v.FieldID = f.FieldID;

您必须处理应用程序中的行。例如,对于 PHP:

<?php

$pdo = new PDO(...);
$sql = "...above query...";

$collection = array();

foreach ($pdo->query($sql) as $row) {
  $id = $row["ItemID"];
  if (!array_key_exists($id, $collection)) {
    $collection[$id] = new stdClass();
    $collection[$id]->Name = $row["ItemName"];
  }
  $collection[$id]->$row["FieldName"] = $row["Value"];
}

现在您有一个对象数组,每个对象对应于数据库中的一个项目。每个对象都有其各自的字段集。

The EAV design is denormalized. That is, it's a non-relational design. There is no rule of normalization that would lead you to use the EAV design.

SQL requires that you know the columns when you write the query, and also that every row of the result set has the same columns. With EAV, the only solution if you don't know how many fields per item is to fetch them back as rows, not columns.

SELECT i.ItemID, i.ItemName, f.FieldName, v.Value
FROM Items i
JOIN FieldsValues v4 ON (v4.ItemID, v4.FieldID, v4.Value) = (i.ItemID, 4, TRUE)
JOIN FieldsValues v ON i.ItemID = v.ItemID
JOIN Fields f ON v.FieldID = f.FieldID;

You have to process the rows in your application. For instance, with PHP:

<?php

$pdo = new PDO(...);
$sql = "...above query...";

$collection = array();

foreach ($pdo->query($sql) as $row) {
  $id = $row["ItemID"];
  if (!array_key_exists($id, $collection)) {
    $collection[$id] = new stdClass();
    $collection[$id]->Name = $row["ItemName"];
  }
  $collection[$id]->$row["FieldName"] = $row["Value"];
}

Now you have an array of objects, and each object corresponds to an item from the database. Each object has its own respective set of fields.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文