Crunching Numbers with AVX and AVX2
MySQL資料管理
目錄
1. 外來鍵(瞭解)
1. 方式1
在建立表的時候,增加約束(麻煩,比較複雜)
create table `grade` ( `gradeId` int(10) not null auto_increment comment '年級id', `gradename` varchar(50) not null comment '年級名稱', primary key (`gradeId`) )engine=innodb default charset=utf8 drop table if exists student /*學生表的gradeId欄位要去引用年級表的gradeId 定義外來鍵key 給這個外來鍵新增約束(執行引用) fk = foreign key的簡寫 */ 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 (2) not null default '女' comment '性別', `birthdat` 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
刪除有外來鍵關係的表的時候,必須先刪除應用別人的表(從表),再刪除被應用的表(主表)
2. 方式2
建立表成功後,新增外來鍵約束
/*建立表的時候,沒有外來鍵關係 alter table 表名 add constraint 約束名 foreign key(作為外來鍵的列) references 引用到的表(引用到的表中的對應的列); */ 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 (2) not null default '女' comment '性別', `birthdat` 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`) ) engine innodb default charset = utf8 alter table `student` add constraint `fk_gradeId` foreign key(`gradeId`) references `grade`(`gradeId`);
以上的操作都是物理外來鍵,資料庫級別的外來鍵,不建議使用!(避免資料庫過多造成困擾,這裡瞭解即可)
最佳實現
-
資料庫就是單純的表,只用來存資料,只有行(資料)和列(欄位)
-
我們想使用多張表的資料,想使用外來鍵(程式去實現)
2. DML語言(全部記住)
資料庫意義:資料儲存,資料管理
DML語言:資料操作語言
- insert
- update
- delete
1. 新增
insert
/*插入語句(新增)
insert into 表名([欄位1,欄位2,欄位3])values('值1'),('值2'),('值3'),......
*/
insert into `grade`(`gradename`) values('大四')
/*由於主鍵自增,我們可以省略主鍵
如果不寫表的欄位,它就會一一匹配
一般寫插入語句,我們一定要資料和欄位一一對應
*/
/*插入多個欄位
values後面的欄位用()包裹,並用,隔開
*/
insert into `grade`(`gradename`)
values('大二'),('大一')
insert into `student`(`name`) values('張三')
insert into `student`(`name`,`pwd`,`sex`) values('張三','aaaaaa','男')
insert into `student`(`name`,`pwd`,`sex`)
values('李四','bbbbbb','男'),('王五','cccccc','男')
語法
insert into 表名([欄位1,欄位2,欄位3])values('值1'),('值2'),('值3'),......
注意事項
- 欄位和欄位之間使用英文逗號隔開
- 欄位是可以省略的,但是後面的值必須一一對應,不能少
- 可以同時插入多條資料,values後面的值需要使用(),(),...隔開
2. 修改
update
/*修改學生的名字
*/
update `student` set `name`='wang' where id = 1
/*不指定條件的情況下,會改動所有表!
*/
update `student` set `name`='wang'
/*修改多個屬性,用逗號隔開*/
update `student` set `name` = 'wang', `email` = '[email protected]' where id = 1
/*通過多個條件,定位資料*/
update `student` set `name` = '這是一個名字' where `name` = 'wang' or `sex` = '女'
語法
update 表名 set column_name = value, [column_name = value,...] where [條件] --column列欄位
條件:where子句 運算子
操作符 | 含義 | 範圍 | 結果 |
---|---|---|---|
= | 等於 | 5=6 | false |
<>或!= | 不等於 | 5<>6 | true |
> | 大於 | 5>6 | false |
< | 小於 | 5<6 | true |
<= | 小於等於 | 5<=6 | true |
>= | 大於等於 | 5>=6 | false |
between...and... | 在某個範圍內,閉合區間 | [2,5] | |
and | &&和 | 5>1 and 1>2 | false |
or | ||或 | 5>1 or 1>2 | true |
注意:
- column_name 是資料庫的列,儘量帶上``
- 條件,篩選的條件,如果沒有指定,則會修改所有的列
- value可以是一個具體的值,也可以是一個變數
3. 刪除
1. delete命令
語法
delete from 表名 [where 條件]
/*刪除資料(避免這樣寫,會全部刪除)*/
delete from `student`
/*刪除指定資料*/
delete from `student` where id = 1
2. truncate命令
作用:完全清空一個數據庫表,表的索引和約束條件不會變!
/*清空student表*/
truncate `student`
3. delete和truncate的區別
- 相同點:都能刪除資料,都不會刪除表結構
- 不同點:
- truncate 能重新設定自增列,計數器會歸零
- truncate 不會影響事務
4. delete刪除的問題
重啟資料庫,現象:
- INNODB:自增列會從1開始(資料存在記憶體當中,斷電即失)
- MYISAM:繼續從上一個自增量開始(資料存在檔案中,不會丟失)
3. DQL語言(最重點)
查詢資料
1.DQL
Data Query Language:資料查詢語言
- 所有的查詢操作都用它 Select
- 簡單的查詢,複雜的查詢它都能做
- 資料庫最核心的語言,最重要的語句
- 使用頻率最高的語言
select完整的語法
select [all | distinct]
{* | table.* | [table.field1[as alias1][,table.field2[as alias]][,...]]}
from table_name [as table_alias]
[left | right | inner join table_name2] -- 聯合查詢
[where ...] -- 等值查詢,指定結果需要滿足的條件
[group by ...] -- 指定結果按照哪幾個欄位來分組
[having] -- 過濾分組的記錄必須滿足的次要條件
[order by ...] -- 排序,指定查詢記錄按照一個或者多個條件排序
[limit {[offset,]row_count | row_countoffset offsets}]; -- 分頁,指定查詢的記錄從哪條至哪條
注意:[ ]代表可選的,{ }代表必選的
2. 指定查詢欄位
-- 查詢全部的學生 select 欄位 from 表名
select * from `student`
-- 查詢指定欄位
select `studentno`, `studentname` from `student`
-- 別名,給結果起一個名字 as
-- 可以給欄位起別名,也可以給表起別名
select `studentno` as 學號, `studentname` as 學生姓名 from `student` as s
-- 函式 concat(a,b)
-- 作用:將多個字串合連線為一個字串
select concat ('姓名:',`studentname`) as 新名字 from `student`
語法
select 欄位1,... from 表
有的時候,列的名字不是那麼的見名知意,此時我們可以起別名 用as
欄位名 as 別名
表名 as 別名
1. 去重
-- 查詢一下有哪些同學參加了考試(有成績)
select * from `result` -- 查詢全部的考試成績
-- 查詢有哪些同學參加了考試
select `studentno` from `result`
-- 發現重複資料,去重
select distinct `studentno` from `result`
作用:去除select查詢出來的結果中重複的資料,重複的資料只顯示一條
2. 資料庫的列(表示式)
-- 查詢系統版本(函式)
select version()
-- 用來計算(表示式)
select 100*3-1 as 計算結果
-- 查詢自增的步長(變數)
select @@auto_increment_increment
-- 學生考試成績+1分檢視
select `studentno`,`studentresult`+1 as 提分後 from result
資料庫中的表示式:文字值,列,Null,函式,計算表示式,系統變數...
語法
select 表示式 from 表
3. where條件子句
作用:檢索資料中符合條件的值
搜尋的條件由一個或多個表示式組成,返回結果為布林值
1. 邏輯運算子
運算子 | 語法 | 結果描述 |
---|---|---|
and && | a and b a&&b | 邏輯與 |
or || | a or b a||b | 邏輯或 |
not ! | not a !a | 邏輯非 |
儘量使用英文字母
-- ================== where ===================
select `studentno`,`studentresult` from result
-- 查詢考試成績在95~100分之間的
select `studentno`,`studentresult` from result
where `studentresult` >=95 and `studentresult` <=100
-- 模糊查詢(區間)
select `studentno`,`studentresult` from result
where `studentresult` between 95 and 100
-- 除了1000號學生之外的同學的成績 not !
-- 注意not的位置!
-- 不加not:where `studentno`=1000,因此not放在 where之後對取值取非
select `studentno`,`studentresult` from result
where not `studentno`=1000
select `studentno`,`studentresult` from result
where `studentno` != 1000
2. 模糊查詢
比較運算子
運算子 | 語法 | 描述 |
---|---|---|
is null | a is null | 如果操作符為null,則結果為true |
is not null | a is not null | 如果操作符為not null,則結果為true |
between...and... | a between b and c | 若a在b和c之間,則結果為true |
like | a like b | SQL匹配,如果a匹配b,則結果為true(可以使用萬用字元) |
in | a in (a1,a2,a3,...) | 假設a在a1,或者a2...其中的某一個值中,結果為true(不能使用萬用字元) |
-- ================== 模糊查詢 ===================
-- ================== like ===================
-- 查詢姓張的同學
-- like結合 %(代表0到任意個字元) _(一個字元)
select `studentno`,`studentname` from `student`
where `studentname` like '張%'
-- 查詢姓張的同學,名字後面只有一個字的
select `studentno`,`studentname` from `student`
where `studentname` like '張_'
-- 查詢姓張的同學,名字後面只有兩個個字的
select `studentno`,`studentname` from `student`
where `studentname` like '張__'
-- 查詢名字中有偉的同學 %偉%
select `studentno`,`studentname` from `student`
where `studentname` like '%偉%'
-- ================== in ===================
-- in是具體的一個或多個值,不可以用萬用字元
-- 查詢1000,1001號學員資訊
select `studentno`,`studentname` from `student`
where `studentno` in (1000,1001)
-- 查詢在北京的學生
select `studentno`,`studentname` from `student`
where `address` in ('北京朝陽')
-- ================== null not null ===================
-- 查詢地址為空的學生 null或者''
select `studentno`,`studentname` from `student`
where `address`='' or `address` is null
-- 查詢有出生日期的同學=不為空
select `studentno`,`studentname` from `student`
where `borndate` is not null
-- 查詢沒有出生日期的同學=為空
select `studentno`,`studentname` from `student`
where `borndate` is null
4. 聯表查詢
1. join對比
-- ================== 聯表查詢 join ===================
-- 查詢參加了考試的同學(學號,學號,科目編號,分數)
select * from student
select * from result
/*思路
1.分析需求,分析查詢的欄位來自哪些表(超過一張表採用連線查詢)
2.確定使用哪種連線查詢?
確定交叉點(這兩個表中哪個資料是相同的)
判斷的條件:學生表中的studentno = 成績表studentno
表的別名.欄位:表示要查詢的欄位來源於哪個表
*/
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`
from `student` as s
right join `result` as r
on s.`studentno` = r.`studentno`
-- Left Join
select s.`studentno`,`studentname`,`subjectno`,`studentresult`
from `student` as s
left join `result` as r
on s.`studentno` = r.`studentno`
-- 查詢缺考的同學
select s.`studentno`,`studentname`,`subjectno`,`studentresult`
from `student` as s
left join `result` as r
on s.`studentno` = r.`studentno`
where `studentresult` is null
操作 | 描述 |
---|---|
inner join | 如果表中至少有一個匹配,就返回行 |
left join | 會從左表中返回所有的值,即使右表中沒有匹配 |
right join | 會從右表中返回所有的值,即使左表中沒有匹配 |
join on 和where
join (連線的表) on (判斷的條件) 連線查詢(多張表)
where 等值查詢(一張表)
查詢多張表
-- 查詢了參加考試的同學資訊:學號,學生姓名,科目名稱,分數
/*思路
1.分析需求,分析查詢的欄位來自哪些表:student,result,subject
2.確定使用哪種連線查詢?
確定交叉點(這兩個表中哪個資料是相同的)
左表為學生表,右表為成績表時,使用右連,這樣可以將所有參加了考試的學生number輸出
on條件為學號相等,即可篩選出參加了考試的學生
查詢科目,將結果表與科目表inner join,on的條件為相同的subjectno,這樣就能查出對應的subjectname
判斷的條件:學生表中的studentno = 成績表studentno
表的別名.欄位:表示要查詢的欄位來源於哪個表
*/
select s.`studentno`,`studentname`,`subjectname`,`studentresult`
from `student` as s
right join `result` as r
on r.`studentno`=s.`studentno`
inner join `subject` as sub
on sub.`subjectno`=r.`subjectno`
/*
我要查詢哪些資料 select ...
從哪幾個表中查 from 表 XXX join 連線的報表 on 交叉條件
假設存在多張表查詢,慢慢來,先查詢兩張表然後再慢慢增加
a left join b on XXX :以a表位基準(左連線)
a right join b on XXX :以b表位基準(右連線)
*/
2. 自連線
自己的表和自己的表連線,核心:一張表拆為兩張一樣的表即可
父類
categoryId | categoryName |
---|---|
2 | 資訊科技 |
3 | 軟體開發 |
5 | 美術設計 |
子類
pid | categoryId | categoryName |
---|---|---|
3 | 4 | 資料庫 |
2 | 8 | 辦公技術 |
3 | 6 | web開發 |
5 | 7 | ps技術 |
操作:查詢父類對應的子類關係
父類 | 子類 |
---|---|
資訊科技 | 辦公資訊 |
軟體開發 | 資料庫 |
軟體開發 | web開發 |
美術設計 | ps技術 |
-- 查詢父子資訊
select a.`categoryname` as '父欄目',b.`categoryname` as '子欄目'
-- 將一張表看為兩個一模一樣的表
from `category` as a,`category` as b
where a.`categoryid`=b.`pid`
5. 分頁和排序
1. 排序
-- ================ 排序 order by ===============
-- 排序:升序 ASC,降序 DESC
-- 語法:order by 通過哪個欄位排序,怎麼排
-- 查詢的結果根據 成績降序 排序
select s.studentno,studentname,subjectname,studentresult
from student as s
inner join result as r
on s.studentno = r.studentno
inner join `subject` sub
on r.subjectno = sub.subjectno
where sub.subjectname = '高等數學-4'
-- 對成績進行降序排序
order by studentresult desc
2. 分頁
-- ================ 分頁 limit ===============
-- 100萬
-- 為什麼要分頁?
-- 緩解資料庫壓力,給人的體驗更好
-- 分頁,每頁只顯示五條資料
-- 語法:limit 起始值,頁面的大小
-- limit 0,5 1~5條資料
-- limit 1,5 2~6條資料
select s.studentno,studentname,subjectname,studentresult
from student as s
inner join result as r
on s.studentno = r.studentno
inner join `subject` sub
on r.subjectno = sub.subjectno
where sub.subjectname = '高等數學-4'
order by studentresult desc
limit 0,1
-- 第一頁 limit 0,5
-- 第二頁 limit 5,5
-- 第三頁 limit 10,5
-- 第n頁 limit (n-1) * pageSize, pageSize
-- pageSize:頁面大小
-- (n-1) * pageSize起始值
-- n:當前頁
-- 資料總數/頁面大小 = 總頁數(向上取整,有餘數時總頁數+1)
語法
-- 語法:limit 起始值,頁面的大小
6. 子查詢
where (這個值是計算出來的)
本質:在where語句中巢狀一個子查詢語句
-- =========================== where ======================
-- 1.查詢 高等數學-4 的所有考試結果(學號,科目,成績),降序排列
-- 方式1:使用連線查詢
select `studentno`,`subjectname`,`studentresult`
from `result` as r
inner join `subject` as sub
on r.`subjectno` = sub.`subjectno`
where `subjectname`='高等數學-4'
order by `studentresult` desc
-- 方式二:使用子查詢(由裡及外)
select `studentno`,`subjectno`,`studentresult`
from `result`
where `subjectno`=(
select `subjectno` from `subject`
where `subjectname`='高等數學-4'
)
order by studentresult desc
-- 分數不小於80分的學生的學號和姓名
select distinct s.`studentno`,`studentname`
from `student` as s
inner join `result` as r
on r.`studentno`=s.`studentno`
where r.`studentresult` >= 80
-- 在這個基礎上增加一個科目,高等數學-2
select distinct s.`studentno`,`studentname`
from `student` as s
inner join `result` as r
on r.`studentno`=s.`studentno`
where r.`studentresult` >= 80 and `subjectno`=(
select `subjectno` from `subject`
where `subjectname`='高等數學-2'
)
-- 查詢課程為 高等數學-2 且分數不小於 80 的同學的學號和姓名
-- 由裡及外
select `studentno`,`studentname`
from `student` where `studentno` in (
select `studentno` from `result`
where `studentresult` >= 80 and `subjectno` = (
select `subjectno` from `subject`
where `subjectname` = '高等數學-2'
)
)
7. 分組和過濾
分組的語法
group by 用於分組的欄位
過濾的語法
having 過濾的條件
-- 注意:having 位於 group by之後!
-- 查詢不同課程的平均分,最高分,最低分,平均分大於80
-- 核心:根據不同的課程分組
select `subjectname` as 科目,avg(`studentresult`) as 平均分,max(`studentresult`) as 最高分,min(`studentresult`) as 最低分
from `result` as r
inner join `subject` as sub
on r.`subjectno` = sub.`subjectno`
-- 通過什麼欄位來分組
group by r.`subjectno`
-- 利用having對分組後的結果進行過濾(此處不能用where是因為where不支援聚合函式),可以使用別名
having 平均分 >= 80
4. MySQL函式
官網:https://dev.mysql.com/doc/refman/5.6/en/sql-function-reference.html
1. 常用函式
-- ======================== 常用函式 ==========================
-- 數學運算
select abs(-8) -- 絕對值
select ceiling(9.4) -- 向上取整
select floor(9.4) -- 向下取整
select rand() -- 返回一個0~1之間的隨機數
select sign(-9) -- 判斷一個數的符號 0返回0,負數返回-1,正數返回1
-- 字串函式
select char_length('這是一段字串') -- 字串長度
select concat('這','是','一句話') -- 拼接字串
select insert('替換失敗',3,2,'成功') -- 查詢,從某個位置開始替換某個長度的字串,此處的開始位置從1開始計算
select lower('ABCdefg') -- 轉小寫字母
select upper('ABCdefg') -- 轉大寫字母
select instr('blue_sky','e') -- 返回第一次出現的子串的索引
select replace('這是原來的字串','原來','替換後') -- 替換出現的指定字串
select substr('這是原來的字串',4,2) -- 返回指定的子字串(源字串,擷取的位置,擷取的長度)
select reverse('這是原來的字串') -- 反轉字串
-- 查詢姓 將姓趙的同學的姓替換為兆
select replace(`studentname`,'趙','兆') from `student`
where `studentname` like '趙%'
-- 時間和日期函式(重要)
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())
-- 系統
select system_user() -- 獲取系統的使用者
select user() -- 獲取系統的使用者
select version() -- 獲取系統的版本
2. 聚合函式(常用)
函式名稱 | 描述 |
---|---|
count() | 計數 |
sum() | 求和 |
avg() | 平均值 |
max() | 最大值 |
min() | 最小值 |
... |
-- ====================== 聚合函式 ====================
-- 都能夠統計 表中的資料(想查詢表中有多少個記錄,就用count())
select count(`studentname`) 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`
3. 資料庫級別的MD5加密(擴充套件)
什麼是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
-- 明文密碼
insert into `testMD5` (`id`,`name`,`pwd`) values
(1,'張三','123456'),
(2,'李四','123456'),
(3,'王五','123456')
-- 加密全部的密碼,使用函式md5()
update `testMD5` set pwd=md5(pwd)
-- 插入的時候加密
insert into `testMD5` (`id`,`name`,`pwd`) values
(4,'小明',md5('123456'))
-- 如何校驗:將使用者傳遞進來的密碼進行MD5加密,然後比對加密後的值
select * from `testMD5` where `name` = '小明' and pwd = md5('123456')