摘要:數(shù)據(jù)庫的命名應(yīng)該遵守操作系統(tǒng)的文件命名規(guī)范。使用命令檢查當前選定的數(shù)據(jù)庫。假如,第一個是,每頁條,所以當前頁的查詢語句數(shù)據(jù)總數(shù)在中,找尋數(shù)據(jù)總數(shù)獲得總數(shù)需要向上取整。常用于版本校驗。建立索引表示的是正向。損失的插入的時間。
基本使用 概念
SQL和NoSQL
文檔 Document
文檔就是鍵值對的一個集合,實際上表達方式和JSON一樣
文檔就是JSON,但是要比JSON多了一些限制:
每個文檔必須有一個特殊的鍵 _id, 這個鍵在集合中必須是保證唯一性.
文檔中鍵的命名,不能含有.和$
文檔中值的額類型,比原生JavaScript更多, 比如:日期,ObjectId(),正則表達式
文檔是給用戶看的,是JSON的表示模式,但實際存儲的時候,是BSON方式(用二進制方式存儲)
集合 Collections
集合就是一組文檔(document),相當于“表”
集合中可以存儲完全不同的結(jié)構(gòu)的文檔
數(shù)據(jù)庫 DataBase
數(shù)據(jù)庫中存儲眾多的集合
數(shù)據(jù)庫最終會變成文件系統(tǒng)里的文件,而數(shù)據(jù)庫名字就是相應(yīng)的文件名。數(shù)據(jù)庫的命名應(yīng)該遵守操作系統(tǒng)的文件命名規(guī)范。
數(shù)據(jù)庫命名不能是admin,local,config
mongodmongo 使用數(shù)據(jù)庫
mongod 開機
mongoimport 導(dǎo)入數(shù)據(jù)
mongod --dbpath c:mongodata // --dbpath 參數(shù),表示數(shù)據(jù)庫的存放位置,文件夾必須事先創(chuàng)建 // mongoDB 有真實的物理文件,對應(yīng)一個個數(shù)據(jù)庫。
db.help(); // 在 mongodb 客戶端中獲得幫助
db.stats(); 顯示數(shù)據(jù)庫名稱、集合數(shù)目,以及數(shù)據(jù)庫中的文檔
MongoDB數(shù)據(jù)模型MongoDB 中的數(shù)據(jù)模式非常靈活。同一集合中的文檔不需要具有同一字段或結(jié)構(gòu),集合文檔的公用字段可能包含不同類型的數(shù)據(jù)。
設(shè)計 MongoDB 模式注意問題根據(jù)用戶需求來設(shè)計模式。
如果想一起使用對象,請將這些對象合并到一個文檔中,否則要將它們分開(但是要確保不需要連接)。
經(jīng)常復(fù)制數(shù)據(jù)(但要有一定限度),因為與計算時間相比,硬盤空間顯得非常便宜。
在寫入時進行連接,而不能在讀取時連接。
針對經(jīng)常發(fā)生的用例來設(shè)計模式。
在模式中實現(xiàn)復(fù)雜的聚合。
數(shù)據(jù)庫中存儲眾多集合。
數(shù)據(jù)庫最終會變?yōu)槲募到y(tǒng)里面的文件,而數(shù)據(jù)庫名字就是相應(yīng)的文件名,所以數(shù)據(jù)庫的命名,應(yīng)該遵守操作系統(tǒng)的文件名命名規(guī)范。
數(shù)據(jù)庫命名不能是admin、local、config
基本命令行操作列出所有數(shù)據(jù)庫
show dbs;
使用某個數(shù)據(jù)庫
use students; // 如果想新建,也是use, use一個不存在的庫名,就是創(chuàng)建一個數(shù)據(jù)庫。
查看當前所在庫
db
集合沒有查看,需要插入數(shù)據(jù)之后,能夠看到。 如果真的想創(chuàng)建剛才未存在的數(shù)據(jù)庫,那么必須插入一個數(shù)據(jù)。不需要創(chuàng)建集合。
例如:
db.student.insert({"name": "xiaoming", "age": 23}); //student就是所謂的集合(collections)。集合中存儲著很多json(document)。 //db. 一個未知的集合名字,這個集合將自動創(chuàng)建。mongodb增刪改查 創(chuàng)建數(shù)據(jù)庫
用 use + 數(shù)據(jù)庫名稱 的方式來創(chuàng)建數(shù)據(jù)庫。use 會創(chuàng)建一個新的數(shù)據(jù)庫,如果該數(shù)據(jù)庫存在,則返回這個數(shù)據(jù)庫。
use mydb
使用命令 db 檢查當前選定的數(shù)據(jù)庫。
db
使用命令 show dbs 來檢查數(shù)據(jù)庫列表。
show dbs
剛創(chuàng)建的數(shù)據(jù)庫(mydb)沒有出現(xiàn)在列表中。為了讓數(shù)據(jù)庫顯示出來,至少應(yīng)該插入一個文檔。
刪除數(shù)據(jù)庫db.dropDatabase(); // 刪除當前所在的數(shù)據(jù)庫導(dǎo)入外部數(shù)據(jù)
mongoimport --db test --collection restaurants --dorp --file ffffd.json // --db test 想往那個數(shù)據(jù)庫中導(dǎo)入 // --collection restaurants 想往那個集合中導(dǎo)入 // --dorp 把集合清空 表示數(shù)據(jù)庫中有默認數(shù)據(jù),覆蓋原有數(shù)據(jù)。 // --file ffffd.json 使用的是哪個文件. mongoimport --db student --collection class1 --dorp --file a.json創(chuàng)建集合(表)
db.class1 //如果集合不存在,幫你創(chuàng)建集合
使用 show collections 來查看創(chuàng)建了的集合。
show collections // 沒有數(shù)據(jù),剛創(chuàng)建的 集合 并不顯示出來。插入數(shù)據(jù)
db.class1.insert({"name": "ting","age": 21});查看數(shù)據(jù)(文檔)
db.class1.find({}); //db.class1.find(); //find() 方法會以非結(jié)構(gòu)化的方式來顯示所有文檔。 db.class1.find().pretty(); //用格式化方式顯示結(jié)果 //在 find() 方法中,如果傳入多個鍵,并用逗號(,)分隔它們,那么 MongoDB 會把它看成是 AND 條件。 db.class1.find({"key1": "val1", "key2": "val2"}); //若基于 OR 條件來查詢文檔,可以使用關(guān)鍵字 $or。 //或 的條件 db.class1.find({$or: [{key1: val1, key2: val2}]});排序
db.class.find().sort({"sex": 1}); //1 升序修改數(shù)據(jù)
// update暗含查找,修改誰,修改結(jié)果 update默認只會修改第一個document,需要第三個參數(shù)支持: {"multi": true} db.class1.update({"name": "xiaoming"},{$set: {"age": 16}}); // 批量修改 db.class1.update({"score.math": "60"},{$set: {"age": 20}}, {"multi": true}); db.class1.update({},{$set: {"age": 20}},{"multi": true}); //第一個參數(shù)為空,表示全部數(shù)據(jù)修改。 // 替換document, 沒有使用$set關(guān)鍵字,完整替換 db.class1.uodate({"name": "xiaoming"},{"age": 12});刪除數(shù)據(jù)
db.student1.drop(); // 刪除集合 (籃子都刪除) db.studnet1.remove({}) //刪除全部 (籃子還存在) db.student1.remove({"score.math": 80}); //會刪除全部匹配得到的 db.student1.remove({"score.math": 80},{justOne: true}); //刪除匹配的第一個nodeJs 使用 mongodb
// 安裝 mongodb npm install mongodbnodejs 操作 mongodb
// mongo db 驅(qū)動 va r MongoClient = require("mongodb").MongoClient; //數(shù)據(jù)庫的地址 /student 表示數(shù)據(jù)庫 // 假如數(shù)據(jù)庫不存在,沒有關(guān)系,程序會自動創(chuàng)建數(shù)據(jù)庫 var url = "mongodb://localhsot:27017/student"; // 建立連接 MongoClient.connect(url,function( err,db ){ // db 參數(shù)就是連接上數(shù)據(jù)庫 實體 所有數(shù)據(jù)庫操作都建立在 實體上。 if( err ){ console.log("數(shù)據(jù)庫連接失敗"); return ; } console.log("數(shù)據(jù)庫成功連接"); db.collection("student").insertOne({ "name": "mlln", "age": 23 },function( err,result ){ if (err) { console.log("插入失敗"); return ; } console.log(result); res.send("1"); db.close(); }); }); // cmd 中查看數(shù)據(jù) 比較多 可以使用 it 查看下一頁插入數(shù)據(jù)
db.collection("class1").isnertOne({"name": "xiaoming", "age": 21},function( err,result ){ if( err ) console.log("數(shù)據(jù)插入失敗"); console.log("數(shù)據(jù)插入成功"); });查詢數(shù)據(jù)
var cousor = db.collection("class1").find({}); // find({}) //可以輸出查詢條件。find({"score.math": 70}); // 遍歷游標 cousor.each(function( err,doc ){ if( doc != null ){ console.log(doc); // 輸出每條記錄 } }); var cursor = db.collection("class1").find({"score.math": {$gt: 30}}); var cursor = db.collection("class1").find({ "score.math": {$gt: 20} , "score.cha": {$lt : 70}}); var cursor = db.collection("class1").find({ $or: [ {"score.math": {$gt: 50}}, {"scror.cha": {$lt: 70}} ] }); // 排序 // 1 正序 , -1 反序 var cursor = db.collection("class1").find({}).sort({"score.math": 1});更新
覆蓋匹配的記錄 //updateOne();
db.collection("class1").updateOne({"name": "mm"}, {"age": 23},function( err,result ){ if( err ) console.log("修改失敗"); console.log("修改成功"); });
修改字段中的值
db.collection.("class1").updateOne({"name": "mlln"}, { $set: {"age": 24} }, function( err,result ){ if ( err ) console.log("修改失敗"); console.log("修改成功"); });
替換記錄 //replaceOne();
db.collection("class1").replaceOne({"name": "mlln"}, {"name": "m1", "age": 20});刪除數(shù)據(jù)
db.collection("class1").deleteMany({"age",25},function( err,reslut ){ if( err ) console.log("刪除失敗"); console.log("數(shù)據(jù)刪除成功"); });DAO層封裝
mongooose 對象與數(shù)據(jù)對應(yīng),產(chǎn)生ODM思想 , 一個對象new出來之后,數(shù)據(jù)庫中就存在。
// db模塊封裝了所有對數(shù)據(jù)庫的常用操作 var MongoClient = require("mongodb").MongoClient; var setting = require("../settings"); // 連接數(shù)據(jù)庫 function _connectDB(callback) { var url = setting.dburl; // 配置文件中讀取 MongoClient.connect(url, function (err, db) { callback(err, db); }); } // 插入數(shù)據(jù) // 往那個集合中增加,增加什么,增加之后的事情。 exports.insertOne = function (collectionName, json, callback) { _connectDB(function (err, db) { if (err) { callback(err, null); db.close(); // 關(guān)閉數(shù)據(jù)庫 return; } db.collection(collectionName).insertOne(json, function (err, result) { callback(err, result); db.close(); // 關(guān)閉數(shù)據(jù)庫 }); }); }; // 查找數(shù)據(jù) // 在那個集合查找,查什么,分頁設(shè)置,查完之后做什么 exports.find = function (collectionName, json, args, callback) { if (arguments.length == 3) { callback = args; args = { "pageamount": 0, "page": 0 } } else if (arguments.length == 4) { } else { throw new Error("find參數(shù)是3個或者四個"); } var result = []; // 應(yīng)該省略的條數(shù) var skipNum = args.pageamount * args.page; // 數(shù)目限制 var limitNum = args.pageamount; _connectDB(function (err, db) { var cursor = db.collection(collectionName).find(json).skip(skipNum).limit(limitNum); cursor.each(function (err, doc) { // each 遍歷的時候存在問題,callback 匹配到一條,就執(zhí)行一次, // callback 意義上是只執(zhí)行一次,使用數(shù)組解決 if (err) { callback(err, null); db.close(); // 關(guān)閉數(shù)據(jù)庫 return; } if (doc != null) { result.push(doc); //放入結(jié)果數(shù)組 } else { // 遍歷結(jié)束,沒有更多文檔 callback(null, result); db.close(); // 關(guān)閉數(shù)據(jù)庫 } }); }); }; // 刪除 exports.deleteMany = function (collectionName, json, callback) { _connectDB(function (err, db) { db.collection(collectionName).deleteMany(json, function (err, result) { callback(err, result); db.close(); // 關(guān)閉數(shù)據(jù)庫 }); }); }; // 修改 exports.updateMany = function (collectionName, json1, json2, callback) { _connectDB(function (err, db) { if (err) { callback(err, null); return false; } db.collection(collectionName).updateMany(json1, json2, function (err, result) { callback(err, result); db.close(); }); }); };mongoDB分頁
// limit() 表示讀取的條數(shù) // skip() 表示略過的條數(shù)
limit和skip配合使用就是分頁查詢。
假如,第一個是page=0,每頁10條,所以當前頁的查詢語句
db.student.find().limit(10).skip(page*10);
數(shù)據(jù)總數(shù)
在shell中,找尋數(shù)據(jù)總數(shù)
db.student.stats().count; // 獲得collections總數(shù) // 需要向上取整。 db.student.find().count(); // find() ,有分頁邏輯 exports.find = function( collectionName,json,args,callback ){ if ( arguments.length == 3 ) { callback = args; args = {"pageamount": 0, "page": 0} } else if ( arguments.length == 4 ) { } else { throw new Error("find參數(shù)是3個或者四個"); return false; } // 應(yīng)該省略的條數(shù) var skipNum = args.pageamount * args.page; //數(shù)目限制 var limitNum = args.pageamount; _connectDB(function ( err,db ) { var cursor = db.collection(collectionName).find(json).skip(skipNum).limit(limitNum); cursor.each(function ( err,doc ) { // each 遍歷的時候存在問題,callback 匹配到一條,就執(zhí)行一次, // callback 意義上是只執(zhí)行一次,使用數(shù)組解決 if ( err ) { callback(err,null); return ; } if ( doc != null ) { result.push( doc ); //放入結(jié)果數(shù)組 } else { //遍歷結(jié)束,沒有更多文檔 callback(null,result); } }); }); };cookie & session cookie
需要cookie-parser中間件支持
HTTP是無狀態(tài)協(xié)議。簡單地說,當你瀏覽了一個頁面,然后轉(zhuǎn)到同一個網(wǎng)站的另一個頁面,服務(wù)器無法認識到,這是同一個瀏覽器在訪問同一個網(wǎng)站。每一次的訪問,都是沒有任何關(guān)系的。
Cookie是一個簡單到爆的想法:當訪問一個頁面的時候,服務(wù)器在下行HTTP報文中,命令瀏覽器存儲一個字符串;瀏覽器再訪問同一個域的時候,將把這個字符串攜帶到上行HTTP請求中。
第一次訪問一個服務(wù)器,不可能攜帶cookie。 必須是服務(wù)器得到這次請求,在下行響應(yīng)報頭中,攜帶cookie信息,此后每一次瀏覽器往這個服務(wù)器發(fā)出的請求,都會攜帶這個cookie。
特點
cookie是不加密的,用戶可以自由看到;
用戶可以刪除cookie,或者禁用它
cookie可以被篡改
cookie可以用于攻擊
cookie存儲量很小。未來實際上要被localStorage替代,但是后者IE9兼容。
作用:
記錄用戶的信息,購買習慣,猜你喜歡。
express中的cookie, res負責設(shè)置cookie, req負責識別cookie。
cookie是沒有跨域限制
cookie使用
var express = require("express"); var cookieParser = require("cookie-parser"); var app = express(); app.use(cookieParser()); app.get("/",function ( req,res ) { // maxAge 在express 是以毫秒為單位 res.cookie("xihao","tfboys",{ "maxAge": 9000, httpOnly: true }); res.send(req.cookies); }); app.listen(80);猜你喜歡
頁面中獲取原先的值,push到數(shù)組中,然后再次設(shè)置回來。供首頁訪問。
var express = require("express"); var cookieParser = require("cookie-parser"); var app = express(); app.use(cookieParser()); app.get("/",function ( req,res ) { // maxAge 在express 是以毫秒為單位 res.send("猜你喜歡" + req.cookies.mudidi ); }); app.get("/gonglve",function ( req,res ) { var mudidi = req.query.mudidi; //記錄用戶的喜好 //讀取用戶的喜好,然后把新的數(shù)據(jù)push設(shè)置新的數(shù)據(jù) var mudidiArr = req.cookies.mudidi || []; mudidiArr.push( mudidi ); res.cookie("mudidi",mudidiArr,{ "maxAge": 9000, httpOnly: true }); res.send(mudidi + "旅游攻略"); }); app.listen(80);session
需要express-session中間件支持
會話,session并不是天生的就有的技術(shù),而是依賴cookie。
用于登陸。當一個瀏覽器禁用cookie的時候,登陸效果消失,或者用戶清除了cookie,登陸也消失。
session比cookie不一樣的地方,session下發(fā)的是亂碼,并且服務(wù)器自己緩存一些東西。下次瀏覽器的請求,帶著亂碼上來。此時與緩存(緩存是存在服務(wù)器內(nèi)存中,一旦服務(wù)器關(guān)了,緩存就消失)進行比較,看看匹配的是哪一個。
所以,一個亂碼,可以對應(yīng)無限大的數(shù)據(jù)。(理論上),但是受內(nèi)存限制。
任何語言中,session的使用,是“機理透明”的,它幫你設(shè)置cookie的.
var express = require("express"); var app = express(); var session = require("express-session"); app.use(session({ secret: "keyboard cat", resave: false, saveUninitialized: true, cookie: { secure: true } })); app.get("/",function( req,res ){ if ( req.session.login == "1" ) { res.send( "歡迎"+ req.session.username +"的登陸" ); } else { res.send("沒有成功登陸"); } }); app.get("/login",function ( req,res ) { req.session.login = "1"; req.session.username = "mlln"; res.send("你已經(jīng)成功登陸"); }); app.listen(80)加密
md5 加密 是函數(shù)型加密。每次加密的結(jié)果相同,沒有隨機位 //永遠不要用明文寫密碼。
特點:
不管加密的文字,多長多短,永遠都是32位英語字母、數(shù)字混合。
那怕只改一個字,密文都會大變。
MD5沒有反函數(shù)的可能。 網(wǎng)上的破解工具,都是字典模式,通過列出明-密對應(yīng)的字典找到明碼。
MD5常用于版本校驗??梢员葘蓚€文件、軟件是否完全一致。
node中,自帶了一個模塊 crypto模塊,負責加密。
//創(chuàng)建hash var md5 = crypto.createHash("md5"); //創(chuàng)建一個hash對應(yīng) //然后update 和 digest var password = md5.update(fields.password).digest("base64");
console.log( md52( md52("123123").slice(11,7) + md52("123123") ) ); function md52( mingma ) { var md5 = crypto.createHash("md5"); var password = md5.update(mingma).digest("base64"); return password; }GM圖像 gm軟件
只要服務(wù)器需要處理圖片,那么這個服務(wù)器就需要安裝graphicsmagick軟件 , 還有其它的圖像處理軟件。ImageMagick 。
GM軟件API
GM-API
nodejs 使用graphicsmagick。需要第三方npm的gm包
GM包運行環(huán)境 鏈接描述
var fs = require("fs"); var gm = require("gm"); gm("./axin.jpg") .resize(50, 50,"!") .write("./axin.jpg", function (err) { if (err) { console.log(err); } });nodejs頭像裁切
gm("./axin.jpg").crop(141,96,152,181).write("./2.jpg",function(err){ //141 96 是寬高 。 152 181是坐標 });索引
index
數(shù)據(jù)庫中,根據(jù)一個字段的值,來尋找一個文檔,是很常見的操作。
查看檢索的過程
db.student.find({"name": "username33"}).explain(); // 過程顯示 { "cursor" : "BasicCursor", "isMultiKey" : false, "n" : 2, "nscannedObjects" : 19999, "nscanned" : 19999, "nscannedObjectsAllPlans" : 19999, "nscannedAllPlans" : 19999, "scanAndOrder" : false, "indexOnly" : false, "nYields" : 0, "nChunkSkips" : 0, "millis" : 16, "indexBounds" : { }, "server" : "YOS-01409231922:27017" }
為了快速進行檢索,可以把唯一字段,建立成"索引".
每個collection是已經(jīng)有一個索引(默認索引_id),再創(chuàng)建另外索引會具備兩條索引。
建立索引:
db.student.createIndex({ "name": 1 }); // 1 表示的是正向。
索引的優(yōu)缺點:
好處:通過索引查詢的速度會更快,因為可以從索引表中找到,當前個文檔。
壞處:當數(shù)據(jù)庫中的數(shù)據(jù)不存在的時候,已經(jīng)建立的索引會存在。以后插入的數(shù)據(jù)會變慢。 損失的插入的時間。得到的是查詢的時間。
復(fù)合索引
db.student.createIndex({ "name": 1, "address": -1 }); // 1 表示的是正向。 -1 表示負向
先以第一個條件排序,然后相同的時候以第二個條件再進行排序。(插入數(shù)據(jù)之前是一條默認的索引,索引建立之后是3條索引)
db.student.createIndex({ "name": 1 }, {unique: true}); // unique 所有的collection都不能相同,如果相同會報錯。
適用范圍:網(wǎng)站并沒有大量插入的操作。(例如:同一時段并沒有大量的人在注冊)
DAO層中添加init函數(shù)使用索引:
function init() { // 對數(shù)據(jù)庫進行一個初始化 _connectDB(function (err, db) { if (err) { console.log(err); return; } // 建立索引 db.collection("users").createIndex( { "username": 1 }, null, function (err, results) { if (err) { console.log(err); return; } console.log("索引建立成功"); } ); }); }
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/86335.html
摘要:數(shù)據(jù)庫的命名應(yīng)該遵守操作系統(tǒng)的文件命名規(guī)范。使用命令檢查當前選定的數(shù)據(jù)庫。假如,第一個是,每頁條,所以當前頁的查詢語句數(shù)據(jù)總數(shù)在中,找尋數(shù)據(jù)總數(shù)獲得總數(shù)需要向上取整。常用于版本校驗。建立索引表示的是正向。損失的插入的時間。 基本使用 概念 SQL和NoSQL showImg(https://segmentfault.com/img/bVzh2M?w=582&h=469); 文檔 Doc...
閱讀 1488·2021-11-09 09:45
閱讀 1865·2021-11-04 16:09
閱讀 1512·2021-10-14 09:43
閱讀 1905·2021-09-22 15:24
閱讀 1708·2021-09-07 10:06
閱讀 1664·2019-08-30 14:15
閱讀 1056·2019-08-30 12:56
閱讀 1628·2019-08-29 17:22