Mysql 數據庫操做基礎及Node中使用Mysql

數據庫:存儲數據的倉庫。mysql

  • 數據結構化git

  • 實現數據共享程序員

    • 能夠減小冗餘數據github

  • 數據獨立性高sql

  • 數據統一管理與控制數據庫

數據庫介紹

  • MySQL 數據庫npm

  • Oraclejson

    • Orcale數據庫管理系統由甲骨文公司開發,在數據庫領域一直處於領先地位數組

    • 商業收費,大型系統,淘寶、京東就使用了 Oracle 數據庫promise

  • SqlServer 數據庫

    • 由微軟公司開發,只能在Windows上運行。.net開發程序員

  • DB2

    • 由IBM公司開發,在金融行業中使用的比較多。IBM的服務器,買服務器送數據庫

    • 商業收費

  • MS SQL Server

    • 以上這些數據庫都是使用 SQL 語言進行操做

    • SQL 語言就是用於 關係型數據庫 的一個操做語言

    • 利用這個 SQL 語言能夠增刪改查庫和表,以及增刪改查表數據

    • 表 就是 關係

    • 表與表之間就是關係

  • MongoDB

    • 非關係型數據庫

    • 沒有表,這個數據庫中存儲的數據都在集合中,相似於 JavaScript 對象,其實就是 json 格式的數據

    • 集合沒有結構,集合就是一個數組

    • 也能夠往集合中插入數據

MongoDB是由10gen公司開發的一個介於關係型數據庫和非關係型數據庫之間的產品,是非關係型數據庫中功能最豐富,最像關係型數據庫的。他支持的數據結構很是鬆散,是相似json的格式,因此能夠存儲比較複雜的數據結構類型。MongoDB數據庫管理系統最大的特色就是它支持的查詢語言很是強大,語法相似於面向對象的查詢語言。它仍是一個開源的數據庫,對於大數據量、高併發的互聯網應用,支持很是不錯。操做非關係型數據庫不須要使用SQL語言。

  • 關係型數據庫存儲結構

    • 數據庫服務器

      • 數據庫管理系統

    • 數據庫

    • 數據表

      • 根據業務設計表結構

    • 記錄

      • 根據表結構存儲記錄數據

oracle、sqlserver、DB二、MySQL 都是關係型數據庫。

安裝和配置 MySQL 數據庫

官方網站:http://www.mysql.com/

啓動 和 中止MySQL服務:

經過Windows的運行,輸入services.msc找到MySQL服務

經過DOS命令啓動MySQL服務(使用管理員權限打開終端)

登陸MySQL數據庫:

mysql -h localhost -P 3306 -u root -p

  • -h:主機名

  • -P:端口

  • -u:用戶名

  • -p:密碼

mysql默認鏈接localhost和3306,因此能夠省略-h和-P:

mysql -u root -p

在命令行中輸入「help;」或者「h」,就會顯示出MySQL的幫助信息。

命令 簡寫 具體含義
? ? 顯示幫助信息
exit q 退出MySQL
help h 顯示幫助信息
quit q 退出MySQL
status s 獲取MySQL服務器狀態信息
use u 用來選擇一個數據庫,以一個數據庫名做爲參數

數據庫的存儲結構

  • 一個數據庫服務器上能夠有多個數據庫

  • 一個數據庫中能夠有多個表

    • 一個表必定要有表結構

    • 全部的數據存儲在表中,因此有了數據庫以後,要先設計你的表結構

  • 一張表中存儲多條記錄

    • 記錄按照表結構的形式進行存儲

建立數據庫和表

建立數據庫

CREATE DATABASE [IF NOT EXISTS] db_name

查看數據庫

SHOW DATABASES;

顯示數據庫建立語句

SHOW CREATE DATABASE db_name;

刪除數據庫

DROP DATABASE [IF EXISTS] db_name;

選擇數據庫

USE db_name;

查看當前使用的數據庫

SELECT database();

數據類型

整數類型

類型 大小 範圍(有符號) 範圍(無符號) 用途
TINYINT 1 字節 (-128,127) (0,255) 小整數值
SMALLINT 2 字節 (-32 768,32 767) (0,65 535) 大整數值
MEDIUMINT 3 字節 (-8 388 608,8 388 607) (0,16 777 215) 大整數值
INT或INTEGER 4 字節 (-2 147 483 648,2 147 483 647) (0,4 294 967 295) 大整數值
... ... ... ... ...

浮點型

在MySQL數據庫中,存儲小數都是使用浮點數和定點數來表示的。

浮點數有兩種:

  • 單精度浮點數(FLOAT)

  • 雙精度浮點數(DOUBLE)

定點數(DECIMAL)[ˈdesɪml]

時間和日期類型

類型 大小(字節) 範圍 格式 用途
DATE 3 1000-01-01/9999-12-31 YYY-MM-DD 日期值
TIME 3 '-838:59:59'/'838:59:59' H:MM:SS 時間值或持續時間
YEAR 1 1901/2155 YYY 年份值
DATETIME 8 1000-01-01 00:00:00/9999-12-31 23:59:59 YYY-MM-DD HH:MM:SS 混合日期和時間值
TIMESTAMP 8 1970-01-01 00:00:00/2037 年某時 YYYMMDD HHMMSS 混合日期和時間值,時間戳

若是插入的數值不合法,系統會自動將對應的零值插入到數據庫中。

  • YEAR

使用4位字符串或數字表示,範圍爲‘1901‘ ~ ‘2155’或1901~2155

例如,輸入‘2016‘或者2016,插入到數據庫的值均爲2016

  • DATE

DATE類型用來表示日期值,不包含時間部分。

可使用「YYYY-MM-DD「或‘YYYYMMDD‘字符串表示

例如,輸入‘2016-10-01‘或’20161001‘插入到數據庫的日期都是2016-10-01

  • TIME

TIME類型用於表示時間值,它的顯示形式通常爲HH:MM:SS,其中HH 表示小時,MM表示分,SS表示秒

可使用下面三種方式指定時間的值:

  1. 以「D HH:MM:SS「字符串格式表示。其中,D表示日,能夠取0-34之間的值,插入數據時,小時的值等於(D*24+HH)

  • 例如,輸入‘2 11:30:50‘,插入數據庫的日期爲 59:30:50

  1. 以‘HHMMSS‘字符串格式或者HHMMSS數字格式表示

  • 例如:輸入‘345454‘或345454,插入數據庫的日期爲34:54:54

  1. 使用CURRENT_TIME或NOW()輸入當前系統時間

  • DATETIME

指定DATETIME類型的值:

  1. 以‘YYYY-MM-DD HH:MM:SS‘或者’YYYYMMDDHHMMSS‘字符串或數字均可以。

  2. 使用NOW來輸入當前系統的日期和時間

  • TIMESTAMP

TIMESTAMP類型顯示形式和DATETIME相同,但取值範圍比DATETIME小。

  1. 輸入CURRENT_TIMESTAMP輸入系統當前日期和時間

  2. 輸入NULL時,系統會自動輸入當前日期和時間

  3. 無任何輸入時,系統會輸入系統當前日期和時間

標記。利用它能夠保存表中某條記錄的最後修改時間。自動維護。

CHAR和VARCHAR

插入值 CHAR(4) 存儲需求 VARCHAR(4) 存儲需求
'' '' 4個字節 '' 1個字節
'ab' 'ab' 4個字節 'ab' 3個字節
'abc' 4個字節 'abc' 4個字節
'abcd' 4個字節 'abcd' 5個字節
'abcde' 'abcd' 4個字節 'abcd' 5個字節

當數據爲CHAR(4)類型時,無論插入值的長度是多少,所佔用的存儲空間都是4個字節。而VARCHAR(4)所對應的數據所佔用的字節數爲實際長度加1.

總結:

  • 字符長度不固定的類型使用VARCHAR 查詢的時候要計算字節的長度

  • 字符串長度固定的使用CHAR 查詢速度快。

  • VARCAHR比CHAR省空間

  • CHAR比VARCHAR省時間

TEXT類型

表示大文本數據,例如:文章內容、評論等

基本操做

查看錶結構

查看當前數據庫中的全部表: show tables;

查看錶結構: desc table_name;

查看建表語句: show create table table_name;

修改數據表

增長列: ALTER TABLE table_name ADD colum datatype;

修改列: ALTER TABLE table_name MODIFY colum datatype;

刪除列: ALTER TABLE table_name DROP colum;

修改表名: rename TABLE table_name to new_table_name;

修改列名: ALTER TABLE table_name change colum_name new_colum_name datatype;

刪除數據表

DROP TABLE table_name;

表的約束

約束條件 說明
PRIMARY KEY 主鍵約束,用於惟一標識對應的記錄
FOREIGN KEY 外鍵約束
NOT NULL 非空約束
UNIQUE 惟一性約束
DEFAULT 默認值約束,用於設置字段的默認值

表的約束條件都是針對表中字段進行限制,從而保證數據表中數據的正確性和惟一性。

主鍵約束

每一個數據表中最多隻能有一個主鍵約束,定義爲PRIMARY KEY 的字段不能有重複值且不能爲NULL值。也就是非空並且惟一

語法:字段名 數據類型 PRIMARY KEY

非空約束

非空約束指的是字段的值不能爲NULL,在MySQL中,非空約束是經過NOT NULL 定義的。

語法:字段名 數據類型 NOT NULL;

惟一約束

惟一約束用於保證數據表中字段的惟一性,即表中字段的值不能重複出現。

語法:字段名 數據類型 UNIQUE;

默認約束

默認約束用於給數據庫中的字段指定默認值,即當在表中插入一條記錄時,若是沒有給這個字段賦值,數據庫系統會爲這個字段插入默認值。

語法:字段名 數據類型 DEFAULT 默認值;

設置表的字段值自動增長

若是想爲表中插入的新紀錄自動生成惟一ID。可使用AUTO_INCREMENT實現

語法:字段名 數據類型 AUTO_INCREMENT;

添加、更新與刪除數據

添加數據

爲表中全部字段添加數據

INSERT INTO 表名
  VALUES(列1值,列2值,...)

注意:

  • values中的值必須與表中的字段一一對應。

  • 插入的數據應與字段中的數據類型相同

  • 數據的大小應該在列的規定範圍內,例如不能將一個長度爲80的字符串插入到長度爲40個列中

  • 字符和日期型數據應該包含在單引號中

  • 若是要插入一個空值,不指定或者使用NULL

按照指定列添加數據:

INSERT INTO 表名(列1名, 列2名,...)
  VALUES(列1值, 列2值,...)

注意: values中的值必須與列聲明中的列一一對應

同時添加多條記錄

INSERT INTO employee
  VALUES (value1,value2,value3...),
          (value1,value2,value3...),
          (value1,value2,value3),
          ...;

更新所有數據:

UPDATE 表名
  SET 列名=值, 列名=值[,列名=值]

按條件更新:

UPDATE 表名
  SET 列名=值, 列名=值[,列名=值]
  WHERE 條件;

總結:

  • UPDATE語句能夠用新值更新原有表中行的列。

  • SET字句指定要修改哪些列和要給與哪些值

  • WHERE須要給定一個條件,表示要更新符號該條件的行,沒有WHERE字句,則更新全部行

條件可使用的運算符:

-- 比較運算符 > < <= >= = <>  大於、小於、大於(小於等於)、不等於
  BETWEEN…AND -- 顯示在某一區間的值
  IN(set) -- 顯示在in列表中的值,例:in(100,200)
  LIKE -- ‘張pattern’ 模糊查詢%
  IS NULL -- 判斷是否爲空

  -- 邏輯運算符 AND 多個條件同時成立
  OR  多個條件任一成立
  NOT 不成立,例:WHERE NOT(salary>100)

刪除數據:

刪除所有數據

DELETE FROM 表名;

根據條件刪除:

DELETE FROM 表名
  WHERE 條件;

初始化

runcate初始化數據表

truncate table_name;

truncate和delete的區別:

  • delete會一條一條的刪

  • truncate先摧毀整張表,再建立一張和原來的表結構如出一轍的表

  • 拿拆遷舉例子

  • truncate在效率上比delete高

  • truncate只能刪除整表的數據,也就是格式化。

  • truncate會把自增id截斷恢復爲1

總結:

  • 若是不使用WHERE語句,將刪除表中全部數據

  • DELETE不能刪除某一列的值,(可以使用UPDATE)

  • 使用DELETE語句僅僅刪除記錄,不刪除表自己,若是要刪除表,使用DROP TABLE語句

  • 刪除表中全部數據也可使用truncate table_name語句

單表查詢

簡單查詢

SELECT [DISTINCT] *|{colum1, colum2, colum3...} FROM table_name;
  • SELECT指定查詢哪些列的數據

  • column指定列名

    • 號表示查詢全部列

  • FROM 指定查詢哪一種表

  • DISTINCT 可選,指查詢結果時,是否去除重複數據

查詢表中全部數據:

SELECT * FROM 表名;

按照指定列查詢表中全部數據:

SELECT 列名,列名[,列名] FROM 表名;

根據條件查詢數據:

SELECT * FROM 表名
  WHERE 條件;

在WHERE字句中常用的運算符

比較運算符 > < <= >= = <> 大於、小於、大於(小於等於)、不等於
比較運算符 BETWEEN…AND 顯示在某一區間的值
比較運算符 IN(set) 顯示在in列表中的值,例:in(100,200)
比較運算符 LIKE ‘張pattern’ 模糊查詢%
比較運算符 IS NULL 判斷是否爲空
邏輯運算符 AND 多個條件同時成立
邏輯運算符 OR 多個條件任一成立
邏輯運算符 NOT 不成立,例:WHERE NOT(salary>100)

LIKE語句中,% 表明零個或多個任意字符,_表明一個字符,例如:name LIKE '_a%';

多表查詢:

-- 多表查詢
  -- 找到表 articles 中 user_id 等於 users 表中 id 的
  -- 多表查詢能夠起別名
  SELECT a.id as article_id, a.title, a.time
  FROM articles as a
  INSERT JOIN users as u
  ON a.user_id=u.id

查詢總記錄數:

-- 查詢表中的總記錄數據
  SELECT COUNT(id) as count FROM articles;

聚合函數

在實際開發中,常常須要對某些數據進行統計,例如統計某個字段的最大值,最小值,平均值等,爲此,MySQL提供了一些函數來實現這些功能。

函數名稱 做用
COUNT() 返回某行的列數
SUM() 返回某列值的和
AVG() 返回某列的平均值
MAX() 返回某列值的最大值
MIN() 返回某列的最小值
  • COUNT(列名)返回某一列,行的總數

  • COUNT(列名)返回某一列,行的總數

  • SUM()函數返回知足WHERE條件的行的和

SELECT SUM(列名) {, SUM(列名)...} FROM table_name
    [WHERE where_definition]

注意:SUM僅對數值起做用,不然報錯; 對多列求和,「,」不能少。

  • MAX()/MIN()函數返回知足WHERE條件的一列的最大/最小值

SELECT MAX(列名) FROM table_name
    [WHERE where_definition];

對查詢結果排序

SELECT colum1, colum2, colum3..
      FROM table_name
      ORDER BY colum ASC|DESC;

ORDER BY 指定排序的列,排序的列表便可以是表中的列名,也能夠是SELECT語句後指定的列名.

  • ASC 升序,DESC 降序

  • ORDER BY 字句應該位於SELECT 語句的結尾

分組查詢

SELECT colum1, colum2, ...
    FROM 表名
    LIMIT [OFFSET, ] 記錄數

LIMIT表示從哪一條記錄開始日後【不包含該記錄】,以及一共查詢多少記錄

OFFSET表示偏移量:

  • 若是爲0則表示從第一條記錄開始

  • 若是爲5則表示從第6條記錄開始

使用場景:分頁查詢

分頁查詢一個例子

-- 僅僅取了前 10 條
  SELECET * FROM articles LIMIT 10
  -- 跳過一條取一條
  SELECET * FROM articles LIMIT 1, 1

爲表和字段區別名

爲表取別名

SELECT 表別名.id,表別名.name... FROM 表名 AS 表別名
    WHERE 表別名.id = 2..

爲字段取別名

SELECT 字段名 [AS] 別名 [,字段名 [AS] 別名,...] FROM 表名;

多表操做

實際開發中業務邏輯比較複雜,可能有幾十到幾百張表不等,因此咱們就須要對多張表來進行查詢操做,對兩張以上的表進行操做,就是多表操做。

外鍵

爲了保證數據的完整性,將兩張表之間的數據創建關係,所以就須要在成績表中添加外鍵約束。

  • 外鍵是指引用另外一個表中的一列或多列,被引用的列應該具備主鍵約束或惟一約束。

  • 外鍵用於創建和增強兩個表數據之間的連接。

爲表添加外鍵約束

建立表的時候添加外鍵:

CREATE TABLE department(
      id INT PRIMARY KEY auto_increment,
      name VARCHAR(20) NOT NULL
  );
  CREATE TABLE employee(
      id INT PRIMARY KEY auto_increment,
      name VARCHAR(20) NOT NULL,
      dept_id INT,
      FOREIGN KEY (id) REFERENCES department(id)
  );

表已經存在,經過修改表的語句增長外鍵:

ALTER TABLE 表名 ADD CONSTRAINT 外鍵名 FOREIGN KEY(外鍵字段名) REFERENCES 外表表名(主鍵字段名);

刪除外鍵約束

ALTER TABLE 表名 DROP FOREIGN KEY 外鍵名;

操做關聯表

關聯關係:

  • 多對一

  • 多對多

  • 一對一

使用 Node 操做 MySQL 數據庫

安裝:

$ npm install --save mysql

使用鏈接池操做 MySQL 數據庫

  • 修改安裝目錄下 my.ini 文件中的: max_connections=1000 默認是 max_connections=151

  • 重啓服務器

connection-pool

鏈接池

封裝過程:

const mysql = require('mysql');

  // 使用鏈接,提升操做數據庫效率
  // 建立一個鏈接池,池子存放的鏈接數量是 100 個
  const pool = mysql.createPool({
    connectionLimit: 100,
    host: 'localhost',
    user: 'root',
    password: 'root',
    database: 'personal'
  });

  for (let i = 0; i < 1000; i++) {
    // 從池子中拿一個可用的鏈接
    pool.getConnection((err, connection) => {
      if (err) {
        throw err;
      }
      connection.query('INSERT INTO `feedback`(`message`, `name`, `email`, `date`) VALUES(?, ?, ?, ?)', [
        '今天的霧霾很醇厚',
        '校長',
        'xiaozhang@abc.com',
        '2016-11-17 09:31:00'
      ], (err, stat) => {
        // 儘早的釋放回鏈接池
        // 只要操做數據庫的回調函數被執行,說明這個鏈接的任務完成了
        connection.release();
        if (err) {
          throw err;
        }
        console.log(`第${i+1}個任務完成了`);
      });
    });
  }

封裝:db.js

const mysql = require('mysql');
  
  const pool = mysql.createPool({
    connectionLimit: 100,
    host: 'localhost',
    user: 'root',
    password: 'root',
    database: 'personal'
  });

  // rest 參數
  // 做爲函數參數的最後一個參數出現,以 ... 開頭,後面跟一個名字
  // rest 參數就代替了 arguments
  exports.query = function (sql, ...values) {
    let callback;
    let params = [];
    if (values.length === 3) {
      params = values[0];
      callback = values[1];
    } else if (values.length === 2) {
      callback = values[0];
    }
    pool.getConnection((err, connection) => {
      if (err) {
        return callback(err);
      }
      // 若是傳遞了兩個參數,則第二個參數就是 callback
      // 也就是說這種狀況下,params 就是 callback
      // 後面的 參數就忽略不計了
      // 若是真的傳遞了三個參數,那就是一一對應
      connection.query(sql, params, (err, result) => {
        connection.release();
        if (err) {
          return callback(err);
        }
        callback(null, result);
      });
    });
  };

promise 版

const mysql = require('mysql');

  const pool = mysql.createPool({
    connectionLimit: 100,
    host: 'localhost',
    user: 'root',
    password: 'root',
    database: 'personal'
  });

  exports.query = (sql, params = []) => {
    return new Promise((resolve, reject) => {
      pool.getConnection((err, connection) => {
        if (err) {
          return reject(err);
        }
        connection.query(sql, params, (err, result) => {
          connection.release();
          if (err) {
            return reject(err);
          }
          resolve(result);
        });
      });
    });
  };

調用示例:

const db = require('./db')

  db.query('SELECT 1 + 1 as solution');
    .then(rows => {
      // use rows
      return db.query('INSERT INTO table_name VALUES(?, ?, ?)', ['值1', '值2', '值3'])
    })
    .then(rows => {
      // use rows
    })
    .catch(err => {
      // handle error
    });

本文原文連接

相關文章
相關標籤/搜索