文章目錄
MySQL
一、SQL結構化查詢語言
概述:通過SQL語言可以操作所有的關係型數據庫。每種數據庫之間會存在差異,稱爲 “方言”。
分類:
DDL(Data Definition Language):數據定義語言,用來定義數據庫對象:庫、表、列等;
DML(Data Manipulation Language):數據操作語言,用來定義數據庫記錄(增、刪、改);
DCL(Data Control Language):數據控制語言,用來定義訪問權限和安全級別;
DQL(Data Query Language):數據查詢語言,用來查詢記錄(數據)。
二、DDL
操作庫:
建庫: create database 庫名;
例: create database mydb;
查看所有庫: show databases;
刪除: drop database 庫名;
例:drop database mydb;
修改數據庫編碼:
alter database 庫名 character set='gbk';
查看數據庫: show create database 庫名;
切換庫: use 庫名;
操作表:
查看該庫下所有的表: show tables;
創建表: create table 表名(字段1 數據類型,字段2 數據類型...);
例: create table student(name varchar(10),age int);
刪除表: drop table 表名;
修改表名:
alter table 舊錶名 rename to 新表名;
對錶頭的操作: alter
添加一個字段:
alter table 表名 add(列名 數據類型);
刪除一個列:
alter table 表名 drop 列名;
修改列名:
alter table 表名 change 舊列名 新列名 新數據類型;
修改列的數據類型:
alter table 表名 modify 列名 新數據類型;
查看建表語句:
show create table 表名;
三、DML
插入數據: insert into
insert into 表名(列名1,列名2...) values(值1,值2...);
給表中所有字段插入值:
insert into 表名 values(值1,值2,...值n);
注意:--字符串類型和日期類型的字段的值要用單引號引起來!
刪除數據:
無條件刪除表中所有數據:
delete from 表名; --逐行刪,效率低
truncate table 表名; --先刪除整個表,再創建一個空表
條件: where
= >= <= > <
and --且
or --或
(is not null) --不爲空
(is null) --爲空 null不能使用=或!=判斷
not --非
between 值1 and 值2 --在值1和值2之間
條件刪除:
delete from 表名 where 條件;
例: delete from student where age>=20; --刪除年齡大於等於20的學生數據
修改表中數據: update
update 表名 set 字段名1=修改的值,字段名2=修改的值... where 條件;
例: update 表名 set age=20 where name='zhangsan'; --把 zhangsan 的年齡改爲20
四、DQL
1、單表查詢
無條件查詢:
--查詢表中所有數據:
select * from 表名;
* --通配符,通配表中所有字段
--查詢個別字段數據:
select 字段名1,字段名2... from 表名;
條件查詢:
select 字段名1,字段名2... from 表名 where 條件;
in(值1,值2...)--等於值1或值2或...
字段運算:
例: select sal,sal*12 from emp; --月薪,月薪*12=年薪
--注意:null參與運算結果是null
ifnull(num,原始值) --如果字段值爲null,則將其替換爲 num ,否則不改變其值
distinct --對字段去重
別名:關鍵字 as
例: select sal as 月薪,sal*12 as 年薪 from emp;
模糊查詢: like
% --通配多個任意字符
_ --通配一個任意字符
例: '_a%' --匹配第二個字母爲a的所有單詞
order by --排序,默認升序 asc:升序 desc:降序
例:
select * from emp order by sal asc;--對工資升序排列
select * from emp order by sal desc;--對工資降序排列
聚合函數:
select count(sal) from emp;--查詢工資這一列有多少行,null不參與統計
select SUM(sal) from emp;--查詢工資的總和
select MAX(sal) from emp;--查詢工資最大值
select MIN(sal) from emp;--查詢工資最小值
select AVG(sal) from emp;--查詢工資平均值
分組: group by
where --在分組之前對數據篩選
having --對分組後的數據再次進行篩選
例:按照部門編號分組,並求出每個部門的平均工資
select deptno as 部門號, AVG(sal) as 部門平均工資 from emp group by deptno;
例:按照部門編號分組,查詢各個部門工資高於1500的員工的工資總和大於6000的部門
select deptno as 部門號, SUM(sal) as 高於3000的工資總和 from emp where sal>3000 group by deptno having 高於3000的工資總和>6000;
分頁查詢: limit
select from 表名 limit 起始索引,本頁條數;
起始索引=(頁碼-1)*本頁條數
例:emp 一共10行數據,每頁展示4行
SELECT * FROM emp LIMIT 0,4; -- 第一頁
SELECT * FROM emp LIMIT 4,4; -- 第二頁
SELECT * FROM emp LIMIT 8,4; -- 第三頁,本頁只有2行
2、約束
約束:對插入表中的數據做出一定的限定,爲了保證數據的有效性和完整性
primary key --主鍵約束:非空且唯一,一張表只能有一個主鍵
方式一:建表時添加約束,字段名後加上約束即可
字段名 數據類型 primary key --添加主鍵約束
方式2:通過修改表添加約束:
alter table 表名 add primary key(字段名);
注意:表中如果已經有超出約束範圍的數據,約束會添加失敗
--聯合主鍵:將多個字段看做一個整體設爲主鍵
create table 表名(字段名1 數據類型,字段名2 數據類型...,primary key(字段名1,字段名2...));
alter table 表名 add primary key(字段名1,字段名2...);
刪除主鍵約束:需要分部刪除
alter table 表名 drop primary key;--刪除唯一
alter table 表名 modify 字段名 數據類型 null;--刪除非空
auto_increment --自增長約束:一般配合主鍵使用
例: id int primary key auto_increment
刪除自增長約束:
alter table 表名 change 字段名 字段名 int;
unique --唯一約束:數據不能重複,對null無效
not null --非空約束
一個字段可以添加多個約束:
字段名 數據類型 not null unique --非空且唯一
unsigned --非負約束
TINYINT --範圍 -128~127
TINYINT UNSIGNED --範圍 0~255
foreign key --外鍵約束
特點: 1、主表一方不能刪除從表一方還在引用的數據;
2、從表一方不能添加主表一方沒有描述的數據。
*添加外鍵約束:
在從表一方添加外鍵約束,去關聯主表一方的主鍵
alter table 從表 add foreign key(從表字段) references 主表(主表字段);
*級聯刪除:
alter table 從表 add foreign key(從表字段) references 主表(主表字段) on delete cascade;
*級聯更新:
alter table 從表 add foreign key(從表字段) references 主表(主表字段) on update cascade;
*處理一對多:在從表中添加一個外鍵,名稱一般爲主表的名稱_id,字段類型一般和主表的主鍵的類型保持一致,爲了保證數據的有效性和完整性,在從表的外鍵上添加外鍵約束即可.
*處理多對多:引入一張中間表,存放兩張表的主鍵,一般會將這兩個字段設置爲聯合主鍵,這樣就可以將多對多的關係拆分成兩個一對多了,爲了保證數據的有效性和完整性,需要在中間表上添加兩個外鍵約束.
*刪除主表中的數據:
方式1: 添加級聯刪除
方式2: 先把帶有外鍵的從表的數據刪除,再刪除主表中的數據
3、多表查詢
--多張表無條件查詢,查詢出的數據是笛卡爾積,沒有任何意義
--笛卡爾積:多張表字段相加,行數相乘
select 表1.*,表2.* from 表1,表2;
--內連接:不符合條件的數據不做展示
格式1: 顯式的內連接 inner可以省略不寫
select a.*,b.* from a inner join b on 表a表b的連接條件;
格式2:隱式的內連接
select a.*,b.* from a,b where 表a表b的連接條件;
左外連接:
--先展示join左邊的(a)表的所有數據,根據條件關聯查詢join右邊的表(b),符合條件展示出來,不符合以null值展示.
select a.*,b.* from a left outer join b on 連接條件; --outer 可以省略不寫
右外連接:
--先展示join右邊的(a)表的所有數據,根據條件關聯查詢join左邊的表(b),符合條件展示出來,不符合以null值展示.
select a.*,b.* from b right outer join a on 連接條件; --outer 可以不寫
子查詢:一個查詢的查詢條件依賴於另一個查詢結果
自連接查詢:給一張表起兩個別名,將他視爲兩張表,來進行查詢
4、複製表
-- 創建一張表,把另一張表中的字段和對應的數據全部複製過去
create table 表名 as select * from 另一張表 where true; --where true 可以省略不寫
-- 創建一張表,只複製另一張表中的個別字段和其對應的數據
create table 表名 as select 字段1,字段2... from 另一張表;
-- 創建一張表,只把另一張表中的字段複製過去
create table 表名 as select * from 另一張表 where false;
--另一張表也可以是臨時表,或者子查詢
五、DCL
root:擁有所有權限
權限賬戶:只擁有部分權限的賬戶
password:md5加密函數(單向加密)
select password('root') --查詢用戶密碼
UPDATE USER SET PASSWORD=PASSWORD('123456') WHERE USER='root';--修改密碼
SELECT * FROM USER; --查詢數據庫用戶
分配權限賬戶:
權限: select insert delete update drop create/ --或all
語法:
GRANT 權限 ON 數據庫名.某張表名 TO '用戶名'@'localhost' IDENTIFIED BY '123456';
--@ 後面可以是localhost,也可以是ip ,也可以給% ,%代表任意一臺計算機都可以連接上來
注意分配多個權限用逗號隔開
GRANT DELETE,SELECT,UPDATE ON day16.employee TO 'eric'@'localhost' IDENTIFIED BY '123456';
刪除賬戶:
Delete FROM user Where User='eric' and Host='localhost';
六、存儲過程 procedure
1、概述
存儲過程是數據庫中的一個對象,存儲在服務端,用來封裝多條SQL語句且帶有邏輯性,可以實現一個功能,由於他在創建時,就已經對SQL進行了編譯,所以執行效率高,而且可以重複調用,類似於Java中的方法。
2、語法
DELIMITER $$
CREATE
PROCEDUR `performance_schema`.`myTestPro`()
BEGIN
--SQL語句
END$$
DELIMITER;
--注意:創建存儲過程需要管理員分配權限
drop procedure 存儲過程名;--刪除存儲過程
show procedure status\G; -- 查看所有的存儲過程狀態 \G:格式化
show create procedure 存儲過程名\G; -- 查看創建存儲過程的語句
3、參數
in:輸入參數
out:輸出參數
inout:輸入輸出參數
4、帶有IF邏輯的存儲過程 if then elseif else
DELIMITER $$
CREATE PROCEDURE pro_testIf(IN num INT,OUT str VARCHAR(2))
BEGIN
IF num>0 THEN
SET str='正數'; -- 注意要用分號結束
ELSEIF num<0 THEN --注意elseif 連寫
SET str='負數';
ELSE
SET str='零';
END IF; --注意要結束if,要寫分號
END $$
DELIMITER;
--調用存儲過程,查看結果
call pro_testIf(100,@rr);
select @rr;
5、while循環 while do
--求1~num的和
DELIMITER $$
CREATE PROCEDURE pro_testWhile(IN num INT,OUT result INT)
BEGIN
-- 定義一個局部變量
DECLARE i INT DEFAULT 1;
DECLARE vsum INT DEFAULT 0;
WHILE i<=num DO
SET vsum = vsum+i;
SET i=i+1;
END WHILE; --結束循環
SET result=vsum;
END $$
DELIMITER;
--控制循環的關鍵字
leave 相當於java中的 break
iterate 相當於java中的 continue
6、變量
全局變量(內置變量):可以在多個會話中訪問
show variables; -- 查看所有全局變量:
select @@變量名 -- 查看某個全局變量:
set @@變量名=新值 -- 修改全局變量:
--設置SQL服務器輸出數據編碼
set @@character_set_results='gbk';
--設置SQL服務器接收數據編碼
set @@character_set_client='utf8';
會話變量: 只存在於當前客戶端與數據庫服務器端的一次連接當中。如果連接斷開,那麼會話變量全部丟失!
set @變量=值 -- 定義會話變量:
select @變量 -- 查看會話變量:
局部變量:在存儲過程或函數中定義的變量是局部變量。只要存儲過程執行完畢,局部變量就丟失!
DECLARE i INT DEFAULT 1; --定義局部變量
set i=10; --給變量設置值
七、觸發器 Trigger
1、概述
觸發器:數據庫中的一個對象,相當於JS中的監聽器,觸發器可以監聽增、刪、改三個動作。
2、語法
DELIMITER $$
CREATE
TRIGGER `mytestdb`.`myTriger` BEFORE/AFTER INSERT/UPDATE/DELETE
ON `mytestdb`.`<Table Name>`
FOR EACH ROW
BEGIN
END$$
DELIMITER ;
BEFORE --行爲發生之前就觸發
AFTER --行爲發生之後觸發
FOR EACH ROW --行級觸發,每操作一行就觸發
old.字段 --可以獲取到被監聽的表中的字段的舊值
new.字段 --可以獲取到被監聽表中更新後的字段的新值
例:修改表t1中的數據,另一張表t2中的數據跟着修改
DELIMITER $$
CREATE
TRIGGER `mytestdb`.`MyTri7` AFTER UPDATE
ON `mytestdb`.`t1`
FOR EACH ROW
BEGIN
UPDATE t2 SET id=new.id,username=new.username,age=new.age WHERE id=old.id;
END$$
DELIMITER ;
八、視圖
視圖:跟表一樣,具有行和列的結構,可以簡化查詢,視圖中的數據,來源於表
--創建視圖
create view my_view as select * from emp;
--查詢視圖,和查表的語法一樣
select * from my_view;
--單表視圖:視圖中的數據來源於一張表
--多表視圖:視圖中的數據來源於多張表的聯合查詢
注意:視圖不能封裝子查詢的數據
--查看創建視圖語句:
show create view my_view;
--刪除視圖
drop view my_view;
--視圖本身不能修改,但可以修改視圖的來源
alter view 視圖名 as 新的select語句;
九、函數
函數:包括內置函數和自定義函數
自定義函數語法:
DELIMITER $$
CREATE
FUNCTION `mytestdb`.`myFun`(num INT)
RETURNS INT
BEGIN
DECLARE i INT DEFAULT 100;
SET i=i+num;
RETURN i;
END$$
DELIMITER ;
調用函數: select 函數名();
函數和存儲過程的區別:
1.存儲過程沒有返回值,函數必須要有返回值。但是存儲過程可以用out實現返回值這個功能
2.存儲過程有in out inout這幾個參數類型,函數沒有
十、數據庫表設計
三大範式
第一範式: 要求表的每個字段必須是不可分割的獨立單元;
第二範式: 在第一範式的基礎上,要求每張表只表達一個意思。表的每個字段都和表的主鍵有依賴。
第三範式: 在第二範式基礎上,要求每張表的主鍵之外的其他字段都只能和主鍵有直接決定依賴關係。