我试图弄清楚我的文档共享系统方法是否不错(我使用的是PHP和SQL)。我认为我的数据库设计不好。
简单来说,概念是创建文档,与他人共享文档,使用注释系统获取更新和反馈。
用户可以与网络(内部网)上的任何其他用户共享他们的文档。用户可以访问其他用户与他们共享的文档,并在文档上留下评论。
(删除了一些列,例如:created_time,user_ip ...等)
- documents:
----------------------
-- document_id
-- document_title
-- document_content
-- document_category
- comments:
----------------------
-- comment_id
-- comment_content
-- document_id
-- user_id
- users:
----------------------
-- user_id
-- user_name
-- user_type
-- user_password
- permissions:
----------------------
-- document_id
-- user_id
用户登录系统后,PHP将使用此SQL查询查看他可以访问的所有文档:
SELECT d.document_title
FROM documents AS d, permission AS p
WHERE d.document_id = p.document_id AND p.user_id = '12'
上面的查询还用于授予对文档的访问权限
现在想象一下,为与200个用户共享的单个文档在网络上创建的行数,在权限表中将是201行!我认为这是一个不好的方法
我正在尝试采用另一种方法,即将权限表更改为此:
- permissions:
----------------------
-- document_id
-- users_ids
这将使我可以在每个文档的一列和一行中保存用户ID。但是我不确定这是否是正确的方法,老实说我看不到如何使用PHP和SQL来实现
请告知我,并给我您的反馈意见
谢谢
答案 0 :(得分:2)
首先,您的查询应为:
SELECT d.document_title
FROM documents d JOIN
permission p
ON d.document_id = p.document_id
WHERE p.user_id = 12;
使用正确的JOIN
语法。大概user_id
是一个数字,因此比较应该是一个数字,而不是字符串。
第二,当您描述文档时,它们似乎拥有所有者。因此,documents
应该类似于owner_user_id
。或者,所有权可能是一种许可。
第三,权限通常具有不同的类型-想到的就是读取,写入和删除。因此,您可能需要权限类型。
第四,为200位用户提供200行不是先验问题。您当然不希望通过与关系数据库实践相反的数据存储来修复它-也就是说,将整数压缩为字符串以在单个列中存储多个值。
相反,您可能需要考虑引入“组”的某些概念,以便用户可以加入组,并且该组可以访问文档。
答案 1 :(得分:1)
想象一下这样的情况:您将拥有像这样的值:
id1,id2,...,idn
现在,让我们看一些问题:
使用您打算完成的更改,您将不得不计算每个权限的逗号数(并加1),这将使您非常头疼。当前,您仅可以计算记录数,就可以根据需要对结果进行分组。
假设您必须在文档的权限列表中添加一个ID。在这种情况下,您将必须搜索文档的许可记录。如果找不到,则需要插入一条记录,并确保将您的ID放在此处。如果找到,那么您将必须更新相同的记录。当前,如果权限不存在,它只是一个插入,通常您已经拥有了信息,甚至不需要查询。
要使用建议的模式实现此目的,您将需要查找文档的权限记录,并检查其是否至少包含逗号。如果是这样,那么您将需要拆分值并构造一个字符序列,该字符序列不包含要删除和更新记录的ID,如果没有逗号,则删除记录。目前,您只需要删除一条记录即可。
使用建议的架构,您将需要执行一些相当慢的字符串操作,例如
like '%,<theid>,%'
并确保此查询的所有字符串以逗号开头和结尾,但没有实际修改数据,因此您需要将实际值与逗号前缀和逗号后缀连接在一起,从而使代码性能不佳且非常困难阅读和维护。目前,您可以轻松查询这些值。
简而言之,您的建议会使您的设计恶化。您将需要问自己自己当前的模式是否真的有问题,如果有的话,这是什么问题。如果您对性能有严重的问题,则需要确保正确识别性能问题,如果这是性能问题,则可以通过向某些列添加索引来改进架构。您的建议会偏离1NF,这是个坏主意。