Sql server SQL中的可变长度int列

Sql server SQL中的可变长度int列,sql-server,Sql Server,我有一个包含两个表的数据库:用户和类别 用户具有以下字段: UserId unique identifier UserName nvarchar CategoryId int CategoryId int CategoryName nvarchar 类别包含以下字段: UserId unique identifier UserName nvarchar CategoryId int CategoryId int Ca

我有一个包含两个表的数据库:用户和类别

用户具有以下字段:

UserId        unique identifier
UserName      nvarchar
CategoryId    int
CategoryId    int
CategoryName  nvarchar
类别包含以下字段:

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

这将为用户所属的每个类别返回一行。有可能让它只返回一行?

此时您有一个一对多的关系,也就是说类别可以与多个用户关联,但一个用户只能与一个类别关联

您需要将其更改为多对多关系,以便每个用户可以与多个类别关联,并且每个类别可以与多个用户关联

这是通过添加一个链接userid和category id的表并从用户表中删除categoryid来实现的

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>
)

我会从用户中删除CategoryId,然后选择3d表格:

UserCategories
- UserId
- CategoryId
如果要搜索用户的所有类别,可以使用以下示例:

SELECT uc.CategoryId, c.CategoryName 
FROM UserCategories uc
JOIN Categories c ON uc.CategoryId = c.CategoryId
WHERE uc.UserId = @UserId

由于这是一种n对n关系,一个类别可以有多个用户,一个用户可以有多个类别,因此实现这一关系的典型方法是使用连接表

但是正如您所说的,由于已经实现的特性,您不想创建第三个表,我想您还可以将用户表中的列CategoryId更改为categorieID,然后可以包含一个文本字段。此文本字段可以包含整数列表,例如,以特殊字符分隔。就我而言,您应该在实现代码上执行拆分操作,因为我不知道在sql中有什么实际的方法可以做到这一点,也许有人可以在这里纠正我

如果您想为每个用户实现“主”类别之类的功能,那么您也可以保留categoryId列


希望这能有所帮助,我也希望能提出一个正确的方法来实现这一点

第三张表是您问题的解决方案。至于您的查询,您应该查看exist和in。如果一个用户有多个类别,那么查询的预期输出是什么?您没有在where子句中使用CategoriesPerUser,因此最简单的方法是从查询中删除该表。在您编辑的示例中,如果用户与多个类别关联,您需要调用您要返回的类别。。。也许只需选择TOP 1即可。但不清楚您想要实现什么。另一种想法是:如果用户属于1个主类别,那么在用户上保留CategoryID字段以及UsersToCategory链接表是非常有效的,并在想要返回1个类别时使用它。@Jamiec我想我需要的是让查询为每个用户返回一行,即使用户处于多个类别中,也要在行中表示所有这些类别。当数据到达我的网站时,我使用查询的每一行生成一个搜索结果。因此,我想生成一个搜索结果,向页面访问者列出用户所属的所有类别,而不是为用户所在的每个类别提供单独的搜索结果。文本字段中逗号分隔的值会让baby jesus哭泣。感谢您的评论,我想做类似的事情,但是,对像这样的ID字符串进行搜索可能会非常低效。是的,第三个表当然是最有效的选择。我只是在想一种不同的方法来实现这一点,如果出于某种原因,你真的不能为这种关系创建一个单独的表-我绝对同意Jamiecs的评论!谢谢你的建议。这对于查找类别中的所有用户非常有用,但是如果我试图根据其他搜索参数查找所有用户,并且希望返回所有用户,则会出现问题 用户所属的类别。@Oliver-请参阅更新。而且,只要数据库结构正确,就可以找到任何东西。这是符合您需求的正确数据库结构。