MySQL是最流行的關係型數據庫管理系統,那麼問題來了:什麼是關係型數據庫呢?還有其餘類型數據庫嘛?mysql
關係型數據庫:數據結構是表,由二維表及其之間的聯繫組成的數據組織(MySQL、SQLServer)git
優勢: (1)易於維護:都是使用表結構,格式統一; (2)使用方便:SQL語言通用,可用於複雜查詢; (3)複雜操做:支持SQL,可用於一個表以及多個表之間很是複雜的查詢 缺點: (1)讀寫性能比較差,尤爲是海量數據的高效率讀寫; (2)固定的結構,靈活差; (3)高併發讀寫需求,關係型數據庫對硬盤I/O是很大的瓶頸
非關係型數據庫:嚴格上不是一種數據庫,而是一種數據結構化存儲方法的集合,也能夠是文檔或鍵值對等(Redis、MongoDB)github
優勢: (1)格式靈活:存儲數據的格式能夠是key,value形式、文檔形式、圖片形式 (2)速度快:可使用硬盤或隨機存儲器做爲載體,關係型只能使用硬盤 (3)高擴展性 (4)成本低:數據庫部署簡單,基本都是開源的 缺點: (1)不提供SQL支持,學習和使用成本較高 (2)無事務處理 (3)數據結構相對複雜,複雜查詢性能
老生常談,工欲善其事必先利其器!相對於windows系列的下一步下一步的安裝,咱們着重看下Ubuntu環境下的MySQL安裝與配置踩過的坑吧。sql
爲何要先卸載呢?你能找到這篇文章,可能此刻的你已經在焦慮安裝MySQL爲何老不成功呢,那麼先按下面卸載掉它;若是你是第一次安裝MySQL的話,請忽略這一步的操做。數據庫
# 先更新下Ubuntu的軟件 sudo apt-get update # 刪除 mysql-server sudo apt-get remove mysql-server # 刪除和mysql相關的服務 sudo apt-get autoremove mysql-server # 刪除 mysql-common sudo apt-get remove mmysql-common # 清除殘留數據 dpkg -l | grep ^rc | awk '{print $2}' | sudo xargs dpkg -P
# 坑就在這裏,記得以前安裝的時候是會讓輸入用戶名和密碼的,但不知道怎滴就沒了 sudo apt-get install mysql-server sudo apt-get install mysql-client sudo apt-get install libmysqlclient-dev # 查看MySQL服務是否安裝成功 sudo netstat -tap | grep mysql
sudo vi /etc/mysql/mysql.conf.d ' # 將 bind-address=127.0.0.1 修改成 bind-address=0.0.0.0 # 也能夠改爲你指定終端的IP地址 bind-address=0.0.0.0 ' # 啓動MySQL服務 sudo /etc/init.d/mysql restart # 重啓MySQL服務 sudo /etc/init.d/mysql restart
$ sudo mysql -u root -p Enter password: # 直接就按Enter鍵就好了,由於在安裝mysql-server的時候沒有設置用戶名和密碼;雖然也能夠操做數據庫可是操做起來很是的不方便。 # 若是在數據庫鏈接工具中鏈接該數據庫就會報錯:ERROR 1698 (28000): Access denied for user 'root'@'localhost' mysql> USE mysql; mysql> SELECT user, plugin FROM mysql.user; # 查詢結果 +------------------+-----------------------+ | user | plugin | +------------------+-----------------------+ | root | mauth_socket | | mysql.session | mysql_native_password | | mysql.sys | mysql_native_password | | debian-sys-maint | mysql_native_password | | root | mysql_native_password | +------------------+-----------------------+ 5 rows in set (0.00 sec) # 結果發現root的plugin='auth_socket'並非本地密碼,所以須要修改它 # 修改root帳戶的密碼和plugin的本地密碼驗證方式 mysql> UPDATE mysql.user SET authentication_string=PASSWORD('123'), plugin='mysql_native_password' WHERE user='root'; # 刷新 mysql> FLUSH PRIVILEGES; # 退出 mysql> exit; # 用再次登陸的時候就輸入用戶名密碼就能夠登陸成功了
mysql> SET GLOBAL validate_password_policy=0; mysql> SET GLOBAL validate_password_mixed_case_count=0; mysql> SET GLOBAL validate_password_number_count=3; mysql> SET GLOBAL validate_password_special_char_count=0; mysql> SET GLOBAL validate_password_length=3; mysql> UPDATE mysql.user SET authentication_string=PASSWORD('123'), plugin='mysql_native_password' WHERE user='root'; mysql> FLUSH PRIVILEGES; mysql> exit;
-- 解決密碼問題:https://blog.csdn.net/qq_32799165/article/details/83574665 -- mysql -u root -h 127.0.0.1 -p GRANT ALL PRIVILEGES ON *.* TO 'root'@''IDENTIFIED BY 'rootpassword' WITH GRANT OPTION; FLUSH PRIVILEGES;
-- 用戶管理特殊命令(PS:用戶權限相關數據保存在mysql書庫的user表中,不建議直接對其操做) -- 建立用戶 CREATE USER '用戶名'@'IP地址' IDENTIFIED BY '密碼'; -- 刪除用戶 DROP USER '用戶名'@'IP地址'; -- 修改用戶 RENAME USER '用戶名'@'IP地址' TO '新用戶名'@'新IP地址'; -- 修改密碼 SET PASSWORD FOR '用戶名'@'IP地址' = PASSWORD('新密碼'); -- -- 用戶權限管理(默認權限什麼都沒有) -- 查看權限 SHOW GRANTS FOR '用戶名'@'IP地址'; -- 受權 -- 權限[ ALL PRIVILEGES 除grant外的全部權限 -- SELECT 僅查權限 -- SELECT,INSERT 查和插入權限 -- ... -- USAGE 無訪問權限 -- ALTER 使用alter table -- ALTER ROUTINE 使用alter procedure和drop procedure -- CREATE 使用create table -- CREATE ROUTINE 使用create procedure -- CREATE TEMPORARY TABLES 使用create temporary tables -- CREATE USER 使用create user、drop user、rename user和revoke all privileges -- CREATE VIEW 使用create view -- DELETE 使用delete -- DROP 使用drop table -- EXECUTE 使用call和存儲過程 -- FILE 使用select into outfile 和 load data infile -- GRANT OPTION 使用grant 和 revoke -- INDEX 使用index -- INSERT 使用insert -- LOCK TABLES 使用lock table -- PROCESS 使用show full processlist -- SHOW DATABASES 使用show databases -- SHOW VIEW 使用show view -- UPDATE 使用update -- RELOAD 使用flush -- SHUTDOWN 使用mysqladmin shutdown(關閉MySQL) -- SUPER 使用change master、kill、logs、purge、master和set global。還容許mysqladmin調試登錄 -- REPLICATION CLIENT 服務器位置的訪問 -- REPLICATION SLAVE 由複製從屬使用 -- ] GRANT INSERT(權限) ON '數據庫'.'表' TO '用戶'@'IP地址'; -- 取消權限 REVOKE INSERT(權限) ON '數據庫'.'表' FROM '用戶'@'IP地址'; -- [數據庫.表: 數據庫.* (數據庫中的全部表)、 -- 數據庫.存儲過程 (指定數據庫中的存儲過程) -- 數據庫.表 (指定數據庫中的某張表) -- *.* (全部數據庫) -- ] -- ['用戶名'@'IP地址' (用戶只能在該IP下才能訪問) -- '用戶名'@'192.168.1.%' (用戶只能在改IP段下才能訪問(通配符%表示任意)) -- '用戶名'@'%' (用戶能夠再任意IP下訪問(默認IP地址爲%))
-- 啓動免受權服務端 -- mysqld --skip-grant-tables -- 客戶端 -- mysql -u root -p -- 修改用戶名和密碼 UPDATE mysql.user SET authentication_string=PASSWORD('password') WHERE user='root'; -- FLUSH PRIVILEGES;
【GitHub示例】windows
-- 顯示數據庫 SHOW DATABASES; -- 建立數據庫 -- utf-8 編碼格式的數據庫 CREATE DATABASE databases_example DEFAULT CHARACTER SET utf8 COLLATE utf8_croatian_ci; -- gbk的數據庫 CREATE DATABASE databases_example DEFAULT CHARACTER SET gbk COLLATE gbk_chinese_ci; -- 使用數據庫 USE databases_example;
-- 使用表 USE databases_example; SHOW TABLES; -- 2.1 建立表 USE databases_example; CREATE TABLE IF NOT EXISTS user_info( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT '自增列', -- 設置爲自增,插入數據時無需設置此列,默認將自增(表中只能有一個自增列) uid INT NOT NULL COMMENT '用戶惟一的UID', -- 主鍵不容許有空值,單列它的值必須惟一,若是是多列,則其組合必須惟一 name VARCHAR(30) NOT NULL COMMENT '用戶名', sex INT NOT NULL COMMENT '用戶性別:0男;1女', -- 不能夠爲空 job VARCHAR(30) NULL COMMENT '用戶職業', -- 能夠爲空 age VARCHAR(20) NOT NULL DEFAULT '請填寫' COMMENT '用戶年齡', -- 建立列時添加默認值,未指定默認值自動添加默認值 address TEXT NOT NULL COMMENT '通訊地址', detail TEXT NULL COMMENT '備註' )ENGINE=InnoDB DEFAULT CHARSET=utf8; USE databases_example; CREATE TABLE IF NOT EXISTS sex ( sex_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT '性別id', sex_name VARBINARY(10) NOT NULL COMMENT '實際性別' )ENGINE=InnoDB DEFAULT CHARSET=utf8; -- 2.2 刪除表 -- TRUNCATE:快速清空數據表的所有數據,不會破壞表的結構 TRUNCATE TABLE databases_example.user_info; -- DELETE:刪除表的指定數據 DELETE FROM databases_example.user_info WHERE id = '11'; -- DROP:刪除表,清空數據並會刪除表的結構 DROP TABLE databases_example.user_info; -- 2.3 修改表 -- 添加列 ALTER TABLE databases_example.user_info ADD add_col VARCHAR(20) COMMENT '表添加的列'; ALTER TABLE databases_example.user_info ADD add_col2 VARCHAR(20) COMMENT '修改表添加的列'; -- 刪除列 ALTER TABLE databases_example.user_info DROP COLUMN add_col2; -- 修改列信息 ALTER TABLE databases_example.user_info MODIFY COLUMN add_col INT COMMENT '表修改的列'; ALTER TABLE databases_example.user_info CHANGE COLUMN add_col2 change_col INT COMMENT '修改列名和該列的類型'; -- 添加主鍵 ALTER TABLE databases_example.user_info ADD PRIMARY KEY(add_col); -- 刪除主鍵 ALTER TABLE databases_example.user_info DROP PRIMARY KEY; ALTER TABLE databases_example.user_info MODIFY add_col INT, DROP PRIMARY KEY; -- 添加外鍵 ALTER TABLE '從表' ADD constraint '外鍵名稱_FK_從表_主表' FOREIGN KEY '從表'('外鍵字段') REFERENCES '主表'('主鍵字段'); ALTER TABLE databases_example.user_info ADD constraint '外鍵名稱_FK_從表_主表' FOREIGN KEY '從表'('外鍵字段') REFERENCES '主表'('主鍵字段'); -- 刪除外鍵 ALTER TABLE databases_example.user_info DROP FOREIGN KEY '外鍵名稱'; -- 修改默認值 ALTER TABLE databases_example.user_info ALTER add_col SET DEFAULT 1000; -- 刪除默認值 ALTER TABLE databases_example.user_info ALTER add_col DROP DEFAULT;
-- 3. 數據類型 -- bit -- int -- bigint -- decimal -- float -- double -- char -- varchar -- text -- mediumtext -- longtext -- enum -- set -- DATE -- TIME -- YEAR -- DATETIME -- TIMESTAMP
【GitHub示例】bash
-- 基本語法:INSERT INTO table_name(clo1, clo2, ..., clon) VALUES(value1, value2, ..., valuen); INSERT INTO databases_example.user_info(uid, name, sex, job, age, address, detail, add_col, change_col) VALUES ('000011', '小A', 0, 'Programmer', 19, '北京朝陽酒仙橋', '喜歡睡覺', 20, 25), ('000012', '小B', 0, 'Programmer', 18, '北京朝陽酒仙橋', '喜歡睡覺', 20, 25), ('000013', '小B', 0, 'Programmer', 18, '北京朝陽酒仙橋', '喜歡睡覺', 20, 25);
-- 基本語法:DELETE FROM table_name; DELETE FROM databases_example.user_info WHERE id=1; TRUNCATE TABLE databases_example.sex; DROP TABLE databases_example.sex;
-- 基本語法:UPDATE table_name SET name='要修改內容' WHERE id=1; UPDATE databases_example.user_info SET name='AA' WHERE id=1;
-- 基本語法: SELECT * FROM databases_example.user_info WHERE id>1; -- 【條件】 SELECT * FROM databases_example.user_info WHERE id>1; SELECT * FROM databases_example.user_info WHERE id BETWEEN 2 AND 5; SELECT * FROM databases_example.user_info WHERE id IN(2, 4, 6); SELECT * FROM databases_example.user_info WHERE id NOT IN(2, 4, 6); SELECT * FROM databases_example.user_info WHERE id IN(SELECT uid FROM user_info ); -- 【通配符】 SELECT * FROM databases_example.user_info WHERE name LIKE '小%'; -- 開頭的全部(多個字符串) SELECT * FROM databases_example.user_info WHERE name LIKE '小_'; -- ale開頭的全部(一個字符) -- 【限制(分頁)】 SELECT * FROM databases_example.user_info LIMIT 3; -- 前三行 SELECT * FROM databases_example.user_info LIMIT 4, 5; -- 從第4行開始後的5行 SELECT * FROM databases_example.user_info LIMIT 2 OFFSET 2; -- 從第2行開始後的1行 -- 【排序】 SELECT * FROM databases_example.user_info ORDER BY id ASC; -- 根據 「列」 從小到大排列 SELECT * FROM databases_example.user_info ORDER BY id DESC; -- 根據 「列」 從大到小排列 SELECT * FROM databases_example.user_info ORDER BY id DESC, uid ASC; -- 根據 「列1」 從大到小排列,若是相同則按列2從小到大排序 -- 【分組】 -- 特別的:group by 必須在where以後,order by以前 SELECT id FROM databases_example.user_info WHERE id > 1 GROUP BY age; -- 【連表】 -- 無對應關係則不顯示 SELECT A.id, A.name, B.sex_name FROM databases_example.user_info AS A, databases_example.sex AS B WHERE A.nid = B.nid; -- 無對應關係則不顯示 SELECT A.id, A.name, B.sex_name FROM databases_example.user_info AS A INNER JOIN databases_example.sex AS B ON A.id = B.sex_id; -- A表全部顯示,若是B中無對應關係,則值爲null SELECT A.id, A.name, B.sex_name FROM databases_example.user_info AS A LEFT JOIN databases_example.sex AS B ON A.id = B.sex_id; -- B表全部顯示,若是B中無對應關係,則值爲null SELECT A.id, A.name, B.sex_name FROM databases_example.user_info AS A RIGHT JOIN databases_example.sex AS B ON A.id = B.sex_id; -- 【組合】 -- 組合,自動處理重合 SELECT name FROM databases_example.user_info AS A UNION SELECT sex_name FROM databases_example.sex AS B; -- 組合,不處理重合 SELECT name FROM databases_example.user_info AS A UNION ALL SELECT sex_name FROM databases_example.sex AS B;
視圖就是一張虛擬表(非真實存在),其本質是 sql 語句獲取動態的數據集併爲其命名,因爲視圖是虛擬表,沒法對進行更新和刪除,僅能作查詢操做。【GitHub示例】服務器
-- 語法格式:CREATE VIEW '視圖名稱' AS 'SQL語句' CREATE VIEW user_id AS SELECT uid FROM databases_example.user_info;
-- 因爲視圖是虛擬表,沒法對進行更新和刪除,僅能作查詢操做 SELECT * FROM databases_example.user_id;
-- 語法格式:DROP VIEW '視圖名稱' DROP VIEW databases_example.user_id;
-- 語法格式:ALTER VIEW '視圖名稱' AS 'SQL語句' ALTER VIEW databases_example.user_id AS SELECT * FROM databases_example.user_info;
對某個表進行【增/刪/改】操做的先後若是但願出發某個特定的行爲時,可使用出發器;觸發器用於定製用戶對錶進行【增/刪/改】先後的行爲。【GitHub示例】session
-- 格式:create trigger 觸發器名 觸發時間(BEFORE|AFTER) 觸發事件 on 表名 for each now -- 觸發器觸發的具體事務 -- 執行過程爲:執行觸發事件做用在某個表上前或後,觸發器執行具體的事物 DELIMITER // CREATE TRIGGER tri_before_insert_user_info BEFORE INSERT ON databases_example.user_info FOR EACH ROW BEGIN SELECT COUNT(*) INTO @num; END // DELIMITER ;
INSERT INTO databases_example.user_info(uid, name, sex, job, age, address, detail, add_col, change_col) VALUES('000016', '小C', 0, 'Programmer', 18, '北京朝陽酒仙橋', '喜歡睡覺', 20, 25); SELECT * FROM databases_example.user_info;
DROP TRIGGER tri_before_insert_user_info; INSERT INTO databases_example.user_info(uid, name, sex, job, age, address, detail, add_col, change_col) VALUES('000015', '小B', 0, 'Programmer', 18, '北京朝陽酒仙橋', '喜歡睡覺', 20, 25);
索引用於快速找出數據表中某一列中有一特定值的行。不使用索引,MySQL必須從第一條記錄開始讀完整個表,直到找出相關的行,表越大查詢的時間相應就越長。索引的創建就是快速達到一個位置去搜索數據文件,而沒必要查看全部數據,將會節省大量時間。數據結構
優勢:(1)MySQL列類型均可以設置索引而且被索引; (2)大大加快數據的查詢速度 缺點:(1)須要建立和維護耗費時間,隨着數據量的增長所耗費的時間也會增長 (2)索引也須要佔空間,索引文件有可能比數據文件都會大 (3)對錶中數據進行增長、刪除、修改時,索引也須要動態維護,下降了數據的維護速度。
【GitHub示例】
普通索引僅有一個功能:加速查詢
-- 建立表的時候建立索引 USE databases_example; CREATE TABLE index_table( nid INT NOT NULL AUTO_INCREMENT PRIMARY KEY , name VARCHAR(20) NOT NULL , email VARCHAR(30) NOT NULL , -- 注意:對於建立索引時若是是 BLOB 和 TEXT 類型,必須指定length。 -- create index ix_extra on in1(extra(32)); INDEX ix_name(name) ); -- 令一種建立索引的方式 CREATE INDEX ix_nid ON index_table(nid); -- 刪除索引 DROP INDEX ix_name ON index_table; -- 查看建立的索引 SHOW INDEX FROM databases_example.index_table;
惟一索引有兩個功能:加速查詢 和 惟一約束(可含NULL);也就是說表中只有一個索引,說明一下自增鍵也是索引的一種。
USE databases_example; CREATE TABLE unique_table( nid INT NOT NULL AUTO_INCREMENT , name VARCHAR(20) NOT NULL , email VARCHAR(20) NOT NULL , extra TEXT , UNIQUE ix_nid(nid) ); -- 另外一種建立惟一索引的方法 CREATE UNIQUE INDEX ix_nid ON databases_example.unique_table(nid) ; -- 查看建立的惟一索引 SHOW INDEX FROM databases_example.unique_table; -- 刪除惟一索引 DROP INDEX ix_name ON databases_example.unique_table;
主鍵索引有兩個功能:加速查詢 和 惟一約束(不可含null)。
USE databases_example; CREATE TABLE primary_table( nid INT NOT NULL AUTO_INCREMENT , name VARCHAR(20) NOT NULL , email VARCHAR(30) NOT NULL , PRIMARY KEY (nid) , INDEX ix_nid(name) ); -- 查看建立的主鍵索引 SHOW INDEX FROM databases_example.primary_table; -- 另外一種建立方法 CREATE INDEX ix_name ON databases_example.primary_table(name); -- 刪除主鍵索引 ALTER TABLE databases_example.primary_table DROP PRIMARY KEY; ALTER TABLE databases_example.primary_table MODIFY INT, DROP PRIMARY KEY;
組合索引時將n個列組合成一個索引,其應用場景爲:頻繁的同事使用n列來進行查詢,如:WHERE n1 = 'ALEX' AND n2 = 666。
USE databases_example; CREATE TABLE mixture_table( nid INT NOT NULL AUTO_INCREMENT PRIMARY KEY , name VARCHAR(20) NOT NULL , email VARCHAR(20) NOT NULL ); -- 建立索引 CREATE INDEX ix_nid_name ON mixture_table(nid, name); -- 查看組合索引 SHOW INDEX FROM mixture_table; -- 刪除組合索引 DROP INDEX ix_nid_name ON mixture_table;
【GitHub示例】
DELIMITER // CREATE FUNCTION f1( i1 INT, i2 INT ) RETURNS INT BEGIN DECLARE num INT; SET num = i1 + i2; RETURN(num); END // DELIMITER ;
SELECT f1(2,3) AS add_result;
DROP FUNCTION f1;
【GitHub示例】
-- 1.1 if語句 CREATE PROCEDURE pro_fi() BEGIN DECLARE i INT DEFAULT 0; IF i = 1 THEN SELECT i; ELSEIF i = 2 THEN SELECT 2; ELSE SELECT 22; END IF ; END ; CALL pro_fi();
-- 1.2 case語句 SELECT CASE WHEN uid = 11 THEN 'A' WHEN uid = 12 THEN 'B' WHEN uid = 13 THEN 'C' ELSE 'X' END AS 'test' FROM databases_example.user_info;
-- 2.1 while循環 USE databases_example; DELIMITER // CREATE PROCEDURE pro_while() BEGIN DECLARE num INT; SET num = 0; WHILE num < 100 DO SELECT num; SET num = num + 20; END WHILE; END // DELIMITER ; CALL pro_while();
USE databases_example; DELIMITER // CREATE PROCEDURE pro_repeat() BEGIN DECLARE i INT; SET i=0; REPEAT SELECT i; SET i = i + 1; UNTIL i<= 5 END REPEAT; END // DELIMITER ; CALL pro_repeat();
USE databases_example; DELIMITER // CREATE PROCEDURE pro_loop() BEGIN DECLARE i INT DEFAULT 0; loop_label: LOOP SET i = i +1; IF i < 8 THEN ITERATE loop_label; END IF; IF i >= 10 THEN LEAVE loop_label; END IF; SELECT i; END LOOP; END ; DELIMITER ; CALL pro_loop();
存儲過程是一個SQL語句的集合,當主動去嗲用存儲過程時,其中內部的SQL語句會按照邏輯執行。
【GitHub示例】
-- 1.1 無參數存儲過程 DELIMITER // CREATE PROCEDURE pro_no_para() BEGIN SELECT * FROM databases_example.user_info; END // DELIMITER ; CALL pro_no_para(); -- 1.2 有參數存儲過程 -- 對於存儲過程可接受參數,其參數有三類: -- in 僅用於傳入參數用 -- out 僅用於返回值用 -- inout 既能夠傳入又能夠看成返回值 DELIMITER // CREATE PROCEDURE pro_para( IN i1 INT, IN i2 INT, INOUT i3 INT, OUT o1 INT ) BEGIN DECLARE temp1 INT; DECLARE temp2 INT DEFAULT 0; SET temp1 = 1; SET o1 = i1 + i2 + temp1 + temp2; SET i3 = i3 + 100; END // DELIMITER ; -- 執行有參數的存儲過程(注意傳參順序傳值的) SET @t1 = 4; SET @t2 = 5; CALL pro_para(1, 6, @t1, @t2); SELECT @t1, @t2;
DELIMITER // CREATE PROCEDURE pr4( IN n1 INT, INOUT n3 INT, OUT n2 INT ) BEGIN DECLARE temp1 INT; DECLARE temp2 INT DEFAULT 0; SELECT * FROM databases_example.user_info; SET n2 = n1 + 100; SET n3 = n3 + n1 +100; END // DELIMITER ; SET @t4 = 111; SET @t5 = 222; CALL pr4(100, @t4, @t5); SELECT @t4, @t5;
DROP PROCEDURE pro_no_para;
MySQL事務主要用於處理操做量大,複雜度高的數據。例如:在人員管理系統中刪除一我的員,須要刪除人員的基本資料,也要刪除和該人員相關的信息,如信箱、文章等,這些數據庫操做語句就構成了一個事務。
(1)原子性:一個事務中的全部操做,要麼所有完成,要麼所有不完成,不會結束在中間某個環節;事務在執行過程當中發生錯誤,會被回滾(Rollback)到事務開始前的狀態,就像這個事務歷來沒有執行過同樣 (2)一致性:在事務開始以前和事務結束之後,數據庫的完整性沒有被破壞。這表示寫入的資料必須徹底符合全部的預設規則,這包含資料的精確度、串聯性以及後續數據庫能夠自發性地完成預約的工做。 (3)隔離性:數據庫容許多個併發事務同時對其數據進行讀寫和修改的能力,隔離性能夠防止多個事務併發執行時因爲交叉執行而致使數據的不一致。事務隔離分爲不一樣級別,包括讀未提交(Read uncommitted)、讀提交(read committed)、可重複讀(repeatable read)和串行化(Serializable)。 (4)持久性:事務處理結束後,對數據的修改就是永久的,即使系統故障也不會丟失。
【GitHub示例】
-- 1.建立事務 DELIMITER // CREATE PROCEDURE pro_transaction( OUT p_return_code tinyint ) BEGIN DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN -- ERROR SET p_return_code = 1; ROLLBACK ; END ; DECLARE EXIT HANDLER FOR SQLWARNING BEGIN -- warning SET p_return_code = 2; ROLLBACK ; END ; START TRANSACTION ; INSERT INTO databases_example.user_info(uid, name, sex, job, age, address, detail, add_col, change_col) VALUES('000015', '事務', 0, 'Programmer', 18, '北京朝陽酒仙橋', '喜歡睡覺', 20, 25); COMMIT ; -- success SET p_return_code = 0; END // DELIMITER ;
-- 2.執行事務 SET @i = 0; CALL pro_transaction(@i); SELECT @i;