Php 文档共享系统的数据库设计

Php 文档共享系统的数据库设计,php,mysql,sql,database,database-design,Php,Mysql,Sql,Database,Database Design,我试图弄清楚我的文档共享系统的方法是否好,我使用的是PHP和SQL。我想我已经建立了一个糟糕的数据库设计 简单地说,这个概念就是创建文档,与他人共享,使用评论系统获取更新和反馈 用户可以与网络intranet上的任何其他用户共享其文档。用户可以访问其他用户与他们共享的文档并在其上留下评论 这是我的数据库模式 删除了一些列,如:创建时间、用户ip…等 用户登录系统后,PHP将使用this SQL查询查看他可以访问的所有文档: SELECT d.document_title FROM documen

我试图弄清楚我的文档共享系统的方法是否好,我使用的是PHP和SQL。我想我已经建立了一个糟糕的数据库设计

简单地说,这个概念就是创建文档,与他人共享,使用评论系统获取更新和反馈

用户可以与网络intranet上的任何其他用户共享其文档。用户可以访问其他用户与他们共享的文档并在其上留下评论

这是我的数据库模式 删除了一些列,如:创建时间、用户ip…等

用户登录系统后,PHP将使用this 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实现它

请给我建议,并给我你的反馈


谢谢

首先,您的查询应该是:

SELECT d.document_title
FROM documents d JOIN
     permission p
     ON d.document_id = p.document_id 
WHERE p.user_id = 12;
使用正确的连接语法。假设user_id是一个数字,那么比较应该是一个数字,而不是一个字符串

其次,当您描述文档时,它们似乎有所有者。因此,文档应该具有类似于所有者\用户\ id的内容。或者,所有权可能是一种权限类型

第三,权限通常有不同的类型——读、写和删除。所以,您可能需要权限类型

第四,为200个用户设置200行并不是一个先验的问题。您当然不希望通过与关系数据库实践相反的方式存储数据来解决这个问题,也就是说,将整数转换为字符串以在单个列中存储多个值


相反,您可能需要考虑引入组的概念,以便用户可以加入组,组可以访问文档。

< P>首先,您的查询应该是:

SELECT d.document_title
FROM documents d JOIN
     permission p
     ON d.document_id = p.document_id 
WHERE p.user_id = 12;
使用正确的连接语法。假设user_id是一个数字,那么比较应该是一个数字,而不是一个字符串

其次,当您描述文档时,它们似乎有所有者。因此,文档应该具有类似于所有者\用户\ id的内容。或者,所有权可能是一种权限类型

第三,权限通常有不同的类型——读、写和删除。所以,您可能需要权限类型

第四,为200个用户设置200行并不是一个先验的问题。您当然不希望通过与关系数据库实践相反的方式存储数据来解决这个问题,也就是说,将整数转换为字符串以在单个列中存储多个值


相反,您可能需要考虑引入一些组的概念,以便用户可以加入一个组,并且组可以访问这些文件。

想象一下,当每个权限而不是一个记录时,记录的权限与许多权限一样多,您将有如下值:

id1,id2,…,idn

现在,让我们来看几个问题:

特权数量 在您打算完成的更改中,您必须计算逗号的数量,并为每个权限添加1,这会让您非常头疼。目前,您可以只计算记录的数量,并根据需要对结果进行分组

向文档添加新权限 假设您必须将id添加到文档的权限列表中。在这种情况下,您必须搜索文档的权限记录。如果找不到,则需要插入一条记录,并确保您的id放在那里。如果找到,则必须更新相同的记录。目前,如果权限不存在,它只是一个插入,通常您已经有了信息,甚至不需要查询

从文档中删除权限 要使用建议的模式实现这一点,您需要找到文档的权限记录,并检查它是否至少包含逗号。如果是这样,则需要拆分值并构造一个字符序列,该序列不包含要删除和更新记录的id,如果没有逗号,则需要删除记录。目前,您只需删除一条记录

查找用户有权访问的文档 使用建议的模式,您需要执行一些非常缓慢的字符串操作,如

like '%,<theid>,%'
并确保此查询的所有字符串都以逗号开头和结尾,但不实际修改数据,因此需要将实际值与逗号前缀和逗号后缀连接起来,从而使代码性能不佳,并且非常难以读取和维护。目前,您可以轻松查询此类值

1NF 简言之,你的建议会使你的设计更糟
N您需要问问自己,您当前的模式是否真的有问题,如果有,是什么问题。如果在性能方面存在严重问题,则需要确保正确识别性能方面的问题,如果这是performancee的问题,则可能通过向某些列添加索引来改进架构。您的建议可能会偏离,这是一个坏主意。

想象一下这样的情况,即不是每个权限都有一个记录,拥有尽可能多的记录和权限,而是拥有如下值:

id1,id2,…,idn

现在,让我们来看几个问题:

特权数量 在您打算完成的更改中,您必须计算逗号的数量,并为每个权限添加1,这会让您非常头疼。目前,您可以只计算记录的数量,并根据需要对结果进行分组

向文档添加新权限 假设您必须将id添加到文档的权限列表中。在这种情况下,您必须搜索文档的权限记录。如果找不到,则需要插入一条记录,并确保您的id放在那里。如果找到,则必须更新相同的记录。目前,如果权限不存在,它只是一个插入,通常您已经有了信息,甚至不需要查询

从文档中删除权限 要使用建议的模式实现这一点,您需要找到文档的权限记录,并检查它是否至少包含逗号。如果是这样,则需要拆分值并构造一个字符序列,该序列不包含要删除和更新记录的id,如果没有逗号,则需要删除记录。目前,您只需删除一条记录

查找用户有权访问的文档 使用建议的模式,您需要执行一些非常缓慢的字符串操作,如

like '%,<theid>,%'
并确保此查询的所有字符串都以逗号开头和结尾,但不实际修改数据,因此需要将实际值与逗号前缀和逗号后缀连接起来,从而使代码性能不佳,并且非常难以读取和维护。目前,您可以轻松查询此类值

1NF
简言之,你的建议会恶化你的设计。您需要问问自己,您当前的模式是否真的有问题,如果有,是什么问题。如果在性能方面存在严重问题,则需要确保正确识别性能方面的问题,如果这是performancee的问题,则可能通过向某些列添加索引来改进架构。您的建议可能会偏离,这是一个坏主意。

学习使用正确、明确、标准的联接语法。不要在FROM子句中使用逗号。学习使用正确、明确、标准的联接语法。千万不要在FROM子句中使用逗号。非常感谢您的加入建议,我将实现它,并肯定会搜索更多关于它的信息。我是SQL的新手。关于您对组和权限类型的建议,这是我将来要考虑的。谢谢你,你认为第一种方法正确吗?老实说,直到我看到权限表中有数千条记录时,我才想到这一点。非常感谢你的加入建议,我将实施它,并肯定会搜索更多关于它的信息。我是SQL的新手。关于您对组和权限类型的建议,这是我将来要考虑的。谢谢你,你认为第一种方法正确吗?老实说,直到我在权限表中看到数千条记录,我才想到这一点。非常感谢你的回答。我只是担心权限表中的数千条记录。@JamalSalim不担心数千条记录。理论上,当你有数百万条记录时,问题就应该开始了。不要过早地进行优化,因为如果您这样做,您将最终修复不一定存在的问题,而不了解这些问题的详细信息。如果任何一个答案解决了你的问题,那么你可以考虑接受它作为正确的答案。非常感谢你的回答。我只是担心权限表中的数千条记录。@JamalSalim不担心数千条记录。理论上,当你有数百万条记录时,问题就应该开始了。不要过早地进行优化,因为如果您这样做,您将最终修复不一定存在的问题,而不了解这些问题的详细信息。如果任何一个答案解决了你的问题,那么你可以考虑接受它作为正确的答案。