簡體   English   中英

一個使用php和mysql的簡單論壇的高效數據庫設計

[英]An efficient database design for a simple forum using php and mysql

我正在為我的網站設計一個用於論壇功能的數據庫。在 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
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

盡管這符合我的目的,但我不禁認為這不是很有效,特別是對於需要遍歷整個表格的特定線程選擇所有帖子。

在我的腦海中,我可以想到這樣一種設計,即Users 表Threads 表保持原樣,但不是為Posts 表創建一個,而是為每個同名的用戶創建一個Posts 表用戶。這種檢索屬於一個線程的所有帖子的方式效率更高,因為我只需要啟動該線程的人的用戶 ID。使用此信息,我搜索具有相同名稱的表以檢索所有帖子具體的線程。但是讓我創建的表的數量直接依賴於注冊用戶的數量是一個好主意嗎?我還想知道的是,這些設計中哪一個可以更好地擴展,更容易管理? 是否有更好的數據庫設計滿足我的要求?

您的設計看起來基本正確。

這是一種經典的“規范化”數據結構——正是關系數據庫所針對的那種形狀。 如果您不了解范式,但想出了這種結構,那么您顯然對關系數據庫的工作方式有一個自然的理解。

http://en.wikipedia.org/wiki/Database_normalization#Normal_forms

為了讓 PHP 避免遍歷整個表,您應該確保發出只選擇您要查找的記錄的 SQL 語句 例如

SELECT * FROM posts WHERE ThreadId = ? ORDER BY Date

您擔心數據庫必須遍歷整個表是公平合理的,盡管您可以避免這種情況——這是一個經典的關系數據庫問題,在 30 多年前它們首次作為商業產品出現時就已經解決了。

您可以支持您正在運行的 SQL 的帖子上創建索引 在這種情況下,大致如下:

CREATE INDEX postThreadsIndex ON posts ( ThreadId, Date )

此索引允許您的數據庫引擎非常快速地找到您選擇的記錄,而無需讀取整個表 如果您想知道如何,請閱讀 b 樹索引。

http://en.wikipedia.org/wiki/B-tree

正如我在前面的回答中所說,這正是關系數據庫的構建目標,您的設計是可靠且恰當的。

不要考慮任何替代方案 - 你第一次就做對了!

但是,為了完成起見 - 讓我們看看您建議的替代方案。

您建議按用戶拆分 Post 表 - 這意味着以下內容:

  • 用戶“UserA”創建一個線程 - 他的初始帖子存儲在 posts_UserA 中
  • 用戶“UserB”回復帖子 - 他的帖子在posts_UserB 中
  • 用戶“UserC”回復帖子 - 她的帖子被記錄在 posts_UserC 中

為了檢索完整的線程,您現在需要查看posts_UserA、posts_UserB 和posts_UserC。

如果這是唯一的三個用戶,那么你就需要通過所有這些threee表中的數據看,以便找到所有的職位,而這將是等於已經在表的帖子中的記錄數的原始設計。

你一無所獲。

如果您有 1000 個其他用戶,您還必須查看其他 1000 個表以發現他們沒有任何記錄。

你仍然一無所獲。

您可以添加另一個表來存儲哪些用戶對哪些帖子發表了評論 - 因此可以查看哪些表,但現在解決方案開始變得復雜。

可以按線程拆分 Post 表 - 這意味着表中的所有帖子都基於創建它們的線程。 這對於選擇單個線程上的帖子可能非常好,但對於以下情況則很糟糕: - 選擇給定用戶發表的所有帖子。 - 無論線程如何,都可以找到最新的帖子。 - 查找在特定日期發布的所有帖子。 - 不涉及特定線程的任何其他內容。

基本上,您建議的替代方案對於非常特定的查詢可能更有效,但對於任何其他查詢幾乎總是非常復雜。

原始設計對於所有查詢都更簡單,並且可以通過添加索引使其性能良好。

如果您曾經因為數據量而導致 SQL 性能太慢,那么您可以查看表分區,它以一種無形的方式完成您所描述的工作。 但老實說,除非您的網站非常受歡迎,否則您不太可能需要它——如果是這種情況,那么那時您可能會有現金投資關系數據庫課程的基礎知識……

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM