4

我們正在構建一個簡單的基於網絡的系統,通過這個系統,某人添加了一個記錄,例如一個CMS頁面,並在網站上顯示之前由負責人批准。應該將記錄草案保存在單獨的表格中嗎?

如果作者隨後決定編輯該頁面,我們希望基於實時副本創建草稿,在批准時它將替換舊的實時頁面。

我們考慮過要完成版本控制,但相信我們可以通過只有1來簡化這個過程。僅僅是一個草稿,2.只是一個活的,或者3.一個草稿,一個活的。

此功能是跨多個「事物」而不僅僅是頁面需要的。

最後問題:你認爲將這兩條記錄存儲在同一張表中還是鏡像表更好會更好?

我想這可能取決於,但我不喜歡具有相同結構的兩個表的理想。對於稍微慢一點的操作(因爲我們必須在顯示數據時始終查詢草稿)是否值得呢?

+0

「操作稍慢」您是否測量過?這是事實嗎?或者你認爲它會變慢? – 2010-03-11 16:13:16

+0

當我還沒寫完它時,它怎麼會是事實?很明顯,我假設添加一個where子句,而不是僅僅從一個活動表中選擇所有記錄會比較慢,但我很樂於瞭解爲什麼我錯了。 – tsdbrown 2010-03-12 09:31:00

+0

如果你還沒有寫它,那麼你需要建立兩個秒殺解決方案,並衡量差異。假設是不好的。測量很好。 – 2010-03-12 10:53:47

回答

3

第一個實體類型,一個表。

理由重新考慮:

  1. 記錄草案由成千上萬的因素多於現場記錄之一。

  2. 安全條件要求訪問數據庫的某些用戶直接對GRANT/REVOKE級別的草稿或活動記錄擁有某種權限,但不得超過其他類型的記錄。

的第二個設計考慮是對項目和LiveItems第二表的一個表。第二個表格僅包含活動項目的ID。這樣你就可以維護你的單表設計,但是你可以通過將你的單列表連接回主表來找到LiveItems。

+0

謝謝你。 – tsdbrown 2010-03-12 09:41:53

8

當狀態發生變化時,將東西從表格移動到表格是一個壞主意。

當您想要將其他狀態添加到工作流程時,您必須添加更多表格。

這只是一種狀態變化 - 這就是關係數據庫的優化對象。

一個表,多個狀態是標準方法。

如果您發現事情非常緩慢 - 並且您可以證明基於狀態的查詢是完整的原因 - 您可以訴諸於「物化視圖」或類似的技術狀態改變(以及由此產生的移動)由RDBMS處理。

Table-per-state是一個壞主意。

  1. 您不能輕鬆添加狀態。你必須添加表格,並且使它變得很痛苦。此外,您必須使用新的表名更新代碼以反映新的工作流程。

    如果一個狀態只是一個列,那麼添加新的狀態就是在代碼中添加新的值和新的if語句。狀態更改只是更新,而不是「刪除 - 插入」。

    數據永遠存在,每當用戶有一個聰明的想法時,工作流程都會來去去去。不要因爲想改變工作流而懲罰他們。

  2. 你不容易有子狀態。許多狀態機實際上是多個嵌套的狀態機。用每個表的狀態添加一個子狀態可以創建更多的規則更多的表。

    如果一個狀態只是一個列,那麼嵌套的子狀態就是代碼中帶有新的if語句的另一列。狀態更改只是更新,而不是「刪除 - 插入」。

  3. 你不容易有並行狀態機。很多時候,有許多並行狀態代碼更改。有時會有手動工作流程(審批)和自動化的工作流程(歸檔,複製到數據倉庫等)。)對於每個狀態表和並行狀態機,沒有辦法合理地實現它

    如果每個狀態只是一個列,那麼並行狀態機就是並行更新。

+0

總的來說,我同意你的意見,但你知道這是不是隻有一個記錄經歷了一系列狀態?這將是初步的,但隨後草案將需要與現場相關記錄一起存在,並可能在批准後稍後進行替換。 – tsdbrown 2010-03-12 09:36:15

+0

@rsdbrown:「添加記錄」。聽起來很奇怪。如果它不是一個記錄,請更新這個問題。重要的是更新多個記錄或更新單個記錄並不重要。每個狀態表是一種糟糕的設計,當您嘗試添加狀態時會迅速惡化。狀態只是該行的狀態碼。 – 2010-03-12 10:55:24

+0

看,我們同意這兩張表是不好的設計,我甚至在我的問題上暗示了我的想法!我問這個問題的原因是因爲我已經看到其他人如何在rails插件中實現這一點,例如acts_as_versioned和has_draft。我不認爲你理解我的問題,這可能是我的做法。不過其他人似乎明白這個想法,我相信這個問題已經足夠清楚了。謝謝您的意見。你的,其他人和我自己的想法已經證實我不會有兩張桌子。 – tsdbrown 2010-03-12 12:00:06

2

同意上面給出的所有意見:只有一個表。
通過scopes,您可以輕鬆獲取已發佈的帖子或草稿。

我不會爲它推薦。
但是,如果您確實希望草稿和發佈的條目有兩種不同的模型,則還有其他解決方案:STI

你就會有兩個型號:

class Post < ActiveRecord::Base 
end 

class Draft < Post 
end 

任何對象草案從表後採取的。
Type參數使其成爲帖子或草稿。

每當你要發佈一個帖子你那麼要做的:

@draft = Draft.first 
@draft[:type] = 'Post' 
+0

STI是我一直在考慮的東西,具有範圍的狀態列幾乎與具有類型列的狀態列相同。你會說範圍/地位的方式會更好嗎?我喜歡STI的想法,因爲控制器就像LivePost.all和DraftPost.all – tsdbrown 2010-03-12 09:41:19

相關問題