2010-07-13 6 views
0

나는 다소 혼란 스럽다.Mysql 및 PDO의 다른 테이블 결과를 기반으로 테이블에서 행 선택

ID : 제목, created_by, 그룹 필드가있는 테이블이 있습니다.

나는 또한 이 필드 그룹의 다른 테이블 : ID, CREATED_BY이 (가) 작성한, GROUP_NAME
및 필드와 사용자의 최종 테이블 : ID, 사용자 이름, 암호 등.

로그인 한 사용자가 만든 항목 또는 로그인 한 사용자가 항목의 사용자 그룹에 속한 항목 만 해당 사용자가 볼 수 있다는 개념입니다.

각 사용자는 불특정 다수의 그룹에 속할 수 있으며 각 그룹에는 불특정 다수의 사용자가 포함될 수 있습니다.

내가 생각할 수있는 유일한 방법은 각 사용자 (구성원 인 모든 그룹 나열)에 대해 별도의 테이블을 만드는 것입니다.

그런 다음 먼저 로그인 한 사용자가 만든 항목에 대한 항목 테이블을 검색합니다.
둘째, 해당 사용자의 "그룹"테이블을 검색하여 해당 그룹이 속한 각 그룹의 ID를 찾은 다음 항목 테이블을 재귀 적으로 검색하고 현재 발견 된 group_id가 항목의 그룹 ID와 일치하는 각 항목을로드합니다.

소수의 항목, 그룹 및/또는 사용자에 대해 올바르게 코딩 된 경우 작동하지만 각 페이지가 큰 테이블을로드/처리하는 데 오랜 시간이 걸릴 것으로 생각됩니다. 또한 수천 명의 사용자와 수천 개의 테이블을 가질 수 있다는 점을 감안할 때 각 사용자마다 새 테이블을 만드는 것이 상당히 지저분한 것처럼 보입니다.

테이블 조인이 솔루션을 제공 할 수 있다고 생각하지만 지금은 어떻게 보이지 않습니다. 이 경우 테이블 필드의 이름을 변경하여이 작업을 수행하는 것이 매우 행복합니다. 항목을 검색하기위한

내 현재 코드 (나는 아마 적합하지 알고)이 있습니다 :

$query = "SELECT * FROM items WHERE user_id=:u_id"; 
$stmt = $conn->prepare($query); 
$stmt->execute(array(':u_id'=>$_SESSION['u_id'])); 
$exist = '<option></option>'; 
while($uRow = $stmt->fetch()) { 
    $exist .= '<option value="'.$uRow['id'].'">'.$uRow['title'].'</option>'; 
} 
$user_groups_tbl = "user_groups_".$_SESSION['u_id']; 
$query1 = "SELECT * FROM $user_groups_tbl"; 
$query2 = "SELECT * FROM items WHERE group_id=:group"; 
$stmt1 = $conn->prepare($query1); 
$stmt2 = $conn->prepare($query2); 
$stmt1->execute(); 
while($gRow = $stmt1->fetch()) {  
    $stmt2->execute(array(':group'=>$gRow['group_id'])); 
    while($row = $stmt2->fetch()) { 
     if($row['user_id'] !== $_SESSION['u_id']) { 
      $exist .= '<option value="'.$uRow['id'].'">'.$uRow['title'].'</option>'; 
     } 
    } 
} 
return $exist; 

이 내 요구와 의도가 분명하다 바랍니다. 어떤 도움을 주시면 감사하겠습니다.

답변

3

내가 생각할 수있는 유일한 방법은 각 사용자 (회원 인 모든 그룹 나열)에 대해 별도의 테이블을 만드는 것입니다.

Yikes! 그렇게하지 마! 약간의 정규화를 사용하여 테이블을 다시 만들어 보겠습니다.

-- Our users 
CREATE TABLE users (
    user_id INTEGER PRIMARY KEY, 
    ... 
); 

-- And our groups 
CREATE TABLE groups (
    group_id INTEGER PRIMARY KEY, 
    ... 
); 

-- New! A list of all groups and the users that belong to them. 
-- This is also conveniently a list of users and the groups that they belong to. 
CREATE TABLE group_users (
    user_id INTEGER REFERENCES users(user_id), 
    group_id INTEGER REFERENCES groups(group_id), 
    UNIQUE KEY(user_id, group_id) 
); 

-- Finally, our mysterious "items" 
CREATE TABLE items (
    item_id ..., 
    title ..., 
    user_id INTEGER REFERENCES users(user_id), 
    group_id INTEGER REFERENCES groups(group_id) 
); 

을 감안할 때 :

아이디어는 사용자로 로그인 한 사용자 또는 항목에 기록에 의해 생성 된 항목 만 해당 사용자가 볼 수있는 항목의 사용자 그룹의 일부이다.

SELECT * 
    FROM items 
WHERE items.user_id = ? 
    OR items.group_id IN(
      SELECT group_id 
      FROM group_users 
      WHERE user_id = ? 
     ) 

이 모든 사용자에 의해 생성 된 아이템 및 사용자가 속한 그룹에 속한 모든 항목을 잡을 것이다. (주의 :이 쿼리는 MySQL 버전에 따라 적절히 최적화되지 않을 수도 있습니다.대신 WHERE 절의 하위 쿼리를 FROM 절에 포함시켜야 할 수도 있습니다.

+0

내 대답과 동일하지만, 더 잘 expmained. – thomasfedb

+0

유익하고 웃게 만들었습니다! 나는 간단한 것을 놓치고 있다는 것을 알았다! 감사! – drent

1

찾고있는 관계는 소유물 많음 또는 HABTM이라고합니다. 당신은 feilds user_id와 group_id를 가진 피벗 테이블이 필요합니다.

그러면 사용자가 있으면 user_id와 연결된 모든 group_id를 찾을 수 있습니다. 그런 다음 해당 항목을 찾을 수 있습니다.

2

안녕하십니까, 좋은 질문입니다. 다 대다 관계 (많은 사용자 대 다수 그룹)를 다루는 표준 방법은 언급 한 것처럼 조인 테이블을 사용하는 것입니다. 다음 표는 다음과 같습니다

  • 항목 : ID, 제목, CREATED_BY이 (가) 작성한, GROUP_ID
  • 그룹 : 등 ID, 사용자 이름, 암호,
  • : ID, CREATED_BY이 (가) 작성한, GROUP_NAME
  • 사용자
  • 그냥 하나의 새로운 테이블 - users_groups : 용할 user_ID GROUP_ID

이제 사용자가 그룹에 참여할 때마다 user_group 테이블에 행을 추가하기 만하면됩니다.

SELECT * FROM items 
JOIN users_groups ON users_groups.group_ID = items.group_ID 
WHERE users_groups.user_ID = :user 

현재 사용자의 사용자 ID와 :user를 교체해야합니다 :

INSERT INTO users_groups SET user_ID=327, group_ID=14; 

는 사용자가 액세스 할 수있는 모든 항목을 나열하려면 예를 들어, 사용자 327 그룹 14에 합류합니다. 또한 테이블에서 사용하는 것과 동일한 열 이름을 사용하지 않을 수도 있으므로주의하십시오.

는 사용자가 속한 그룹 나열하려면 기본적으로

SELECT * FROM groups 
JOIN users_groups ON users_groups.group_ID = groups.ID 
WHERE users_groups.user_ID = :user 
+0

감사합니다. 이것은 또한 매우 유용했습니다! – drent

관련 문제