我的数据库有两个表,一个包含一个用户列表,另一个包含角色列表。每个用户将属于一个或多个角色,当然每个角色将具有多个用户。
我遇到了两种链接信息的方法。第一个是添加第三个表,其中包含两个表的ID。然后,简单联接将返回属于某个角色的所有用户,或该用户所属的所有角色。但是,随着数据库的增长,这些简单查询返回的数据集将呈指数增长。
第二种方法是在用户表中添加一列,其中存储了定界的角色列表。这将消除对第三个链接表的需求,这可能会对数据库的增长产生积极影响。缺点是SQL无法使用定界列表。我发现处理该信息的唯一方法是使用临时表和自定义函数。
在查看我的执行计划时,“表扫描”事件是占用最多资源的事件。从等式中删除表格会加快处理速度,这是有道理的。该功能仅占用不到1%的资源。
这些测试是在少于20条记录的数据库上完成的。随着数据库大小的增加,表扫描将花费更长的时间,因此也许限制它们是最好的选择。
如果使用定界列表是一个好方法,为什么没人这样做呢?
请告诉我哪种方法是您首选的方法(即使它与我的两种方法不同)以及原因。
谢谢你。
最佳答案
如果您有一个定界列表,查找具有给定角色的用户将变得非常昂贵:有效地,您需要对该表进行完全扫描,并查看每一行中该列的所有值,以尝试查看是否它包含一个给定的角色。
要使用单独的表(规范化的,多对多关系),并且使用正确的索引将不会发生完整的扫描。
例如:
User: UserId, Name, ....
Role: RoleId, Name, ....
UserRole: UserRoleId, UserId, RoleId
(UserRoleId是可选的,您也可以将PK设置为UserId + RoleId,在这里我将不讨论替代vs复合键)
您需要在(UserId,RoleId)上的索引为UNIQUE,以强制不重复。这也将有助于您尝试查看特定用户是否具有特定角色的所有查询(WHERE userId = x AND roleId = y)
如果要查找用户具有的所有角色,则只需要在UserId上建立索引。
相反,如果您要查找给定角色拥有的所有用户,则仅RoleId上的索引将加快该过程。如果您不执行此查询或执行此查询的次数很少,则没有此索引将略微提高插入/更新的性能,因为这是一件少事。这是数据库调整的谨慎平衡行为。