因為我的一個網站需要升級成 discuz系統. 所以需要把以前的帖子都導入到discuz中, 當然也包括以前的注冊用戶也需要導入到discuz中. 導入用戶的事情, 待會寫另一篇帖子說. 先說導入帖子的事.
以前完全不了解discuz 的數據庫結構. 帖子到底怎么存的,完全不知道. 從哪下手呢?
先准備環境.
1. 當讓先本地安裝php環境, 以便調試. 推薦 WampServer Version . 自己上網搜一下就知道了, 傻瓜操作,一路next安裝.
2. 安裝discuz 到本地. 過程略.
重點來了, 從哪下手? (當然可以去找discuz的文檔, 但是我沒有找到.)
當然是從數據庫本身下手最直接. 想法非常簡單. 就是手動發一個帖子, 然后對比發帖前后數據庫的差異, 就知道要發一個帖子,需要修改哪些數據了.
但是怎么才能知道數據庫前后的差異呢. 簡單, 發帖前把數據庫備份下來, 發完貼再備份一次, 比較這兩次的差異.
備份數據庫的方法很多, 但是那種方式最簡單直接, 最能讓人發現其中的差異呢?
我們知道phpmyadmin 這個神器,有一個功能就是導出數據庫(或者導出其中的某些表). 而且導出的是 sql文件, 所有的內容都是文本的明文. 這樣我們只需要一個文本比較工具,就能對比差異了.
為了完整起見, 其實我也不知道要導出哪些表, 所以就選擇導出整個數據庫. 先導出一份, origional.sql, 手動去發個帖子, 再導出一份, post.sql, 注意都是導出整個數據庫. 還要注意的就是導出的時候, 不能用快速導出, 要點開自定義選項, 找到最下面的 "轉儲數據時所使用的函數", 改成 replace, 默認是insert. 至於為什么, 等會你就懂了.
然后請出文本比較神器, beyond Compare.
其中差異不多, 出了一些更新用戶積分之類的操作之外, 很快就定位到這兩個表:
pre_forum_post 和 pre_forum_thread
細看這兩個表的字段不難發現.
post表應該指的是帖子, 其中包含了帖子所有字段,包括標題,內容,時間,作者等等. thread表表示的是所有主題帖子, 但是thread表並不包含帖子的內容等詳細信息, 值包含一個pid. 這個pid就是post表的id.
所以, 所有的帖子, 包括主題帖子以及主題帖子下面的回復應該都是作為一個post放在pre_forum_post表中的. 而 pre_forum_thread 只記錄主題帖子的信息, 以及主題帖子對應的post的id.
到這里, 我們就知道了. 我只需要導入帖子到 post表中, 並且, 更新 thread表. 因為我每個帖子都是作為一個主題帖子導入的, 不需要考慮 回復的問題.
其中的pid 和tid 都是一一對應的. 所以更新着兩個表就行了. 細節就不說了.
直接導入.
導入很順利, 但是 導入之后論壇打開,首頁, 發現一個帖子也沒有. 但是各個板塊點開里面有帖子 呃, 說明我們還有數據沒有更新對. 怎么辦, 再次仔細比較差異.
發現這樣一個差異, 在pre_forum_forum表中:
這個表貌似是包含了, 每個版塊的概要信息, 就是論壇首頁要顯示的信息.
比如每個版塊的名字, 每個版塊總的發帖數, 版塊的設置. 以及這個版塊最后一個帖子的詳細信息. 包括帖子標題, 發帖時間等等.
就是這里用到的信息:
知道了這個,就好辦了. 我們把帖子導入到post和thread表之后, 在來這里更新 版塊的信息就好了.
這里要更新幾個具體的字段,
threads: 版塊內的主題數.
posts: 版塊內的帖子數.
todayposts: 版塊內, 今日發帖的個數. 這個是post的個數, 不是thread的個數.
lastpost: 這個字段比較奇葩, 看名字它是表示本版塊最新一個帖子. 但它的值比較有意思, 這是一個字符串, 由四部分組成, 每部分之間用 \t 制表符分割. 第一部分是這個帖子的pid, 第二部分是帖子的標題, 第三部分是帖子的發帖時間, 第四部分是帖子的作者名. 這個字段可能是為了提高論壇首頁的性能, 有了他之后,首頁就負擔輕了很多.
其他的字段就不說了.
按這個再來一次. 首先需要把數據庫還原到最開始沒有導過的樣子, 怎么做? 記得剛開始備份的 origional.sql 文件嗎? 把他導入到數據庫中就好了啊. 剛才讓選replase 還記得嗎, 如果沒有選replace的話, 你現在導入時會失敗的,不信你試試.
言歸正傳. 還原數據庫-> 成功. 再次導入帖子(需要更新 pre_forum_post , pre_forum_thread 以及 pre_forum_forum 這三個表.), 一路調試過程自不必說. 如果其中有失敗了, 請重新還原數據庫, 再視. 經過數次調試之后. 終於成功了.
這個時候打開論壇首頁, 每個版塊都能正確顯示最后發帖信息, 點開每個版塊里面的帖子也都正常. 都點幾次也都沒有問題. 大功告成.....
好了,上線. 等等, 我手一抖, 咱發個帖子玩玩吧. 點發帖. opps.......
失敗啦..................... 腫么辦. 難道是我們把數據庫改壞了? ..........不會吧........................
不要慌張, 看看它說什么先.
它在向post表中插入新帖子的時候出錯了. 說主鍵重復. 它插入的時候用的pid主鍵是1, 但是我剛才已經導入了很多帖子了. 1這個值在post表中早就被占了啊. 當然會出錯了. 但是奇怪的是, pid本來就是自增的, 為什么它在插入新帖的時候還要強行指定一個pid呢? 那這個強行指定的pid又是從哪來的呢. 如果能知道從哪來的, 我就能把它改對了.
它有堆棧信息, 程序員的最愛. 一路打開相應的文件. 一探究竟.
在堆棧的第四層, 就是 function_form.php 的941行找到了如下代碼:
看樣子, 它就是在這指定pid的.
這里應該是在做分表, 我們知道discuz有分表功能, 就是帖子可以分表存放, 因為帖子太多的話, 一個表就會降低性能.
其實了解這個分表不重要. 重要的是看 pid從哪取的.
這里有個表 forum_post_tableid. 這個表比較有意思. 它只有一列pid, 而且還是自增的. 上面的邏輯顯示, 當用戶添加新帖子時, 會先從這個表中自增一個pid作為帖子的id, 然后再把帖子連帶這個pid一起插入到post表中. 了解了這個, 就明白了. 我們剛才導入帖子的時候, pid用的是自增的值. 這是不對的, 應該先從forum_post_tableid表中自增一個pid, 然后連同這個pid和帖子的內容一起插入到post表中, 而不應該直接用post表的自增值.
知道了這個, 改程序,再來.
先還原數據庫, 不用說了吧. 然后導入, 經過數次調試之后. 終於通過了. 導入完成.
哈哈, 等等, 我發個帖子先.
等等, 我再發一個試試. .............................
發帖成功.
到此, 導入帖子的問題就解決了.
打完收工.
稍后, 再分享一篇, 如何把已經注冊的用戶 也導入到discuz中.
歡迎大家多多交流.
@byNeil.com
From All by Neil, post 直接導入帖子到Discuz 論壇數據庫.
原文來自 All by Neil, post 直接導入帖子到Discuz 論壇數據庫. 轉載請注明出處。本站保留一切權力