數據庫概述及基本操做

一 概念

1 數據庫誕生和發展歷史

數據庫: 按照數據結構來組織,存儲,管理數據的倉庫 python


誕生
計算機的發明是爲了作科學計算的,而科學計算須要大量的數據輸入和輸出。
早期是經過打孔機和燈泡來表示數據的輸入和輸出。
後來,數據能夠存儲在磁帶上,順序的讀,寫入磁帶
1956年IBM發明了磁盤驅動器,其支持了隨機訪問,再也不是以前的順序訪問。
隨着信息時代的到來,有了硬件存儲技術的發展,有大量的數據須要存儲和管理,數據庫管理系統DBMS就誕生了。
無論使用什麼存儲介質,數據庫的數據模型纔是其核心和基礎。mysql

2 早期數據庫分類

按照數據模型分類: 網狀數據庫,層次數據庫,關係型數據庫 sql


1 層次數據庫

以樹形結構表示實體之間的關聯,關係只支持一對多,樹不能有交叉,表明數據庫有IBM 的 IMS 數據庫

數據庫概述及基本操做


2 網狀數據庫

通用電氣最先在1964年開發出網狀數據庫IDS,只能運行在GE自家的主機上設計模式

數據庫概述及基本操做

節點描述數據,節點的聯繫就是數據之間的關係 安全

可以直接描述客觀世界,能夠表示實體鍵多種複雜關係,而這是層次數據庫沒法作到的,好比,一個節點能夠有多個父節點,節點之間能夠支持多對多的關聯。網絡


3 關係數據庫

使用行,列組成的二維表來組織數據和關係,表中行(記錄)便可描述數據實體。也可描述實體鍵的關係。session

關係模型比網狀模型,層次模型更簡單,不須要關係數據存儲的物理細節,專心於數據的邏輯構建,而關係模型有論文的嚴格的數學理論基礎支持。數據結構


1970 年,IBM E.F.Codd發表了名爲"A Relational Model of Data for large Shared Data Banks"的論文,提出來關係模型的概念,奠基了關係模型的理論基礎,關係模型,有嚴格的數據基礎,抽象級別較高,簡單清晰,便於理解和使用。多線程

基於關係模型構建的數據庫成爲RDBMS(Relational DataBase System)。

3 關係型數據庫發展歷史

1 Oracle 發展

Larry Ellison 在IBM的關係數據庫論文的基礎上,發展出通用商用的數據庫Orcale,1992年,Oracle7 才漸漸穩定下來,並取得巨大成功,2001年的9i版本本普遍應用。

2009年4月20日,甲骨文公司宣佈將以每股9.50美圓,總計74億美圓收購sun(計算機系統)公司,2010年1月成功收購
2013 年,甲骨文超過IBM,成爲繼微軟以後的第二大軟件公司


2 MySQL 發展

1985年幾個瑞典人爲大型零售商項目設計了一種利用索引順序存取數據庫的軟件,這就是MyISAMd的前身,1996年。MySQL1.0 發佈,隨後發佈了3.11.1版本,並開始往其餘平臺移植,200年MySQL採用GPL協議開源,MySQL4.0開始支持MyISAM,InnoDB存儲引擎,2005年10月,MySQL 5.0 稱爲里程碑版本。
2008年1月被sun公司收購
2009年1月,在Oracle收購MySQL以前,Monty Wideniusa擔憂收購,就從MySQL Server 5.5 開始一條存的GPL分支,起名爲MariaDB
MySQL 的引擎是插件化的,能夠支持不少引擎
MyISAM,不支持事務,插入,查詢速度快
InnoDB,支持事物,行級鎖,MySQL 5.5 起的默認引擎


3 NoSQL
NoSQL 是對非SQL,非傳統關係型數據庫的統稱
NoSQL一詞誕生於1998年,2009年這個詞彙被再次提出指非關係型,分佈式,不提供ACID的數據庫設計模式

隨着互聯網時代的到來,數據爆發式增加,數據庫技術發展突飛猛進,要適應新的業務需求,隨着移動互聯網,物聯網的到來,大數據的技術中NoSQL也一樣重要。

二 MySQL數據庫概述和SQL基本操做

1 MySQL數據庫概述

MySQL數據庫是一種關係型數據庫管理軟件,支持網絡訪問,默認端口是3306

MySQL通訊使用的是mysql協議

MySQL的底層是基於TCP協議的。由於UDP會丟包,而數據庫的數據是絕對不能丟包的。

2 SQL

1 概述

SQL 是結構化查詢語言Structured Query Language,1987年被ISO組織標準化,全部主流的關係型數據庫都支持SQL,NoSQL也有很大一部分支持SQL。


SQL 語句分爲:

DDL : 數據定義語言,負責數據庫定義,數據庫對象定義。由CREATE,ALTER 和 DROP 三個語法組成


DML: 數據操做語言,負責對數據庫對象的操做,CRUD增刪改查


DCL: 數據庫控制語言,負責對數據庫權限訪問控制,由GRANT 和 REVOKE 兩個指令組成


TCL : 事務控制語言,負責處理ACID事務,支持commit,rollback 指令


SQL 語句對大寫不敏感,SQL語句的末尾應該使用分號結束。

2 數據庫基本術語

1 PRIMARY KEY 主鍵

表中一列或多列組成惟一的key,.也就是經過這一個或多個列能惟一標識一條記錄,主鍵的列不能有空,及不能有NULL,主鍵每每設置爲整數類型,長整數類型型,且自增AUTO_INCREMENT,表中能夠沒有主鍵,可是,通常的表設計中,都會包含主鍵。


主鍵用過了不回頭,就算刪除了當前主鍵的值,下一條插入語句也會從下一個數字進行存儲。

2 索引 index

能夠看作是一本大字典的目錄,爲了快速檢索使用,空間換時間,顯著提高查詢效率,能夠對一列或多列設定索引。


主鍵索引,主鍵會自動創建主鍵索引,主鍵自己就是爲了快速定位惟一記錄的。


惟一索引,表中的索引列組成的索引必須惟一,但能夠是空,非空值必須惟一,空值能夠有多個


普通索引,沒有惟一性要求,就是構建了一個字典目錄而已


索引也有反作用,能顯著提高查詢效率,但會致使插入和刪除效率低下。

3 約束 Constraint

UNIQUE 約束(惟一鍵約束)
定義了惟一索引,就定義了惟一鍵約束


PRIMATY KEY 約束
定義了主鍵,就定義了主鍵約束


外鍵約束 Foreign Key

外鍵: 在B表中的列,關鍵A表中的主鍵,B表中的列就是外鍵
若是在表B中插入一條數據,B中的外鍵插入一個值,這個值必須在表A中是存在的主鍵的值,修改表B的外鍵的值也是一樣的,外鍵對應的值必須在表A的主鍵中存在

若是表A要刪除一條記錄。那麼就等於刪除了一個主鍵,若是表B中引用了這個主鍵,就必須先刪除表B中引用這個主鍵的記錄,才能刪除表A中的記錄,不然會致使刪除失敗

修改表A的主鍵,因爲主鍵惟一性,修改的主鍵至關於插入新的主鍵,那麼表B引用這個主鍵,將組織表A修改主鍵,必須刪除表B的相關記錄後,才能修改表A的主鍵。

外鍵約束,爲了保證數據完整性,一致性,杜絕數據冗餘,數據訛誤。

4 視圖

視圖,也成虛表,看起來像表,它是由查詢語句生成的,能夠經過視圖進行CRUD操做,

視圖的做用: 簡化操做,將複雜查詢SQL語句定義爲視圖,能夠簡化查詢
數據安全,視圖能夠只顯示真實表的部分列,或計算後的結果,隱藏真實表的數據。

3 MySQL中的數據類型

類型 含義
tinyint 1 字節,帶符號的範圍是-128到127,無符號的範圍是0到255,bool或boolenan,就是tinyint,0 表示假,非0表示真
smaillint 2 字節,帶符號的返回爲-32768到32767,無符號是0到65535
int 整數類型,4字節,同integer,帶符號的範圍是-2147483648到2147483647,無符號的範圍是0到4294967295
bigint 長整數類型,8 字節,帶符號的範圍是-9223372036854775808到9223372036854775807,無符號數是0到18446744073709551615
float 單精度浮點數精確到大約7位小數
dobule 雙精度浮點數精確到大約15位小數
DATE 日期。支持的範圍是1000-01-01到9999-12-31
DATETIME 支持的範圍是 1000-01-01 00:00:00 9999-12-31 23:59:59
TIMESTAMP 時間戳。範圍是'1970-01-01 00:00:00' 到 2037年
char(M) 固定長度,右邊填充空格已達到長度要求,M爲長度,返回爲0-255,M值的是字符個數
varchar(M) 變長字符串,M表示最大列長度,M的範圍是0到65535,但不能突破行最大字節數 65535
text 大文本,最大長度爲 65535(2^16-1)個字符
BLOB 大字節,最大長度爲 65535(2^16-1)字節的BLOB列

LENGTH 函數返回字節數,而char 和varchar 定義的M是字符數限制

char 能夠將字符串變成等長,空間換時間,效率略高,varchar變長,節省了空間。

4 MySQL 操做基本語言

1 DCL

GRANT 受權 REVOKE 撤銷

GRANT  ALL  ON  *.*  TO  admin@localhost  IDENTIFIED  BY  'Admin@Roo123';

參數說明:

其中 ALL,表明授予全部權限,固然能夠單獨授予 SELECT,DELETE,UPDATE等權限
ON 後面的*.* 表示庫和表,如test.*,則表示test庫中的全部表,test.test則表示test庫中的test表,

TO 後面的admin 表示用戶名 @ 後面的localhost表示本地受權登陸,固然可使用'%'表示全部均可登陸,

IDENTIFIED BY 後面的表示密碼.

使用此命令便可登陸成功

mysql  -uadmin  -pAdmin@Roo123

REVOKE 撤銷權限

REVOKE ALL  ON *.*  FROM  admin@localhost;

參數說明:

此中的ALL 也是全部的權限,也能夠撤銷部分權限,如SELECT,DELETE等
ON 後面的和上述相同
FROM 後面的表示的是用戶名和容許登陸的範圍

登陸查詢

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
+--------------------+
1 row in set (0.00 sec)

其只能管理這個開放庫了

2 DDL

1 刪除用戶

DROP USER admin@localhost;

此時將不能登陸

[root@python ~]# mysql  -uadmin  -pAdmin@Roo123
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user 'admin'@'localhost' (using password: YES)

2 建立數據庫

庫是數據的集合,全部數據按照數據模型組織在數據庫中

CREATE DATABASE IF NOT EXISTS  test CHARACTER SET utf8mb4  COLLATE  utf8mb4_general_ci;

CHARACTER SET 是指定字符集,utf8mb4 是utf8 的擴展,支持4字節的utf8mb4,須要大於MySQL 5.5.3+
COLLATE 指定字符集的校對規則,用來作字符串的比較的。

刪除數據庫

DROP DATABASE  IF EXISTS test;

建立數據表

表分爲行和列,MySQL是行存儲數據,數據是一行行存儲的,列必須固定多少列。

行Row,也成爲記錄Record,元祖
列 Column,也成爲字段Field

CREATE TABLE `employees` (
  `emp_no` int(11) NOT NULL COMMENT '主鍵',
  `birth_date` date NOT NULL COMMENT '生日',
  `first_name` varchar(14) NOT NULL COMMENT '用戶-姓',
  `last_name` varchar(16) NOT NULL COMMENT '用戶-名',
  `gender` enum('M','F') NOT NULL COMMENT '性別',
  `hire_date` date NOT NULL COMMENT '入職時間',
  PRIMARY KEY (`emp_no`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

反引號標註的名稱,被認爲是非關鍵字

不一樣數據類型佔用字節數不一樣
數字範圍決定了存儲方式,小範圍整數使用字符串比較合適,大範圍整數則使用數字類型存儲比較合適。

NOT NULL 不能爲空

定義字段完成後定義約束,如上述的PRIMARY KEY (emp_no) 則被稱爲主鍵約束

3 DESC 查詢列信息

mysql> DESC employees;
+------------+---------------+------+-----+---------+-------+
| Field      | Type          | Null | Key | Default | Extra |
+------------+---------------+------+-----+---------+-------+
| emp_no     | int(11)       | NO   | PRI | NULL    |       |
| birth_date | date          | NO   |     | NULL    |       |
| first_name | varchar(14)   | NO   |     | NULL    |       |
| last_name  | varchar(16)   | NO   |     | NULL    |       |
| gender     | enum('M','F') | NO   |     | NULL    |       |
| hire_date  | date          | NO   |     | NULL    |       |
+------------+---------------+------+-----+---------+-------+
6 rows in set (0.00 sec)

mysql> DESC employees  '%name';
+------------+-------------+------+-----+---------+-------+
| Field      | Type        | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| first_name | varchar(14) | NO   |     | NULL    |       |
| last_name  | varchar(16) | NO   |     | NULL    |       |
+------------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

4 Navicat premium 基本設計表原則

設計一個登錄表


1 基本上必須有主鍵,且必須是無符號的自增序列
2 loginname 必須不能爲空,若爲空,則會出問題,password也不能爲空
3 必需要有冗餘字段,由於線上業務若正在運行,則添加字段可能致使線上業務的中斷或用戶體驗相關的問題
4 必須設置索引,以加快select查詢速度

數據庫概述及基本操做

數據庫概述及基本操做

查看自動遞增數字

數據庫概述及基本操做

查看生成SQL

數據庫概述及基本操做

CREATE TABLE `login` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主鍵',
  `loginname` varchar(48) NOT NULL COMMENT '登陸名',
  `username` varchar(48) DEFAULT NULL COMMENT '用戶名',
  `password` varchar(255) NOT NULL COMMENT '用戶密碼',
  `revered1` varchar(255) DEFAULT NULL,
  `revered2` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `ln` (`loginname`) USING BTREE COMMENT '登陸名稱索引'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

5 SQL 導入

1 選擇表,右鍵選擇運行SQL文件

數據庫概述及基本操做
數據庫概述及基本操做

工具建立視圖

數據庫概述及基本操做

選擇視圖和建立工具

數據庫概述及基本操做

將須要建立的視圖拉入框內,並選擇對應的列來完成視圖的建立工做

數據庫概述及基本操做

保存

數據庫概述及基本操做

預覽

數據庫概述及基本操做

3 DML

1 關係操做

關係:在關係數據庫中,關係就是二維表

關係操做就是對錶的操做

選擇 (select): 又稱爲限制,是從關係中選擇出知足給定條件的元祖
select * from test where id=1
投影(projection): 在關係上投影就是從選擇出若干屬性列組成新的關係
select name,password from test where id=1;# 此處至關於投影,是按字段,按列進行相關操做的
連接(join): 將不一樣的兩個關係連接成一個關係

2 insert 語句

INSERT INTO table_name(key1,key2...) VALUES(vaule1,value2...);
向表中插入一行數據,自增字段,缺省字段,可爲空字段能夠不寫

INSERT INTO table_name SELECT ...;

將SELECT 查詢的結果插入到表中

INSERT INTO table_name(key1,key2,...) VALUES(value1,value2,...) ON DUPLICATE KEY UPDATE key1=value1...;

若是主鍵衝突,惟一鍵衝突就執行update後面的設置,這條語句的意思是,主鍵不是在新增記錄,主鍵就在更新部分字段。

INSERT IGNORE INTO table_name(key1,key2,...) VALUES(value1,value2,...);

若是主鍵衝突,惟一鍵衝突就忽略錯誤,返回一個警告,並回滾。

3 update 語句

UPDATE [IGNORE] table_name SET col_name1=expr1[,col_name2=expr2...] [WHERE where_defintion] IGNORE(此處的含義和上述相同)

UPDATE reg SET name='1234' WHERE id=5

UPDATE 若不加where則會致使所有修改,某種狀況下可能會致使嚴重的問題

4 delete 語句

DELETE [IGNORE] FROM table_name [WHERE where_defintion]
刪除符合條件的記錄

4 select語句

SELECT [DISTINCT] select_expr,... [FROM tanle_references] [ WHERE where_defintion] [GROUP BY {col_name | expr | position} [ASC | DESC],... [WITH ROLLUP]] [HAVING where_definition] [ORDER BU {col_name | expr | position} [ ASC | DESC ],...] [LIMIT {[offset,]row_count | row_count OFFSET offset}] [FOR UPDATE | LOCK IN SHARE MODE]

中括號中表明可選
最後面的是排他鎖和共享鎖

FOR UPDATE 會把進行寫鎖定,這是排他鎖

1 簡單查詢

select 10/5;  # 算數計算
select now();  # 查詢當前時間
select * from  employees;  # 查詢該表中的全部數據

2 字符串合併查詢

CONCAT(str1,str2,str3)

select  emp_no,last_name  from  employees;  # 只顯示兩列 
select  emp_no,CONCAT(last_name," ",last_name)  from  employees;  # 使用CONCAT() 將多個字符串進行合併

3 AS 別名定義

select  emp_no  as  no,CONCAT(first_name," ",last_name)  as name  from  employees as  emp;

4 LIMIT 限定返回的條數,經常使用於分頁

select * from  employees LIMIT  2;  # 顯示前兩行數據 

 select * from  employees LIMIT  2  offset  4; # 從第四行開始,顯示下面的兩行數據,默認是從第0行仍是的,
 select * from  employees LIMIT  2,4;  # 此處表示偏移爲2,顯示4行

5 where 字句

運算符 描述
= 等於
<> 不等於
>,<,>=,<= 大於,小於,大於等於,小於等於
BETWEEN 在某個範圍之間,between a and b 等價與 [a,b] a到b的閉區間
LIKE 字符串模式匹配,% 表示任意多個字符,_表示一個字符
IN 指定針對某列的多個可能值
AND
OR

注意: 若是不少表達式須要使用AND,OR 計算邏輯表達式的值時,因爲有結合律的問題,建議使用小括號來避免產生錯誤。

SELECT  * from  employees  WHERE emp_no  < 10015  and  last_name  like  'P%';

 SELECT  * from employees   WHERE  emp_no  BETWEEN  10010  AND  10015  AND  last_name  like  'P%';

 SELECT  *  from  employees  WHERE  emp_no  in  (10001,10002,10010);

6 Order BY 字句

對查詢結果進行排序,能夠是升序,降序 DESC ,默認是升序

SELECT  *  from  employees  ORDER BY  emp_no DESC ;

SELECT  *  from  employees  ORDER BY  gender,emp_no;

SELECT  *  from  employees  ORDER BY  emp_no  desc,gender;   # 一個降,另外一個升

7 DISINCT 不返回重複記錄

select   DISTINCT dept_no from  dept_emp;
select   DISTINCT dept_no,emp_no  from  dept_emp;  # 兩個聯合不重複

8 聚合數據

函數 描述
COUNT(expr) 返回記錄中的數目,若是指定列,則返回非NULL的行數
COUNT(DISTINCT expr,[expr...]) 返回不重複的非NULL 值的行數
AVG([DISTINCT expr]) 返回平均值,返回不一樣值的平均值
MAX(expr),MIN(expr) 最大最,最小值
SUM([DISTINCT] expr) 求和,DISTINCT 返回不一樣值的求和
SELECT  COUNT(DISTINCT emp_no),AVG(emp_no),MAX(emp_no),MIN(emp_no),SUM(emp_no)  from      employees;

SELECT  COUNT(DISTINCT emp_no),AVG(emp_no),MAX(emp_no),MIN(emp_no),SUM(emp_no)  from      employees  WHERE emp_no>10025;

9 分組查詢

使用 GROUP BY 字句,若是有條件,使用Having子句過濾分組,聚合過的結果。默認聚合後只顯示第一個。

-- 簡單的分組查詢
SELECT  COUNT(*),sum(salary) FROM  test.salaries  GROUP  BY  emp_no;  

-- 聚合分組查詢,顯示兩個相同的部分

SELECT  emp_no,sum(salary),count(*),max(salary),min(salary)  from   test.salaries GROUP BY  emp_no,from_date;

SELECT  emp_no,sum(salary),count(*),max(salary),min(salary)  from   test.salaries GROUP BY  emp_no  HAVING  emp_no >10007;

結果以下

數據庫概述及基本操做

數據庫概述及基本操做

數據庫概述及基本操做

執行順序:先是from後面的內容,其次是where過濾,後面是group by 分組,後面是having過濾,最後是order by 排序

10 子查詢

子查詢: 查詢語句能夠嵌套,內部查詢就是子查詢
子查詢必須在一組小括號中
子查詢中不能使用order by;

SELECT  * FROM  employees  WHERE emp_no  in (SELECT  emp_no FROM  employees  WHERE  emp_no>10020)  ORDER BY  emp_no;

SELECT  emp.emp_no,emp.first_name     FROM  (SELECT  * FROM employees  WHERE emp_no > 10010) AS emp  WHERE emp.emp_no < 10015  ORDER BY  emp_no  DESC;

-- IN後面跟單列是比較合適的,子查詢是有意義的,內層選擇只須要對使用的字段進行顯示便可
SELECT  *     FROM  employees  WHERE  emp_no  IN  (SELECT  emp_no    FROM  employees  WHERE  emp_no  > 10025 ) ORDER BY  emp_no  DESC 

-- 子查詢最好的使用方式
SELECT  * FROM  (SELECT  emp_no,first_name,gender  FROM  employees  WHERE emp_no > 10025)  AS emp   WHERE  emp.emp_no < 10030  ORDER BY emp_no Desc;

11 鏈接 join

鏈接 join
交叉鏈接 cross join
笛卡爾乘積,所有交叉
在MySQL中,CROSS JOIN 從語法上和INNER JOIN 等同

1 交叉鏈接 CROSS JOIN ,及笛卡爾乘積,所有交叉
SELECT  * FROM  employees  CROSS  JOIN  dept_manager

每個結果分別和另外一個結果集的全部數據相乘獲得的伺機。

此種鏈接在生產環境中基本上是被廢棄的,不用的

2 內鏈接 inner join ,省略爲 join

等值鏈接,只選擇某些filed相等的元組(行),使用ON 限定關聯的結果
天然鏈接,特殊的等值鏈接,會過濾掉重複的行,用的少

等值鏈接

-- 此種方式因爲沒有配置ON,所以其值和交叉鏈接結果相同
SELECT  * FROM  employees  INNER   JOIN  dept_manager;
-- 此處會選擇兩個表中相同字段相同部分呈現出來,並將兩張表中相同的字段重複顯示出來 
SELECT  * FROM  employees   JOIN  salaries  ON   employees.emp_no=salaries.emp_no

數據庫概述及基本操做

其只顯示等值的連接,對於在任何一張表中不存在的都不會顯示

天然鏈接

-- 此處會選擇兩個表中相同字段相同部分呈現出來,並去除兩張表中的相同字段的列,但某種狀況下兩張表中的含義相同的字段並不是名稱相同,所以不必定會使用到

SELECT  * FROM  employees  NATURAL JOIN  salaries;

數據庫概述及基本操做

3 外鏈接 outer join

左外鏈接

左連接: 左表的全部行都得有,左表和右表對不上的行也是須要顯示的,右表中的數據有沒有無所謂。

SELECT * from  dept_emp  LEFT JOIN  departments   on  departments.dept_no=dept_emp.dept_no;

數據庫概述及基本操做

左表中加入了31號員工,未加入到任何部門,但在部門表中加入了管理部,此處未顯示。

默認是以左表爲主的,右表中的數據全不全無關

右外鏈接

右表中的40行在左表中所有都能找到,因此顯示的是所有,視角在右表

SELECT  * from  employees  RIGHT JOIN   salaries  on employees.emp_no=salaries.emp_no;

此處是等值關係,和具體的行沒有關係

數據庫概述及基本操做

此處未加入部門的31號員工也未出如今此表中。而管理部出如今詞表中

12 自鏈接

表本身和本身連接

SELECT  *  FROM employees  as  manager,employees as  worker  WHERE manager.emp_no=worker.emp_no  and worker.emp_no=10010;

SELECT  *  FROM employees   manager INNER JOIN   employees worker   ON manager.emp_no=worker.emp_no  WHERE  worker.emp_no=10010;

第一種方式寫着簡單,可使用第一種方式進行處理,若須要特別的左連接或右連接時建議使用第二種方式


經過查詢建立工具方式建立

數據庫概述及基本操做

三 MySQL事務

1 概述和屬性

1 概述

事務Transaction
InnoDB 引擎,支持事務
事務,由若干條語句組成,指的是要作的一系列操做。

2 屬性

關係型數據庫中支持事務,必須支持其四種屬性(ACID)

特性 描述
原子性(atomicity) 一個事務是不可分割的工做單位,事務中包括全部操做要麼所有作完,要麼什麼都不作
一致性(consistency) 事務必須是使數據庫從一個一致性狀態變換到另外一個一致性狀態,一致性與原子性是緊密相關的
隔離性(isolation) 一個事務的執行不能被其餘事務干擾,及一個事務內部的操做及使用的數據對併發的其餘事務是隔離的,併發執行的各個事務之間不能互相干擾
持久性(durability) 持久性也成爲永久性(permanence),指一個事務一旦提交,它對數據庫中的數據改變也就應該是永久性的,接下來的其餘操做或者故障不該該對其有任何影響

3 具體理解

原子性: 要求事務中全部的操做,不可分割,不能作了一部分操做,剩下一部分操做。


一致性:多個事務並行執行的結果,應該和事務排隊執行的結果一致,若是事務的併發執行和多線程讀寫共享資源同樣不可預期,就不能保證一致性


隔離性:多個事務訪問共享的數據了,應該互相不干擾,隔離性,指的是究竟在一個事務處理期間,其餘事務能不能訪問的問題


持久性:較好的理解,就是事務提交後,數據不能丟失。

2 事務的隔離級別

1 隔離性很差帶來的問題

1 更新丟失 lost update

事務A 和事務B,更新同一個數據,都讀取了初始值100,A要減10,B要加100,A減去10以後是90,B加100後是200,若A先寫入,則B讀取到的是100,而實際的結果已是90了,而B使用100計算的結果是200,則此時便覆蓋了A的90,將本來的190變成了200.

2 髒讀 (讀取到了中間狀態)

事務A和事務B,事務B讀取到事務A未提交的數據(這個數據多是一箇中間值,也多是事物A回滾的值),只要讀取到了這個被修改的數據就是髒讀,只要沒有提交,就是沒有落地,就是髒數據,若中間出現了狀態,回滾,則這個中間狀態的數據也是髒數據。

3 不可重複讀 (unrepeatable read) 同一條記錄的修改

事務A 在同一個事務中執行了相同兩次的查詢語句,獲得了不一樣的結果,不能保證同一條查詢語句重複讀相同的結果就是不可重複讀。

例如: 事務A查詢了一次後,事務B修改了數據,事務A又查詢了一次,發現數據不一致了。

注意: 髒讀是能夠讀取到相同的數據,可是讀取到的是一個未提交的數據,不是提交的最終結果

4 幻讀(phantom read) (增長了數據的不可重複讀)

事務A中同一個查詢要進行屢次,事務B插入的數據,致使A返回不一樣的結果集,如同幻覺,就是幻讀
數據集有記錄增長了,能夠看作是增長了記錄的不可重複度

2 事務的隔離級別

針對上述問題,提出了4中事務的隔離級別,以下

隔離級別 描述
READ UNCOMMITTED 讀取到未提交的數據
READ COMMITTED 讀已經提交的數據
REPEATABLE READ 可重複讀,MySQL的默認隔離級別
SERIALIZABLE 可串行化,事務鍵徹底隔離,事務不能併發,只能串行化執行

隔離級別越高,串行化越高,數據庫執行效率越低,隔離級別越低,並行度越高,性能越高

隔離級別越高,當前事物處理的中間結果對其餘事務不可見程度越高,

SERIALIZABLE:串行化能解決全部問題,但帶來的確是效率極其低下。

REPEATABLE READ:事務A中同一條查詢語句返回一樣的結果,就是能夠重複復讀取數據了,解決的方式有:
1 對select的數據加鎖,不容許其餘事務刪除,修改操做
2 第一次select的時候,對最後一次確切提交的事務的結果進行快照
但上述方式不能解決幻讀

READ COMMITTED:在事務中,每次select能夠讀取到別的事務剛提交成功的數據,由於讀到的是提交後的數據,解決了髒讀,可是不能解決不可重複讀的問題

READ UNCOMMITTED:能讀取到別的事務尚未提交的數據,徹底沒有隔離性可言,出現了髒讀

3 設置會話或者全局的隔離級別

-- 設置全局或會話級別的隔離級別
SET  [SESSION | GLOBAL ] TRANSACTION  ISOLATION  LEVEL    {READ  UNCOMMITTED | READ COMMITTED | REPEATABLE READ |  SERIALIZABLE } 

-- 查詢隔離級別 
SELECT  @@global.tx_isolation;
SELECT  @@tx_isolation;

4 事務語法

START TRANSACTION 或 BEGIN 開始一個事務,START TRANSACTION 是標準的SQL的語法


使用COMMIT提交事務後,變動成永久變動。


ROLLBACK 能夠在提交事務以前,回滾變動,事務中的操做就如同沒有發生過同樣


SET AUTOCOMMIT 語句能夠禁用或啓用默認的autocommit模式,用於當前連接,SET AUTOCOMMIT=0 表示禁用自動提交事務,若是開啓自動提交,若是有一個修改表的語句執行後,會當即把更新存儲到磁盤上。


開發過程當中自動提交通常都是關閉的,通常的是一次提交屢次修改的值。

測試重複讀

新建一張表,以下

CREATE TABLE `t` (
  `id` int(11) DEFAULT NULL,
  `username` varchar(255) DEFAULT NULL,
  `password` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
mysql> desc  t;
+----------+--------------+------+-----+---------+-------+
| Field    | Type         | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| id       | int(11)      | YES  |     | NULL    |       |
| username | varchar(255) | YES  |     | NULL    |       |
| password | varchar(255) | YES  |     | NULL    |       |
+----------+--------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

查看事務的隔離級別

mysql> select @@tx_isolation;
+-----------------+
| @@tx_isolation  |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set (0.00 sec)

在窗口1關閉自動提交

mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)

在窗口1 查詢t表中內容

mysql> select  * from  t;
Empty set (0.00 sec)

在窗口2中直接進行插入操做並查看

mysql> insert  into  t value(1,'admin','admin');
Query OK, 1 row affected (0.00 sec)

mysql> select  * from  t;
+------+----------+----------+
| id   | username | password |
+------+----------+----------+
|    1 | admin    | admin    |
+------+----------+----------+
1 row in set (0.00 sec)

在窗口1 中再次查詢,無結果,再次進行提交後查詢,則產生告終果,此處代表解決了重複讀問題。

mysql> select  * from  t;
Empty set (0.00 sec)

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> select  * from  t;
+------+----------+----------+
| id   | username | password |
+------+----------+----------+
|    1 | admin    | admin    |
+------+----------+----------+
1 row in set (0.00 sec)
讀已提交測試

修改窗口1 的級別爲讀提交,並提交這次修改

mysql>  set session  transaction isolation level  read committed;
Query OK, 0 rows affected (0.00 sec)

mysql> select @@tx_isolation;
+----------------+
| @@tx_isolation |
+----------------+
| READ-COMMITTED |
+----------------+
1 row in set (0.00 sec)

mysql> commit; 
Query OK, 0 rows affected (0.00 sec)

在窗口2 進行插入

mysql> insert  into  t value(2,'root','root');
Query OK, 1 row affected (0.00 sec)

mysql> select  * from  t;
+------+----------+----------+
| id   | username | password |
+------+----------+----------+
|    1 | admin    | admin    |
|    2 | root     | root     |
+------+----------+----------+
2 rows in set (0.00 sec)

在窗口1 進行查看,修改提交的數據能夠看到,此處代表修改爲讀提交成功

mysql> select  * from  t;
+------+----------+----------+
| id   | username | password |
+------+----------+----------+
|    1 | admin    | admin    |
|    2 | root     | root     |
+------+----------+----------+
2 rows in set (0.00 sec)

3 其餘屬性

1 數據倉庫和數據庫的區別

本質上說沒有區別,都是存放數據的得房,可是數據庫關注的是數據的持久化,數據的關係,爲業務提供系統支持,事務支持,數據倉庫存儲數據是爲了分析或者發掘而設計的表結構,能夠存儲海量數。

數據庫存儲在線交易數據OLTP;數據倉庫存儲歷史數據用於分析OLAP。
數據庫支持在線業務,須要頻繁增刪改查,數據倉庫通常囤積歷史數據支持用於分析的SQL,通常不建議刪改。

2 遊標

操做查詢的結果集的一種方法
能夠將遊標當作是一個指針,指向結果集中的某一行。

3 存儲過程,觸發器

存儲過程(Stored Procedure),數據庫系統中,一段完成特定功能的SQL語句,編寫成相似函數的方式,能夠傳遞參數並調用,支持流程控制語句。

觸發器(Tirgger),由事件觸發的特殊的存儲過程,例如insert時數據觸發

觸發器雖然功能強大,但基本不多使用了

相關文章
相關標籤/搜索