2
创建表属性 (
    id VARCHAR(40),
    输入 VARCHAR(16),
    数据VARCHAR(2048),
    主键(ID,类型)
);

这是我尝试运行的一般查询格式。一般的想法是“对象”具有唯一的 ID,然后像 javascript 对象一样具有键/值对。

选择 a1.id、a1.data、a2.data、a3.data、a4.data、a6.data
    FROM 属性 a1、属性 a2、属性 a3、属性 a4、属性 a5
    LEFT JOIN 属性 a6 ON (a6.id=a5.id AND a6.type = 'Foreign Id')
        哪里 a1.id=a2.id
            和 a1.id=a3.id
            和 a1.id=a4.id
            和 a1.id=a5.id
            AND a1.type = '名字'
            AND a2.type = '中间名'
            AND a3.type = '姓氏'
            AND a4.type = '时间戳'
            AND a5.type = '计数'
            AND a5.data = 'MY_ID'

在此查询'Foreign Id'中是一个可选属性。问题是我得到

SELECT 将检查超过 MAX_JOIN_SIZE 行;检查您的 WHERE 并使用 SET SQL_BIG_SELECTS=1 或 SET MAX_JOIN_SIZE=# 如果 SELECT 没问题。

我意识到我可以按照所说的去做,但是警告让我担心这个查询效率非常低。有没有更好的方法来制定查询?

4

2 回答 2

5

由于主键是ID, Type您可以使用聚合函数并确保查询仍然是确定性的,从而将查询减少到 0 个连接:

SELECT  a.ID,
        MAX(CASE WHEN a.type = 'First Name' THEN a.Data END) AS FirstName,
        MAX(CASE WHEN a.type = 'Last Name' THEN a.Data END) AS LastName,
        MAX(CASE WHEN a.type = 'Timestamp' THEN a.Data END) AS `Timestamp`,
        MAX(CASE WHEN a.type = 'Count' THEN a.Data END) AS `Count`,
        MAX(CASE WHEN a.type = 'MY_ID' THEN a.Data END) AS MY_ID,
        MAX(CASE WHEN a.Type = 'Foreign Id' THEN a.Data END) AS ForeignId
FROM    Attributes a
GROUP BY a.ID;

值得注意的是,实体-属性-值模型是一种 SQL 反模式,您最好将数据规范化以将属性存储为列,而不必使用上述查询将行转换为列。

编辑

要添加基于属性的过滤器,请使用以下HAVING子句:

SELECT  a.ID,
        MAX(CASE WHEN a.type = 'First Name' THEN a.Data END) AS FirstName,
        MAX(CASE WHEN a.type = 'Last Name' THEN a.Data END) AS LastName,
        MAX(CASE WHEN a.type = 'Timestamp' THEN a.Data END) AS `Timestamp`,
        MAX(CASE WHEN a.type = 'Count' THEN a.Data END) AS `Count`,
        MAX(CASE WHEN a.type = 'MY_ID' THEN a.Data END) AS MY_ID,
        MAX(CASE WHEN a.Type = 'Foreign Id' THEN a.Data END) AS ForeignId
FROM    Attributes a
GROUP BY a.ID
HAVING MAX(CASE WHEN a.type = 'MY_ID' THEN a.Data END) = 1;
于 2013-07-18T18:31:47.897 回答
0

您的属性表很窄,但有很多行。你要么做一堆自连接,要么group by a.id用聚合函数查询和使用。后一种方法消除了连接,但仍然会命中很多行。

我认为更好的选择是对您的数据模型进行一些非规范化。这将涉及创建一个包含“名字”列、“中间名”列等的表。然后,与 ID 关联的各种属性都在同一行上。您最终会得到一个更宽的表,但行数要少得多并且没有连接。

于 2013-07-18T18:36:52.453 回答