1. 程式人生 > 其它 >mysql-增刪改查-基礎

mysql-增刪改查-基礎

(mysql增刪改查,連表,排序,等,)--教學來自(bilibili狂神!)(筆記是自己學習過程中純手寫,由於是直接複製筆記,有些可以忽略)
(學習方法“先理解,在敲一遍”之後複習三到五遍,網路搜題,做題,就OK了)

systemctl start mysqld --啟動mysql
systemctl status mysqld --檢視mysql狀態

grep -i password /var/log/mysqld.log --通過mysqllog過濾出mysql初始密碼


#### 修改密碼

```mysql
mysql -uroot -p123123
alter user  user() identified by '密碼';    --這裡注意,填寫密碼的時候滿足8位並且儘量是混合密碼(英文、下劃線、數字)
--可以修改密碼策略
----------------------------------------------------------
 set global validate_password_policy=low; 			//將密碼級別改為弱
 set global validate_password_length=6;				//將密碼長度改為6

/*
	執行完之後,我們可以將剛才設定的混合密碼
	改為自己想要的數字密碼或英文密碼了
*/
 set password = password('123456');		    //修改當前密碼
-----------------------------------------------------

flush privileges;  -- 重新整理許可權操作
-----------------------------------------------------------------------

--所用語句都用;號結尾
show databases; -- 檢視所有資料庫
use kuming  -- 切換庫kuming

show tables; -- 檢視資料庫中所有的表
desc biaoming; -- 展示表結構
create database kuming; -- 建立一個名為kuming的資料庫
--exit 退出連線
-- 單行註釋(SQL)
/*
多行註釋
*/



直接破解mysql密碼請點選

資料庫xxx語言CRUD增刪改查

DDL 定義

DML操作

DQL查詢

DCL控制

登入命令詳解

MySQL登入:MySQL -h (sever——ip) -P (port) -u (username) -p (password) -D(database_name) --prompt=(prompt_name),
-h為伺服器IP地址,本機可以寫為localhost或者127.0.0.1,—P(大寫)為埠號,預設為3306,-u為使用者名稱,-p為密碼,——prompt=可以設定命令列提示符

2.1操作資料庫

create database if not exists ku;-- 如果不存在庫ku就建立ku
drop database if exists ku; -- 如果存在ku就刪除資料庫ku
`特殊` 如果你的表名或者欄位是一個特殊字元,就需要帶上``
show databases; 檢視所有資料庫

2.2資料庫的列型別

數值

(常用標黑)

  • tinyint 十分小的資料 1個位元組

  • smallint 較小的資料 2個位元組

  • mediumint 中等大小的資料 3個位元組

  • int 標準的整數 4個位元組 常用的 int

  • bigint 較大的資料 8個位元組

  • float 浮點數 4個位元組

  • double 浮點數 8個位元組

  • decimal 字串形式的浮點數 金融計算的時候,一般是使用decimal(9個位元組)

  • decimal(M,D)
    M的取值範圍是1–65,
    D的取值是0–30.(精度D最大為30,表示有30位小數。)

    對於浮點數(M,D),雙精度數(M,D)或十進位制數(M,D), M必須是>= D(列'money')。

字串

(常用標黑)

  • char 字串固定大小 0~255
  • varchar 可變字串 0~65535 常用的變數
  • tinytext 微型文字 2^8-1
  • text 文字串 2^16-1 儲存大文字

時間日期

(常用標黑)

  • date YYYY-MM-DD 日期格式
  • time HH:mm:ss時間格式
  • datetime YYYY-MM-DD HH:mm:ss 最常用的時間格式
  • timestamp 時間戳 , 如:1952年到現在的毫秒數! 也較為常用!
  • year 年份表示

null

  • 沒有值,未知
  • 注意,不要使用NULL進行運算,結果為NULL
  • comment 註釋

2.3資料庫的欄位屬性

Unsigned:

  • 無符號的整數
  • 聲明瞭該列不能宣告為複數

zerofill:

  • 0填充

  • 不足的位數,使用0來填充; 示例:int(3)定義3個位數 , 5--- 005零填充了位數

    ​ (3)是定義寬度,就算是1也可以寫好多位,只是零填充而已001

自增

  • 通常理解為自增,自動在上一條記錄的基礎上+1(預設)
  • 通常用來設計唯一的主鍵~ index ,必須是整數型別
  • 可以自定義設計主鍵自增的起始值和步長

非空NULL not null

  • 假設設定為 not null ,如果不給他賦值,就會報錯!
  • NULL ,如果不填寫值,預設就是null!

預設

  • 設定預設的值!default
  • sex,預設值為男,如果不指定該列的值,則會有預設的值!

拓展(瞭解就好)

/*每一個表,都必須存在以下五個欄位!未來做專案用的,表示一個記錄存在意義!
id 主鍵
`version` 樂觀鎖
is_delete 偽刪除
gmt_create 建立時間
gmt_update 修改時間
*/

第一個練習(建立表)

  • 建立學生表(列,欄位)使用SQL建立

  • 學號int 登入密碼varchar(20) 姓名,性別varchar(2),出生年月(datatime),家庭住址,email

  • 注意點,使用英文(),表的名稱和欄位儘量使用 `` 括起來

  • AUTO INCREMENT 自增

  • 字串使用 單引號括起來!

  • 所有的語句後面加 , (英文的) , 最後一個不加

  • PRIMARY KEY 主鍵,一般一個表只有一個唯一的主鍵!

  • default預設值

  • comment註釋

CREATE TABLE IF NOT	EXISTS `student`(
`id` int(4) not null auto_increment comment '學號',
`name` varchar(30) not null default '匿名' comment '姓名',
`pwd` VARCHAR(20) not null default '123456' comment '密碼',
`sex` VARCHAR(20) not null default '女' comment '性別',
`birthday` datetime default null comment '出生日期',
`address` varchar(100) default null comment '家庭住址',
`email` varchar(50) default null comment '郵箱',
primary key(`id`)
)ENGINE=INNODB DEFAULT charset=utf8

desc詳解

| Field | Type | Null | Key | Default | Extra |

Field:欄位表示的是列名

Type:欄位表示的是列的資料型別

Null :欄位表示這個列是否能取空值

Key :在mysql中key 和index 是一樣的意思,這個Key列可能會看到有如 下的值:PRI(主鍵)、MUL(普通的b-tree索引)、UNI(唯一索引)

Default: 列的預設值

Extra :其它資訊

create格式(必須會)

CREATE TABLE [IF NOT EXISTS]`表名`(
`欄位名` 列型別[屬性] [索引] [註釋],
……
`欄位名` 列型別[屬性] [索引] [註釋]
[設定主鍵列]
)[表型別][字符集設定][註釋]

2.5、資料表的型別

引擎可能是面試題

--關於資料庫引擎ENGINE=
/*
INNOOB 預設使用
MYISAM 早些年前使用
*/
對比 MYISAM INNODB
事務支援 不支援 支援
資料行鎖定 不支援 支援
外來鍵約束 不支援 支援
全文索引 支援 不支援
表空間的大小 較小 較大,約為MYISAM的兩倍

常規使用操作對比

  • MYISAM 節約空間,速度較快
  • INNODB 安全性高,事務的處理,多表多使用者操作

在物理機上的位置

​ 所有資料庫檔案都存在data目錄下,一個資料夾就對應一個數據庫

本質還是檔案的儲存!

Mysql 引擎在物理機檔案上的區別

  • innoDB在資料庫表中只有一個*.frm檔案,以及上級目錄下的ibdata1檔案
  • MYISAM對應檔案
    • *.frm 表結構的定義檔案
    • *.MYD 資料檔案(data)
    • *.MYI 索引檔案(index)

常用命令

數值資料庫字符集編碼 CHARSET=utf8

​``` mysql
show create table 表名  --展示表結構(查看錶的定義語句)
show create database 庫名 --檢視建立資料庫的語句
desc 表名 --顯示錶結構

2.6修改,刪除表

修改

--修改表名 alter table 舊名 rename as 新名;
	alter table student1 rename as student;
--增加表的欄位 alter table 表名 add 欄位名 欄位屬性;
	alter table student add age int(11);
--修改表的欄位(重新命名,修改約束)
alter table 表名 modify 欄位名 列屬性 --修改約束
	alter table student modify age varchar(10);
alter table 表名 change 舊名 新名 新列屬性; --修改欄位名
	alter table student change age age1 int(1);
--刪除表字段 alter table 表名 drop 欄位名;
	alter table student drop age1;

刪除

-- 刪除表(如果表存在在刪除)
drop table if exists 表名;

提示:****所有的建立和刪除操作儘量加上判斷,以免報錯

注意點

  • ``欄位名,使用這個包裹!這個在linux的命令列不好使,在mysql可以
  • 註釋-- /* */
  • sql關鍵字大小寫不敏感,建議大家寫小寫
  • 所有符號都用英文
  • 只有最後一句不需要加,號

MySQL資料管理

3.1、外來鍵(瞭解即可)

方法一、在建立表的時候,增加約束(麻煩,比較複雜)

--學生表的gradeid欄位 要去引用年級表的gradeid
--定義外來鍵key
--給這個外來鍵新增約束(執行引用)references 引用
grade	CREATE TABLE `grade` (
  `gradeid` int(10) NOT NULL AUTO_INCREMENT COMMENT '年紀id',
  `gradename` varchar(255) NOT NULL COMMENT '年級名稱',
  PRIMARY KEY (`gradeid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

student	CREATE TABLE `student` (
  `id` int(4) NOT NULL AUTO_INCREMENT COMMENT '學號',
  `name` varchar(30) NOT NULL DEFAULT '匿名' COMMENT '姓名',
  `pwd` varchar(20) NOT NULL DEFAULT '123456' COMMENT '密碼',
  `sex` varchar(20) NOT NULL DEFAULT '女' COMMENT '性別',
  `birthday` datetime DEFAULT NULL COMMENT '出生日期',
  `gradeid` int(10) NOT NULL COMMENT '學生的年級',
  `address` varchar(100) DEFAULT NULL COMMENT '家庭住址',
  `email` varchar(50) DEFAULT NULL COMMENT '郵箱',
  PRIMARY KEY (`id`),
  KEY `fk_gradeid` (`gradeid`),
  CONSTRAINT `fk_gradeid` FOREIGN KEY (`gradeid`) REFERENCES `grade` (`gradeid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

刪除有外來鍵關係的表的時候,必須要先刪除引用別人的表(從表),在刪除被引用的表(主表)

方法二:建立表完成後,新增外來鍵約束

alter table `student`
add CONSTRAINT `fk_gradeid` foreign key(`gradeid`) REFERENCES `grade`(`gradeid`);
-- alter table 表名
add constraint 約束名 foreign key(作為外來鍵的列) references 哪個表(哪個欄位)

以上的操作都是物理外來鍵,資料庫級別的外來鍵,我們不建議使用!(避免資料庫過多造成困擾)

最佳實踐

  • 資料庫就是單純的表,只是用來存資料,只用行(資料)和列(欄位)
  • 我們想使用多張表的資料,想使用外來鍵(可以用程式去實現)

3.2、DML語言(全部記住,背下來)

資料庫意義:資料儲存,資料管理

DML語言:資料操作語言

  • insert
  • update
  • delete

3.3新增,插入語句

--插入語句insert into

-- 插入單個欄位
insert into `student`(`name`) values('李四');

-- 插入多個欄位
insert into `student`(`name`,`pwd`,`sex`) values('張三','111111','變性人');

-- 插入多個欄位2
insert into `student`(`name`,`pwd`,`sex`) values('王五','115151','外星人'),('戰神','x','埼玉');

-- 插入多個欄位3 (可以不寫欄位名,但是值要一一對應表字段)
insert into `student`values(7,'ailis','','女','20200101','洛杉磯','不告訴你');

語法:

insert into 表名(欄位名1,欄位名2,欄位名3....) values('值1','值2','值3'.....);

注意事項:

  • 欄位之間用逗號隔開
  • 欄位可以省略,但是後面值要一一對應,不能少
  • 可以同時插入多條資料,如:values(),() (與插入多個欄位2一樣)

3.4修改

update

-- 修改單個欄位
update student set `name`='空氣' where id=1;

-- 不加條件修改欄位,(會改動整個表要修改的列)直接爆炸
update student set `name` ='複製人'; --修改了整個所有行的name欄位

-- 修改多個屬性,逗號隔開
update student set `name`='戰神',`email`='222#@126.com' where sex='女';

-- 通過多個條件定位資料,更精確定位,使用 and 
update student set `name`='憨批' where `sex` = '女' and `address`='洛杉磯';

語法

update 表名 set colnum_name='values',colnum_name='values'... where [條件]

條件:****where子句 運算子 id 等於某個值,大於某個值,在某個區間內修改...

操作符 含義 範圍 結果
= 等於 5=6 false
<>或!= 不等於 5<>6 true
< 小於 5<6 true
> 大於 5>6 false
<= 小於等於 5<=6
>= 大於等於 5>=6 false
and 5and9
or 3or>5 1..3or5..
-- where 條件練習
update `student` set `name`='人' where `id`>2 ;
update `student` set `name`='人' where `id`<>2 ;
update `student` set `name`='A級' where `id`=2 or `id`=5 ;
update `student` set `name`='c級' where `id`=1 and `sex`='女' ;

注意:

  • -- colnum-name 是資料庫的列,儘量帶上``號
  • 條件,篩選的條件,如果沒有指定條件,會修改表中所有列
  • value 十一個具體的值,也可以是一個變數
-- 時間函式示例 current_date(當前日期)
update `student` set `birthday`=CURRENT_DATE where `name`='複製人';

3.5刪除

delete:用來刪除表資料,不刪除表結構

語法: delete from 表名 [where 條件]

-- 刪除表資料(避免這樣寫會全部刪除)
delete from 表名;

-- 清空表資料,並重置自增列
truncate 表名

delete 與 truncate
/*相同點,都能刪除資料,都不會刪除表結構
  不同點:truncate 重置自增列,和不影響事務*/
以上部分儘量不要使用

-- 刪除表指定資料
delete from `student` where id=1; 

4、DQL查詢資料

(Data Query Languang:資料查詢語言)

select

查詢語法

****依次排序(從上到下不能亂)**(語法順序很重要)

*SELECT 欄位 FROM TABLE as 名字
INNER JOIN -- 連表
-- 也可以起別名

on 等值判斷
WHERE 欄位 -- 條件 子查詢
GROUP BY -- 通過欄位分組
HAVING -- 過濾分組資訊
ORDER BY -- 排序
limit -- 分頁**

-- 查詢全部欄位 
SELECT * FROM `student`

-- 查詢指定欄位
select `studentname`,`sex` from `student`;

-- 別名,給結果起一個名字 as (欄位表名都可以起別名)
select `studentname`as 姓名,`sex`as 性別 from  `student` as 學生表;

-- 函式 Concat (a,b)拼接字串
select concat('姓名:',`studentname`) as 學生姓名 from `student`;

語法:select 欄位... from 表名;

列的名字可以起別名: AS 欄位名 as 別名 表名 as 別名

去重

-- 去重 distinct
-- (去掉了studentno列重複的行)
select distinct `studentno` from `result`; 

資料庫的列(表示式)

-- 檢視系統版本(函式)
select VERSION();

-- 用來計算
select 5*3-1 as 結果為;

-- 學員成績+1分檢視
select `studentno`,`studentresult`+1 as '加分後' from `result`; 
select studentno*100 from student ; -- 也可以*

資料庫中的表示式:文字值,列,null,函式,計算表示式,系統變數

select 表示式 from 表;

4.3、where條件子句

作用:檢索資料中符合條件的值

搜尋的條件由一個或者多個表示式組成!結果布林值

邏輯運算子:(儘量使用英文,不使用符號)

運算子 語法 描述
and && a anb b a&&b 邏輯與,兩個都為真,結果為真
or || a or b a||b 邏輯或,一個為真,結果為真
not ! not a !a 邏輯非,真為假,假為真 (取反)

與、或、非三種簡單示例:

-- 查詢成績在95~100之間 三種方式
select studentresult FROM result where studentresult>=95 and studentresult<=100;

-- and && 
select studentresult FROM result where studentresult>=95 && studentresult<=100;

-- 模糊查詢[區間] between
select studentresult FROM result where studentresult between 95 and 100;

-- 除了1000號學生之外的同學的成績 兩種方式
SELECT studentno,studentresult from result WHERE studentno  !=1000;
SELECT studentno,studentresult from result WHERE not studentno =1000;
-- 查詢60分以下和90分以上的成績
SELECT studentresult FROM result WHERE studentresult>90 or studentresult<60;
SELECT studentresult FROM result WHERE studentresult>90 || studentresult<60;

模糊查詢

運算子 語法 描述
is null a is null 如果操作符為null,結果為真
is not null a is not null 如果操作符不為null,結果為真
between a between b and c 若a在b和c之間,則結果為真
like a like b sql匹配,如果a匹配b,則結果為真
in a in (a1,a2,a3).... 假設a在a1或者a2...其中的某個值中,結果為真

LIKE模糊查詢

-- 查詢姓埼的同學
-- like結合 %(代表0到任意個字元) _(代表一個字元) %_(適用於like)
SELECT studentname FROM student WHERE studentname LIKE '埼%';

-- 查詢姓張的同學,名字後面只有一個字的
SELECT studentname FROM student WHERE studentname LIKE '張_';

-- 查詢姓張的同學,名字後面只有兩個字的(兩個_ _線)
SELECT studentname FROM student WHERE studentname LIKE '張__';

-- 查詢名字中間帶有空的同學(之所以用%號是因為怕有四個字的同學)
SELECT studentname FROM student WHERE studentname LIKE '%空%';

IN模糊查詢

-- 查詢1001,1002號學員
SELECT studentno,studentname FROM student WHERE studentno IN (1001,1002);
-- 查詢在北京和洛陽的同學
SELECT studentno,studentname FROM student WHERE address IN ('北京','洛陽');

is null 和 is not null

-- 查詢地址不為空的同學
SELECT studentno,studentname FROM student WHERE address is not null; -- 寫法1
SELECT studentno,studentname FROM student WHERE address!=''; -- 寫法2

4.4、連表查詢

-- 聯表查詢 join 
/*思路
1.分析需求,分析查詢的欄位來自哪些表,(連表查詢)
2.確定使用哪種連線查詢?七種
確定交叉點(這兩個表中哪個資料是相同的)
3.判斷條件
*/
/*
解題思路
我要查詢哪些資料 select ...
從哪幾個表中查 from 表  xxx join 連線的表 on 交叉條件
假設存在一種多張表查詢,先查詢兩張表然後在慢慢增加
-- from a left join b 以a表為基準查詢
-- from a right join b 以b表為基準查詢
*/

join(連線的表) on(條件判斷) 連線查詢

where 等值查詢
-- 程式碼例項
select * from student
select * from result
-- 查詢參加了考試的同學(學號,姓名,科目編號,分數)
SELECT s.studentno,studentname,subjectno,studentresult 
FROM student AS s 
INNER JOIN result AS r
ON s.studentno=r.studentno

-- right join 
SELECT s.studentno,studentname,subjectno,studentresult -- 確定要查詢哪些資料 別名s.判斷去用那張表的相同列資料
FROM student s   						-- 別名 as 可以省略
RIGHT JOIN result r					-- 右查詢以右表為基準 result
ON s.studentno=r.studentno 	-- 確定交叉條件(兩張表同樣的列資料)

-- left join 以左表為準查詢
SELECT s.studentno,studentname,subjectno,studentresult 
FROM student s   						
left JOIN result r					
ON s.studentno=r.studentno 

-- 查詢參加考試的同學資訊:學號,學生姓名,科目名,分數 (三表查詢)
SELECT s.studentno,studentname,subjectname,studentresult
from student s
RIGHT JOIN result r
ON s.studentno=r.studentno
INNER JOIN `subject` ll
ON ll.subjectno=r.subjectno
inner join 如果表中至少有一個匹配,就返回行
left join 會從左表中返回所有的值,即使右邊表中沒有匹配
right join 會從右表中返回所有的值,即使左表中沒有匹配

自連線****(瞭解)

自己的表和自己的表連線,核心:一張表拆為兩張一樣的表即可

父類

categoryid categorname
2 資訊科技
3 軟體開發
5 美術設計

父類categoryid=子類pid

子類

pid categorryid categoryname
3 4 資料庫
2 8 辦公資訊
3 6 web開發
5 7 ps技術
-- 連表查詢
-- 把一張表拆分為兩張表
SELECT a.categoryname a,b.categoryname b
from  category a ,category b
where a.pid=b.categoryid
order by a.pid desc		-- 以父pid倒敘排列
limit 2;  -- 只顯示兩行

4.5、分頁和排序

排序

-- 排序:升序 asc 降序 desc
-- order by 欄位 升序或者降序
-- 查詢的結果根據 成績降序 排序
select studentname,a.studentno,`subjectname`,studentresult
from student a
INNER JOIN `result` b
on a.studentno=b.studentno
INNER JOIN `subject` ll
on b.subjectno=ll.subjectno
order by studentresult desc;  --	降序 升序是 asc

分頁

limit

-- 語法 select * from 表名 limit i,n;    limit必須在表的最後邊
i:為查詢結果的索引值(預設從0開始),當i=0時可省略i
n:為查詢結果返回的數量
i與n之間使用英文逗號","隔開

-- 查詢10條資料,索引從0到9,第1條記錄到第10條記錄
select * from t_user limit 10;
select * from t_user limit 0,10;

-- 查詢8條資料,索引從5到12,第6條記錄到第13條記錄
select * from t_user limit 5,8;

4.6、子查詢

連表和巢狀掌握一種就OK

-- 分數不小於80分學生學號和姓名
select  b.studentno,studentresult,studentname
from student a
right JOIN result b
on a.studentno=b.studentno
where b.studentresult>=80
order by b.studentresult desc

-- 在上面基礎上在增加一個科目,高等數學-2
-- 聯表查詢
select  b.studentno,studentresult,studentname,subjectname
from student a
right JOIN result b
on a.studentno=b.studentno
inner join subject l
on l.`subjectno`=b.subjectno
where b.studentresult>=80 and subjectname='高等數學-2'
order by b.studentresult desc

-- 巢狀查詢 
select  b.studentno,studentresult,studentname
from student a
right JOIN result b
on a.studentno=b.studentno
where studentresult>=80 
and `subjectno`=(SELECT subjectno from `subject`
where `subjectname`='高等數學-2')
 
-- 巢狀示例2(有裡及外)不太實用
SELECT studentno,studentname FROM student WHERE studentno IN(
SELECT studentno FROM result WHERE studentresult>80 AND subjectno=(
SELECT subjectno FROM `subject` WHERE `subjectname`='高等數學-2'))

5、MySql函式

常用函式

-- 常用函式
-- ()裡的內容是示例
-- 數學運算
SELECT abs(-9) -- 絕對值
SELECT ceiling(9.1) -- 向上取整 
SELECT rand() -- 返回一個0~1之間的隨機數
SELECT sign(10) -- 判斷一個數的符號
-- 字串函式
SELECT CHAR_LENGTH('持之以恆') -- 顯示字串長度
SELECT CONCAT('one','朝夕','one','收穫') -- 拼接字串
SELECT LOWER('yifeichongtian')  -- 轉換成小寫字母
SELECT UPPER('yifeichongtian')  -- 轉換成大字字母
SELECT INSTR('yang','g') -- 返回第一次出現的子串的索引 g在本字串為4
SELECT REPLACE('戰爭','戰','不')-- 替換出現的字串
SELECT SUBSTR('加油只爭朝夕',3,4)-- 返回指定的子字串(源字串,擷取位置,擷取長度)
SELECT REVERSE('加油只爭朝夕')-- 反轉字串

-- 上邊部分了解即可
-- 時間和日期函式(記住)
SELECT CURRENT_DATE()-- 獲取當前日期
SELECT CURDATE()-- 獲取當前日期 
SELECT NOW() -- 獲取當前年月日時分秒 
SELECT LOCALTIME()-- 本地時間
SELECT SYSDATE() -- 系統時間

SELECT YEAR(NOW()) -- 當前年
SELECT MONTH(NOW())-- 當前月
SELECT DAY(NOW())-- 當前日
SELECT HOUR(NOW())-- 當前時
SELECT MINUTE(NOW())-- 當前分
SELECT SECOND(NOW())-- 當前秒

-- 在建立時間欄位的時候

DEFAULT CURRENT_TIMESTAMP
-- 表示當插入資料的時候,該欄位預設值為當前時間 5.7一下無法執行

ON UPDATE CURRENT_TIMESTAMP
-- 表示每次更新這條資料的時候,該欄位都會更新成當前時間 --5.7一下無法執行

-- 系統
SELECT SYSTEM_USER()
SELECT USER()
SELECT VERSION()

5.1聚合函式(常用)

函式名稱 描述
count() 計數
sum() 求和
avg() 平均值
max() 最大值
min() 最小值
...... .......
-- 聚合函式
-- 統計行數,就使用這個count()
SELECT COUNT(studentno) FROM student; -- count(欄位),會忽略所有的null
-- 一般用第一個 後兩個幾乎沒有區別
SELECT COUNT(*) FROM student; -- count(*)不會忽略null 本質統計行數
SELECT COUNT(1) FROM student; -- count(1)不會忽略所有null 本質統計行數

SELECT SUM(studentresult) as 總分 FROM result; -- 統計總分
SELECT AVG(studentresult) as 平均分 FROM result; -- 統計平均分
SELECT MAX(studentresult) as 最高分 FROM result; -- 統計最高分
SELECT MIN(studentresult) as 最低分 FROM result; -- 統計最低分

分組過濾

group by 欄位 having

-- 查詢不同課程的平均分,最高分,最低分,平均分大於80
SELECT `subjectname`,AVG(studentresult) 平均分,
MAX(studentresult) 最高分,MIN(studentresult) 最低分
FROM result a 
INNER JOIN `subject` b
ON a.`subjectno` = b.`subjectno`
GROUP BY a.`subjectno` -- 通過什麼欄位來分組
HAVING 平均分<60; -- 相當於條件篩選,但它與WHERE篩選不同,HAVING是對於GROUP BY物件進行篩選。

5.3、資料庫級別的MD5加密(擴充套件)

什麼是MD5?

主要增強演算法複雜度和不可逆性。

MD5不可逆,具體的值md5是一樣的

MD5破解網站的原理,背後有一個字典,MD5加密後的值,加密的前值

-- 原表
CREATE table `testMD5`(
`id` int(4) not null ,
`name` varchar(20) not null ,
`pwd` varchar(50) not null,
primary key(`id`)
)engine=innodb default charset=utf8;
-- MD5()加密函式
-- 明文密碼
insert into testmd5 values('1','zhangsan','123456'),('2','lisi','14556'),('3','wangwu','464821');
-- 加密
update 
update testmd5 SET pwd=MD5(pwd) where id=1; -- 加密了id=1的行

update testmd5 set pwd=MD5(pwd);-- 加密了全部pwd欄位,加密了全部密碼

-- 插入數值的時候就加密
insert into testmd5 values('5','小紅',MD5('123456'))

-- 如何校驗:將使用者傳遞進來的密碼,進行MD5加密,然後對比加密後的值
select `pwd` from testmd5 where  pwd=MD5('123456');
update testmd5 set pwd=MD5(pwd); -- 再次加密(加密了兩次)
select `pwd` from testmd5 where   pwd=MD5(MD5('123456')); -- 巢狀MD5直接查出加密後密碼

6、事務(重要)


什麼是事務

要麼都成功,要麼都失敗


1、SQL執行 A給 B 轉賬 A1000 ---> B 200

2、SQL執行 B收到A的錢 A800 ----> B 400


事務原則:ACID原則:原子性,一致性,隔離性,永續性 (髒讀,幻讀.....)

點選參考部落格連結:


原子性(Atomicity)

要麼都成功,要麼都失敗

一致性(Consistency)

事務前後資料的完整性必須保持一致。

隔離性(Isolation)

多個使用者併發訪問資料庫時,資料庫為每一個使用者開啟的事務,不能被其他事務的操作資料所幹擾,多個併發事務之間要相互隔離。

永續性(Durability)

事務一旦提交則不可逆,被持久化存到資料庫,接下來即使資料庫發生故障也不應該對其有任何影響


隔離所導致的一些問題

髒讀

指一個事務讀取了另外一個事務未提交的資料。

不可重複讀

在一個事務內讀取表中的某一行資料,多次讀取結果不同。(這個不一定是錯誤,只是某些場合不對)

虛讀(幻讀)

是指在一個事務內讀取到了別的事務插入的資料,導致前後讀取數量總量不一致。
(一般是行影響,如下圖所示:多了一行)


執行事務

-- mysql 是預設開啟事務自動提交的
SET autocommit = 0 -- 關閉
SET autocommit = 1 -- 開啟 (預設的)

-- 手動處理事務
SET autocommit = 0 -- 關閉自動提交

-- 事務開啟
start TRANSACTION -- 標記一個事務的開始,從這個之後的sql 都在同一個事務內

-- 提交:持久化 (成功!)
commit
-- 回滾:回到的原來的樣子(失敗!)
ROLLBACK

-- 事務結束
SET autocommit = 1 --開啟自動提交

-- 瞭解
SAVEPOINT -- 儲存點名  設定一個事務的儲存點
ROLLBACK TO SAVEPOINT -- 儲存名 回滾到儲存點
RELEASE SAVEPOINT -- 儲存名 撤銷儲存點

模擬場景

-- 上邊是庫表

-- 模擬轉賬:事務(事務是一組不可再分割的操作集合)
set autocommit = 0; -- 關閉自動提交
start transaction -- 開啟一個事務(一組事務)

UPDATE account SET money=money-500 WHERE `name` = 'a' ;-- a 減500
UPDATE account SET money=money+500 WHERE `name` = 'b' ;-- b 加500

commit; -- 提交事務,就被持久化了
rollback; -- 回滾

set autocommit = 1; -- 開啟自動提交 (回覆預設值)

7、索引

MySQL索引背後的資料結構及演算法原理

MySQL官方對索引的定義為:索引(Index)是幫助MySQL高效獲取資料的資料結構。提取句子主幹,就可以得到索引的本質:索引是資料結構。

索引的分類

在一個表中,主鍵索引只能有一個,唯一索引可以有多個

  • 主鍵索引 primary key
    • 唯一的標識,主鍵不可重複,只能有 一個列作為主鍵
  • 唯一索引 unique key
    • 避免重複的列出現,唯一索引可以重複,多個列都可以表示為唯一索引
  • 常規索引 key或index
    • 預設的,index,key 關鍵字來設定
  • 全文索引 fulltext
    • 在特定的資料庫引擎下才有,MyISAM
    • 快速定位資料
    • InnoDB 1.2.x版本開始支援全文檢索

基礎語法

-- 索引的使用
-- 1.在建立表的時候給欄位增加索引
-- 2.在建立完畢後,增加索引

-- 顯示所有的索引資訊
show index from student

-- 增加一個全文索引 (索引名)(列名)
alter table ybt.student add FULLTEXT INDEX studentname(studentname)

-- explain 分析aql執行的情況
explain select * from student; -- 非全文索引

explain select * from student where MATCH(studentname) against('劉')

7.2、測試索引

-- 百萬條資料查詢速度測試
SELECT * from   app_user WHERE `name`='使用者9999'; -- 用時2.9s

-- id_表名_欄位名
-- create index 索引名 on 表(欄位)
create index pp on app_user(`name`); -- 給name 欄位新增索引
-- 新增後查詢
SELECT * from   app_user WHERE `name`='使用者9999'; -- 用時00.52秒

EXPLAIN SELECT * FROM app_user WHERE `name`='使用者9999';

-- 刪除索引語法 DROP INDEX <索引名> ON <表名>
drop INDEX pp on app_user ;

索引在小資料量的時候,用處不大,但是,在大資料的時候,區別十分明顯

7.3、索引原則

  • 索引不是越多越好
  • 不要對程序變動資料加索引
  • 小資料量的表不需要加索引
  • 索引一般加在常用來查詢的欄位上

索引的資料結構

Hash型別的索引

Btree:innodb的預設資料結構

8、資料庫備份

備份目的

  • 保證資料不丟失

  • 資料轉移

    資料庫備份方式 -- 儲存成sql檔案

-- 命令列輸入
-- mysql -h主機名 -u使用者名稱 -p密碼 庫名 表名1 表名2 表名3  > 備份位置(預設當前目錄)
-- 備份單張或多張表操作
mysqldump -hlocalhost  -uroot -p123456 school category laji ji > /home/
-- 備份資料庫操作
-- mysql -h主機名 -u使用者名稱 -p密碼 庫名  > 備份位置(預設當前目錄)
mysqldump -hlocalhost  -uroot -p123456 school > /home/

-- 匯入
-- 資料庫操作:use到指定資料庫
-- source 備份檔案
-- 命令列操作
-- mysql -h主機名 -u使用者名稱 -p密碼 庫名  < 備份檔案

9、許可權管理

-- 建立使用者 create user 使用者名稱 IDENTIFIED by 密碼
create user kk identified by '123456';

-- 修改當前使用者密碼
set password = password('123456');

-- 修改指定使用者密碼
set password for kk =password('123457');

-- 使用者重新命名 
rename user kk to kk1; 

-- 使用者授權all privileges 全部許可權, 庫.表
-- all privileges 除了給別人授權,其他許可權都有
grant all privileges on *.* to kk;

-- 查詢許可權
show grants for kk;
-- kk使用者所擁有的許可權
-- GRANT ALL PRIVILEGES ON *.* TO 'kk'@'%' IDENTIFIED BY PASSWORD '*F13F0EEE74714A1A9922D61FC15789AD75FE4958'
-- 查詢root許可權
show grants for root;
-- root 所擁有的許可權
-- GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER ON *.* TO 'root'@'%' IDENTIFIED BY PASSWORD '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' WITH GRANT OPTION

-- 撤銷許可權 revoke 哪些許可權,在哪個庫撤銷,給誰撤銷
-- 撤銷全部許可權
revoke all privileges on *.* from kk;

-- 刪除使用者
drop user kk1

10、規範資料庫設計

當資料庫比較複雜的時候,我們就需要設計了

糟糕的資料庫設計:

  • 資料冗餘,浪費空間
  • 資料庫插入和刪除都會麻煩,異常【遮蔽使用物理外來鍵】
  • 程式的效能差

良好的資料庫設計

  • 節省記憶體空間
  • 保證資料庫的完整性
  • 方便我們開發系統

軟體開發中,關於資料庫設計

  • 分析需求:分析業務和需要處理的資料庫需求
  • 概要設計:設計關係圖E-R圖

設計資料庫步驟:(個人部落格為例)瞭解

  • 收集資訊,分析需求

    • 使用者表(使用者登入登出,使用者的個人資訊,寫部落格,建立分類)
    • 分類表(文章分類,誰建立的)
    • 文章表(文章的資訊)
    • 評論表
    • 友連結串列(友情資訊
    • 自定義表(系統資訊,某個關鍵的字,或者一些主欄位)key:value
  • 標識實體(把需求落地到每個欄位)

  • 標識實體 之間的關係

    • 寫部落格:user--->blog
    • 建立分類:user-->category
    • 關注:user-->user
    • 友鏈:links
    • 評論:user-user-blog

總結:設計資料庫的時候儘量想的全面一些

11、三大正規化

為什麼需要資料規範化?

  • 資訊重複

  • 更新異常

  • 插入異常

    • 無法正常顯示資訊
  • 刪除異常

    • 丟失有效的資訊

第一正規化(1NF)

原子性:保證每一列不可再分

第二正規化(2NF)

前提:滿足第一正規化

每張表只描述一件事情

第三正規化(3NF)

前提:滿足第一第二正規化

第三正規化需要確保資料表中的每一列數都和主鍵直接相關,而不能間接相關

規範性 和 效能的問題

關聯查詢的表不得超過三張表

  • 考慮商業化的需求和目標,(成本,使用者體驗!)資料庫的效能更加重要
  • 在規範效能的問題的時候,需要適當的考慮一下規範性!
  • 故意給某些表增加一些冗餘的欄位(從多表查詢中變為單表查詢)
  • 故意增加一些計算列(從大資料量降低為小資料量的查詢)