其實我一直在準備另一篇博文的基礎資料,但是和朋友聊天,他問我最近在做什麼,我說在做系統Log模組,並和他交流了一下,於是這篇部落格就應運而生。
所有資料都可以用如下形式表述:ID,表名,列名,Value。
比如說現在有這麼一條資料要插入User表:
IDGuid,這裡為了方便理解用Int) |
Username |
Password |
Email |
1 |
CrazyJinn |
123456 |
CrazyJinn@W.C |
這一條記錄可以轉換為:
ID |
表名 |
列名 |
Value |
1 |
User |
Username |
CrazyJinn |
1 |
User |
Password |
123456 |
1 |
User |
Email |
CrazyJinn@W.C |
你可以在各種對靈活性要求高的地方看到這種設計,比如說在《我們該如何設計資料庫(三)》的留言中,就有園友提到了類似的設計。
當然,這種方式效率不是很高;不過可以把叢集索引加到表名上,然後非叢集索引加在列名上,再水平分割一下,如果你心情好,再做個讀寫分離,相信就非高並發、千萬資料量級的應用來說,理論上還是可以接受的。
好了,現在進入本文。
現在要做一個通用的Log模組。
既然是通用的,那就意味著靈活性要非常強,因為你不知道Log中要記錄的資料結構是如何的。
而且給我的需求有一個非常變態的地方:要有回退功能。不過這個我們先不去管他。
根據之前的討論,我們可以很容易設計出一張Log表。
ID |
表名 |
列名 |
Type(Create\Edit\Delete) |
Value |
最後修改時間 |
如果處理的全是無關係的問題,這樣做就足夠了。但是要知道,RDBMS,最重要的就是關係的處理。
比如說要Log這樣兩張表:
上文所設計出的Log表面對這樣的一對多關聯性是無法儲存的,不要往了,我們還有多對多關係。
當然可以拓展Log表來實現儲存一對多/多對多關係,雖然我不確定能不能做到,因為我沒有就這方面去深入的思考。如果您想到了好的設計,歡迎留言和我探討。
讓我們來重新思考一下Log模組的本質:
1、大量資料。
2、只是大量資料和別的模組沒有關聯,純粹的資料)。
這種情境讓我不由自主的想到了Nosql。在這裡,使用MongoDB來實現。關於MongoDB入門,可以參考下面兩篇文章:
祥叔:《MongoDB開發學習1)開天闢地,經典入門》
Fish Li:《MongoDB實戰開發 零基礎學習,附完整Asp.net樣本】》
MongoDB使用Bson來儲存資料,你可以簡單的把Bson理解為Json。眾所周知,Json是一個非常易於擴充的,鬆散的的資料格式;基於Json易於擴充的特性,我們可以這樣來設計Log表
LogID |
ID |
表名 |
Content所儲存的內容,包含了最後修改時間,修改類型,以及新的修改ID) |
如果我對User表修改了6次,那麼我們Log的資料如:
我們主要把注意力集中在用紅框標註的3條資料上。
第一條資料,ContactList是一個Array類型,長度為0,這表示沒有對應的Contact。
第二條資料,ContactList長度變為1,這表示這次修改為User添加了一個Contact的關聯,我們將第二條資料完全展開來看:
可以看到,包含了一個完整的Contact進來。