做了一年的大一年度項目了,對于關(guān)系型數(shù)據(jù)庫結(jié)構(gòu)還是有些了解了,有的時候還是覺得這種二維表不是很順手。在看過一篇文章之后,對NoSQL有了初步的了解,(https://keen.io/blog/53958349217/analytics-for-hackers-how-to-think-about-event-data)。這篇文章寫的很好,確實寫出來了在實際情況下NoSQL的“用武之地”,而且用了MineCraft作分析,但是也許不夠全面。比如文章中只是提到了,entity數(shù)據(jù)用關(guān)系型怎么存,event數(shù)據(jù)用NoSQL怎么存,我想借我這篇文章,來分析一下event類型的數(shù)據(jù)原始的關(guān)系型數(shù)據(jù)庫是怎樣存數(shù)據(jù)的,然后再對這兩種儲存方式做一種對比,算是對原文都一種補充吧。
對于這種死亡事件,有這樣的兩條數(shù)據(jù),一個是關(guān)于creeper的爆炸,一種是掉進巖漿。如果必須用關(guān)系型二維表數(shù)據(jù)庫,我會這樣存儲。(如果您還不知道是什么樣的數(shù)據(jù),可以先看之后的NoSQL儲存方法,那樣看起來更清楚。)
這種情況的數(shù)據(jù)可以說是數(shù)據(jù)庫設(shè)計中比較復(fù)雜的一種情況了,因為它包含兩種情況(當然不止這兩種情況,那么就會產(chǎn)生更多的結(jié)構(gòu)),不同情況的數(shù)據(jù)表結(jié)構(gòu)是不同的,這非常麻煩。我們一般的解決方案是設(shè)計四個表格,利用關(guān)系型數(shù)據(jù)庫的關(guān)系性。設(shè)計如下四張表格。(在這里我就簡寫了)
第一張表
id #首先用于關(guān)聯(lián),主表需要有個id,這個倒不是什么區(qū)別,因為NoSQL一般也會有個_id的預(yù)設(shè)
timestamp #所有共同部分就可以存在一張表中。
cause
player_UID
player_experience
player_age #對于player_inveneory_id 因為這是一個可以任意長度的數(shù)組,又只能保存在另一個表中了
第二張表(用于保存creeper死亡方式的死亡事件的)
id #這是這張表的id以后可以跟別的表格關(guān)聯(lián)
mid #用于關(guān)聯(lián)主表
enemy_type
enemy_power
enemy_distance
enemy_age
第三張表(用于保存lava死亡方式的死亡事件的)
id #這是這張表的id以后可以跟別的表格關(guān)聯(lián)
mid #用于關(guān)聯(lián)主表
place_x
place_y
place_z
第四張表(用于保存player_inveneory)
id #這是這張表的id以后可以跟別的表格關(guān)聯(lián)
mid #用于關(guān)聯(lián)主表
inveneory
至此關(guān)系性數(shù)據(jù)庫就將這種有不同結(jié)構(gòu)的事件存放方式規(guī)定好了,接下來存放如下(我就不畫表格了)
1.
id timestamp cause player_UID player_experience player_age
1 "2013-05-23T1:50:00-0600" "creeper" "99234890823" 8873729 228
2 "2013-05-24T23:25:00-0600" "lava" "99234890823" 88737 22
2.
id mid enemy_type enemy_power enemy_distance enemy_age
1 1 "creeper" .887 3.34 .6677
3.
id mid place_x place_y place_z
1 2 45.366 -13.333 -39.288
4.
id mid inveneory
1 1 "diamend sword"
2 1 "torches"
3 2 "stone"
至此,我們就用關(guān)系性數(shù)據(jù)庫將這兩個事件數(shù)據(jù)存下了。(好麻煩是吧?。?/p>
我們再看NoSQL的儲存方法,因為每條數(shù)據(jù)并不受字段(列名)限制,完全可以直接保存,不用分表。(比如JSON格式)
#第一條數(shù)據(jù)
{
"timestamp": "2013-05-23T1:50:00-0600",
"cause":"creeper",
"enemy":{
"type":"creeper"
"power": .887
"distance_from_player":3.34
"age":.6677
},
"player": {
"UID":"99234890823",
"experience": 8873729,
"age": 228,
"inveneory":["diamend sword","torches"]
}
}
#第二條數(shù)據(jù)
{
"timestamp": "2013-05-24T23:25:00-0600",
"cause":"lava",
"place":{
x:45.366
y:-13.333
z:-39.288
}
"player": {
"UID":"99234890823",
"experience": 88737,
"age": 22,
"inveneory":["stone"]
}
}
下面我們分析NoSQL對這種數(shù)據(jù)存放方式的好處
1.首先是把分散的表結(jié)構(gòu)整合了,讓應(yīng)該在一起的數(shù)據(jù)在一起了。
這就像C語言中開多個數(shù)組儲存還是用一個結(jié)構(gòu)體數(shù)組的區(qū)別,將一些有關(guān)系的數(shù)據(jù)放在一起是人類一種自然的想法,當然會讓人更加舒服,而且可以提高關(guān)聯(lián)性和升級擴展的簡易程度。
2.存放變得方便
讓我們來考慮有數(shù)據(jù)來了我們怎么儲存。
對于二維表數(shù)據(jù)庫:
1.分析數(shù)據(jù)是那種類型的
2.存放主表數(shù)據(jù),并獲得返回id
3.分支,加上主表id在不同情況下向lava或creeper表中存放數(shù)據(jù)
4.開循環(huán),向inveneory表中插入多條記錄
這還只是一個簡述,還要考慮到對多個表格操作時的數(shù)據(jù)回滾問題,實際寫起來30行左右,那么出錯的可能就大大提高了。
對于NoSQL類型
一句話:
insert(data);#偽碼
其實想想便知道,取數(shù)據(jù)時原來的關(guān)系性數(shù)據(jù)庫也會同樣麻煩。
3.NoSQL更利于動態(tài)生成存放方式,靈活性高了很多,至少我們可以在存放數(shù)據(jù)的時候再設(shè)計數(shù)據(jù)庫了(雖然可能預(yù)先設(shè)計會好一些)
當然,如果存儲的不是事件性或者類似此類數(shù)據(jù)那么就另當別論了,二維表還是有很多它本身的優(yōu)勢的。以上是我的一些個人的分析,當然還有很多普遍認同的觀點,以下是一些普遍認同的關(guān)于兩種數(shù)據(jù)庫模式的優(yōu)缺點分析,我也基本同意。
關(guān)系性優(yōu)勢:
1.事務(wù)處理---保持數(shù)據(jù)的一致性;
2.由于以標準化為前提,數(shù)據(jù)更新的開銷很?。ㄏ嗤淖侄位旧现挥幸惶帲?;
3.可以進行Join等復(fù)雜查詢。
關(guān)系型缺點:
1. 擴展困難:由于存在類似Join這樣多表查詢機制,使得數(shù)據(jù)庫在擴展方面很艱難;
2. 讀寫慢:這種情況主要發(fā)生在數(shù)據(jù)量達到一定規(guī)模時由于關(guān)系型數(shù)據(jù)庫的系統(tǒng)邏輯非常復(fù)雜,使得其非常容易發(fā)生死鎖等的并發(fā)問題,所以導(dǎo)致其讀寫速度下滑非常嚴重;
3. 成本高:企業(yè)級數(shù)據(jù)庫的License價格很驚人,并且隨著系統(tǒng)的規(guī)模,而不斷上升;
4. 有限的支撐容量:現(xiàn)有關(guān)系型解決方案還無法支撐Google這樣海量的數(shù)據(jù)存儲;
NoSQL優(yōu)勢,主要體現(xiàn)在下面幾點:
1. 簡單的擴展:典型例子是Cassandra,由于其架構(gòu)是類似于經(jīng)典的P2P,所以能通過輕松地添加新的節(jié)點來擴展這個集群;
2. 快速的讀寫:主要例子有Redis,由于其邏輯簡單,而且純內(nèi)存操作,使得其性能非常出色,單節(jié)點每秒可以處理超過10萬次讀寫操作;
3. 低廉的成本:這是大多數(shù)分布式數(shù)據(jù)庫共有的特點,因為主要都是開源軟件,沒有昂貴的License成本;
NoSQL數(shù)據(jù)庫還存在著很多的不足,常見主要有下面這幾個:
1. 不提供對SQL的支持:如果不支持SQL這樣的工業(yè)標準,將會對用戶產(chǎn)生一定的學(xué)習和應(yīng)用遷移成本;
2. 支持的特性不夠豐富:現(xiàn)有產(chǎn)品所提供的功能都比較有限,大多數(shù)NoSQL數(shù)據(jù)庫都不支持事務(wù),也不像MS SQL Server和Oracle那樣能提供各種附加功能,比如BI和報表等;
3. 現(xiàn)有產(chǎn)品的不夠成熟:大多數(shù)產(chǎn)品都還處于初創(chuàng)期,和關(guān)系型數(shù)據(jù)庫幾十年的完善不可同日而語;
您可能感興趣的文章:- Android設(shè)備之間通過Wifi通信的示例代碼
- Linux系統(tǒng)安裝NoSQL(MongoDB和Redis)步驟及問題解決辦法(總結(jié)篇)
- 大數(shù)據(jù)時代的數(shù)據(jù)庫選擇:SQL還是NoSQL?
- 建立在Tablestore的Wifi設(shè)備監(jiān)管系統(tǒng)架構(gòu)實現(xiàn)