1、關系型數據庫和非關系型數據庫
一致性: 事務完成時,必須讓所有的數據具有一致的狀態,例如要寫入100個數據,前99個成功了,結果第100個不合法,此時事務會回滾到最初狀態。這樣保證事務結束和開始時候的存儲數據處於一致狀態。
關系型數據庫: 一致性要求高,讀寫性能低,使用通用sql
非關系型數據庫:靈活,key-value的形式,讀寫性能好,數據結構不固定
2、事務,ACID特性
事務:指對數據庫一個序列上的操作,比如先執行插入,再執行更改,兩個操作按順序執行, 要么都執行,要么都不執行。
ACID特性:
原子性(Atomicity):事務中的所有操作作為一個整體提交或回滾。
一致性(Consistemcy):事物完成時,數據必須是一致的,以保證數據的無損。
隔離性(Isolation):對數據進行修改的多個事務是彼此隔離的。
持久性(Durability):事務完成之后,它對於系統的影響是永久的,該修改即使出現系統故障也將一直保留。
3、數據庫中的游標
是處理數據的一種方法,為了查看或者處理結果集中的數據,游標提供了在結果集中一次一行或者多行前進或向后瀏覽數據的能力(向后或向前瀏覽數據,結果集可以是表,也可以是索引)
4、數據庫中鎖機制的概念
執行多線程時強制限制資源訪問, 比如兩個用戶同時對數據庫進行更改操作,到底是該執行誰的命令,這時候就有鎖的概念.
5、索引
索引是對數據庫表中一列或多列的值進行排序的一種結構,使用索引可快速訪問數據庫表中的特定信息。(在數據庫中按照某個字段(或多個)按值排序的一種結構,然后按值查找,主要能實現快速查找和定位)
開始學習indexDB
1、indexDB的誕生:
IndexedDB 就是瀏覽器提供的本地非關系型數據庫,它可以被網頁腳本創建和操作,允許存儲大量數據,提供查找和建立索引等功能
2、indexDB的特點
1、非關系型數據庫(NoSQL)
2、key-value形式存儲
3、異步 注意localStorage是同步的
4、支持事務,索引、游標
5、同源限制
6、存儲空間大 250M+
7、支持存儲二進制
8、提供查找接口和能夠建立索引
同源 異步 支持事務 、索引...
3、基本概念
1、數據庫
2、對象倉庫 相當於關系型數據庫中的表
3、數據記錄 相當於表中的每一條記錄
4、索引 為了加速數據的檢索,可以在對象倉庫里面,為不同的屬性建立索引。
5、事務
4、基本使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
#btn,#update,#get{
line-height: 30px;
font-size: 16px;
color: #fff;
background-color: blue;
padding: 0 30px;
}
</style>
</head>
<body>
<button id="btn">添加數據</button>
<button id="update">更新數據</button>
<button id="get">獲取數據</button>
<script>
//異步的處理方式是回調,可以用promise改寫,也可以寫一個發布訂閱模式
var indexDB = {
db: null,
dbName: "",
objectStoreList: [],
init: function (dbName, objectStoreList) {
this.dbName = dbName;
this.objectStoreList = objectStoreList.slice(0);
this.openDB(dbName);
},
openDB: function (name, version) {
var _this = this;
version = version ? version : 1;//version不能為0
var request = window.indexedDB.open(name, version);
request.onerror = function (e) {
console.log(e.currentTarget.error.message);
}
request.onsuccess = function (e) {
_this.db = e.target.result;
console.log("DB " + name + " created");
}
request.onupgradeneeded = function (e) {
//創建objectStore(也就是表)
var db = e.target.result;
if (_this.objectStoreList.length != 0){
for(var i = 0; i < _this.objectStoreList.length; i++){
var item = _this.objectStoreList[i];
if (!db.objectStoreNames.contains(item.name)) {
//keyPath 鍵值 (也就是用哪一個字段做鍵)
var store = db.createObjectStore(item.name, { keyPath: item.keyPath });
//建立索引
if (item.index && item.index.length !== 0){
for (var j = 0; j < item.index.length; j++){
var innerItem = item.index[j];
console.log(innerItem);
store.createIndex(innerItem.name, innerItem.key, innerItem.property);
}
}
}
}
}
console.log('DB version changed to ' + version);
}
},
closeDB: function () {
if (this.db){
this.db.close();
}
},
deleteDB: function (){
if (this.dbName){
window.indexedDB.deleteDatabase(this.dbName);
}
else{
console.log("no such DB");
}
},
//清除某個objectStore的數據
clearObjectStore: function(storeName) {
var transaction = this.db.transaction(storeName, 'readwrite');
var store = transaction.objectStore(storeName);
store.clear();
},
deleteObjectStore: function (storeName){
if (db.objectStoreNames.contains(storeName)) {
db.deleteObjectStore(storeName);
}
},
//以下方法為對數據的增刪改查
addData: function (storeName, data) {
if (!Array.isArray(data)){
console.error("data must be array");
return;
}
//添加數據需要用到事務
var transaction = this.db.transaction(storeName, 'readwrite');
var store = transaction.objectStore(storeName);
for (var i = 0; i < data.length; i++) {
store.add(data[i]);
}
console.log("inserted!");
},
getDataByKey: function(storeName, key, callback) {
var transaction = this.db.transaction(storeName, 'readwrite');
var store = transaction.objectStore(storeName);
var request = store.get(key);
var _this = this;
request.onsuccess = function (e) {
var result = e.target.result;
if (typeof callback === "function"){
callback.call(_this, result);
}
};
},
updateDataByKey: function(storeName, key, data) {
var transaction = this.db.transaction(storeName, 'readwrite');
var store = transaction.objectStore(storeName);
var _this = this;
var request = store.get(key);
var _this = this;
request.onsuccess = function (e) {
var result = e.target.result;
result = Object.assign(result, data);
store.put(result);
}
console.log("updated!");
},
deleteDataByKey: function (storeName, key) {
var transaction = this.db.transaction(storeName, 'readwrite');
var store = transaction.objectStore(storeName);
store.delete(key);
},
//關於索引和游標的使用,需要在建表的時候建立索引
//下面利用index獲取數據
//參數: objectStore indexName value(要查找的值) callback
getDataByIndex: function (storeName, indexName, value, callback) {
var transaction = this.db.transaction(storeName);
var store = transaction.objectStore(storeName);
var index = store.index(indexName);
var _this = this;
index.get(value).onsuccess = function (e) {
var result = e.target.result;
if (typeof callback === "function"){
callback.call(_this, result);
}
}
},
//利用游標遍歷
getMultipleDataByIndex(storeName, indexName, value, callback) {
var transaction = this.db.transaction(storeName);
var store = transaction.objectStore(storeName);
var index = store.index(indexName);
var request = index.openCursor(IDBKeyRange.only(value))
var values = [], _this = this;
request.onsuccess = function (e) {
var cursor = e.target.result;
if (cursor) {
var value = cursor.value;
//這里是遍歷體
values.push(value);
cursor.continue();
}
else{
if (typeof callback === "function") {
callback.call(_this, values);
}
}
}
}
}
var btn = document.getElementById("btn");
indexDB.init("testDB", [
{
name: "students",
keyPath: "id",
//索引信息
index: [
{name: "nameIndex", key: "name", property: {unique: true}},
{ name: "ageIndex", key: "age", property: { unique: false}}
]
},
{
name: "employees",
keyPath: "id",
}
]);//創建一個數據庫和多張objectStore(表)。
//添加數據
btn.onclick = function (e) {
var students = [{
id: 1001,
name: "Byron",
age: 24
}, {
id: 1002,
name: "Frank",
age: 30
}, {
id: 1003,
name: "Aaron",
age: 26
}, {
id: 1004,
name: "Aaron2",
age: 26
}];
indexDB.addData("students", students);
}
document.getElementById("get").onclick = function (e) {
indexDB.getDataByKey("students", 1001, function (result) {
// console.log(this.db); this指向indexDB
console.log(result);
});
//通過索引拿數據
//在 索引名為 nameIndex中尋找 "Frank"
//參數: objectStore indexName value(要查找的值) callback
indexDB.getDataByIndex("students", "nameIndex", "Frank", function (result) {
console.log(result);
})
//游標遍歷索引
indexDB.getMultipleDataByIndex("students", "ageIndex", 26, function (result) {
//這里可以獲取兩條數據
console.log(result);
})
}
document.getElementById("update").onclick = function (e) {
indexDB.updateDataByKey("students", 1001, {age: 19});
indexDB.deleteDataByKey("students", 1003);
}
</script>
</body>
</html>
應用場景
前端處理大量結構化的數據