当有大量不同的数据发挥作用时,需要支持正确查询我的数据库

时间:2015-04-26 23:33:42

标签: mysql

假设您有这个架构:

Schema example

当然,在这个例子中它过于简化了,只是假装你有一个用户集合,用很多不同的表来描述,就像这里绘制的那样。

您可以认为:

  • 任何用户都有名称
  • 任何用户都可以说一种或多种语言
  • 任何用户都可以拥有一个或多个标题认证
  • 任何用户都可以拥有一个或多个体验

假设您必须向需要灵活访问的第三个用户显示大量数据,搜索并轻松管理此(大量)数据。

做了什么:

我的第一种方法是显示每个用户最相关的信息,提供管理员可以从中开始的第一个干净界面,并允许他使用数据库上可用的所有数据过滤显示的记录。 / p>

简而言之,管理员可以(或应该能够)显示所有男性用户英语并为 IBM "在屏幕上,只看到一个干净简洁的记录列表,如果他需要,他将能够以不同的方式进一步检查。

我的查询结果如何:

SELECT
users.id as id,
name,
surname,
etc,
certificazioni.title as certifications,
lingue.language as language,
esperienze.company,
FROM users 
LEFT JOIN lingue ON users.id = lingue.iduser 
LEFT JOIN certificazioni ON users.id = certificazioni.iduser 
LEFT JOIN esperienze ON users.id = esperienze.iduser 
GROUP BY users.id 
ORDER BY users.id

我构建了一个给出一些用户输入的接口,能够为这个查询附加条件,如下所示:

WHERE language ='英语' AND Sex =' m'

现在出现问题:

通过此查询,我能够确定某个用户是否会说英语,是男性等等,但是却无法确定用户是否有会说英语和荷兰人说一句。

为什么吗

(从我的角度来看)这是因为(我没有找到一个好方法,因为)之间的关系用户和其他表,在大多数情况下是一对多的,并导致此查询的输出类似:

没有GROUP BY

ID NAME  SEX LANGUAGE COMPANY
-----------------------------
12 Alamo M   English  IBM
12 Alamo M   Italian  NBA
12 Alamo M   Dutch    NULL
12 Alamo M   French   NULL

(每种语言的不同价值,经验等的组合)

使用GROUP BY

ID NAME  SEX LANGUAGE COMPANY
-----------------------------
12 Alamo M   Italian  NBA

(当然,这种情况与按功能分组的信息明显松散有关)

现在要求:

我需要找到一个不同的方法来解决这个问题,考虑到我所施加的限制,并且在大多数情况下仍允许我有效地查询我的数据库。

我还上传了该平台的屏幕,以更好地描述我期望的用户输入类型:

Some user inputs

2 个答案:

答案 0 :(得分:1)

这不是微不足道的。对于添加到查询的每种语言/技能/认证条件,您需要(内部)加入另一个表。请注意,当同一个表出现多次时,每个实例都必须有自己的别名,并且您可以使用group_concat将多个输入行值放在同一输出行上,例如。

Select u,name, group_concat(c.title)
From users u
Inner join lingue l1
On u.id=l1.user_Id
And l1.language='Italian'
Inner join lingue l2
On l1,user_Id=l2.user_id
And l2.language='French'
Inner join certificazioni c
On u.id=c.user_id
Group by u.name

列出讲法语和意大利语且至少拥有一项资格的人员的姓名和资格。但是您可能会发现将数据库反规范化为一个或两个表并使用全文搜索更简单。

答案 1 :(得分:1)

一种方法是为每个条件使用子查询:

SELECT *
FROM users
WHERE
    users.id IN (SELECT users_id FROM lingue WHERE language = 'English')
    AND
    users.id IN (SELECT users_id FROM lingue WHERE language = 'Dutch')
    AND
    ...