用于查找记录所有者的Db模式



我正在寻找一种模式来处理这样一种情况,即表中的一条记录可能与1相关,并且只与其他几个记录中的一个相关,我需要知道是哪一个。这很难描述,所以我将使用一个最近项目中的oauth客户端的例子。

客户端有id和机密,团队或用户可能拥有客户端

clients
client_id|client_secret
user_clients
user_id|client_id
team_clients
team_id|client_id

这里的问题是,当有人试图使用客户端凭据来获取访问令牌时,我需要知道这些凭据是属于团队还是用户。我真的不确定处理这个问题的最佳方法,我控制数据库,这样就可以进行更改。

我考虑过的一些选项:

Modify clients and remove user_clients and team clients
clients
client_id|client_secret|team_id(nullable)|user_id(nullable)
Create a client owners table and remove user_clients and team_clients
client_owners
team_id(nullable)|user_id(nullable)|client_id
Adding a type to the clients table and doing 2 queries or a conditional query
clients
client_id|client_secret|type(user or team)
Left joins and filtering/mapping in code.
select * from clients c left join user_clients u ... left join team_clients t ... where c.client_id = ?

这些选项都感觉不太好,所以我想知道是否有更好的模式。这是一个简化的例子,有时这些对象要复杂得多,并且有更多可能的关系,因此在使用orm时,查询可能会变得非常棘手,也很难管理(尽管系统的某些部分需要原始sql不是问题(。

我很想听听人们是如何解决这个问题的。

提前谢谢。

设计

你描述的是1:n关系:

  • 一个用户可以拥有多个客户端
  • 一个团队可以拥有多个客户

因此,第一种方法非常合适:客户机表有一个用户列和一个客户机列。

现在您说客户端只能由用户客户端拥有。您将在客户端表上为此设置一个检查约束,以确保只设置了一个ID。(如果每个客户端都必须有一个所有者,那么这个约束也会关心这一点。(

一些示例查询

如果你想让所有的客户端都归用户所有:

select * from clients where user_id is not null;

如果你想知道客户是由用户还是团队所有:

select
c.*,
case when user_id is not null then 'user' 
when team_id is not null then 'team' 
else 'none'
end as owner
from clients c;

如果您想要用户或团队信息:

select c.*, coalesce(u.name, t.name) as owner_name
from clients c
left join users u on u.user_id = c.user_id
left join teams t on t.team_id = c.team_id;

左联接的想法是可以接受的。只使用clientID离开clients表,然后在user_clientsteam_clients上加入它。

您也可以将其与第一个选项结合起来,为user_clientsIDteam_clientsID添加一列,并在添加到左侧时加入clients.user_clientsID <> 0,这将对您有所帮助。

第二个和第三个选项也是我见过的。第二种选择可能是有时最令人头疼的选择。

您还可以考虑创建一个视图表,其中包含您可能需要的的所有信息

最新更新