2011-09-02 5 views
2

UsersCategories의 두 테이블을 가진 데이터베이스가 있습니다.SQL의 가변 길이 int 열

Users 다음 필드가 있습니다

UserId  unique identifier 
UserName  nvarchar 
CategoryId int 

Categories 다음 필드가 있습니다 순간

CategoryId int 
CategoryName nvarchar 

, 모든 사용자는 하나 개의 범주에있다. 각 사용자가 원하는 수의 카테고리를 가질 수 있도록 변경하고 싶습니다. 이 작업을 수행하는 가장 좋은 방법은 무엇입니까?

내 사이트는 비용이 많이 드는 검색을 많이하므로 가능한 한 효율적으로 솔루션을 사용해야합니다. 나는 각 사용자가 세 번째 테이블에있는 범주의 목록을 넣고 싶지 않습니다. 다시 말하면 검색을 끌어 오면 각 사용자가 여러 행에 동시에 표시됩니다 (최소한이 일은 일어날 것입니다. 나는 내 SQL 현재 상당히 원유, 이해 검색을 구현하는 경우)

편집 :.

다 대 다 관계를 설정하는 경우, 각 사용자에 대해 하나 개의 행을 반환 할 수 있습니까? 예를 들어

는 :

DECLARE @SearchUserID nvarchar(200) = 1; 

SELECT * 
FROM Users JOIN Categories JOIN CategoriesPerUser 
WHERE UserId = @SearchUserID 

이것은 사용자가 속한 각 카테고리에 대해 하나 개의 행을 반환합니다. 하나의 행만 반환 할 수 있습니까?

+1

세 번째 테이블은 문제의 해결 방법입니다. 당신의 쿼리에 관해서는'exist'와'in'을 살펴 봐야합니다. http://msdn.microsoft.com/en-us/library/ms177682.aspx http://msdn.microsoft.com/en-us/library/ms188336.aspx –

+0

쿼리의 예상 출력은 어떻게됩니까? 사용자에 대해 하나 이상의 카테고리가 있습니까? Where 절에서 CategoriesPerUser를 사용하지 않으므로 가장 쉬운 방법은 쿼리에서 테이블을 제거하는 것입니다. –

+0

편집 된 예에서 사용자가 여러 카테고리와 연결되어있는 경우 사용자는 어떤 카테고리로 돌아갈지를 결정해야합니다. 예를 들어 'SELECT TOP 1'과 같이 간단 할 수 있습니다. 그러나 당신이 성취하고자하는 것은 분명하지 않습니다. – Jamiec

답변

4

일대일 관계가있는 순간, 즉 많은 사용자가 카테고리를 지정할 수 있지만 사용자는 한 카테고리 만 지정할 수 있습니다.

각 사용자를 여러 범주로 분류하고 각 범주를 많은 사용자와 연관시킬 수 있도록이를 다 대다 관계로 변경해야합니다. 이것은

이 가장 효율적인 방법입니다 (사용자 테이블에서 카테고리 ID 및 제거) 마지막 단락으로

Table: UserToCategory 
UserId  int 
CategoryId int 

을 ID와 카테고리 ID를 연결하는 테이블을 추가하여 달성 요구 사항 모델링. 동일한 카테고리와 연관된 사용자를 두 번 중지하려면이 테이블에서 UserId/CategoryId PrimaryKey 조합을 만들어야합니다. 이렇게하면 특정 범주에 대해 두 번 반환 된 사용자의 문제가 중지됩니다.

찾을 수있는 SQL, 예를 들어, 범주와 관련된 모든 사용자가 코멘트를 한 후

SELECT u.* 
FROM Users u 
INNER JOIN UserToCategory uc 
    ON u.UserId = uc.UserID 
WHERE uc.CategoryId = 123 

편집 될 것이다 : 당신은 사용자의 수를 발견하는 쿼리를 가지고 있고, 당신이 원하는 이러한 사용자와 관련된 카테고리의 별개의 목록은이 내가 사용자로부터 카테고리 ID를 삭제하고 차원 테이블 갈 것

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

제안 해 주셔서 감사합니다. 이 기능은 카테고리에서 모든 사용자를 찾을 때 유용하지만 일부 검색 매개 변수를 기반으로 모든 사용자를 찾고 사용자가 속한 모든 카테고리를 반환하려는 경우 문제가 발생합니다. – Oliver

+0

@Oliver - 업데이트 참조. 또한 올바른 데이터베이스 구조로 * anything *을 (를) 찾을 수 있습니다. 이것은 요구 사항에 맞는 올바른 데이터베이스 구조입니다. – Jamiec

1

같이 할 수있다 :

UserCategories 
- UserId 
- CategoryId 

당신은 예를 들어 사용할 수있는 사용자의 모든 카테고리를 검색하려면이로

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

는 관계 N-에-N (하나 개의 범주는 여러 사용자가 하나의 사용자를 가질 수있다 여러 카테고리가있을 수 있음)이를 구현하는 일반적인 방법은 접합 테이블을 갖는 것입니다.

하지만 이미 구현 된 기능 때문에 세 번째 테이블을 만들고 싶지는 않습니다. 사용자 테이블의 "CategoryId"열을 "CategorieIds"로 변경할 수도 있습니다. 텍스트 필드. 이 텍스트 필드는 특수 문자 (예 : ",")로 구분 된 정수 목록을 포함 할 수 있습니다. 지금까지 나는 SQL에서이 작업을 수행하는 실용적인 방법을 모르기 때문에 구현 코드에서 분할 연산을 수행해야합니다 (어쩌면 누군가 나를 수정할 수 있습니다 ...).

사용자별로 '기본'카테고리와 같은 것을 구현하려는 경우 categoryId Column을 유지할 수도 있습니다.

호프가 도움이 되었으면하고이를 구현하는 올바른 방법을 제안하기를 바랍니다.

+2

텍스트 필드의 쉼표로 구분 된 값은 아기 예수의 울음을 만듭니다. – Jamiec

+0

의견을 주셔서 감사합니다. 그런 식으로 생각했습니다.하지만 그런 ID 문자열을 검색하는 것은 매우 비효율적 일 수 있습니다. – Oliver

+0

예, 물론 세 번째 테이블이 가장 뛰어난 옵션입니다. 나는 당신이 정말로 관계에 대한 별도의 테이블을 만들 수없는 어떤 이유로 든 이것을 구현하는 다른 방법을 생각하고있었습니다. 나는 분명히 Jamiecs 코멘트에 동의합니다! –