我有一个包含两个表的数据库:Users
和 Categories
。
Users
具有以下字段:
UserId unique identifier
UserName nvarchar
CategoryId int
类别
具有以下字段:
CategoryId int
CategoryName nvarchar
目前,每个用户都属于一个类别。我想改变这一点,以便每个用户可以属于任意数量的类别。最好的方法是什么?
我的网站进行了大量非常昂贵的搜索,因此解决方案需要尽可能高效。我真的不想将每个用户拥有的类别列表放在第三个表中,因为这意味着当我拉回搜索时,每个用户将同时表示在几行中(至少,这是会发生的情况)如果我用我目前对 sql 的相当粗略的理解来实现搜索。)
编辑:
如果设置多对多关系,是否可以为每个用户只返回一行?
例如:
DECLARE @SearchUserID nvarchar(200) = 1;
SELECT *
FROM Users JOIN Categories JOIN CategoriesPerUser
WHERE UserId = @SearchUserID
这将为用户所属的每个类别返回一行。可以让它只返回一行吗?
最佳答案
目前是一对多的关系,也就是说一个类别可以关联多个用户,但一个用户只能关联一个类别。
您需要将其更改为多对多关系,以便每个用户可以与多个类别关联,每个类别可以与多个用户关联。
这是通过添加一个链接用户 ID 和类别 ID 的表(并从用户表中删除类别 ID)来实现的
Table: UserToCategory
UserId int
CategoryId int
至于您的最后一段,这是对您的需求进行建模的最有效的方法。您应该将 UserId/CategoryId 组合作为此表中的主键,以阻止用户与同一类别关联两次。这可以解决用户针对特定类别返回两次的问题。
例如,查找与某个类别关联的所有用户的 SQL 为
SELECT u.*
FROM Users u
INNER JOIN UserToCategory uc
ON u.UserId = uc.UserID
WHERE uc.CategoryId = 123
评论后编辑:如果您的查询查找多个用户,并且您想要与这些用户关联的不同类别列表,可以这样做
SELECT c.*
FROM Categories c
WHERE CategoryId IN
(
SELECT uc.CategoryID
FROM UserToCategory uc
INNER JOIN Users u ON uc.UserId = u.UserID
WHERE <some criteria here to filter users>
)
关于sql-server - SQL 中的可变长度 int 列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7281390/