【问题标题】:Database design for a document sharing system文档共享系统的数据库设计
【发布时间】:2019-07-03 12:24:15
【问题描述】:

我正在尝试确定我的文档共享系统方法是否良好(我正在使用 PHP 和 SQL)。我认为我构建了一个糟糕的数据库设计。

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

用户可以与网络(内联网)上的任何其他用户共享他们的文档。用户可以访问其他用户与他们共享的文档,并在上面留下 cmets。

这是我的数据库架构

(删除了一些列,例如: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 行!我认为这是一种不好的方法

我正在尝试另一种方法,即将 permission 表更改为:

- permissions:
----------------------
-- document_id
-- users_ids

这将允许我将用户 ID 保存在每个文档的一列和一行中。但我不确定这是否是正确的方法,老实说,我不知道如何使用 PHP 和 SQL 来实现它

请给我建议并给我您的反馈

谢谢

【问题讨论】:

  • 学习使用正确、明确、标准 JOIN 语法。 从不FROM 子句中使用逗号。

标签: php mysql sql database database-design


【解决方案1】:

首先,您的查询应该是:

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 行不是问题先验。您当然不希望通过与关系数据库实践相反的方式存储数据来修复它——即将整数转换为字符串以在单个列中存储多个值。

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

【讨论】:

  • 非常感谢您的 JOIN 建议,我会实施它并肯定会搜索更多相关信息(我是 SQL 新手)。关于您对组和权限类型的建议,这是我将来考虑的。谢谢那么,您认为第一种方法正确吗?老实说,直到我在权限表中看到数千条记录时,我才想到它。
【解决方案2】:

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

id1,id2,...,idn

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

权限数

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

向文档添加新权限

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

从文档中删除权限

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

查找用户有权访问的文档

使用您建议的架构,您将需要执行一些非常慢的字符串操作,例如

like '%,<theid>,%'

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

1NF

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

【讨论】:

  • 非常感谢您的回答。我只是担心权限表中的数千条记录。
  • @JamalSalim 不用担心成千上万的记录。从理论上讲,当您在那里拥有数百万条记录时,问题就应该开始了。不要过早地进行优化,因为如果你这样做了,你最终会修复那些在没有详细信息的情况下不一定存在的问题。如果任何答案解决了您的问题,那么您可以考虑将其作为正确答案接受。
猜你喜欢
  • 1970-01-01
  • 2018-02-25
  • 2012-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多