MySQL6天筆記——day05

MySQL

全部SQL源文件鏈接:https://pan.baidu.com/s/1wc51qkVetSRybFzcIYGBIg
提取碼:3wpt

DDL語言

常見的約束

  • 含義:一種限制,用於限制表中的數據,爲了保證表中的數據的準確和可靠性。

  • 分類

    六大約束
    	NOT NULL:非空,用於保證該字段的值不能爲空
    	比如姓名、學號等
    	DEFAULT:默認,用於保證該字段有默認值
    	比如性別
    	PRIMARY KEY:主鍵,用於保證該字段的值具有唯一性,並且非空
    	比如學號、員工編號等
    	UNIQUE:唯一,用於保證該字段的值具有唯一性,可以爲空
    	比如座位號
    	CHECK:檢查約束【mysql中不支持】
    	比如年齡、性別
    	FOREIGN KEY:外鍵,用於限制兩個表的關係,用於保證該字段的值必須來自於主表的關聯列的值
    		在從表添加外鍵約束,用於引用主表中某列的值
    	比如學生表的專業編號,員工表的部門編號,員工表的工種編號
    
  • 添加約束的時機:1.創建表時;2.修改表時

  • 約束的添加分類:

    • 列級約束:六大約束語法上都支持,但外鍵約束沒有效果
    • 表級約束:除了非空、默認,其他的都支持
  • 語法

CREATE TABLE 表名{
	字段名 字段類型 列級約束,
	字段名 字段類型,
	表級約束
};

一、創建表時添加約束

#先新建一個庫
CREATE DATABASE students;
  • 1.添加列級約束

  • 語法:直接在字段名和類型後面追加 約束類型即可。只支持:默認、非空、主鍵、唯一

  • 案例

USE students;

DROP TABLE stuinfo;

CREATE TABLE stuinfo(
	id INT PRIMARY KEY,#主鍵
	stuName VARCHAR(20) NOT NULL UNIQUE,#非空
	gender CHAR(1) CHECK(gender='男' OR gender ='女'),#檢查
	seat INT UNIQUE,#唯一
	age INT DEFAULT  18,#默認約束
	majorId INT REFERENCES major(id)#外鍵
);

CREATE TABLE major(
	id INT PRIMARY KEY,
	majorName VARCHAR(20)
);

#查看stuinfo中的所有索引,包括主鍵、外鍵、唯一
SHOW INDEX FROM stuinfo;
  • 2.添加表級約束
  • 語法:語法:在各個字段的最下面 【constraint 約束名】 約束類型(字段名)
TABLE IF EXISTS stuinfo;
CREATE TABLE stuinfo(
	id INT,
	stuname VARCHAR(20),
	gender CHAR(1),
	seat INT,
	age INT,
	majorid INT,
	
	CONSTRAINT pk PRIMARY KEY(id),#主鍵
	CONSTRAINT uq UNIQUE(seat),#唯一鍵
	CONSTRAINT ck CHECK(gender ='男' OR gender  = '女'),#檢查
	CONSTRAINT fk_stuinfo_major FOREIGN KEY(majorid) REFERENCES major(id)#外鍵	
);

SHOW INDEX FROM stuinfo;
  • 通用的寫法:★
CREATE TABLE IF NOT EXISTS stuinfo(
	id INT PRIMARY KEY,
	stuname VARCHAR(20),
	sex CHAR(1),
	age INT DEFAULT 18,
	seat INT UNIQUE,
	majorid INT,
	CONSTRAINT fk_stuinfo_major FOREIGN KEY(majorid) REFERENCES major(id)
);

create table 表名(
  	字段名 字段類型 not null,#非空
  	字段名 字段類型 primary key,#主鍵
  	字段名 字段類型 unique,#唯一
  	字段名 字段類型 default,#默認
  	constraint 約束名 foreign key(字段名) references 主表(被引用列)
);

注意:
  			   支持類型		      可以起約束名			
列級約束		除了外鍵		     不可以
表級約束		除了非空和默認	  可以,但對主鍵無效
  
列級約束可以在一個字段上追加多個,中間用空格隔開,沒有順序要求
  • 主鍵和唯一的區別
		保證唯一性  是否允許爲空    一個表中可以有多少個   是否允許組合
主鍵		√				×			至多有1個           √,但不推薦
唯一		√				√			可以有多個          √,但不推薦

二、修改表時添加約束

  • 語法
1、添加列級約束
alter table 表名 modify column 字段名 字段類型 新約束;

2、添加表級約束
alter table 表名 addconstraint 約束名】 約束類型(字段名) 【外鍵的引用】;
  • 案例
DROP TABLE IF EXISTS stuinfo;
CREATE TABLE stuinfo(
	id INT,
	stuname VARCHAR(20),
	gender CHAR(1),
	seat INT,
	age INT,
	majorid INT
);

DESC stuinfo;
#1.添加非空約束
ALTER TABLE stuinfo MODIFY COLUMN stuname VARCHAR(20)  NOT NULL;

#2.添加默認約束
ALTER TABLE stuinfo MODIFY COLUMN age INT DEFAULT 18;

#3.添加主鍵
    #①列級約束
    ALTER TABLE stuinfo MODIFY COLUMN id INT PRIMARY KEY;
    #②表級約束
    ALTER TABLE stuinfo ADD PRIMARY KEY(id);

#4.添加唯一
    #①列級約束
    ALTER TABLE stuinfo MODIFY COLUMN seat INT UNIQUE;
    #②表級約束
    ALTER TABLE stuinfo ADD UNIQUE(seat);

#5.添加外鍵
ALTER TABLE stuinfo ADD CONSTRAINT fk_stuinfo_major FOREIGN KEY(majorid) REFERENCES major(id); 

三、修改表時刪除約束

#1.刪除非空約束
ALTER TABLE stuinfo MODIFY COLUMN stuname VARCHAR(20) NULL;

#2.刪除默認約束
ALTER TABLE stuinfo MODIFY COLUMN age INT ;

#3.刪除主鍵
ALTER TABLE stuinfo DROP PRIMARY KEY;

#4.刪除唯一
ALTER TABLE stuinfo DROP INDEX seat;

#5.刪除外鍵
ALTER TABLE stuinfo DROP FOREIGN KEY fk_stuinfo_major;

SHOW INDEX FROM stuinfo;

修改表時添加或刪除約束的具體語法總結:

1、非空
添加非空
alter table 表名 modify column 字段名 字段類型 not null;
刪除非空
alter table 表名 modify column 字段名 字段類型 ;

2、默認
添加默認
alter table 表名 modify column 字段名 字段類型 default;
刪除默認
alter table 表名 modify column 字段名 字段類型 ;

3、主鍵
添加主鍵
alter table 表名 addconstraint 約束名】 primary key(字段名);
刪除主鍵
alter table 表名 drop primary key;

4、唯一
添加唯一
alter table 表名 addconstraint 約束名】 unique(字段名);
刪除唯一
alter table 表名 drop index 索引名;

5、外鍵
添加外鍵
alter table 表名 addconstraint 約束名】 foreign key(字段名) references 主表(被引用列);
刪除外鍵
alter table 表名 drop foreign key 約束名;

四、自增長列(標識列)

  • 含義:可以不用手動的插入值,系統提供默認的序列值

  • 特點

    1.不用手動插入值,可以自動提供序列值,默認從1開始,步長爲1
      auto_increment_increment
      如果要更改起始值:手動插入值
      如果要更改步長:更改系統變量
      set auto_increment_increment=;
    2.一個表至多有一個自增長列
    3.自增長列只能支持數值型
    4.自增長列必須爲一個key
    
  • 案例

#一、創建表時設置標識列
DROP TABLE IF EXISTS tab_identity;

CREATE TABLE tab_identity(
	id INT  ,
	NAME FLOAT UNIQUE AUTO_INCREMENT,
	seat INT 
) TRUNCATE TABLE tab_identity;

INSERT INTO tab_identity(id,NAME) VALUES(NULL,'john');

INSERT INTO tab_identity(NAME) VALUES('lucy');

SELECT * FROM tab_identity;

SHOW VARIABLES LIKE '%auto_increment%';

SET auto_increment_increment=3;
  • 語法總結
一、創建表時設置自增長列
create table(
	字段名 字段類型 約束 auto_increment
);

二、修改表時設置自增長列
alter tablemodify column 字段名 字段類型 約束 auto_increment;

三、刪除自增長列
alter tablemodify column 字段名 字段類型 約束;

TCL語言

Transaction Control Language 事務控制語言

  • 事務:一個或一組sql語句組成一個執行單元,這個執行單元要麼全部執行,要麼全部不執行。

    案例:轉賬
    
    張三丰  1000
    郭襄	1000
    
    updateset 張三丰的餘額=500 where name='張三丰'
    意外
    updateset 郭襄的餘額=1500 where name='郭襄'
    
  • 事務的特性(ACID)

    • 原子性:一個事務不可再分割,要麼都執行要麼都不執行
    • 一致性:一個事務執行會使數據從一個一致狀態切換到另外一個一致狀態
    • 隔離性:一個事務的執行不受其他事務的干擾
    • 持久性:一個事務一旦提交,則會永久的改變數據庫的數據.

事務的使用步驟 ★

  • 瞭解

    • 隱式(自動)事務:沒有明顯的開啓和結束,本身就是一條事務可以自動提交,比如insert、update、delete

    • 顯式事務:事務具有明顯的開啓和結束的標記;前提:必須先設置自動提交功能爲禁用

      開啓事務的語句;
      updateset 張三丰的餘額=500 where name='張三丰'
      
      updateset 郭襄的餘額=1500 where name='郭襄' 
      結束事務的語句;
      
  • 具體步驟:

    步驟1:開啓事務
    set autocommit=0;
    start transaction;可選的
    
    步驟2:編寫事務中的sql語句(select insert update delete)
    語句1;
    語句2;
    ...
    
    步驟3:結束事務
    commit;提交事務
    rollback;回滾事務
    
  • 案例

SHOW VARIABLES LIKE 'autocommit';
SHOW ENGINES;

#1.演示事務的使用步驟
DROP TABLE IF EXISTS account;
CREATE TABLE account(
	id INT PRIMARY KEY AUTO_INCREMENT,
	username VARCHAR(20),
	balance DOUBLE
);
INSERT INTO account(username,balance)
VALUES('張無忌',1000),('趙敏',1000);

#開啓事務
SET autocommit=0;
START TRANSACTION;
#編寫一組事務的語句
UPDATE account SET balance = 1000 WHERE username='張無忌';
UPDATE account SET balance = 1000 WHERE username='趙敏';

#結束事務
ROLLBACK;
#commit;

SELECT * FROM account;

併發事務

  • 1、事務的併發問題是如何發生的?

    • 多個事務同時操作 同一個數據庫的相同數據時
  • 2、併發問題都有哪些?

    • 對於同時運行的多個事務, 當這些事務訪問數據庫中相同的數據時, 如果沒有采取必要的隔離機制, 就會導致各種併發問題:
    • 髒讀:一個事務讀取了其他事務還沒有提交的數據,讀到的是其他事務“更新”的數據;
    • 不可重複讀:一個事務多次讀取,結果不一樣;
    • 幻讀:一個事務讀取了其他事務還沒有提交的數據,只是讀到的是 其他事務“插入”的數據。
  • 數據庫事務的隔離性: 數據庫系統必須具有隔離併發運行各個事務的能力, 使它們不會相互影響, 避免各種併發問題.

  • 一個事務與其他事務隔離的程度稱爲隔離級別. 數據庫規定了多種事務隔離級別, 不同隔離級別對應不同的干擾程度, 隔離級別越高, 數據一致性就越好, 但併發性越弱

  • 3、如何解決併發問題?

    • 通過設置隔離級別來解決併發問題
  • 4、隔離級別

							髒讀			不可重複讀		  幻讀
read uncommitted:讀未提交     ×                ×              ×        
read committed:讀已提交      √                ×              ×
repeatable read:可重複讀     √                √              ×
serializable:串行化          √                √              √
  • Oracle 支持的2 種事務隔離級別:READ COMMITED, SERIALIZABLE。Oracle 默認的事務隔離級別爲: READ COMMITED
  • Mysql 支持4 種事務隔離級別. Mysql 默認的事務隔離級別爲: REPEATABLE READ
查看隔離級別
select @@tx_isolation;
設置隔離級別
set session|global transaction isolation level 隔離級別;

#2.演示事務對於delete和truncate的處理的區別
SET autocommit=0;
START TRANSACTION;

DELETE FROM account;
ROLLBACK;

回滾點的演示

  • savepoint 節點名;設置保存點
#3.演示savepoint 的使用
SET autocommit=0;

START TRANSACTION;
DELETE FROM account WHERE id=25;
SAVEPOINT a;#設置保存點
DELETE FROM account WHERE id=28;
ROLLBACK TO a;#回滾到保存點

SELECT * FROM account;

其他

視圖

什麼是視圖?

  • 視圖:虛擬表,和普通表一樣使用。mysql5.1版本出現的新特性,是通過表動態生成的數據。

  • 應用場景

    • 多個地方用到同樣的查詢結果
    • 該查詢結果使用的sql語句較複雜
  • 案例

SELECT stuname,majorname FROM stuinfo s
INNER JOIN major m ON s.`majorid`= m.`id`
WHERE s.`stuname` LIKE '張%';

CREATE VIEW v1 AS
SELECT stuname,majorname
FROM stuinfo s
INNER JOIN major m ON s.`majorid`= m.`id`;

SELECT * FROM v1 WHERE stuname LIKE '張%';

視圖的創建

  • 語法:create view 視圖名 as 查詢語句;
  • 案例
USE myemployees;

#1.查詢姓名中包含a字符的員工名、部門名和工種信息
    #①創建
    CREATE VIEW myv1 AS
    SELECT last_name,department_name,job_title
    FROM employees e
    JOIN departments d ON e.department_id  = d.department_id
    JOIN jobs j ON j.job_id  = e.job_id;

    #②使用
    SELECT * FROM myv1 WHERE last_name LIKE '%a%';

#2.查詢各部門的平均工資級別
    #①創建視圖查看每個部門的平均工資
    CREATE VIEW myv2 AS
    SELECT AVG(salary) ag,department_id
    FROM employees GROUP BY department_id;

    #②使用
    SELECT myv2.`ag`,g.grade_level FROM myv2
    JOIN job_grades g
    ON myv2.`ag` BETWEEN g.`lowest_sal` AND g.`highest_sal`;

#3.查詢平均工資最低的部門信息
SELECT * FROM myv2 ORDER BY ag LIMIT 1;

#4.查詢平均工資最低的部門名和工資
    CREATE VIEW myv3 AS
    SELECT * FROM myv2 ORDER BY ag LIMIT 1;

    SELECT d.*,m.ag FROM myv3 m
    JOIN departments d
    ON m.`department_id`=d.`department_id`;
  • 視圖的好處
    • 重用sql語句
    • 簡化複雜的sql操作,不必知道它的查詢細節
    • 保護數據,提高安全性

視圖的修改

  • 語法

    方式一:
    create or replace view 視圖名 as 查詢語句;
    方式二:
    alter view 視圖名 as 查詢語句;
    
  • 案例

#方式一:
/*
create or replace view  視圖名 as 查詢語句;
*/
SELECT * FROM myv3 

CREATE OR REPLACE VIEW myv3 AS
SELECT AVG(salary),job_id
FROM employees GROUP BY job_id;

#方式二:
/*
語法:
alter view 視圖名 as 查詢語句;
*/
ALTER VIEW myv3 AS SELECT * FROM employees;

視圖的刪除

  • 用戶可以一次刪除一個或者多個視圖,前提是必須有該視圖的drop權限。

  • 語法:drop view 視圖1,視圖2,…;

  • 案例

/*
語法:drop view 視圖名,視圖名,...;
*/
DROP VIEW emp_v1,emp_v2,myv3;

視圖的查看

  • 語法

    desc 視圖名;
    show create view 視圖名;
    
  • 案例

DESC myv3;
SHOW CREATE VIEW myv3;

視圖的更新

  • 1.插入:insert
  • 2.修改:update
  • 3.刪除:delete
  • 4.查看:select
CREATE OR REPLACE VIEW myv1
AS
SELECT last_name,email,salary*12*(1+IFNULL(commission_pct,0)) "annual salary"
FROM employees;

CREATE OR REPLACE VIEW myv1
AS
SELECT last_name,email
FROM employees;

SELECT * FROM myv1;
SELECT * FROM employees;
#1.插入

INSERT INTO myv1 VALUES('張飛','[email protected]');

#2.修改
UPDATE myv1 SET last_name = '張無忌' WHERE last_name='張飛';

#3.刪除
DELETE FROM myv1 WHERE last_name = '張無忌';
  • 注意:視圖一般用於查詢的,而不是更新的,所以具備以下特點的視圖都不允許更新
    • 包含以下關鍵字的sql語句:分組函數、distinct、group by、having、union或者union all
    • 常量視圖
    • Select中包含子查詢
    • join
    • from一個不能更新的視圖
    • where子句的子查詢引用了from子句中的表
#具備以下特點的視圖不允許更新
#①包含以下關鍵字的sql語句:分組函數、distinct、group  by、having、union或者union all

CREATE OR REPLACE VIEW myv1
AS
SELECT MAX(salary) m,department_id
FROM employees
GROUP BY department_id;

SELECT * FROM myv1;

#更新
UPDATE myv1 SET m=9000 WHERE department_id=10;

#②常量視圖
CREATE OR REPLACE VIEW myv2
AS
SELECT 'john' NAME;

SELECT * FROM myv2;

#更新
UPDATE myv2 SET NAME='lucy';

#③Select中包含子查詢

CREATE OR REPLACE VIEW myv3
AS
SELECT department_id,(SELECT MAX(salary) FROM employees) 最高工資
FROM departments;

#更新
SELECT * FROM myv3;
UPDATE myv3 SET 最高工資=100000;

#④join
CREATE OR REPLACE VIEW myv4
AS
SELECT last_name,department_name
FROM employees e
JOIN departments d
ON e.department_id  = d.department_id;

#更新
SELECT * FROM myv4;
UPDATE myv4 SET last_name  = '張飛' WHERE last_name='Whalen';
INSERT INTO myv4 VALUES('陳真','xxxx');

#⑤from一個不能更新的視圖
CREATE OR REPLACE VIEW myv5
AS SELECT * FROM myv3;

#更新
SELECT * FROM myv5;
UPDATE myv5 SET 最高工資=10000 WHERE department_id=60;

#⑥where子句的子查詢引用了from子句中的表

CREATE OR REPLACE VIEW myv6
AS
SELECT last_name,email,salary
FROM employees
WHERE employee_id IN(
	SELECT  manager_id
	FROM employees
	WHERE manager_id IS NOT NULL
);

#更新
SELECT * FROM myv6;
UPDATE myv6 SET salary=10000 WHERE last_name = 'k_ing';

視圖和表的對比

		關鍵字		  是否佔用物理空間			使用
視圖	view		佔用較小,只保存sql邏輯	一般用於查詢
表	    table		保存實際的數據			  增刪改查

歡迎斧正!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章