第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

web 數(shù)據(jù)庫

之前的章節(jié)有討論過 web 中的存儲方式,包括傳統(tǒng)的 cookie 和新的 localstorage,這兩種方式實現(xiàn)了 HTML 中的離線存儲,但是存儲方式比較簡單,在有些復(fù)雜的業(yè)務(wù)場景可能不能滿足條件。本章我們介紹一個計算機(jī)中一個重要的學(xué)科數(shù)據(jù)庫,以及它在 HTML5 中的支持。數(shù)據(jù)庫是一個內(nèi)容龐大的知識體系,本章只介紹一些簡單的用法以及它在 HTML 中的適用場景。

1. 適用場景

既然適用 localstorage 也可以做簡單的數(shù)據(jù)存儲,那么為什么還需要適用數(shù)據(jù)庫呢?假設(shè)一個業(yè)務(wù)場景中將所有用戶信息臨時存儲到瀏覽器中,這些信息包括昵稱、姓名、性別等,現(xiàn)在需要搜索出性別是男的所有用戶。如果使用 localstorage 的話,需要將所有的數(shù)據(jù)提取出來,一條條遍歷,得出結(jié)果。這樣的搜索算法的時間復(fù)雜度是 O(n),性能較差。如果使用數(shù)據(jù)庫存儲的話,只需要給性別列加上索引,然后使用 SQL 搜索,時間復(fù)雜度是 O(lgn),性能提升了一個等量級。關(guān)系型數(shù)據(jù)庫的特點是:

  • 數(shù)據(jù)模型基于關(guān)系,結(jié)構(gòu)化存儲,完整性約束;
  • 支持事務(wù),數(shù)據(jù)一致性;
  • 支持 SQL,可以復(fù)雜查詢;

缺點是:

  • SQL 解析會影響性能;
  • 無法適應(yīng)非結(jié)構(gòu)化存儲;
  • 橫向擴(kuò)展代價高;
  • 入門門檻較高。

2. Web SQL

Web SQL不是 HTML5 標(biāo)準(zhǔn)中的一部分,它是一個獨立的規(guī)范,引入了 SQL 的 api,關(guān)于 SQL 的語法可以參考第三方的教程,在此不做解釋。Web SQL 有 3 個函數(shù)

2.1 openDatabase

這個函數(shù)用于打開一個數(shù)據(jù)庫,如果數(shù)據(jù)庫不存在就創(chuàng)建。它有 5 個參數(shù),分別表示:

  • 數(shù)據(jù)庫名稱;
  • 版本號;
  • 數(shù)據(jù)庫備注;
  • 初始化數(shù)據(jù)大小;
  • 創(chuàng)建/打開成功回調(diào)函數(shù)
/**
     * 創(chuàng)建數(shù)據(jù)庫 或者此數(shù)據(jù)庫已經(jīng)存在 那么就是打開數(shù)據(jù)庫
     * name: 數(shù)據(jù)庫名稱
     * version: 版本號
     * displayName: 對數(shù)據(jù)庫的描述
     * estimatedSize: 設(shè)置數(shù)據(jù)的大小
     * creationCallback: 回調(diào)函數(shù)(可省略)
     */
    var db = openDatabase("MySql", "1.0", "數(shù)據(jù)庫描述", 1024 * 1024);

2.2 transaction

這個函數(shù)使用事務(wù)執(zhí)行 SQL 語句,它是一個閉包,例如:

dataBase.transaction( function(tx) { 
    tx.executeSql(
    "create table if not exists test (id REAL UNIQUE, name TEXT)", 
    [],
    function(tx,result){ alert('創(chuàng)建test表成功'); }, 
    function(tx, error){ alert('創(chuàng)建test表失敗:' + error.message); 
    });
});

2.3 executeSql

這個方法用于執(zhí)行 SQL 語句。

tx.executeSql(
"update stu set name = ? where id= ?",
[name, id],
function (tx, result) {
},
function (tx, error) {
alert('更新失敗: ' + error.message);
});
});

3. indexedDB

IndexedDB 是 HTML5 規(guī)范里新出現(xiàn)的瀏覽器里內(nèi)置的數(shù)據(jù)庫。它提供了類似數(shù)據(jù)庫風(fēng)格的數(shù)據(jù)存儲和使用方式。存儲在 IndexedDB 里的數(shù)據(jù)是永久保存,不像 cookies 那樣只是臨時的。IndexedDB 里提供了查詢數(shù)據(jù)的功能,在線和離線模式下都能使用。

3.1 對比 Web SQL

跟 WebSQL 不同的是,IndexedDB 更像是一個 NoSQL 數(shù)據(jù)庫,而 WebSQL 更像是關(guān)系型數(shù)據(jù)庫。

3.2 判斷瀏覽器是否支持


window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
if(!window.indexedDB){
    console.log("你的瀏覽器不支持IndexedDB");
}

3.3 創(chuàng)建庫

使用 open 方法創(chuàng)建數(shù)據(jù)庫。

 var request = window.indexedDB.open("testDB", 2);//第一個參數(shù)是數(shù)據(jù)庫的名稱,第二個參數(shù)是數(shù)據(jù)庫的版本號。版本號可以在升級數(shù)據(jù)庫時用來調(diào)整數(shù)據(jù)庫結(jié)構(gòu)和數(shù)據(jù)
 request.onsuccess = function(event){
    console.log("成功打開DB");
 }//成功之后的回調(diào)函數(shù)

3.4 添加數(shù)據(jù)

var transaction = db.transaction(["students"],"readwrite");//先創(chuàng)建事務(wù),具有讀寫權(quán)限
transaction.oncomplete = function(event) {
    console.log("Success");
};
transaction.onerror = function(event) {
    console.log("Error");
};  
var test = transaction.objectStore("test");
test.add({rollNo: rollNo, name: name});//添加數(shù)據(jù)

3.5 查詢

var request = db.transaction(["test"],"readwrite").objectStore("test").get(rollNo);//創(chuàng)建具備讀寫功能的事務(wù)
request.onsuccess = function(event){
    console.log("結(jié)果 : "+request.result.name);    
};//成功查詢的回調(diào)函數(shù)

3.6 修改


var transaction = db.transaction(["test"],"readwrite");//創(chuàng)建事務(wù)
var objectStore = transaction.objectStore("test");
var request = objectStore.get(rollNo);
request.onsuccess = function(event){
    console.log("Updating : "+request.result.name + " to " + name);
    request.result.name = name;//修改數(shù)據(jù)
    objectStore.put(request.result);//執(zhí)行修改
};

3.7 刪除

//創(chuàng)建事務(wù),并刪除數(shù)據(jù)
db.transaction(["students"],"readwrite").objectStore("students").delete(rollNo);

4. 實際項目應(yīng)用

實例演示
預(yù)覽 復(fù)制
復(fù)制成功!
<!DOCTYPE html>
<html>
    <head lang="en">
        <meta charset="UTF-8">
        <title>離線記事本</title>
        <meta name="viewport" content="width=device-width,initial-scale=1">
        <link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" />
        <script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
        <script src="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script><!-- 引用jQuery插件 -->
    </head>
    <script>
var datatable = null;
var db = openDatabase("note", "", "notebook", 1024 * 100);
//初始化函數(shù)方法
function init() {
    datatable = document.getElementById("datatable");
    showAllData();
}
function removeAllData() {
    for(var i = datatable.childNodes.length - 1; i >= 0; i--) {
        datatable.removeChild(datatable.childNodes[i]);
    }
    var tr = document.createElement("tr");
    var th1 = document.createElement("th");
    var th2 = document.createElement("th");
    var th3 = document.createElement("th");
    th1.innerHTML = "標(biāo)題";
    th2.innerHTML = "內(nèi)容";
    th3.innerHTML = "時間";
    tr.appendChild(th1);
    tr.appendChild(th2);
    tr.appendChild(th3);
    datatable.appendChild(tr);
}
//顯示數(shù)據(jù)庫中的數(shù)據(jù)
function showData(row) {
    var tr = document.createElement("tr");
    var td1 = document.createElement("td");
    td1.innerHTML = row.title;
    var td2 = document.createElement("td");
    td2.innerHTML = row.content;
    var td3 = document.createElement("td");
    var t = new Date();
    t.setTime(row.time);
    td3.innerHTML = t.toLocaleDateString() + " " + t.toLocaleTimeString();
    tr.appendChild(td1);
    tr.appendChild(td2);
    tr.appendChild(td3);
    datatable.appendChild(tr);
}
//顯示所有的數(shù)據(jù)
function showAllData() {
    db.transaction(function(tx) {
        tx.executeSql("CREATE TABLE IF NOT EXISTS item(title TEXT,content TEXT,time INTEGER)", []);
        tx.executeSql("SELECT * FROM item", [], function(tx, rs) {
            removeAllData();
            for(var i = 0; i < rs.rows.length; i++) {
                showData(rs.rows.item(i))
            }
        })
    })
}
//添加一條記事本數(shù)據(jù)
function addData(title, content, time) {
    db.transaction(function(tx) {
        tx.executeSql("INSERT INTO item VALUES (?,?,?)", [title, content, time], function(tx, rs) {
                alert("保存成功!");
            },
            function(tx, error) {
                alert(error.source + "::" + error.message);
            }
    )
    })
}
//點擊保存按鈕
function saveData() {
    var title = document.getElementById("name").value;
    var content = document.getElementById("memo").value;
    var time = new Date().getTime();
    addData(title, content, time);
    showAllData();
}
    
    </script>
    <body onload="init()">
        <div data-role="page" id="pageone">
            <div data-role="header" data-position="fixed">
                <h1>離線記事本</h1>
            </div>
            <div data-role="main" class="ui-content">
                <p align="center">記事</p>
                <table data-role="table" class="ui-responsive">
                    <thead>
                        <tr>
                            <th>標(biāo)題:</th>
                            <th>內(nèi)容:</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td><input type="text" id="name"></td>
                            <td><input type="text" id="memo"></td>
                        </tr>
                    </tbody>
                </table>
                <button type="submit" onclick="saveData()">保存</button>
                <table data-role="table" data-mode="" class="ui-responsive" id="datatable">
                </table>
            </div>

        </div>
    </body>
</html>
運行案例 點擊 "運行案例" 可查看在線運行效果

上述代碼通過使用 websql 實現(xiàn)了一個簡單的離線記事本的功能,數(shù)據(jù)庫中保留 3 個字段,分別是標(biāo)題、內(nèi)容、時間,點擊保存按鈕調(diào)用insert 豫劇將數(shù)據(jù)添加到數(shù)據(jù)庫,然后通過使用 select語句將數(shù)據(jù)庫中的數(shù)據(jù)展示出來。如果瀏覽器不主動清空數(shù)據(jù)的情況下離線數(shù)據(jù)將會永久保存,這樣的話借助 websql 可以實現(xiàn)與桌面應(yīng)用相差無幾的功能。

5. indexedDB 和 websql 對比

  • 訪問限制: indexdb 和 websql 一致,均是在創(chuàng)建數(shù)據(jù)庫的域名下才能訪問,且不能指定訪問域名。

  • 存儲時間: 這兩位的存儲時間也是永久,除非用戶清除瀏覽器數(shù)據(jù),可以用作長效的存儲。

  • 大小限制: 理論上講,這兩種存儲的方式是沒有大小限制的。然而 indexeddb 的數(shù)據(jù)庫超過50M的時候瀏覽器會彈出確認(rèn),基本上也相當(dāng)于沒有限制了。但是由于不同的瀏覽器的實現(xiàn)有一定的差別,實際使用中需要根據(jù)不同的瀏覽器做相應(yīng)的容量判斷容錯。

  • 性能測試: indexeddb 查詢少量數(shù)據(jù)花費差不多 20MS 左右。大量數(shù)據(jù)的情況下,相對耗時會變長一些,但是也就在 30MS 左右,也是相當(dāng)給力了,10W 數(shù)據(jù)+,畢竟 nosql。而 websql 的效率也不錯,10w+ 數(shù)據(jù),簡單查詢一下,只花費了20MS左右。

  • 標(biāo)準(zhǔn)規(guī)范: Web SQL 數(shù)據(jù)庫是一個獨立的規(guī)范,因為安全性能等問題,官方現(xiàn)在也已經(jīng)放棄了維護(hù);indexedDB 則屬于 W3C 標(biāo)準(zhǔn)。

6. 小結(jié)

回顧本章,由關(guān)系數(shù)據(jù)庫的優(yōu)缺點及適用場景引申到 HTML5 中的數(shù)據(jù)庫解決方案,以及使用方法,需要注意的是在使用 HTML 數(shù)據(jù)庫的過程中需要檢測瀏覽器是否支持?jǐn)?shù)據(jù)庫。實際開發(fā)項目由于考慮前端數(shù)據(jù)庫的安全性以及性能等問題,如果切實需要使用需要謹(jǐn)慎,畢竟一般項目中數(shù)據(jù)庫保存的都是敏感數(shù)據(jù),即使保存在服務(wù)器中也需要一定的安全加密措施,所以一般前端存儲的都是一些臨時的數(shù)據(jù)。