关于扩展表的查询问题

2020-04-28 16:20:34 +08:00
 IMFFA
一张主表(user),存人员基本信息
user_id,name,age,gender 等等
一张扩展属性表(user_info)
user_info_id,user_id,key,value

因为不同类型的人员下面一直会增加属性,因此除了基本的人员表,还使用了一张属性扩展表用来存额外的属性,现在有需求要做多条件筛选,可能会有十个以上的条件。
比如 age>20,gender = ‘男’,salary> 5000,address=‘广东’。其中 salary 和 address 是存在扩展表 info 中的,那么多条件查询的时候 sql 要怎么写才高效呢

目前的写法是
SELECT * FROM user
WHERE age> 20 AND gender = ‘男’ AND user_id IN (
SELECT user_id FROM user_info
WHERE (`key` ='salary' AND value > 5000) OR (`key` ='address' AND value = ‘广东’)
GROUP BY user_id )
但是用 IN 查询太慢了

而且而且扩展表里的属性有可能包含时间,value 是 string 格式的,如果涉及到时间区间的筛选又该怎么处理呢
请教各位大手子
2741 次点击
所在节点    MySQL
10 条回复
haidii
2020-04-28 16:44:40 +08:00
可以使用 elasticsearch 、或者 mongoDB 来做。
关系型数据库的话,最好这些信息放到一张表里面,
否则没有好的办法。
littleylv
2020-04-28 16:48:38 +08:00
没细看,感觉你这里的 OR 会有问题
IMFFA
2020-04-28 17:06:25 +08:00
@littleylv 暂时用起来没发现异常,这里的 OR 可能会导致什么问题呢
littleylv
2020-04-28 17:12:52 +08:00
@IMFFA #3 总感觉没法同时满足 salary> 5000 和 address=‘广东’?
IMFFA
2020-04-28 17:17:36 +08:00
@littleylv 啊啊,太低级了,居然会犯这种错( ̄ω ̄;),我已经给逻辑绕晕了,感谢指出。那现在这个也不能用了 o(╥﹏╥)o
asAnotherJack
2020-04-28 17:46:55 +08:00
关于 2 楼说的问题,用下边这种方式是不是可以解决,子查询改成
SELECT user_id FROM user_info
GROUP BY user_id
HAVING COUNT(IF( `key` ='salary' AND value > 5000 , 1, null)) > 0
AND COUNT(IF( `key` ='address' AND value = ‘广东’, 1, null)) > 0

另外这种方式可行的话,是不是可以两个表 join 然后 group by XXX having XXXX
xuanbg
2020-04-28 19:26:05 +08:00
直接两表 join 不就好了吗?
xuanbg
2020-04-28 19:35:46 +08:00
如果用有包含在 info 表的条件,就 join 一次 info 表,如果是楼主说的情况,就这样写:select u.* from uesr u join user_info s on s.user_id = u.id and s.key = 'salary' and s.value > 5000 join user_info a on a.user_id = u.id and a.key = 'address' and a.value = '广东';
xizismile
2020-04-28 19:39:37 +08:00
感觉这张扩展属性表没有必要,趁早把一个人的多条数据合并成一条数据,要不然后续的查询需求搞死你
lumious
2020-04-29 10:06:15 +08:00
用 exists 条件查询

SELECT *
FROM USER
WHERE AGE > 20
AND GENDER = '男'
AND EXISTS (SELECT ''
FROM USER_INFO
WHERE USER.USER_ID = USER_INFO.USER_ID
AND KEY = 'salary'
AND VALUE > 5000
UNION ALL
SELECT ''
FROM USER_INFO
WHERE USER.USER_ID = USER_INFO.USER_ID
AND KEY = 'address'
AND VALUE = '广东')

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/666975

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX