2

我正在处理的网站有 3 种不同类型的用户:管理员、申请人、审阅者。这些组中的每一个都将具有一些需要存储的基本信息(姓名、ID、电子邮件等)以及每个组独有的一些数据。我已经users为每个特定组创建了一个表以及一个表来存储它们的唯一数据。

  • 用户:id、f_name、l_name、email、user_type
  • users_admin: id, user_id, office, emp_id
  • users_applicant: id, user_id, dob, 地址
  • users_reviewer:id、user_id、active_status、地址、电话

如果用户user_type为“1”(申请人)登录,我将需要到JOINusers_applicants中检索他们的完整记录。我尝试使用 aUNION但我的表有很大不同的列。

有没有办法根据用户的类型编写一个条件查询JOIN来访问正确的表?我会以完全错误的方式解决这个问题吗?

在此先感谢您的帮助!

4

3 回答 3

2

好吧,最后你的桌子已经有缺陷了。为什么每种类型都有一张桌子?为什么不将所有这些字段放入users表中,或者可能是一个user_details表(如果您真的想要一个用于非通用数据字段的额外表)?目前,您实际上是从关系的角度创建 4 个独立的用户表。

那么为什么类型表有代理键呢?为什么已经不是user_id(唯一的)主键?

如果你改变了它,你只需要用户 id 来检索你想要的数据,而且你已经得到了(或者你甚至无法检索用户类型)。

于 2012-12-20T17:45:26.537 回答
1

您可以以编程方式执行此操作,也可以使用一系列CASEs 和LEFT JOINs 执行此操作。

为简单起见,让我们使用一个表来执行此操作users,您可以在其中拥有类型 1(普通用户)、2(高级用户)或 3(管理员)的用户。普通用户有一个电子邮件但没有电话,高级用户有一个地址和一个称为“超级大国”的字段,管理员只有一个电话号码,没有别的。

由于您想SELECT对所有人都使用相同的内容,因此您当然需要将所有这些放在您的SELECT:

SELECT user.id, user.type, email, address, superpower, telephone

然后你需要LEFT JOIN恢复这些

FROM user
LEFT JOIN users_data ON (user.id = users_data.user_id)
LEFT JOIN power_data ON (user.id = power_data.user_id)
LEFT JOIN admin_info ON (user.id = admin_info.user_id)

现在“未使用”字段将为NULL,但您可以提供默认值:

SELECT
    CASE WHEN user.type = 0 THEN email ELSE 'nobody@nowhere.com' END AS email,
    CASE WHEN user.type = 1 OR user.type = 2 THEN ... ELSE ... END as whatever,
    ...

您可以自行设置特定WHERE条件JOIN,例如,如果您只想要 J 部门的管理员,您可以使用

LEFT JOIN admin_info ON (user.id = admin_info.user_id AND admin_info.sector = 'J')

总查询时间应该不会太长,因为大多数JOINs 将返回很少(并且,如果您指定用户 ID,它们实际上不会很快返回任何内容)。

你也可以使用 a 来做同样的事情UNION,这会更快:

SELECT user.id, 'default' AS email, 'othermissingfield' AS missingfieldinthistable,
  ... FROM user JOIN user_data ON (user.id = user_data.user_id)
  WHERE ...
UNION
SELECT user.id, email, 'othermissingfield' AS missingfieldinthistable,
  ... FROM user JOIN power_data ON (user.id = power_data.user_id)
  WHERE ...
UNION
  ...

现在,如果您指定用户 ID,除一个之外的所有查询都将很快失败。每个查询都具有相同的WHERE重复条件以及任何特定于表的条件。该UNION版本的可维护性较差(除非您以编程方式生成它),但应该稍微快一些。

在所有情况下,建议您在适当的字段上保持更新的索引。

于 2012-12-20T17:37:39.470 回答
1

相反,我会建议你像这样重建你的表结构。

创建表

users_types : 
id 
type

然后用外键创建另一个表 users

users :     
id 
f_name 
l_name 
email 
office 
emp_id 
dob 
address 
active_status 
phone 
users_types_id

现在,当您需要在特定用户不需要的字段中插入数据时,请插入 null。您可以简单地根据 id 获取记录。也使用左连接会给你用户类型的名称。

于 2012-12-20T17:42:34.540 回答