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 表名 add 【constraint 約束名】 約束類型(字段名) 【外鍵的引用】;
- 案例
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 表名 add【 constraint 約束名】 primary key(字段名);
刪除主鍵
alter table 表名 drop primary key;
4、唯一
添加唯一
alter table 表名 add【 constraint 約束名】 unique(字段名);
刪除唯一
alter table 表名 drop index 索引名;
5、外鍵
添加外鍵
alter table 表名 add【 constraint 約束名】 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 table 表 modify column 字段名 字段類型 約束 auto_increment;
三、刪除自增長列
alter table 表 modify column 字段名 字段類型 約束;
TCL語言
Transaction Control Language 事務控制語言
-
事務:一個或一組sql語句組成一個執行單元,這個執行單元要麼全部執行,要麼全部不執行。
案例:轉賬 張三丰 1000 郭襄 1000 update 表 set 張三丰的餘額=500 where name='張三丰' 意外 update 表 set 郭襄的餘額=1500 where name='郭襄'
-
事務的特性(ACID)
- 原子性:一個事務不可再分割,要麼都執行要麼都不執行
- 一致性:一個事務執行會使數據從一個一致狀態切換到另外一個一致狀態
- 隔離性:一個事務的執行不受其他事務的干擾
- 持久性:一個事務一旦提交,則會永久的改變數據庫的數據.
事務的使用步驟 ★
-
瞭解
-
隱式(自動)事務:沒有明顯的開啓和結束,本身就是一條事務可以自動提交,比如insert、update、delete
-
顯式事務:事務具有明顯的開啓和結束的標記;前提:必須先設置自動提交功能爲禁用
開啓事務的語句; update 表 set 張三丰的餘額=500 where name='張三丰' update 表 set 郭襄的餘額=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 保存實際的數據 增刪改查