2010-04-12 15 views
7

背景
我正在寫一個調查,這將是一個很大的觀衆。它包含15個問題,每個問題有五個可能的答案以及潛在的評論。如果我需要將數據庫上的流量降到最低,那麼存儲問卷和調查答案的最佳方式是什麼?

用戶可以在所有15個問題中按任意順序回答問題,並可以隨時離開問卷調查並回答問題。

一旦在所有15個問題上嘗試了答案,就會出現一個提交按鈕,允許他們將問題提交爲最終答案。在該階段之前,只要用戶加載調查頁面,就需要可檢索所有答案。

要求是用戶只能看到一個頁面上的一個問題,'上一個'和'下一個'按鈕允許用戶滾動瀏覽問題。

要求
我可以在用戶每次點擊一個按鈕時要求的問題,並保存當前的響應等等,但是這將是一個大量結果到已經大量使用的數據庫。我沒有時間去購買一臺新的服務器等,所以我不得不與我有什麼關係。有什麼辦法可以緩存用戶機器和/或響應的問題嗎?很明顯,我需要響應數據是安全的,只有用戶知道,所以我覺得這樣做的最佳方式有點卡住了。任何指針?

如果這意味着我會得到一些高質量的討論和反饋,我準備在這個問題上提供100分的獎勵。

+1

爲什麼你需要最小化數據庫訪問?性能?如果設計得當,這看起來不應該是數據庫密集型的。 – 2010-04-13 01:14:13

+0

您是否在意擴大羅曼? – 2010-04-15 08:55:26

回答

1

您有需要平衡三個方面的要求:

  • 用戶必須能夠在任何時候通過用戶輸入的
  • 答案必須用數據損失儘可能少的機會被保存回到自己的調查
  • 需要儘量減少數據庫的訪問

涉及在不穩定的地方(Cookie,會話等)的緩存回答任何解決方案都會增加數據丟失的風險。最終的解決方案取決於您如何對重要性的三個要求進行排名。如果數據庫問題位於頂部,那麼您需要承擔數據丟失的風險,或者使用一些臨時存儲方案(例如Kevin的平面文件構思)花費大量額外時間來編寫解決方案。

幾個人的建議,你可能會過早地優化。我建議你首先考慮這個想法 - 也許這整個事情是沒有意義的。

但是,假設你的數據庫情況是一個真正的問題,我認爲你的需求最好的平衡將是一個系統,立即保存數據庫的答案(以防止數據丟失),但仔細管理,當你實際上必須擊中D b。

  1. 當應用程序啓動時(或第一個用戶請求調查時)將調查及其問題加載到應用程序緩存中。如果任何問題有可能的答案的選擇列表,也加載這些。您只需在應用程序生命週期(或緩存持續時間)內打一次數據庫即可加載調查數據。
  2. 當用戶開始他們的調查時,運行單個查詢以將任何現有答案(如果他們是回訪用戶)加載到會話中的對象中 - 可以像<List>string那樣簡單。 (如果您可以以某種方式識別新用戶而不必擊中數據庫,那麼您可以跳過此步驟以供新用戶使用。)
  3. 在會話緩存中使用會話應答對象以及調查問題對象來填充每個頁面而不點擊再次分貝。
  4. 當用戶提交答案時,將其與會話答案對象進行比較,以查看它是否發生了變化(她可能只是單擊帶有先前輸入的答案的頁面上的「下一個」)。如果答案是新的或已更改,則將其保存到數據庫和會話答案對象。
  5. 當用戶離開調查時,您無需執行任何操作 - 所有內容都已保存。

通過這個方案,您可以打一次數據庫來加載調查,當每個用戶開始(或重新啓動)調查時爲每個用戶加一次調查,併爲每個新的或修改後的答案添加一次。可能沒有你期望的那麼大,但是它爲你提供了最好的數據保護。

1

如果數據庫旅行是一個問題,您可以緩存他們在Web服務器(或任何應用程序所在),但它聽起來好像需要記錄每個答案的用戶進入到下一個問題。

如果每個人的問題和可能的答案都是相同的,我肯定會將它們緩存在應用程序層 - 這可以存儲在Application對象中。無論如何,您當然可以優化數據庫調用以儘可能高效地返回結果 - 即多個結果集或來自單個存儲過程的聯合結果集。如果您不介意每個會話有多個Copes(或者如果有變化),則可以將其存儲在Session對象中。將它存儲在客戶端(即一個cookie)並不真正安全,並且可以保持Web服務器 - 客戶端帶寬的節省。儘管如此,這聽起來像很不成熟的優化。

+0

我並不認爲帶寬是一個問題。關注似乎是重創數據庫 – 2010-04-12 19:34:21

+0

@David我不知道爲什麼緩存它在客戶端比Web /應用程序服務器更好。 – 2010-04-12 19:37:54

+0

只要流量不在數據庫(SQL Server)上,我就可以對應用服務器上的緩存提出建議,那麼這就是贏家。 – 2010-04-12 19:41:17

0

你的意思是一個餅乾?

+0

安全是必須的 - 我如何確保cookie的安全? – 2010-04-12 19:41:54

+1

加密。加密cookie的內容。 – aepheus 2010-04-12 19:53:47

+0

我對Safari有過不好的體驗,並更改了cookie值。即使是現在的版本。如果您必須支持該瀏覽器,請注意一些事項。 – NotMe 2010-04-13 16:53:45

1

這是一個經典的問題做一個基於瀏覽器的系統頁面之間保持狀態。我還假設,即使用戶註銷並稍後回來,我們也希望這些數據持續存在。下面是選項:

  • 具備高可用性的服務器,我們可以保持在內存中(不會話)15個回答單個集合爲此用戶(可能不是一個好主意,不容易負載平衡)
  • 我們denormalise 15個答案爲1行中的SQL表
  • 我們堅持使用Cookie或localStorage的(IE8)客戶端上的數據。

我的感覺是,前兩個選項可能不是你要找的,所以讓我們來探索最後一個選項。

你可以很簡單地將答案存儲在cookie中。這很可能會丟失,並且用戶可能從另一臺機器登錄,但這可能是一個可接受的風險。使用支持HTML5的最新瀏覽器(包括IE8 afaik),您可以獲得localStorage的好處,而不像Cookie那樣輕鬆刪除。如果這不可用,你可以回到cookie。

如果需要,可以對cookie進行加密。

1

不確定您正在使用的語言等,但大多數都有應用程序緩存。我會將問題存儲在那裏,並從數據庫中檢索它們,並在它們不在緩存中時將其存儲(應用程序回收時)。

至於答案,用戶是否登錄了一些如何?在所有問題得到解答之前,將答案保存在cookie中是否可行?

編輯: 如果cookie不夠可靠,您可以在應用程序緩存中存儲要執行的查詢列表(插入/更新),直到達到查詢限制時纔會執行它們,或者在某些條件下(即當用戶請求列表中的答案時執行查詢列表,應用程序回收時執行列表等)。

相當粗糙,但你的想法:

if (function == "get question" && userQuestionIsInQueue) || function == "finish survey" 
execute(Application["querylist"]); 
continue as normal... 

if function == "submit answer" 
if Application["querylist"] == null 
Application["querylist"] = newAnswerQuery; 
else 
Application["querylist"] += newAnswerQuery; 

還就需要(應用[「querylist」])添加到執行回收事件,我相信你可以在全局鉤子它.asax

編輯2: 我也會將一個請求的所有數據庫事務累加到1中,如果您確實必須執行清單,然後爲用戶獲取答案,請在同一事務中執行並保存行程。優化時的常用做法。

+0

我使用ASP.NET這就是爲什麼我標記它。我還標記了VB.Net和C#,但Adam刪除了這些。我對編碼感到滿意,因爲原理是一樣的。 – 2010-04-12 19:37:56

+0

感謝編輯 - 這聽起來很有趣,你有這樣的技術的例子嗎? – 2010-04-12 19:42:51

+0

應用[「my_questions」] =問題; – aepheus 2010-04-12 19:43:08

2

除非有使用數據庫的原因,否則您可以始終將結果存儲在服務器本身的平面文件中。這聽起來不像你存儲的數據是以任何方式關係的。最糟糕的是,你總是可以將它們作爲批處理作業插入到關係數據庫中。

另一種選擇是應用程序緩存。但是,如果您的Web服務器突然崩潰,則可能會丟失此處的信息。

您還可以將值存儲在用戶的Cookie中。

1

您的場景是Predictive Fetch Pattern的完美人選。我建議你緩存所有問題。當用戶登錄使用該模式來獲取前5個答案(如果他們已經給出了答案)並且基於他們的導航(他們當前的問題在哪裏)從Response對象或從DB獲取信息。

HTH

1

我想向你提供這就是所謂的Dom存儲,但因爲只有新的瀏覽器都支持它,它可以使用它在這一點上有問題HTML5的新特性。

使用DOM存儲,您可以將數據存儲在用戶瀏覽器中。由於它可以在Mozilla Firefox [3],Google Chrome和Opera中爲每個域存儲高達5MB的Internet Explorer中的每個存儲區10MB,因此您可以在DOM存儲中存儲答案和問題ID。

即使DOM存儲,更不用說數據庫命中,就可以降低服務器打爲好。

因爲我們都知道使用cookie的工作是麻煩有時,它可以存儲4KB,最簡單的方法,現在存儲鍵值信息在DOM存儲是。

您可以爲會議以及本地存儲具體鍵值信息。會話結束時,基於會話的信息將從瀏覽器中清除,但如果存儲基於本地的值,則即使用戶關閉了該選項卡,鍵值也會保留一段時間。

示例代碼:

<p> 
    You have viewed this page 
    <span id="count">an untold number of</span> 
    time(s). 
</p> 
<script> 
    var storage = window.localStorage; 
    if (!storage.pageLoadCount) storage.pageLoadCount = 0; 
    storage.pageLoadCount = parseInt(storage.pageLoadCount, 10) + 1; 
    document.getElementById('count').innerHTML = storage.pageLoadCount; 
</script> 

您可以瞭解更多有關DOM存儲從下面的鏈接:

2

根據我個人的經驗(每秒提供數千個簡短的調查頁面),我懷疑你的擔心是沒有根據的。除其他原因之外,DBMS會將您可以更有效地緩存這些少量數據。

我測試過這一點,加載問題和答案爲應用程序範圍收集在啓動時,之後,從內存中爲他們服務的 - 經常是沒有區別的。

你的選擇是一次發送給所有的瀏覽器,並將其保存爲JavaScript應用程序,存儲的數據(加密),餅乾和只命中數據庫時,整個事情是完成的。這是乏味但不難。

相關問題