MySQL數(shù)據(jù)庫簡筆(第一篇系列筆記-后續(xù)持續(xù)上傳)

MySQL安裝包以及資料(比較全)百度網(wǎng)盤鏈接:
鏈接:https://pan.baidu.com/s/1jQdDfUdZqEa6ZOYonTTtdg?pwd=1314?
提取碼:1314
如何在cmd中啟動 mysql服務(wù)
net stop Mysql ? ?// 關(guān)閉mysql服務(wù)
net start Mysql ?// 啟動mysql服務(wù)
# 解釋一下 在這里大小寫其實(shí)都可以 都不影響 只要你敲擊的是對的就沒事了 ?干就完了#鏈接MySQL服務(wù)
mysql -u 用戶(在cmd中是root 這個管理員權(quán)限大 牛逼) -p (以用戶名 密碼的方式去登陸 接下來要輸入mysql密碼)
Enter password : 123456 ?
三種關(guān)閉MySQL的方式
\q ? ? ? quit ? ?exit ?#這三種方式都能退出 mysql ?還有一種暴力的方式 直接把終端關(guān)了
cls ?清空屏幕
添加data文件 就是保存數(shù)據(jù)的文件夾
cd C:\Program Files\MySQL\MySQL Server 5.7\bin ? # 先移動到安裝MySQL的文件夾
mysqld --initialize-insecure --user=root ? #輸入這樣一行命令 甭管是啥意思 輸入就完了 輸入完成回車后 會生成一個data文件 干就完了# 顯示所有的倉庫
show databases; ? ? # 后面的分號不要忘了 #創(chuàng)建倉庫
create database student; ?# create就是創(chuàng)建的意思 database 就不用加復(fù)數(shù)形式了 ?最后跟上個表名
#創(chuàng)建倉庫比較有逼格的寫法
create database if not exists student; ? # if not exists 簡單來說就是查看這個倉庫是不是存在 不存在的話就創(chuàng)建一個
刪除數(shù)據(jù)庫
drop database student; # 刪除指定的數(shù)據(jù)庫
#更加高級的寫法
drop database if exists student; # 如果存在即刪除
查看創(chuàng)建student倉庫的語句
mysql> ?show create database student;
+----------+--------------------------------------------------------------------+
| Database | Create Database ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?|
+----------+--------------------------------------------------------------------+
| student ?| CREATE DATABASE `student` /*!40100 DEFAULT CHARACTER SET latin1 */ |
+----------+--------------------------------------------------------------------+
1 row in set (0.00 sec)
#從這里可以看到倉庫是怎么創(chuàng)建的 語句是什么樣的
創(chuàng)建數(shù)據(jù)庫并且指定字符
create database if not exists student charset=gbk ? #也可以是utf8
#在學(xué)習(xí)練習(xí)的時候使用gbk ?但是上傳到服務(wù)器的時候 記得使用utf8 這是全世界公認(rèn)的中文字符編碼
修改數(shù)據(jù)庫字符編碼
alter database teacher charset=gbk
#alter相當(dāng)于是一個更新的操作 ?修改字符編碼
引用數(shù)據(jù)庫并且查看是否創(chuàng)建了表
mysql> use longlong_school;
Database changed ? ?#指定了接下來用哪個數(shù)據(jù)庫
show tables; #查看該數(shù)據(jù)庫有多少個表
創(chuàng)建一個表
mysql> create table student( ? #創(chuàng)建表 后面用括號接上然后回車 這樣描寫看的清楚些
? ?-> id int, ? ? ?#字段的名字 ? 后面的是數(shù)據(jù)類型 ?后面用“,”跟上回車直接
? ?-> name varchar(30), ? ?#這里的字符類型是 varchar 括號里面的是長度
? ?-> age int ?#最后你沒有字段可寫不用寫括號
? ?-> ); ? #最后用分號來結(jié)尾
創(chuàng)建一個表(B格)
create table if not exists teacher( ? #查看是不是有這個表
? ?-> id int auto_increment primary key comment '主鍵id', ?
? ?# ?auto_increment 自動增長
? ?# ?primary key 主鍵
? ?# ?comment '主鍵id' ?# 前面的英文單詞是注釋的意思 ?后面的是注釋的內(nèi)容
? ?—> name varchar(30) not null ? ?#這個字段不為空
name varchar(30) not null comment '老師的名字', ? ? ?
phone varchar(20) comment '電話號碼', ?
address varchar(100) default '暫時未知' comment '住址' ?#default 默認(rèn)值
)engine=innodb; ?#最后一個逼格最牛逼 是指定數(shù)據(jù)庫的引擎
# 插入一個注冊表可能產(chǎn)生的一些問題
# age int[varchar(10)] default "沒說就是永遠(yuǎn)的19歲" comment "bilibili大學(xué)學(xué)生的年齡"
? # 此情況 default后面的字符文字和該定義的字符格式產(chǎn)生沖突問題 所以可以更改的有兩種情況
? ?# ?1 將字符類型 int 改為 varchar 這樣就可以直接完美兼容
? ?# ?2 將default這個累贅的東西直接刪除 我們在comment后面可以對該字段進(jìn)行一個描述 避免出現(xiàn)問題
注意:表名千萬不要取 long int varchar 這樣的名字 ?會報錯
補(bǔ)充:說出來創(chuàng)建表時的最大隱患問題 ? 當(dāng)你定義字符類型為 int(11) 時 你輸入的只能是10位的數(shù)據(jù) 估摸著 它把11 位的數(shù)據(jù) 分成了 -2的10次方 到 2的10次方 ? 所以當(dāng)你想要輸入11位的電話號碼時 最好輸入int(12) ?相反字符串就沒有這樣的顧慮 ?因?yàn)樗鼪]有正負(fù)數(shù)這個概念 ? ? 當(dāng)你定義的這個數(shù)不可能為負(fù)數(shù)時 不妨試試unit類型
查看表的結(jié)構(gòu)比較好看的那種
desc teacher; ?#輸入這行命令可以查看表的結(jié)構(gòu)
+---------+--------------+------+-----+----------+----------------+
| Field ? | Type ? ? ? ? | Null | Key | Default ?| Extra ? ? ? ? ?|
+---------+--------------+------+-----+----------+----------------+
| id ? ? ?| int(11) ? ? ?| NO ? | PRI | NULL ? ? | auto_increment |
| name ? ?| varchar(30) ?| NO ? | ? ? | NULL ? ? | ? ? ? ? ? ? ? ?|
| phone ? | varchar(20) ?| YES ?| ? ? | NULL ? ? | ? ? ? ? ? ? ? ?|
| address | varchar(100) | YES ?| ? ? | 暫時未知 ?| ? ? ? ? ? ? ? ?|
+---------+--------------+------+-----+----------+----------------+
修改表
# 具體大概的流程是 進(jìn)行什么樣的操作 操作類型 操作的具體對象 進(jìn)行怎么樣的具體操作 后面的是操作改變的
alter table fuck add age varchar(20) not null; # 加上add你就可以在最后添加內(nèi)容
alter table fuck add gender varchar(1) after name; ?# 指定添加到誰的后面 ?after指定 后面的那個就是字段
alter table fuck add fuck varchar(1) first; ?# 這種就是直接放在最前面
alter table fuck drop fuck; # 刪除指定的字段 ? ?
alter table fuck change age age int(3); ?# 修改指定的字段 ?需要跟上關(guān)鍵字 change 咱解釋下后面為什么會有兩個age 一個是原來的字段名 后面的是修改后的名字 你可以隨便改后面的名字 后面的數(shù)據(jù)類型你也可以自己去修改 ? ? 這個是修改字段類型和字段名
alter table fuck modify age varchar(3); ? # 只修改字段的類型
# 這里說一個問題 假如你修改字段類型 它后面還有比如不為空 就是 not null default 后面也標(biāo)注了默認(rèn)值 ?你要是不加上它會直接全部刪的一干二凈 ?很坑
alter table fuck rename to longlong; ? # 修改表的名字
插入數(shù)據(jù)
insert into fuck_to (id, name, gender, age, phone, address) values(1, 'longlong', '男', '19', '15823735335', '武漢'); ? ?#表中插入數(shù)據(jù) insert into ?'插入' 操作的對象 (要添加的字段名稱) values(添加的具體的數(shù)據(jù) ——>注意數(shù)據(jù)類型要與上述字段數(shù)據(jù)類型一致)
# 查看插入的數(shù)據(jù) ?select * from ?fuck_to ? 查詢fuck_to表上的所有的數(shù)據(jù) 并且顯示出來
# 要是寫入的數(shù)據(jù)是按照表的完整的來的 你不妨寫一下如下這一行
insert into fuck_to value(~~~~~) #后面跟上一堆的東西 不過要注意的是 你寫如入的數(shù)據(jù)類型記得和上面的定義時候的數(shù)據(jù)類型一摸一樣
#一次性插入多行數(shù)據(jù)
insert into fuck_to values(1, 'longlong', '男', '19', '15828779335', '武漢'),(1, 'longlong', '男', '19', '158234788755', '武漢'); #大致是這樣的 用逗號可以實(shí)現(xiàn)插入多行數(shù)據(jù)
結(jié)合上面的數(shù)據(jù) 做出解釋 id定義為 自動增長 所以id可以寫成 null ?但是有些定義為 not null 這樣的就必須要闡述其值
刪除數(shù)據(jù)
delete from fuck where id=4; #刪除數(shù)據(jù) delete是刪除 where 刪誰? id=4 是指定要刪除的東西
delete from fuck where name="Tom" #假設(shè)tom有三個的話 這一條語句會一次性直接刪除三條數(shù)據(jù)
#所以我們要注意 刪除的時候刪除唯一的東西就行 比如說id這一類東西是唯一的 因?yàn)樵O(shè)置了~~~
delete from fuck where age>30; ?#會把a(bǔ)ge大于30的刪除
delete from fuck; #刪除該數(shù)據(jù)表中所有的數(shù)據(jù) 不建議要遍歷 太慢了
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
truncate table fuck; ? ? ? ?#給你創(chuàng)建一個原模原樣的表 不過表中的數(shù)據(jù)都被清空了 相當(dāng)于骨架子還給你留著 不過里面的東西都干沒了
# 小細(xì)節(jié) 你如果用delete 來清空表的話 它里面的id會一直延續(xù)下去 比如你之前插入了四行 用delete刪除了之后 再重新插入數(shù)據(jù) id會從5開始 但是你用truncate將所有的數(shù)據(jù)內(nèi)容刪除后 id會重新從1開始
更新表
update fuck set name="瀧瀧" where id=1; ? ?#update更新 set后面是你要更改的東西 ? where 后面是條件 你該的對象的東西 ? ? 你要注意where這一類東西 記住你想更新一條數(shù)據(jù) 就要注意where后面的條件
update fuck set name="瀧瀧",phone="13~~~" where id=1; ?#where后面的一定要寫 ?注意條件的把控 ?
update fuck set address="上海" where id=3 or id=2 ?#這句話的意思就是可以把id為3或者id為2的數(shù)據(jù)改成上海 不過好像都改成上海了
update fuck set address="荊門" where name="瀧瀧" or name="夢夢"; ?#更改數(shù)據(jù)條件需寫清楚 不要搞錯
----+------+--------+-----+-------------+---------+
| id | name | gender | age | phone ? ? ? | address |
+----+------+--------+-----+-------------+---------+
| ?1 | 瀧瀧 | 男 ? ? | 19 ?| 15828788735 | 荊門 ? ?|
| ?2 | 小超 | 男 ? ? | 19 ?| 18338778979 | 貴州 ? ?|
| ?3 | 夢夢 | 女 ? ? | 19 ?| 15828787835 | 荊門 ? ?|
+----+------+--------+-----+-------------+---------+
SQL注入攻擊
結(jié)合上面的這樣的語句 我們知道 where 語句不寫的話 會將所有數(shù)據(jù)值都進(jìn)行更改
黑客就是利用這一特性 用腳本將你所有的數(shù)據(jù)進(jìn)行更改
查詢數(shù)據(jù)
select * from fuck_to(表名); # 這樣的查詢會把表中所有的數(shù)據(jù)顯示出來 ?當(dāng)然哈,你所要查詢的表中應(yīng)該是有數(shù)據(jù)的 不應(yīng)該是空的 所以一切的前提是 ?create table 創(chuàng)建了表的結(jié)果 ?insert into ~~~~ values ~~~~~ 插入了表中的基本數(shù)據(jù)后 你才可以顯示數(shù)據(jù)
select id,name,age from fuck_to(表名); # 你可以抽取幾個感興趣想要查詢的關(guān)鍵字 然后將它輸出出來 中間用"," 分隔開來
注意事項(xiàng):
mysql> show variables like 'character_set_%';
+--------------------------+---------------------------------------------------------+|
Variable_name ? ? ? ? ? ?| Value ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
+--------------------------+---------------------------------------------------------+
| character_set_client ? ? | gbk ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
| character_set_connection | gbk ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
| character_set_database ? | gbk ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
| character_set_filesystem | binary ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?|
| character_set_results ? ?| gbk ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
| character_set_server ? ? | latin1 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?|
| character_set_system ? ? | utf8 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?|
| character_sets_dir ? ? ? | C:\Program Files\MySQL\MySQL Server 5.7\share\charsets\ |
+--------------------------+---------------------------------------------------------+
# ?在練習(xí)的時候 我們使用的終端環(huán)境是gbk格式 ?但是要真正在企業(yè)當(dāng)中去用的話 是utf-8 這樣的中文國際編碼
# ?需要注意的是 當(dāng)出現(xiàn)中文亂碼的時候 要查看編碼是不是對的 就是到底是gbk字符格式還是utf-8的格式 是否與當(dāng)前操作環(huán)境相符
int 類型的大小 以及實(shí)際操作時候的注意事項(xiàng)
smallint unsigned ? # ?smallint 兩個字節(jié)大小 ? unsigned 無符號
TINYINT1 Bytes(-128,127)(0,255)小整數(shù)值SMALLINT2 Bytes(-32 768,32 767)(0,65 535)大整數(shù)值MEDIUMINT3 Bytes(-8 388 608,8 388 607)(0,16 777 215)大整數(shù)值INT或INTEGER4 Bytes(-2 147 483 648,2 147 483 647)(0,4 294 967 295)大整數(shù)值BIGINT8 Bytes(-9,223,372,036,854,775,808,9 223 372 036 854 775 807)(0,18 446 744 073 709 551 615)極大整數(shù)值FLOAT4 Bytes(-3.402 823 466 E+38,-1.175 494 351 E-38),0,(1.175 494 351 E-38,3.402 823 466 351 E+38)0,(1.175 494 351 E-38,3.402 823 466 E+38)單精度 浮點(diǎn)數(shù)值DOUBLE8 Bytes(-1.797 693 134 862 315 7 E+308,-2.225 073 858 507 201 4 E-308),0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308)0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308)雙精度 浮點(diǎn)數(shù)值DECIMAL對DECIMAL(M,D) ,如果M>D,為M+2否則為D+2依賴于M和D的值依賴于M和D的值小數(shù)值
浮點(diǎn)型
----------+-------------+------+-----+---------+-------+
| Field ? ?| Type ? ? ? ?| Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| number_1 | float(3,1) ?| YES ?| ? ? | NULL ? ?| ? ? ? |
| number_2 | double(5,2) | YES ?| ? ? | NULL ? ?| ? ? ? |
+----------+-------------+------+-----+---------+-------+
float
double
#前面的是總長度 ?后面的是小數(shù)長度 ? 加入你插入的數(shù)超過了規(guī)定的小數(shù)長度 那么數(shù)據(jù)庫就會采取四舍五入的方式 ?比如你輸入 2.98 根據(jù)四舍五入后 ?結(jié)果就是3.0這個數(shù)
# 會有丟失精度的問題 ?存錢存一些關(guān)鍵的數(shù)據(jù)不會被使用
定點(diǎn)數(shù)
decimal ?# 不會四舍五入 ? ?小數(shù)跟整數(shù)是分開存的 ?可以用來存錢 ? 也支持無符號
字符串
varchar # 變長字符 可以回收后面你沒有用到的空間
char # 定長字符 ?
text # 長文本數(shù)據(jù) ?比如你博客里面的長文章 就可以使用這個存儲
布爾類型
boolean # true false ?保存真假
枚舉類型
gender enum('man','woman','?','nothing','it')
+--------+----------------------------------------+------+-----+---------+-------+
| Field ?| Type ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | Null | Key | Default | Extra |
+--------+----------------------------------------+------+-----+---------+-------+
| gender | enum('man','woman','?','nothing','it') | YES ?| ? ? | NULL ? ?| ? ? ? |
+--------+----------------------------------------+------+-----+---------+-------+
# 枚舉類型就是你只能取里面的這幾個數(shù)據(jù) ? 不能取其他數(shù)據(jù) 規(guī)定死了
# 別看它顯示的時候是字符串 其實(shí)存的時候是 1 2 3 4 這樣的數(shù)
mysql> insert into t_5 values(2);
+--------+
| gender |
+--------+
| ? ? ? ?|
| woman ?|
+--------+
# 我們存入2 的時候它具體顯示的是 woman ?根據(jù)枚舉的排序來的 這樣更加節(jié)省空間
# 這樣存入數(shù)據(jù)也是枚舉的另類存儲方式
# 枚舉類型的速度快 節(jié)省空間 限制數(shù)據(jù) ?把那種不要臉的數(shù)據(jù) 直接用枚舉類型就可以解決
set 集合類型
#比如你在b站上選擇你喜歡的標(biāo)簽 用什么來存取 當(dāng)然是用set啦
hobby set('哲學(xué)','經(jīng)濟(jì)學(xué)','文學(xué)','IT','數(shù)學(xué)','美學(xué)') ?
+-------+------------------------------------------------+------+-----+---------+-------+
| Field | Type ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | Null | Key | Default | Extra |
+-------+------------------------------------------------+------+-----+---------+-------+
| hobby | set('哲學(xué)','經(jīng)濟(jì)學(xué)','文學(xué)','IT','數(shù)學(xué)','美學(xué)') ? | YES ?| ? ? | NULL ? ?| ? ? ? |
+-------+------------------------------------------------+------+-----+---------+-------+
# insert into t_6 values('IT','經(jīng)濟(jì)學(xué)'); ? 錯誤樣例 我們要一次性存入數(shù)據(jù) 而不是分成兩個字符串形式
# 正確的方式
mysql> insert into t_6 values('IT,經(jīng)濟(jì)學(xué)'); ?
# 輸入的順序無所謂 最后會按照set里面的內(nèi)容來重新排序
補(bǔ)充:你可以看作是 enum 單選 ?set 多選
時間日期類型
最好每張表單都有一個時間類型 ?記錄代碼上傳 或者修改的時間
實(shí)際使用的時候 datetime 就可以 這個比較完整 顯示的清楚些
# 時間這地方還有一點(diǎn)補(bǔ)充的地方
## 在用戶進(jìn)行配置的時候會有一種假象 我輸入的時候自動填充時間或者說每次更新的時候數(shù)據(jù)表也自動更新時間
類型大小 ( bytes)范圍格式用途DATE31000-01-01/9999-12-31YYYY-MM-DD日期值TIME3'-838:59:59'/'838:59:59'HH:MM:SS時間值或持續(xù)時間YEAR11901/2155YYYY年份值DATETIME8'1000-01-01 00:00:00' 到 '9999-12-31 23:59:59'YYYY-MM-DD hh:mm:ss混合日期和時間值TIMESTAMP4'1970-01-01 00:00:01' UTC 到 '2038-01-19 03:14:07' UTC結(jié)束時間是第 2147483647 秒,北京時間 2038-1-19 11:14:07,格林尼治時間 2038年1月19日 凌晨 03:14:07YYYY-MM-DD hh:mm:ss混合日期和時間值,時間戳+-------------+----------+------+-----+---------+-------+
| Field ? ? ? | Type ? ? | Null | Key | Default | Extra |
+-------------+----------+------+-----+---------+-------+
| createdTime | datetime | YES ?| ? ? | NULL ? ?| ? ? ? |
+-------------+----------+------+-----+---------+-------+
1 row in set (0.00 sec)
mysql> insert into t_7 values('2023-06-05 16:16:00');
Query OK, 1 row affected (0.01 sec)
mysql> select * from t_7;
+---------------------+
| createdTime ? ? ? ? |
+---------------------+
| 2023-06-05 16:16:00 |
+---------------------+
1 row in set (0.00 sec)
# 在實(shí)際開發(fā)過程中 不會讓我們手動插入數(shù)據(jù) 一般是通過java或者其他語言插入
列屬性完整性
列屬性問題
auto_increment # 自增長有一個弊端 當(dāng)你有四行數(shù)據(jù)的時候 你將其中的第三行數(shù)據(jù)刪除后
# 你再想插入id為 3 的數(shù)據(jù)它就會報錯
# 有了auto_increment 必須有 PRI 但是有PRI 不一定要有 auto_increment
主鍵的作用以及企業(yè)用途
絕對唯一且能夠確認(rèn)數(shù)據(jù)的唯一性不可重復(fù)性被我們稱為主鍵
# 不可能為重復(fù)的 一個表只能有一個主鍵 ?這個主鍵也可能由很多個字段組成
組合鍵(復(fù)合鍵)
極端情況 兩個字段弄成一個主鍵
唯一鍵 *
在這單個表里面是唯一的 不會在其他表中看到克隆版
# 可以為空 但是必須是唯一的
unique # 唯一鍵 像電話號碼和身份證這種的 不可能為重復(fù)的 唯一 字如其意
phone varchar(20) unique ?# 設(shè)置唯一鍵
+-------+-------------+------+-----+---------+-------+
| Field | Type ? ? ? ?| Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id ? ?| int(11) ? ? | NO ? | PRI | NULL ? ?| ? ? ? |
| phone | varchar(20) | YES ?| UNI | NULL ? ?| ? ? ? |
+-------+-------------+------+-----+---------+-------+
# ?刪除唯一鍵
alter table t_11 drop index phone ?# index 后面指明唯一鍵的名稱
外鍵 ?(刪除會有點(diǎn)東西)
## 就是兩個表之間有相同的內(nèi)容 比如學(xué)生表中的學(xué)生姓名 ?應(yīng)該跟是他共有相同的字段的干飯表 也有學(xué)生的姓名
### ?也有主表跟從表的概念
foreign key (外鍵字段) references 主表(主鍵字段); ?#外鍵字段的來自主鍵哪個字段的干活
# foreign key ?: 在從表要設(shè)置的外鍵的字段 ?
# (外鍵字段) : 和主表對應(yīng)的字段
# references ?來自哪個表
### 十分重要的一件事 ?就是單獨(dú)指認(rèn) 外鍵 需要單獨(dú)寫一行
?### 十分重要的一件事 ?就是單獨(dú)指認(rèn) 外鍵 需要單獨(dú)寫一行
### 十分重要的一件事 ?就是單獨(dú)指認(rèn) 外鍵 需要單獨(dú)寫一行
### 后期修改字段
# alter table eatery_2(表名) add foreign key (外鍵字段) references 主表(主鍵字段);
# ? ? ? 創(chuàng)建一個主表 ? ?在這兩個表的情況下 主表的主鍵字段是外表的外鍵引入
create table stu(
? ?-> stuid int(4) primary key,
? ?-> name varchar(20)
? ?-> );
? ?
? ?
# ? ? ? 從表 ?
create table eatfuck(
? ?-> id int primary key,
? ?-> money decimal(10,4),
? ?-> stuid int(4), ? ?# 創(chuàng)建和主表相同的字段 ?用于鏈接 ?當(dāng)然名字可以不一樣 不過里面數(shù)據(jù)的格式和數(shù)據(jù)的內(nèi)容應(yīng)該是重復(fù)的
? ?-> foreign key (stuid) references stu(stuid) ?# 單獨(dú)起一行 用于聲明外鍵 若和字段寫一行 會報錯
? ?-> );
# ?最后的效果
## 如果Key是MUL, 那么該列的值可以重復(fù) (網(wǎng)上官方的) ? 就和access數(shù)據(jù)庫的可重復(fù)一樣
+-------+---------------+------+-----+---------+-------+
| Field | Type ? ? ? ? ?| Null | Key | Default | Extra |
+-------+---------------+------+-----+---------+-------+
| id ? ?| int(11) ? ? ? | NO ? | PRI | NULL ? ?| ? ? ? |
| money | decimal(10,4) | YES ?| ? ? | NULL ? ?| ? ? ? |
| stuid | int(4) ? ? ? ?| YES ?| MUL | NULL ? ?| ? ? ? |
+-------+---------------+------+-----+---------+-------+
# ?刪除外鍵:需要刪除表生成的別名 ?
## 以下是查詢了eatfuck 這個表的創(chuàng)建方式之后反饋的
| eatfuck | CREATE TABLE `eatfuck` (
?`id` int(11) NOT NULL,
?`money` decimal(10,4) DEFAULT NULL,
?`stuid` int(4) DEFAULT NULL, ?PRIMARY KEY (`id`), ?KEY `stuid` (`stuid`), ?CONSTRAINT `eatfuck_ibfk_1` FOREIGN KEY (`stuid`) REFERENCES `stu` (`stuid`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk |
eatfuck_ibfk_1 # 是我們刪除外鍵是要刪除的字段 不是stuid哦 ######
# 刪除操作
alter table eatfuck drop foreign key eatfuck_ibfk_1; # key 后面的是當(dāng)前外鍵從表生成的別名字段
### 外鍵的三種使用操作
置空: #用于外鍵刪除數(shù)據(jù) ? ?你刪除主表的數(shù)據(jù) 從表的數(shù)據(jù)還是會保存 不過id變成了null而已 就和食堂打飯一樣的 你不可能刪除了用戶之后你的錢還一并刪除吧 ?(主表相當(dāng)于用戶 你主表用戶刪除了 從表的用戶id 不會直接被干掉 就像你的錢財一樣 你錢財?shù)挠脩裘急粍h除了 你錢還能存在? 所以直接指認(rèn)id為空 ?你money 這個字段的數(shù)據(jù)還在 ?小錢錢就保住了)
級聯(lián): #用于外鍵更新數(shù)據(jù) ?屬于那種一榮俱榮一損俱損的 主表更新了數(shù)據(jù) 從表有關(guān)聯(lián)的也會一并更新
# 大哥動了 小弟也要跟著行動 ?差不多是這個意思
foreign key(stuId) references stu(stuId) on delete set null on update cascade
置空操作
on delete set null # 設(shè)置置空
級聯(lián)操作
on update cascade # 設(shè)置級聯(lián)
聯(lián)合操作 ?
### 級聯(lián)
select * from stu;
+-------+-------+
| stuId | name ?|
+-------+-------+
| ? ? 1 | tom ? |
| ? ? 2 | jerry |
+-------+-------+
select * from eatery; ? ? ? ? ? ? ? ? ?
+----+----------+-------+
| id | money ? ?| stuId |
+----+----------+-------+
| ?1 | ?20.5000 | ? ? 2 |
| ?2 | ?78.6000 | ? ? 1 |
| ?3 | ?99.9000 | ? ? 2 |
| ?4 | 748.4000 | ? ? 1 |
| ?5 | 748.4000 | ? ? 2 |
+----+----------+-------+
### 將主表的id進(jìn)行更改后 發(fā)現(xiàn)從表 進(jìn)行外鍵關(guān)聯(lián)的這個表 相對應(yīng)的數(shù)據(jù)也進(jìn)行了更改
update stu set stuId='4' where name='tom'; ?
select * from stu;
+-------+-------+
| stuId | name ?|
+-------+-------+
| ? ? 2 | jerry |
| ? ? 4 | tom ? |
+-------+-------+
select * from eatery; ? ? ? ? ? ? ? ? ?
+----+----------+-------+
| id | money ? ?| stuId |
+----+----------+-------+
| ?1 | ?20.5000 | ? ? 2 |
| ?2 | ?78.6000 | ? ? 4 |
| ?3 | ?99.9000 | ? ? 2 |
| ?4 | 748.4000 | ? ? 4 |
| ?5 | 748.4000 | ? ? 2 |
+----+----------+-------+
# 只要進(jìn)行了外鍵關(guān)聯(lián) 級聯(lián)就是牽一發(fā)動全身 多用于更新操作 以上案例就可以體現(xiàn)出來
### 置空
# 刪除id為2的數(shù)據(jù) 我們來看看外鍵關(guān)聯(lián)表會怎么樣
delete from stu where ?stuId='2';
select * from eatery;
+----+----------+-------+
| id | money ? ?| stuId |
+----+----------+-------+
| ?1 | ?20.5000 | ?NULL |
| ?2 | ?78.6000 | ? ? 4 |
| ?3 | ?99.9000 | ?NULL |
| ?4 | 748.4000 | ? ? 4 |
| ?5 | 748.4000 | ?NULL |
+----+----------+-------+
# 刪除就是置空 更新就是級聯(lián) 大致可以這樣來分 ?前提是你在制作外鍵從表的時候記得
foreign key(stuId) references stu(stuId) on delete set null on update cascade
單表查詢
select
select
#select是一個常見的術(shù)語,它表示從多個選項(xiàng)中選擇一個來執(zhí)行的操作。例如,當(dāng)我們在計算機(jī)程序中使用select語句時,可以根據(jù)條件的不同,選擇執(zhí)行不同的代碼塊。
select 'fuck your' as bitch;
+-----------+
| bitch ? ? |
+-----------+
| fuck your |
+-----------+ ? ? ? ## ?as 后面的是別名 ? ?as 也可以省略,但是為了裝逼我們保留下來
select 2*7;
+-----+
| 2*7 |
+-----+
| ?14 |
+-----+
from
from
#用于介紹某個東西的來源、起始點(diǎn)或者來源地
## 一般使用的時候后面跟上表名
select * from t1;
# 后面跟上來自什么表就行
select * from t1,t2;
# 跟上兩個表會有化學(xué)反應(yīng)
#### 笛卡爾集
# 當(dāng)兩個表查詢時,規(guī)則是:從第一張表中,取出一行和第二張表的每一行進(jìn)行組合,返回結(jié)果【含有兩張表的所有列】
# 簡單粗暴來說就是雜亂組合 第一張表每一行數(shù)據(jù) 都要帶上第二張表每行 ? ? ### ?就是特么矩陣相乘
mysql> select * from t1;
+------+-------+
| id ? | name ?|
+------+-------+
| ? ?1 | tom ? |
| ? ?2 | jerry |
+------+-------+
2 rows in set (0.00 sec)
mysql> select * from t2;
+-------+-------+
| scor1 | scor2 |
+-------+-------+
| ? ?98 | ? ?99 |
| ? ?47 | ? ?78 |
+-------+-------+
2 rows in set (0.00 sec)
mysql> select * from t1,t2;
+------+-------+-------+-------+
| id ? | name ?| scor1 | scor2 |
+------+-------+-------+-------+
| ? ?1 | tom ? | ? ?98 | ? ?99 |
| ? ?2 | jerry | ? ?98 | ? ?99 |
| ? ?1 | tom ? | ? ?47 | ? ?78 |
| ? ?2 | jerry | ? ?47 | ? ?78 |
+------+-------+-------+-------+
dual
#在MySQL中,dual 是一個虛擬的表,通常用于在查詢中保證至少有一行結(jié)果返回。dual 表只有一列和一行,可以用于測試、健康檢查和生成臨時數(shù)據(jù)等場景。
例如,在查詢中使用 dual 虛擬表可以返回當(dāng)前日期和時間:
SQL
SELECT NOW() FROM dual;
上述查詢將返回當(dāng)前的日期和時間。由于 dual 表只有一行,因此可以確保至少有一行結(jié)果返回。
需要注意的是,在某些MySQL版本中,dual 可能不是必須的。在這些版本中,可以直接使用常量或表名來代替 dual,例如:
SQL
SELECT NOW();
上述查詢在這些版本的MySQL中同樣能夠返回當(dāng)前的日期和時間。
select now() from dual;
+---------------------+
| now() ? ? ? ? ? ? ? |
+---------------------+
| 2023-06-16 17:59:48 |
+---------------------+
select 2*7 as res from dual; ?# 完整的寫法是這樣 ?不過可以省略不寫 ?dual只是個虛擬的表 用于測試使用
where
where ? ?# 一條一條的去篩選 從表那去篩選
#后面只需要跟上指定的條件就行 比如> < >= <= ?and or not 啥啥啥的
select * from t2 where age>=18; ?
+------+------+
| id ? | age ?|
+------+------+
| ? ?1 | ? 18 |
| ? ?2 | ? 23 |
+------+------+
select * from longlong where name='瀧瀧' or ?name='夢夢';
+----+------+-----+-------------+--------------------------------------------------+
| id | name | age | phone ? ? ? | address ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?|
+----+------+-----+-------------+--------------------------------------------------+
| ?1 | 瀧瀧 | ?19 | 15828758885 | 湖北省鄂州市華容區(qū)武漢職業(yè)技術(shù)學(xué)院(葛店校區(qū)) ? ? ? ? |
| ?2 | 夢夢 | ?19 | 17727527225 | 湖北省鄂州市鄂城區(qū)鳳凰街道77號鄂州職業(yè)大學(xué)東校區(qū) ? ? |
+----+------+-----+-------------+--------------------------------------------------+
and # 同理 加上and 在查詢成分復(fù)雜的數(shù)據(jù)的時候 可以更好的細(xì)分差別
in
in
# 包括 ? 還有一種not in 不包括
select * from longlong where name in('瀧瀧','夢夢'); ? ? ?
+----+------+-----+-------------+--------------------------------------------------+
| id | name | age | phone ? ? ? | address ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?|
+----+------+-----+-------------+--------------------------------------------------+
| ?1 | 瀧瀧 | ?19 | 158272877835 | 湖北省鄂州市華容區(qū)武漢職業(yè)技術(shù)學(xué)院(葛店校區(qū)) ? ? ? ? |
| ?2 | 夢夢 | ?19 | 177712875585 | 湖北省鄂州市鄂城區(qū)鳳凰街道77號鄂州職業(yè)大學(xué)東校區(qū) ? ? |
+----+------+-----+-------------+--------------------------------------------------+
# 跟python的in差不多一個理
select * from longlong where name in('瀧瀧','夢夢') or age='18'; ? # 可以組合使用 嘿嘿
+----+----------+-----+-------------+--------------------------------------------------+
| id | name ? ? | age | phone ? ? ? | address ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?|
+----+----------+-----+-------------+--------------------------------------------------+
| ?1 | 瀧瀧 ? ? | ?19 | 15822222335 | 湖北省鄂州市華容區(qū)武漢職業(yè)技術(shù)學(xué)院(葛店校區(qū)) ? ? ? ? |
| ?2 | 夢夢 ? ? | ?19 | 17771507854 | 湖北省鄂州市鄂城區(qū)鳳凰街道77號鄂州職業(yè)大學(xué)東校區(qū) ? ? |
| ?3 | 云翔瀧夢 | ?18 | 1582787545 | 湖北省荊門市沙洋縣? ? ? ? ? ? ? ? ? ?|
+----+----------+-----+-------------+--------------------------------------------------+
between ... and ...
# 第一種寫法 ?這種比較簡單粗暴 沒有逼格
select * from t3 where age>=15 and age<25;
+------+------+
| id ? | age ?|
+------+------+
| ? ?1 | ? 18 |
| ? ?2 | ? 19 |
| ? ?3 | ? 15 |
| ? ?4 | ? 21 |
+------+------+
# 第二種寫法 ? 不過這是一個閉區(qū)間范圍
select * from t3 where age between 15 and 21;
+------+------+
| id ? | age ?|
+------+------+
| ? ?1 | ? 18 |
| ? ?2 | ? 19 |
| ? ?3 | ? 15 |
| ? ?4 | ? 21 |
+------+------+
is null ?
# 對這里的寫法是 is null ? is 在這里就是表示有沒有的意思
select * from t3 where age is null; ? # 查詢?yōu)榭?br>+------+------+
| id ? | age ?|
+------+------+
| ? ?5 | NULL |
+------+------+
select * from t3 where age is not null; ?# 查詢不為空
+------+------+
| id ? | age ?|
+------+------+
| ? ?1 | ? 18 |
| ? ?2 | ? 19 |
| ? ?3 | ? 15 |
| ? ?4 | ? 21 |
| ? ?5 | ? 34 |
+------+------+
聚合函數(shù)
select * from score ;
+------+------+---------+---------+
| id ? | math | chinese | english |
+------+------+---------+---------+
| ? ?1 | ? 98 | ? ? ?99 | ? ? 100 |
| ? ?2 | ? 87 | ? ? ?79 | ? ? ?90 |
| ? ?2 | ? 87 | ? ? ?79 | ? ? ?90 |
+------+------+---------+---------+
select sum(math) from score; ? # 求出math這一列的和 ? ? ?
+-----------+
| sum(math) |
+-----------+
| ? ? ? 272 |
+-----------+
select max(math) from score; # 最大數(shù)
select min(math) from score; # 最小數(shù)
select avg(math) from score; # 平均
select count(math) from score; ?# 統(tǒng)計
like
# 模糊查詢
select * from student where name like '張%';
+----+--------+--------+------+-------------+
| id | name ? | gender | age ?| phone ? ? ? |
+----+--------+--------+------+-------------+
| ?4 | 張三 ? | 0 ? ? ?| ? 15 | 15454797999 |
| ?5 | 張八 ? | 0 ? ? ?| ? 17 | 14876467998 |
| ?7 | 張躍進(jìn) | 0 ? ? ?| ? 18 | 14177378373 |
+----+--------+--------+------+-------------+
# 其中l(wèi)ike 后面是條件 ? ?重點(diǎn)介紹下 % 變相于有些語言中的* 等于一個或者多個字符#
select * from student where name like '張_';
+----+------+--------+------+-------------+
| id | name | gender | age ?| phone ? ? ? |
+----+------+--------+------+-------------+
| ?4 | 張三 | 0 ? ? ?| ? 15 | 15454797999 |
| ?5 | 張八 | 0 ? ? ?| ? 17 | 14876467998 |
+----+------+--------+------+-------------+
# _ ?這個下劃線代表一個字符 #
以上兩種字符結(jié)合著頭腦可以設(shè)計一些條件篩選出來 ?模糊查詢對條件的篩選很有效
order by
desc #表示降序
asc #表示升序
# order by 排序查詢 age 設(shè)置的條件字段 ?
mysql> select * from info order by age desc; ?
+----+------+--------+---------+
| id | age ?| gender | address |
+----+------+--------+---------+
| ?3 | ? 26 | 女 ? ? | 北京 ? ?|
| ?1 | ? 25 | 男 ? ? | 上海 ? ?|
| ?6 | ? 24 | 女 ? ? | 深圳 ? ?|
| ?2 | ? 23 | 女 ? ? | 上海 ? ?|
| ?4 | ? 23 | 男 ? ? | 北京 ? ?|
| ?5 | ? 21 | 男 ? ? | 上海 ? ?|
+----+------+--------+---------+
group by 分組查詢
select avg(age) as '年齡' ,gender as '性別' from info group by gender;
+---------+------+
| 年齡 ? ?| 性別 ?|
| 23.0000 | 男 ? |
| 24.5000 | 女 ? |
+---------+------+
# 解釋一下上面的語句 ?查找年齡的平均值 ?按什么來查呢 ?就按照group by 后面的那一行條件來查
## group by 后面的可以看作是 分組的條件 就是按照什么為一組 ?然后輸出這個組每個元素的信息(這些信息可能是由很多的數(shù)據(jù)組成的)
## 后者是你要分組的對象 前者是聚合函數(shù) 或者說數(shù)據(jù)一類
Group_concat()
GROUP_CONCAT(xxx):#是將分組中括號里對應(yīng)的字符串進(jìn)行連接.如果分組中括號里的參數(shù)xxx有多行,那么就會將這多行的字符串連接,每個字符串之間會有特定的符號進(jìn)行分隔。
# 簡單粗暴來說就是把分組后的數(shù)據(jù) 挪到一行來顯示 ?就是女性的顯示一行 男性的顯示一行的那種
select group_concat(name) , gender from student group by gender;
+------------------------------------+--------+
| group_concat(name) ? ? ? ? ? ? ? ? | gender |
+------------------------------------+--------+
| Tom,longlong,張三,張八,王五,張躍進(jìn) ? | 0 ? ? ?|
| Jerry ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| 1 ? ? ?|
+------------------------------------+--------+
# 比較好玩
# 結(jié)合上面兩個再次說明一下要想達(dá)到分組的目的效果 ?找準(zhǔn)分組的條件 需要分組顯示的數(shù)據(jù) ?前者多為聚合函數(shù) 或者說 group_concat一類的數(shù)據(jù) ?
having
### 對查詢之后的數(shù)據(jù)進(jìn)行篩選 ?(對結(jié)果進(jìn)行篩選) ? ?## 補(bǔ):不是對數(shù)據(jù)庫進(jìn)行篩選哦
#@
SELECT avg(age) as '年齡' ,address as '地區(qū)' from info group by address having 年齡 >24
# 以上是對查詢之后的結(jié)果進(jìn)行篩選 ? having后面的字段 與篩選出來的結(jié)果字段一一對應(yīng)
# 意思就是 你as后面是啥 你having后面的條件就是該字段
## 注: 除非你把a(bǔ)s后面的字段進(jìn)行更改 否則就是as改掉后的或者原字段內(nèi)容
@#
where : 是對數(shù)據(jù)進(jìn)行篩選后再查詢 ? 就是先判斷條件再把滿足條件的篩選出來
limit
限定起始位置 默認(rèn)0開始
select * from info limit 0,3; ? ? ? ?
+----+------+--------+---------+
| id | age ?| gender | address |
+----+------+--------+---------+
| ?1 | ? 25 | 男 ? ? | 上海 ? ?|
| ?2 | ? 23 | 女 ? ? | 上海 ? ?|
| ?3 | ? 26 | 女 ? ? | 北京 ? ?|
+----+------+--------+---------+
# 查找年齡最大的三個人的信息
select * from info order by age desc limit 3;
+----+------+--------+---------+
| id | age ?| gender | address |
+----+------+--------+---------+
| ?3 | ? 26 | 女 ? ? | 北京 ? ?|
| ?1 | ? 25 | 男 ? ? | 上海 ? ?|
| ?6 | ? 24 | 女 ? ? | 深圳 ? ?|
+----+------+--------+---------+
# 以age對查詢數(shù)據(jù)進(jìn)行降序排列 再對目標(biāo)截取前三名 ? limit 后面跟大多數(shù)語言一樣 ?從零開始 結(jié)束那里是個開區(qū)間(0,3) 會取012
distinct all
distinct : ?去重 ? # 解釋下all :默認(rèn)情況下咱們忽略了而已
select distinct address from info; ? ? ? ? ? ? ?
+---------+
| address |
+---------+
| 上海 ? ?|
| 北京 ? ?|
| 深圳 ? ?|
+---------+