我正在为我的网站设计域模型和数据映射器系统。系统具有不同类型的用户域对象,具有用于管理员,mod和禁止用户的子类的用户的基类。每个域对象都使用名为“users”的表中的数据,而子类有一个额外的表来存储admin / mod / banned信息。用户类型由表'users'中名为'userlevel'的列确定,其值为3表示管理员,2表示mod,1表示注册用户,-1表示禁止用户。
现在,当我为我的网站工作成员列表功能时出现问题,因为成员列表应该从数据库加载所有用户(使用分页,但现在不用担心)。问题是我想从基本用户表和附加的admin / mod / banned表加载数据。如您所见,注册用户没有额外的表来存储额外的数据,而对于admin / mod / banned用户,表是不同的。而且,这些表中的列也不同。
那么我应该如何使用SQL查询处理这种情况?我知道我只需从基本用户表中选择,然后使用多个查询来加载其他数据,如果发现用户级别是给定值,但这是一个坏主意,因为它将导致n + 1个查询admins / mods / banned用户,这是一次非常昂贵的数据库之旅。我该怎么办?请帮忙。
答案 0 :(得分:1)
如果要使用一个查询查询所有usertypes,则必须包含结果表中所有表的列,其中一些表填充null
- 值。
要让他们填充数据,请使用左连接,如下所示:
SELECT *
FROM userdata u
LEFT OUTER JOIN admindata a
ON ( u.userid = a.userid
AND u.usertype = 3 )
LEFT OUTER JOIN moddata m
ON ( u.userid = m.userid
AND u.usertype = 2 )
LEFT OUTER JOIN banneddata b
ON ( u.userid = b.userid
AND u.usertype = -1 )
WHERE...
您可能会删除usertype
条件,因为其中一个连接表中只应该有数据,但您永远不会知道......
然后,您的程序代码将根据usertype
选择正确的列。
P.S。:并非select *
仅为了简单起见,在实际代码中更好地列出所有列名...
答案 1 :(得分:0)
虽然在您的域类中具有此层次结构是完全正常的,但我建议您更改数据库中的方法。否则你的查询会非常复杂和缓慢。
您可以只使用另一个名为users_additional_info,包含您所有用户类型所需的列的混合。然后就可以了
SELECT * FROM users
LEFT JOIN users_additional_info ON users.id = users_additional_info.user_id
在单个简单查询中获取所有信息。信不信由你,这种方法将在你的桌子开始增长或你决定添加其他类型的用户时,将来会给你带来很多麻烦。