代码之家  ›  专栏  ›  技术社区  ›  blockhead

查询实体属性值模型的有效方法是什么

  •  1
  • blockhead  · 技术社区  · 14 年前

    我正在使用这样的数据库设置:

      entity field       value
       1      start_date  June 1, 2010
       1      end_date    August 30, 2010
       1      artist      some name
    

    我想查询艺术家名称为“some name”且已开始但未结束的所有实体。

    我想到了这样的事情:

    SELECT start.entity
    FROM field_values AS `start`
      INNER JOIN field_values AS `end`
      INNER JOIN field_values AS `artist`
    WHERE 
      (start.field = 'start_date' AND end.field = 'end_date' AND artist.field='artist')  AND 
      (STR_TO_DATE(start.value, '%M %d, %Y') < NOW() AND 
       STR_TO_DATE(end.value, '%M %d, %Y') > NOW())  AND 
      artist.value="some artist";
    

    但这并不能让我觉得是非常有效的。有更好的方法吗?

    2 回复  |  直到 14 年前
        1
  •  1
  •   Wolph    14 年前

    为了清楚起见,您可以将join子句项放在join子句中,但在查询优化方面,这几乎是实现这一点的方法。

    不过,您可以考虑将查询重写为如下内容:

    SELECT start.entity
    FROM entity
      JOIN field_values AS start
        ON entity.id = start.entity AND start.field = 'start_date'
      INNER JOIN field_values AS end
        ON entity.id = end.entity AND end.field = 'end_date'
      INNER JOIN field_values AS artist
        ON entity.id = artist.entity AND artist.field = 'artist'
    WHERE STR_TO_DATE(start.value, '%M %d, %Y') < NOW()
      AND STR_TO_DATE(end.value, '%M %d, %Y') > NOW()
      AND artist.value="some artist"
    ;
    

    还可以规范化字段以节省一些空间(假设该字段不是枚举)

        2
  •  1
  •   Wrikken    14 年前

    虽然EAV有它的位置,但您已经有了3个有一定保证的属性名(因为您正在搜索它,所以我假设许多实体共享这些属性)。闻起来像不是EAV的候选者,或者是可能的属性组合,这些属性可能放在各自的独立表中。 artistdates (id,artist,start,end) 可能在EAV表中链接为 E=<whatever>,A=artistdate_id,V=<artistdate_id> 如果你喜欢的话。

    EAV的功能是针对实际属性不一致的情况,通常只通过实体ID或属性的存在(可能与值组合)进行查询。一旦你在寻找属性的组合性能 问题是,这些数据是应该单独存在于EAV结构中,还是应该拆分为“传统的”基于行的表。