使用php和mysql为简单论坛设计高效的数据库
我正在为我的网站设计一个论坛功能数据库。在搜索了SO和google之后,我提出了以下设计: 用户表使用php和mysql为简单论坛设计高效的数据库,php,mysql,database,optimization,Php,Mysql,Database,Optimization,我正在为我的网站设计一个论坛功能数据库。在搜索了SO和google之后,我提出了以下设计: 用户表 Username : varchar(256) Password : varchar(256) ThreadId : int UserId : int, related to Users table Title : varchar(255) Date : timestamp, when a thread was created PostId : int
Username : varchar(256)
Password : varchar(256)
ThreadId : int
UserId : int, related to Users table
Title : varchar(255)
Date : timestamp, when a thread was created
PostId : int
ThreadId : int, related to Threads table
UserId : int, related to Users table
Date : timestamp, when post was made
Title : varchar(255) - post title (optional)
Body : text - the actual body of a post
线程表
Username : varchar(256)
Password : varchar(256)
ThreadId : int
UserId : int, related to Users table
Title : varchar(255)
Date : timestamp, when a thread was created
PostId : int
ThreadId : int, related to Threads table
UserId : int, related to Users table
Date : timestamp, when post was made
Title : varchar(255) - post title (optional)
Body : text - the actual body of a post
帖子表
Username : varchar(256)
Password : varchar(256)
ThreadId : int
UserId : int, related to Users table
Title : varchar(255)
Date : timestamp, when a thread was created
PostId : int
ThreadId : int, related to Threads table
UserId : int, related to Users table
Date : timestamp, when post was made
Title : varchar(255) - post title (optional)
Body : text - the actual body of a post
尽管这符合我的目的,但我还是忍不住认为这不是很有效,特别是对于选择某个特定线程的所有帖子,需要遍历整个表
从我的脑海中,我可以想到一种设计,其中用户表和线程表保持原样,而不是为帖子表设置一个表,我为每个与用户同名的用户创建了一个Posts表,因为我只需要启动线程的人的用户ID。根据这些信息,我搜索同名表以检索特定线程的所有帖子。但是,让我创建的表的数量直接取决于注册用户的数量是不是一个好主意?我还想知道的是,这些设计中,哪一种更易于管理,规模更大?有更好的数据库设计满足我的要求吗?您的设计看起来基本正确 这是一种典型的“标准化”数据结构,正是构建关系数据库的目的。如果您不知道标准形式,但提出了这种结构,那么您显然对关系数据库的工作方式有着自然的理解 为了让PHP避免遍历整个表,您应该确保发出一条SQL语句,该语句只选择要查找的记录。例如
SELECT * FROM posts WHERE ThreadId = ? ORDER BY Date
您对数据库必须遍历整个表的担心是合理的,尽管您可以避免这种情况——这是一个经典的关系数据库问题,在30多年前作为商业产品首次出现时就已经解决了
您可以在帖子上创建一个支持您正在运行的SQL的索引。在这种情况下,应遵循以下原则:
CREATE INDEX postThreadsIndex ON posts ( ThreadId, Date )
此索引允许数据库引擎快速查找所选记录,而无需读取整个表。如果你想知道怎么做,请仔细阅读b树索引
正如我在前面的回答中所说的,这正是构建关系数据库的目的,您的设计是可靠和适当的
不要考虑任何其他的选择——你第一次做对了!<强>
但是,为了完整起见,让我们看看您建议的替代方案
您建议按用户拆分Post表-这意味着:
- 用户“UserA”创建一个线程-他的初始帖子存储在posts\u UserA中
- 用户“UserB”响应帖子-他的帖子被存储在posts\u UserB中
- 用户“UserC”响应帖子-她的帖子被存储在posts\u UserC中
如果您的SQL性能由于数据量太大而变得太慢,那么您可以看看表分区,它以一种不可见的方式实现了您所描述的功能。但老实说,除非你的网站非常受欢迎,否则你不太可能需要它——如果是这样的话,那么你可能会有足够的资金来投资关系数据库基础课程……看看:尽管显然使用PDO或mysqli代替,即使我为帖子创建了索引,threadid由于php服务器必须遍历整个表以检索特定threadid的记录,因此它仍然是低效的(内部),因此我提出了第二种设计。您对第二种数据库设计(而不是第一种)有何看法?不,PHP不需要遍历整个表,因为您将使用SQL选择所需的记录。例如,从threadId=?抱歉,sql必须遍历整个表才能找到具有特定threadId的所有条目的帖子中选择*。您认为以下内容在内部是如何工作的?通过遍历整个表来完成吗?即使从threadId=?,的帖子中选择*,会做我想做的,但会比第二个数据库设计慢,对吗?不,不会,如果你使用索引t