我有点难过。
我有一个项目表,其中包含字段:ID,title,created_by,group 。
我还有另一个包含字段的组表: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;
我希望我的需求和意图是明确的。任何帮助将不胜感激。
答案 0 :(得分:3)
目前唯一可以考虑这样做的方法是为每个用户创建一个单独的表(列出他们所属的所有组)。
糟糕!不要那样做!让我们使用一些规范化来重新创建表格。
-- 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子句。)
答案 1 :(得分:2)
嘿drent,这是个好问题。如上所述,处理多对多关系(许多用户到多个组)的标准方法是使用连接表。以下是表格:
现在,只要用户加入组,只需在user_group表中添加一行即可。例如,如果用户327加入组14:
INSERT INTO users_groups SET user_ID=327, group_ID=14;
列出用户可以访问的所有项目:
SELECT * FROM items
JOIN users_groups ON users_groups.group_ID = items.group_ID
WHERE users_groups.user_ID = :user
确保将:user
替换为当前用户的用户ID。另外,我可能没有使用与表中完全相同的列名,因此请小心。
列出用户所属的组:
SELECT * FROM groups
JOIN users_groups ON users_groups.group_ID = groups.ID
WHERE users_groups.user_ID = :user
答案 2 :(得分:1)
您正在寻找的关系(我认为)称为has-and-belongs-to-many或HABTM。您需要使用feilds user_id和group_id所谓的数据透视表。
然后,如果您有一个用户,您可以找到与user_id相关联的所有group_id。然后你可以用它来找到物品。