一、概念
昭平網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián),昭平網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為昭平成百上千家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站建設(shè)要多少錢,請(qǐng)找那個(gè)售后服務(wù)好的昭平做網(wǎng)站的公司定做!
SQL?(Structured?Query?Language)?數(shù)據(jù)庫,指關(guān)系型數(shù)據(jù)庫。主要代表:SQL?Server,Oracle,MySQL(開源),PostgreSQL(開源)。
NoSQL(Not?Only?SQL)泛指非關(guān)系型數(shù)據(jù)庫。主要代表:MongoDB,Redis,CouchDB。
二、區(qū)別
1、存儲(chǔ)方式
SQL數(shù)據(jù)存在特定結(jié)構(gòu)的表中;而NoSQL則更加靈活和可擴(kuò)展,存儲(chǔ)方式可以省是JSON文檔、哈希表或者其他方式。SQL通常以數(shù)據(jù)庫表形式存儲(chǔ)數(shù)據(jù)。舉個(gè)栗子,存?zhèn)€學(xué)生借書數(shù)據(jù):
而NoSQL存儲(chǔ)方式比較靈活,比如使用類JSON文件存儲(chǔ)上表中熊大的借閱數(shù)據(jù):
2、表/數(shù)據(jù)集合的數(shù)據(jù)的關(guān)系
在SQL中,必須定義好表和字段結(jié)構(gòu)后才能添加數(shù)據(jù),例如定義表的主鍵(primary?key),索引(index),觸發(fā)器(trigger),存儲(chǔ)過程(stored?procedure)等。表結(jié)構(gòu)可以在被定義之后更新,但是如果有比較大的結(jié)構(gòu)變更的話就會(huì)變得比較復(fù)雜。在NoSQL中,數(shù)據(jù)可以在任何時(shí)候任何地方添加,不需要先定義表。例如下面這段代碼會(huì)自動(dòng)創(chuàng)建一個(gè)新的"借閱表"數(shù)據(jù)集合:
NoSQL也可以在數(shù)據(jù)集中建立索引。以MongoDB為例,會(huì)自動(dòng)在數(shù)據(jù)集合創(chuàng)建后創(chuàng)建唯一值_id字段,這樣的話就可以在數(shù)據(jù)集創(chuàng)建后增加索引。
從這點(diǎn)來看,NoSQL可能更加適合初始化數(shù)據(jù)還不明確或者未定的項(xiàng)目中。
3、外部數(shù)據(jù)存儲(chǔ)
SQL中如何需要增加外部關(guān)聯(lián)數(shù)據(jù)的話,規(guī)范化做法是在原表中增加一個(gè)外鍵,關(guān)聯(lián)外部數(shù)據(jù)表。例如需要在借閱表中增加審核人信息,先建立一個(gè)審核人表:
再在原來的借閱人表中增加審核人外鍵:
這樣如果我們需要更新審核人個(gè)人信息的時(shí)候只需要更新審核人表而不需要對(duì)借閱人表做更新。而在NoSQL中除了這種規(guī)范化的外部數(shù)據(jù)表做法以外,我們還能用如下的非規(guī)范化方式把外部數(shù)據(jù)直接放到原數(shù)據(jù)集中,以提高查詢效率。缺點(diǎn)也比較明顯,更新審核人數(shù)據(jù)的時(shí)候?qū)?huì)比較麻煩。
4、SQL中的JOIN查詢
SQL中可以使用JOIN表鏈接方式將多個(gè)關(guān)系數(shù)據(jù)表中的數(shù)據(jù)用一條簡單的查詢語句查詢出來。NoSQL暫未提供類似JOIN的查詢方式對(duì)多個(gè)數(shù)據(jù)集中的數(shù)據(jù)做查詢。所以大部分NoSQL使用非規(guī)范化的數(shù)據(jù)存儲(chǔ)方式存儲(chǔ)數(shù)據(jù)。
5、數(shù)據(jù)耦合性
SQL中不允許刪除已經(jīng)被使用的外部數(shù)據(jù),例如審核人表中的"熊三"已經(jīng)被分配給了借閱人熊大,那么在審核人表中將不允許刪除熊三這條數(shù)據(jù),以保證數(shù)據(jù)完整性。而NoSQL中則沒有這種強(qiáng)耦合的概念,可以隨時(shí)刪除任何數(shù)據(jù)。
6、事務(wù)
SQL中如果多張表數(shù)據(jù)需要同批次被更新,即如果其中一張表更新失敗的話其他表也不能更新成功。這種場景可以通過事務(wù)來控制,可以在所有命令完成后再統(tǒng)一提交事務(wù)。而NoSQL中沒有事務(wù)這個(gè)概念,每一個(gè)數(shù)據(jù)集的操作都是原子級(jí)的。
7、增刪改查語法
8、查詢性能
在相同水平的系統(tǒng)設(shè)計(jì)的前提下,因?yàn)镹oSQL中省略了JOIN查詢的消耗,故理論上性能上是優(yōu)于SQL的。
nosql的操作的sql 的操作都是一樣的增刪改查,只是形式上有些差別,不一定是表格,像redis 就是鍵值對(duì)的方式
下文例子中演示了如何插入、獲取、刪除一條記錄
LevelDB 簡介
一、LevelDB入門
LevelDB是Google開源的持久化KV單機(jī)數(shù)據(jù)庫,具有很高的隨機(jī)寫,順序讀/寫性能,但是隨機(jī)讀的性能很一般,也就是說,LevelDB很適合應(yīng)用在查詢較少,而寫很多的場景。LevelDB應(yīng)用了LSM (Log Structured Merge) 策略,lsm_tree對(duì)索引變更進(jìn)行延遲及批量處理,并通過一種類似于歸并排序的方式高效地將更新遷移到磁盤,降低索引插入開銷,關(guān)于LSM,本文在后面也會(huì)簡單提及。
根據(jù)LevelDB官方網(wǎng)站的描述,LevelDB的特點(diǎn)和限制如下:
特點(diǎn):
1、key和value都是任意長度的字節(jié)數(shù)組;
2、entry(即一條K-V記錄)默認(rèn)是按照key的字典順序存儲(chǔ)的,當(dāng)然開發(fā)者也可以重載這個(gè)排序函數(shù);
3、提供的基本操作接口:Put()、Delete()、Get()、Batch();
4、支持批量操作以原子操作進(jìn)行;
5、可以創(chuàng)建數(shù)據(jù)全景的snapshot(快照),并允許在快照中查找數(shù)據(jù);
6、可以通過前向(或后向)迭代器遍歷數(shù)據(jù)(迭代器會(huì)隱含的創(chuàng)建一個(gè)snapshot);
7、自動(dòng)使用Snappy壓縮數(shù)據(jù);
8、可移植性;
限制:
1、非關(guān)系型數(shù)據(jù)模型(NoSQL),不支持sql語句,也不支持索引;
2、一次只允許一個(gè)進(jìn)程訪問一個(gè)特定的數(shù)據(jù)庫;
3、沒有內(nèi)置的C/S架構(gòu),但開發(fā)者可以使用LevelDB庫自己封裝一個(gè)server;
LevelDB本身只是一個(gè)lib庫,在源碼目錄make編譯即可,然后在我們的應(yīng)用程序里面可以直接include leveldb/include/db.h頭文件,該頭文件有幾個(gè)基本的數(shù)據(jù)庫操作接口,下面是一個(gè)測試?yán)樱?/p>
#include iostream
#include string
#include assert.h
#include "leveldb/db.h"
using namespace std;
int main(void)
{
leveldb::DB *db;
leveldb::Options options;
options.create_if_missing = true;
// open
leveldb::Status status = leveldb::DB::Open(options,"/tmp/testdb", db);
assert(status.ok());
string key = "name";
string value = "chenqi";
// write
status = db-Put(leveldb::WriteOptions(), key, value);
assert(status.ok());
// read
status = db-Get(leveldb::ReadOptions(), key, value);
assert(status.ok());
coutvalueendl;
// delete
status = db-Delete(leveldb::WriteOptions(), key);
assert(status.ok());
status = db-Get(leveldb::ReadOptions(),key, value);
if(!status.ok()) {
cerrkey" "status.ToString()endl;
} else {
coutkey"==="valueendl;
}
// close
delete db;
return 0;
}
上面的例子演示了如何插入、獲取、刪除一條記錄,編譯代碼:
g++ -o test test.cpp libleveldb.a -lpthread -Iinclude
執(zhí)行./test后,會(huì)在/tmp下面生成一個(gè)目錄testdb,里面包含若干文件:
------------------------------------------------------------
LevelDB是google開源的一個(gè)key-value存儲(chǔ)引擎庫,類似于開源的Lucene索引庫一樣。其他的軟件開發(fā)者可以利用該庫做二次開發(fā),來滿足定制需求。LevelDB采用日志式的寫方式來提高寫性能,但是犧牲了部分讀性能。為了彌補(bǔ)犧牲了的讀性能,一些人提議使用SSD作為存儲(chǔ)介質(zhì)。
對(duì)于本地化的Key-value存儲(chǔ)引擎來說,簡單的使用一般都分成三個(gè)基本的步驟:(1)打開一個(gè)數(shù)據(jù)庫實(shí)例;(2)對(duì)這個(gè)數(shù)據(jù)庫實(shí)例進(jìn)行插入,修改和查詢操作;(3)最后在使用完成之后,關(guān)閉該數(shù)據(jù)庫。下面將詳細(xì)討論該三個(gè)步驟:
一、打開一個(gè)數(shù)據(jù)庫實(shí)例
一個(gè)leveldb數(shù)據(jù)庫有一個(gè)對(duì)應(yīng)一個(gè)文件系統(tǒng)目錄的名字。該數(shù)據(jù)庫的所有內(nèi)容都存儲(chǔ)在這個(gè)目錄下。下面的代碼描述了怎樣打開一個(gè)數(shù)據(jù)庫或者建立一個(gè)新的數(shù)據(jù)庫。
#include assert.h
#include "leveldb/db.h"
leveldb::DB* db;
leveldb::Options options;
options.create_if_missing = true;
leveldb::Status status = leveldb::DB::Open(options,"/tmp/testdb", db);
assert(status.ok());
如果打開已存在數(shù)據(jù)庫的時(shí)候,需要拋出錯(cuò)誤。將以下代碼插在leveldb::DB::Open方法前面:
options.error_if_exists = true;
二、對(duì)數(shù)據(jù)庫的簡單讀、寫操作
LevelDB提供了Put,Delete和Get三個(gè)方法對(duì)數(shù)據(jù)庫進(jìn)行修改和查詢。例如,下面的代碼片段描述了怎樣將key1對(duì)應(yīng)的value值,移到key2對(duì)應(yīng)的值。
std::string value;
leveldb::Status s = db-Get(leveldb::ReadOptions(), key1, value);
if(s.ok()) s = db-Put(leveldb::WriteOptions(), key2, value);
if(s.ok()) s = db-Delete(leveldb::WriteOptions(), key1);
三、關(guān)閉數(shù)據(jù)庫
在對(duì)數(shù)據(jù)庫進(jìn)行了一系列的操作之后,需要對(duì)數(shù)據(jù)庫進(jìn)行關(guān)閉。該操作比較簡單:
... open the db as described above...
... do something with db ...
delete db;
上面對(duì)levelDB的簡單使用做了基本的介紹,接下來就是如何自己寫一個(gè)完成并且能運(yùn)行的例子。
1、下載源碼 git clone
2、編譯源碼 cd leveldb make all
3、編寫test.cpp
#include assert.h
#include string.h
#include leveldb/db.h
#include iostream
int main(){
leveldb::DB* db;
leveldb::Options options;
options.create_if_missing = true;
leveldb::Status status = leveldb::DB::Open(options,"/tmp/testdb", db);
assert(status.ok());
//write key1,value1
std::string key="key";
std::string value = "value";
status = db-Put(leveldb::WriteOptions(), key,value);
assert(status.ok());
status = db-Get(leveldb::ReadOptions(), key, value);
assert(status.ok());
std::coutvaluestd::endl;
std::string key2 = "key2";
//move the value under key to key2
status = db-Put(leveldb::WriteOptions(),key2,value);
assert(status.ok());
status = db-Delete(leveldb::WriteOptions(), key);
assert(status.ok());
status = db-Get(leveldb::ReadOptions(),key2, value);
assert(status.ok());
std::coutkey2"==="valuestd::endl;
status = db-Get(leveldb::ReadOptions(),key, value);
if(!status.ok()) std::cerrkey" "status.ToString()std::endl;
else std::coutkey"==="valuestd::endl;
delete db;
return 0;
}
4、編譯鏈接 g++ -o test test.cpp ../leveldb/libleveldb.a -lpthread -I../leveldb/include
注意libleveldb.a 和leveldb include的路徑。
5、運(yùn)行結(jié)果./test:
value
key2===value
key NotFound:
sql增刪改查基本語法如下:
1、“INSERT?INTO”語句,用于向表格中增加新的行。
2、“DELETE”語句,用于刪除表中的行。
3、“Update”語句,用于修改表中的數(shù)據(jù)。
4、“SELECT”語句,用于從表中選取數(shù)據(jù)。
sql語言特點(diǎn):
SQL可以獨(dú)立完成數(shù)據(jù)庫生命周期中的全部活動(dòng),包括定義關(guān)系模式、錄入數(shù)據(jù)、建立數(shù)據(jù)庫、查詢、更新、維護(hù)、數(shù)據(jù)庫重構(gòu)、數(shù)據(jù)庫安全性控制等一系列操作,這就為數(shù)據(jù)庫應(yīng)用系統(tǒng)開發(fā)提供了良好的環(huán)境,在數(shù)據(jù)庫投入運(yùn)行后,還可根據(jù)需要隨時(shí)逐步修改模式,且不影響數(shù)據(jù)庫的運(yùn)行,從而使系統(tǒng)具有良好的可擴(kuò)充性。
package basic;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBC {
public void findAll() {
try {
// 獲得數(shù)據(jù)庫驅(qū)動(dòng)
//由于長時(shí)間不寫,驅(qū)動(dòng)名和URL都忘記了,不知道對(duì)不對(duì),你應(yīng)該知道的,自己改一下的哈
String url = "jdbc:oracle:thin:@localhost:1521:XE";
String userName = "system";
String password = "system";
Class.forName("oracle.jdbc.driver.OracleDriver");
// 創(chuàng)建連接
Connection conn = DriverManager.getConnection(url, userName,
password);
// 新建發(fā)送sql語句的對(duì)象
Statement st = conn.createStatement();
// 執(zhí)行sql
String sql = "select * from users";
ResultSet rs = st.executeQuery(sql);
// 處理結(jié)果
while(rs.next()){
//這個(gè)地方就是給你的封裝類屬性賦值
System.out.println("UserName:"+rs.getString(0));
}
// 關(guān)閉連接
rs.close();
st.close();
conn.close();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void delete(){
try {
//步驟還是那六個(gè)步驟,前邊的兩步是一樣的
String url = "jdbc:oracle:thin:@localhost:1521:XE";
String userName = "system";
String password = "system";
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn = DriverManager.getConnection(url,userName,password);
//這里的發(fā)送sql語句的對(duì)象是PreparedStatement,成為預(yù)處理sql對(duì)象,因?yàn)榘礂l件刪除是需要不定值的
String sql = "delete from users where id = ?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(0, 1);
int row = ps.executeUpdate();
if(row!=0){
System.out.println("刪除成功!");
}
// 關(guān)閉連接
rs.close();
st.close();
conn.close();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
NoSQL數(shù)據(jù)庫有很多種,實(shí)現(xiàn)方式差別很大。有接近SQL查詢方式的,也有純粹的鍵值對(duì)查詢。
對(duì)于K-V型數(shù)據(jù)庫,比較典型的是Redis,系統(tǒng)提供了get、set之類的命令用于增刪改查。關(guān)鍵是鍵值對(duì)的鍵和值怎么設(shè)計(jì)。
當(dāng)前標(biāo)題:nosql增刪查改的簡單介紹
URL網(wǎng)址:http://chinadenli.net/article42/dsshghc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供小程序開發(fā)、標(biāo)簽優(yōu)化、手機(jī)網(wǎng)站建設(shè)、定制開發(fā)、建站公司、網(wǎng)站策劃
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)