我正在建立一个练习用的小论坛。我看到像 phpBB 这样的论坛将线程文本存储在一个单独的表中。
为什么?为什么不将它们全部存储在同一张表中?
就像是:thread_id, thread_date, thread_text, thread_author
为什么这样做?你会怎么做?
我实际上不知道为什么要这样做,但我可以想象的一个原因是优化帖子元数据(日期、作者等)的搜索和检索。
根据 Joel(而且 Joel 永远是对的!;-) 数据库将它们的数据存储在由固定长度记录组成的固定长度字段中,因此只需将指针增加一个字节长度就可以轻松地从一行跳转到下一行。记录。但是用于存储帖子文本的大文本字段不能具有固定大小,因为帖子的长度在很大范围内变化,并且创建足够大以容纳所有帖子的固定长度存储会浪费大量空间。这意味着当您想要检索大量帖子的元数据时,将帖子文本与其他信息存储在同一个表中会使速度变慢,就像每次有人查看主论坛页面时所做的那样。
两全其美的方法是将固定长度字段(即除帖子文本之外的所有内容)放在一个表中,将可变长度字段(即帖子文本)放在另一个表中。
从来没有看过 phpBB 的胆量,但也许是因为全文索引。主表的 Inno-db 引擎允许事务和不允许事务。MyIsam 用于全文索引。
一方面,大多数关系数据库的文件系统布局使得存储大块任意文本或数据会降低系统速度。由于数据通常按行存储,因此在进行搜索时,即使在查找不相关的字段时,数据库现在也必须跳过可变长度的文本字段。
其次,如果您需要为每个 thread_id 提供更多数据,例如,将所有内容放在一个表中会使以后添加到数据模型中变得更加困难。
很好地设计数据库模式需要一些教育。您应该从http://en.wikipedia.org/wiki/Database_normalization开始。一定要理解第三范式。
InnoDB
不支持FULLTEXT
索引,MyISAM
也不支持事务。
不知道phpBB
,但可能这就是他们分开表格的原因。
由于表格可以达到的大小,它们不会将文本存储在同一个表格中。
这样,即使有非常多的条目,线程列表表也很小,索引很好,并且可以快速扫描它。仅在必要时使用主键访问文本,这也很快。
对于小型论坛,我认为这没有必要,因为有一点编码开销。
除了 Julien 的出色回答之外,将帖子移动到其他线程(比如管理员或版主)是很常见的。将文本放在“发布表”中有助于支持这一点。