sql語言概述
技術標籤:常見的sql語句
文章目錄
- unit01-MySQL
unit01-MySQL
什麼是SQL語言?
SQL是一門用於操作關係型資料庫的通用的語言(使用SQL可以操作所有的關係型資料庫)
使用SQL可以操作資料庫、表、表記錄
(1)建立資料庫、刪除資料庫、修改資料庫、查詢資料庫
(2)建立表、刪除表、修改表、查詢表
(3)新增表記錄、刪除表記錄、修改表記錄、查詢表記錄
使用SQL也可以操作儲存過程/檢視/索引等。 每句話分號結尾。
提示:SQL是一個標準通用的操作關係型資料庫的語言(普通話),每個資料庫廠商為了增強自己資料庫的功能,都提供了支援自己資料庫的語言,稱之為數據庫的方言。方言不通用!
連線mysql伺服器
**通過命令列工具(也可以通過第三方的工具如:Navicat , SQLyog )**可以登入MySQL客戶端,連線MySQL伺服器,從而訪問伺服器中的資料。
1、連線mysql伺服器:
mysql -uroot -p密碼 -- 注意空格 這個沒有分號特殊.其他的sql語句每句話幾乎都有分號. 輸入密碼 可以寫 -P +回車 (密碼在下一行書寫) 密碼不顯示安全輸入
**-u:**後面的root是使用者名稱,這裡使用的是超級管理員root; (mysql預設的使用者名稱就是root)
**-p:(小寫的p)**後面的root是密碼,這是在安裝MySQL時就已經指定的密碼;
2、連線mysql伺服器並指定IP和埠:
mysql -uroot -proot -h127.0.0.1 -P3306
-h:後面給出的127.0.0.1是伺服器主機名或ip地址,可以省略的,預設連線本機(即 如果是這個ip地址代表本機,可以省略不寫);
**-P:(大寫的P)**後面的3306是連線埠,可以省略,預設連線3306埠 (3306埠可以省略);
3、退出客戶端命令:quit或exit或 \q
4、FAQ:常見問題:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-99puAbpA-1608909624265)(JAVAWEB-NOTE01.assets/e23a06d3921d5d68c48d6e51024aae8a.jpg)]
解決方法:複製mysql安裝目錄下的bin目錄的路徑,將bin目錄的路徑新增到path環境變數中!!
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-mMRuLqzB-1608909624268)(C:\Users\pc\AppData\Roaming\Typora\typora-user-images\image-20200530090843033.png)]
把mysql安裝目錄放到最前面 用 “ ,”隔開。 win7
win8 win10 沒有分號。 編輯後上移即可。
重灌 mysql要先停用服務:
計算機—右鍵管理----服務和應用程式 ,服務----mysql(mariadb)—右鍵—停止 右鍵屬性—啟動型別—手動或禁用. 每次開啟計算機它會隨著作業系統會自動啟動.
擴充套件內容3:
(1)在cmd中連線mysql伺服器之後,可以使用 #、/**/、-- 等符號添加註釋,例如:
注意: – (這個註釋後面先要加空格)
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-g0mQdjjM-1608909624270)(JAVAWEB-NOTE01.assets/7765164a8afaa8d26d9b31ff3356bc33.png)]
(2)在cmd中連線mysql伺服器之後,在書寫SQL語句時,可以通過 \c 取消當前語句的執行。例如:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-1qLrQtUu-1608909624275)(JAVAWEB-NOTE01.assets/4c6edbd263d6c870ac745e34d4b207d0.png)]
資料庫及表操作
建立、刪除、檢視資料庫(注意刪資料庫不要把它系統自帶的資料庫刪除 mysql,information_schema, performance_schema)
提示: (1)SQL語句對大小寫不敏感。推薦關鍵字使用大寫,自定義的名稱(庫名,表名,列名等)使用小寫。
SHOW DATABASES; -- 檢視當前資料庫伺服器中的所有庫 多個s query:查詢
CREATE DATABASE mydb1; -- 建立mydb1庫 database 資料庫
(2)並且在自定義名稱時,針對多個單詞不要使用駝峰命名,而是使用下劃線連線。(例如:tab_name,而不是 tabName )
– 01.檢視mysql伺服器中所有資料庫
show databases; -- 檢視伺服器所有的資料庫
show tables; -- 查詢當前庫所有表 table表
– 02.進入某一資料庫(先進入資料庫後,才能操作庫中的表和表記錄)
– 語法:USE 庫名;
use mysql;-- 進入到"mysql"資料庫
show tables; -- 查詢當前庫所有表
– 檢視已進入的庫(瞭解)
select database(); -- select選擇,選定 這個語法比較特殊
– 03.檢視當前資料庫中的所有表
-- 先進入某一個庫,再檢視當前庫中的所有表
use test;
show tables;
– 04.刪除mydb1庫
– 語法:DROP DATABASE 庫名;
drop database mydb1;-- 刪除mydb1庫,但如果刪除的庫不存在,則會報錯。 drop 減少
-- 思考:當刪除的庫不存在時,如何避免錯誤產生?
drop database if exists mydb1;
-- 如果mydb1庫存在則刪除,如果不存在,也就不會執行刪除操作。
– 05.重新建立mydb1庫,並指定編碼為utf8
– 語法:CREATE DATABASE 庫名 CHARSET 編碼;
– 需要注意的是,mysql中不支援橫槓(-),所以utf-8要寫成utf8;
create database mydb1 charset utf8;-- 字符集和 charset
– 如果不存在則建立mydb1; //建立資料庫需要先判斷是否有一個同名的資料庫,有需要先進行刪除操作(因為不能在建立一個相同名字的資料庫),之後再進行建立.
create database if not exists mydb1 charset utf8;
– 06.檢視建庫時的語句(並驗證資料庫庫使用的編碼) 這個主要是驗證資料庫的編碼用的(瞭解)
– 語法:SHOW CREATE DATABASE 庫名; 直接在建立資料庫的語句前加個 show
show create database mydb1;
建立、刪除、查看錶 (對錶進行操作需要先進入到資料庫)
總結: 對資料庫和表的建立和刪除,檢視 都是 create drop show,建立和刪除都是先進行判斷,建立是不存在建立資料庫,而表是先刪除表在建立.
– 07.進入mydb1庫,刪除stu學生表(如果存在)
– 語法:DROP TABLE 表名; 注意多條sql語句可以一起執行前提是有分號(;)隔開.
use mydb1;-- 進入到mydb1庫
drop table if exists stu;-- 如果存在stu表,則刪除
– 08.建立stu學生表(編號[數值型別]、姓名、性別、出生年月、考試成績[浮點型]),建表的語法:
CREATE TABLE 表名(
列名 資料型別, (逗號分隔)
列名 資料型別,
...
列名 資料型別
);
SQL語句: 主鍵不一定是數值,也有可能是字串,自由主鍵是數字的時候才能設定為自增.
-- 如果存在,則刪除stu表
drop table if exists stu;
-- 建立stu學生表
create table stu( -- 先換行(shift+enter,單獨的enter鍵是執行sql命令),在tab縮排一下
-- 如果id是主鍵並且是數值,可以設定為自增.可以保證每次的id值都不一樣.
id int primary key auto_increment, -- 給id新增主鍵約束,並自增。
name varchar(50), -- 可變長字串 ,50代表最多隻能存50個字元。
gender varchar(10) not null, -- 給gender新增非空的約束。
birthday date,
score double -- 最後不需要逗號。列和列之間用 ,隔開
) ;
– 09.檢視stu學生表結構
– 語法:desc 表名;
desc stu;
Null:表示將來給這些列插入值是否允許為空(yes代表允許) Default:表示如果不給值的話預設為null
新增、更新、刪除(表記錄)
注意在sql語句中寫的都是英文符號,java也是不要寫成中文.可以再輸入法中設定標點符號為英文的格式.
在輸入法上右鍵–設定—勾選在中文是使用英文標點—確定.
– 10.往學生表(stu)中插入記錄(資料)
– 語法:INSERT INTO 表名(列名1,列名2,列名3…) VALUES(值1,值2,值3…);
-- 如果是在cmd中執行插入記錄的語句,先 set names gbk; 再插入記錄!
-- 由於id已經設定了主鍵自增,所以再插入資料,id可以不用給值,但不可以不給,寫個null。 在資料庫中字串和日期用單引號,不要寫雙引號。
insert into stu(id,name,gender,birthday,score) value(null,'tom','male','2000-3-4',89);-- 注意前後順序一致.
insert into stu value(null,'john','male','2002-5-4',79);-- 同時插入多行資料,從第二行開始前面的那個()的內容可以省略.
insert into stu value(null,'andy','fmale','2004-5-4',69);-- insert 插入 into到...裡面
-- 查詢學生表中的所有記錄
select*from stu; -- *代表所有的
提示:
(1)當為所有列插入值時,可以省寫列名(從第二個),但值的個數和順序必須和宣告時列的個數和順序保持一致!
(2)SQL語句中的值為字串或日期時,值的兩邊要加上單引號(有的版本的資料庫雙引號也可以,但推薦使用單引號)。
(3)(針對cmd視窗)在插入資料之前,先設定編碼:set names gbk; -- 因為cmd視窗預設是gbk
或者用以下命令連線mysql伺服器:
mysql --default-character-set=gbk -uroot -proot
等價於:
mysql -uroot -proot
set names gbk;
– 11.查詢stu表所有學生的資訊
– 語法:SELECT 列名 | * FROM 表名
select * from stu; -- *代表所有 select幾乎都是對錶進行查詢操作的,除了檢視當前進入的庫.
– 12.修改stu表中所有學生的成績,加10分特長分
– 修改語法: UPDATE 表名 SET 列=值,列=值,列=值…[WHERE子句];
update stu set score=score+10; -- update更新 (不寫條件代表更新所有的score)
-- score+=10 mysql中不支援+=
– 13.修改stu表中編號為1的學生成績,將成績改為83分。
update stu set score=83 where id=1;-- where一般用於語句中加個條件時,進行過濾用的
-- 修改3號學生的性別為'male',成績改為99;
update stu set score=99,gender='male' where id=3;
提示:where子句用於對記錄進行篩選過濾,保留符合條件的記錄,將不符合條件的記錄剔除。
– 14.刪除stu表中所有的記錄 (刪除的語法是最簡單的) 注意增刪改查都是對錶的記錄進行操作的
– 刪除記錄語法: DELETE FROM 表名 [where子句]
delete from stu; -- 刪除stu表中的所有記錄 刪除表中的記錄用的是delete,那2個用的是drop
– 僅刪除符合條件的 (刪除是直接刪,不像查詢樣考慮顯示的資料,直接刪就完了)
delete from stu where id>2; -- 刪除stu表中id大於2的記錄
查詢表記錄
– 準備資料: 以下練習將使用db10庫中的表及表記錄,請先進入db10資料庫!!!
基礎查詢
SELECT 語句用於從表中選取資料。結果被儲存在一個結果表中(稱為結果集)。
語法:SELECT 列名稱 | * FROM 表名
提示:(1) *(星號)為萬用字元,表示查詢所有列。
select * from emp;
(2)但使用 *(星號)有時會把不必要的列也查出來了,並且效率不如直接指定列名
– 15.查詢emp表中的所有員工,顯示姓名,薪資,獎金
select name,sal,bonus from emp;
– 16.查詢emp表中的所有部門和職位
select dept,job from emp;
思考:如果查詢的結果中,存在大量重複的記錄,如何剔除重複記錄,只保留一條? */
– 在select之後、列名之前,使用DISTINCT 剔除重複的記錄
select distinct dept,job from emp; -- distinct 不同種類的
WHERE子句查詢
WHERE子句查詢語法:SELECT 列名稱 | * FROM 表名稱 WHERE 列 運算子 值
WHERE子句後面跟的是條件,條件可以有多個,多個條件之間用連線詞(or | and)進行連線
下面的運算子可在 WHERE 子句中使用:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-h2yzb6Rn-1608909624278)(JAVAWEB-NOTE01.assets/7b2b5598fb3af3f96d552b5d9779d892.png)]
– 17.查詢emp表中【薪資大於3000】的所有員工,顯示員工姓名、薪資
select name,sal from emp where sal>3000;
– 18.查詢emp表中【總薪資(薪資+獎金)大於3500】的所有員工,顯示員工姓名、總薪資
select name,sal+bonus from emp ; -- 求所有員工的總薪資
select name,sal+bonus from emp
where sal+bonus>3500;
–如果將’韓少雲’的獎金更新為null值,在執行上面的SQL語句,會有問題嗎?(null+任何值=null)
update emp set bonus=null where name='韓少雲';
– ifnull(列名, 值)函式: 判斷指定的列是否包含null值,如果有null值,用第二個值替換null值
(null一般用0替換)
select name,sal+ifnull(bonus,0) from emp
where sal+ifnull(bonus,0)>3500;
– 注意檢視上面查詢結果中的表頭,如何將表頭中的 sal+bonus 修改為 “dec總薪資”
– 使用as
可以為表頭指定別名
select name as 姓名,sal+ifnull(bonus,0) as 總薪資 from emp
where sal+ifnull(bonus,0)>3500;
– 另外as可以省略
select name 姓名,sal+ifnull(bonus,0) 總薪資 from emp
where sal+ifnull(bonus,0)>3500;
– 19.查詢emp表中【薪資在3000和4500之間】的員工,顯示員工姓名和薪資
select name, sal from emp
where sal>=3000 and sal<=4500; -- and
– 提示: between…and… 在…和…之間
select name,sal from emp
where sal between 3000 and 4500; -- 包括3000,也包括4500.如果不包括頭和尾不能用between and.
– 20.查詢emp表中【薪資為 1400、1600、1800】的員工,顯示員工姓名和薪資
select name,sal from emp
where sal=1400 or sal=1600 or sal=1800; -- or表示或則
– 或者
select name,sal from emp
where sal in(1400,1600,1800); //查詢滿足其中一個條件的 表
– 21.查詢薪資不為1400、1600、1800的員工,顯示員工姓名和薪資
select name,sal from emp
where not(sal=1400 or sal=1600 or sal=1800);
-- 或
select name,sal from emp
where sal not in(1400,1600,1800);
– 22.(自己完成) 查詢emp表中薪資大於4000和薪資小於2000的員工,顯示員工姓名、薪資。
select name,sal from emp
where sal>4000 or sal<2000;
– 23.(自己完成) 查詢emp表中薪資大於3000並且獎金小於600的員工,顯示員工姓名、薪資、獎金。
select name,sal,bonus from emp
where sal>3000 and bonus<600; -- 結果有誤差,少了一行資料 null的哪一行
– 處理null值(null值和任何值比較都是false)
select name,sal,ifnull(bonus,0) from emp
where sal>3000 and ifnull(bonus,0)<600;
– 24.查詢沒有部門的員工(即部門列為null值)
select * from emp where dept=null; -- 條件錯誤,在where條件裡不能用某一個列名等於null值作為條件去篩選.
select * from emp where dept is null; -- 資訊正確
– 思考:如何查詢有部門的員工(即部門列不為null值)
select * from emp where dept is not null;
-- 或則
select * from emp where not (dept is null);
模糊查詢
LIKE 操作符用於在 WHERE 子句中搜索列中的指定模式。
可以和萬用字元(%、_)配合使用,其中"%"表示0或多個任意的字元
,"_"表示一個任意的字元
。
語法:SELECT 列 | * FROM 表名 WHERE 列名 LIKE 值
示例:
– 25.查詢emp表中姓名中以"劉"字開頭的員工,顯示員工姓名。
select name from emp where name like '劉%';
– 26.查詢emp表中姓名中包含"濤"字的員工,顯示員工姓名。
select name from emp where name like '%濤%';
– 27.查詢emp表中姓名以"劉"開頭,並且姓名為兩個字的員工,顯示員工姓名。
select name from emp where name like '劉_';
select name from emp where name like '劉_ _';
多行函式查詢
多行函式也叫做聚合(聚集)函式,根據某一列或所有列進行統計。
常見的多行函式有:
多行函式 | 作用 |
---|---|
COUNT( 列名 | * ) | 統計結果集中指定列的記錄的行數。 – 數數,計算 |
MAX( 列名 ) | 統計結果集中某一列值中的最大值 |
MIN( 列名 ) | 統計結果集中某一列值中的最小值 |
SUM( 列名 ) | 統計結果集中某一列所有值的和 |
AVG( 列名 ) | 統計結果集中某一列值的平均值 |
提示:(1**)多行函式不能用在where子句中(注意:能和where子句連用)**
(2)多行函式和是否分組有關,分組與否會直接影響多行函式的執行結果。
(3)多行函式在統計時會對null值進行過濾,直接將null值丟棄,不參與統計。
– 28.統計emp表中薪資大於3000的員工個數(就是把查詢的列名,用關鍵字包起來)
select count(*)from emp where sal>3000; --count* 對所有列統計行數 7
select count(id)from emp where sal>3000; --countid 對所有id統計行數 7
– 29.求emp表中的最高薪資
select max(sal) from emp; -- 返回最高薪資 5000
– 30.統計emp表中所有員工的薪資總和(不包含獎金)
select sum(sal) from emp;-- 薪資總和:39650
select sum(bonus) from emp;--獎金總和:5900 數值正確,多行函式會對null值處理,直接丟棄,不參與統計.
– 31.統計emp表員工的平均薪資(不包含獎金)
select avg(sal) from emp;-- 39650/12
多行函式需要注意的問題:
-
多行函式和是否分組有關,如果查詢結果中的資料沒有經過分組,預設整個查詢結果是一個組,多行函式就會預設統計當前這一個組的資料。產生的結果只有一個。
-
如果查詢結果中的資料經過分組(分的組不止一個),多行函式會根據分的組進行統計,有多少個組,就會統計出多少個結果。
select * from emp;
例如:統計emp表人數
select count(*) from emp; -- 12 沒分組按照是預設是同一個組進行統計人數.一個組只會參生一個結果.
結果返回的就是emp表中的所有人數
再例如:根據性別對emp表中的所有員工進行分組,再統計每組的人數,顯示性別和對應人數
select count(*) from emp group by gender; --10 2
分組查詢
GROUP BY 語句根據一個或多個列對結果集進行分組。 (類似於where子句,放在查詢表後面)
在分組的列上我們可以使用 COUNT,SUM,AVG,MAX,MIN等函式。
語法:SELECT 列 | * FROM 表名 [WHERE子句] GROUP BY 列;(注意如果有where子句則先寫where子句在寫分組)
– 32.對emp表,按照部門對員工進行分組,檢視分組後效果。
select name,dept from emp group by dept; -- 只顯示每組的第一個人 group 組
--統計分組後,每組的人數
select count(*) from emp group by dept;-- 3個組,所以會統計出三個結果
– 33.對emp表按照職位進行分組,並統計每個職位的人數,顯示職位和對應人數
-- 根據job進行分組,統計每個組的人數(每個職位的人數)
select job,count(*) from emp group by job;
– 34.對emp表按照部門進行分組,求每個部門的最高薪資(不包含獎金),顯示部門名稱和最高薪資
88888888888
-- 如果不分組,直接使用max(sal),這是統計整個emp表中的最高薪資
select max(sal) from emp;-- 5000;
-- 如果根據部門分組,可以分為三個組,在使用max(sal),就是統計每個組的最高薪資.
select dept,max(sal) from emp group by dept;
排序查詢
注意: where子句>分組>排序 先寫where在寫分組,在寫排序. (優先順序)
使用 ORDER BY 子句將結果集中記錄根據指定的列排序後再返回
語法:SELECT 列名 FROM 表名 ORDER BY 列名 [ASC|DESC]
ASC(預設)升序,即從低到高;DESC 降序,即從高到低。
– 35.對emp表中所有員工的薪資進行升序(從低到高)排序,顯示員工姓名、薪資。
select name,sal from emp order by sal ; -- 預設是升序asc可以省略 order 順序
select name,sal from emp order by sal asc; -- 升序 order by 排序依據 (ascend上升)
– 36.對emp表中所有員工的獎金進行降序(從高到低)排序,顯示員工姓名、獎金。
select name,bonus from emp order by bonus desc; -- 降序 不能省略 (descend降序)
分頁查詢
先寫 where 分組 排序 分頁 (優先順序)
總結: 它們都是放在查詢表之後的位置.
在mysql中,通過**limit進行分頁查詢,**查詢公式為:
limit (頁碼-1)*每頁顯示記錄數, 每頁顯示記錄數
– 37.查詢emp表中的所有記錄,分頁顯示:每頁顯示3條記錄,返回所有頁的資料。
-- 每頁顯示3條,查詢第1頁資料 limit 界限,範圍
select * from emp limit 0,3; -- 第一頁頁碼是1,(1-1)*3=0 每頁記錄數;3條記錄為:3
-- 每頁顯示3條,查詢第2頁資料
select * from emp limit 3,3;
-- 每頁顯示3條,查詢第3頁資料
select * from emp limit 6,3;
– 38.求emp表中薪資最高的前3名員工的資訊,顯示姓名和薪資
-- 現根據薪資降序(從高到低)排序
select name,sal from emp order by sal desc;
-- 在排序的基礎上分頁查詢,只查詢第一頁
select name,sal from emp order by sal desc limit 0,3;
其他函式(可以用在where子句中)
函式名 | 解釋說明 |
---|---|
curdate() | 獲取當前日期,格式是:年月日 用法: select curdate(); |
curtime() | 獲取當前時間 ,格式是:時分秒 同上 |
sysdate()/now() | 獲取當前日期+時間,格式是:年月日 時分秒 同上 |
year(date) | 返回date中的年份 用法:裡面需要傳一個引數 |
month(date) | 返回date中的月份 select month(now()); 獲取now這個時間中的月份 |
day(date) | 返回date中的天數 |
hour(date) | 返回date中的小時 |
minute(date) | 返回date中的分鐘 |
second(date) | 返回date中的秒 |
CONCAT(s1,s2…) | 將s1,s2 等多個字串合併為一個字串 |
CONCAT_WS(x,s1,s2…) | 同CONCAT(s1,s2,…)函式,但是每個字串之間要加上x,x是分隔符 |
– 39.查詢emp表中所有【在1993和1995年之間出生】的員工,顯示姓名、出生日期。
-- 將運算子兩邊的值都轉成日期型別,在進行比較
select name,birthday from emp
where birthday>='1993-1-1' and birthday<='1995-12-31';
--或則,將日期中的年份提取出來,用年份和年份進行比較
select name,birthday from emp
where year(birthday)>=1993 and year(birthday)<=1995;
– 40.查詢emp表中本月過生日的所有員工
select * from emp
where month(now())=month(birthday);
– 41.查詢emp表中員工的姓名和薪資(薪資格式為: xxx(元) )
select name,concat(sal,'(元)') from emp; -- concat(s1,s2,s3...)
– 補充練習:查詢emp表中員工的姓名和薪資(薪資格式為: xxx/元 )
-- 用concat 函式實現
select name,concat(sal,'/元') from emp;
-- 或則 用concat_ws實現, concat_ws(x,s1,s2,s3...)
select name, concat_ws('/',sal,'元') from emp; -- 即,s1與s2兩兩拼接會加上一個x
mysql的資料型別
數值型別
MySQL中支援多種整型,其實很大程度上是相同的,只是儲存值的大小範圍不同而已。
tinyint:佔用1個位元組,相對於java中的byte
smallint:佔用2個位元組,相對於java中的short
int:佔用4個位元組,相對於java中的int (重點掌握)
bigint:佔用8個位元組,相對於java中的long
其次是浮點型別即:float和double型別
float:4位元組單精度浮點型別,相對於java中的float
double:8位元組雙精度浮點型別,相對於java中的double (重點掌握)
字串型別
1、char(n) 定長字串,最長255個字元。n表示字元數,例如:
– 建立user表,指定使用者名稱為char型別,字元長度不超過10
字元數量: 張三,2個字元. Tom,3個字元.
create table user(
username char(10),
...
);
所謂的定長,是當插入的資料的長度小於指定的長度時,剩餘的空間會用空格填充。(缺點:這樣可能會浪費空間)
優點是 :效率比varchar更高。
char型別往往用於儲存長度固定的資料。(如:身份證號,學生編號)
2、varchar(n) 變長字串,最長不超過65535個位元組,n表示字元數,一般超過255個字元,會使用text型別,例如: various 各種各樣的。
iso8859-1碼錶:一個字元佔用1個位元組,1*n <65535, n最多等於 65535
utf8碼錶:一箇中文漢字佔用3個位元組,3*n<65535,n最多等於 65535/3
GBK碼錶:一箇中文漢字佔用2個位元組,2*n<65535,n最多等於 65535/2
– 建立user表,指定使用者名稱為varchar型別,長度不超過10個字元
create table user(
username varchar(10)
);
所謂的不定長,是當插入的資料的長度小於指定的長度時,剩餘的空間可以留給別的資料使用。(節省空間)
總結:長度固定的資料,用char型別,這樣既不會浪費空間,效率也比較高。
如果長度不固定,使用varchar型別,這樣不會浪費空間。
3、大文字(長文字)型別
最長65535個位元組,一般超過255個字元列的會使用text,超過用char或varchar型別.
– 建立user表:
create table user(
resume text
);
另,text也分多種,其中bigtext儲存資料的長度約為4GB。
擴充套件內容3:(面試題)char(n)、varchar(n)、text都可以表示字串型別,其區別在於:
(1)char(n)在儲存資料時,如果存入的字串長度小於指定的長度n,後面會用空格補全,因此可能會造成空間浪費,但是char型別的儲存速度較varchar和text快。
因此char型別適合儲存長度固定的資料,這樣就不會有空間浪費,儲存效率比後兩者還快!
(2)varchar(n)儲存資料時,按資料的真實長度儲存,剩餘的空間可以留給別的資料用,因此varchar不會浪費空間。
因此varchar適合儲存長度不固定的資料,這樣不會有空間的浪費。
(3)text是大文字型別,一般文字長度超過255個字元,就會使用text型別儲存。
日期型別
date:年月日
time:時分秒
datetime:年月日 時分秒
timestamp:時間戳(實際儲存的是一個時間毫秒值),與datetime儲存日期格式相同。兩者的區別是:
-
timestamp最大表示1970~2038年,而datetime範圍是1000~9999
-
timestamp在插入資料、修改資料時,可以自動更新成系統當前時間(後面用到時再做講解)
mysql的欄位約束
欄位約束/列約束 --> 約束: 即新增一些限制.
主鍵約束
主鍵約束:如果為一個列添加了主鍵約束,那麼這個列就是主鍵,主鍵的特點是唯一且不能為空。
主鍵的作用: 作為一個唯一標識,唯一的表示一條表記錄(作用類似於人的身份證號,可以唯一的表示一個人一樣。)
新增主鍵約束,例如將id設定為主鍵: primary key
create table stu(
id int primary key, -- primary 主要的 key 鍵
...
);
如果主鍵是數值型別,為了方便插入主鍵(並且保證插入資料時,主鍵不會因為重複而報錯),可以設定一個主鍵自增策略。 – 注意:只有是數值型別才可以設定自增。
主鍵自增策略是指:設定了自增策略的主鍵,可以在插入記錄時,不給id賦值,只需要設定一個null值,資料庫會自動為id分配一個值(AUTO_INCREMENT變數,預設從1開始,後面依次+1),這樣既可以保證id是唯一的,也省去了設定id的麻煩。
注意:設定自增 第二個數刪除後 在插入一個數直接回變為3
設定自增 也可以從新賦值 如果大於自增的值 則會返回一個+1的數 因為id不能重複
將id主鍵設定為自增:
create table stu(
id int primary key auto_increment, -- automatic 自動的
... -- increament 增加
);
注意:主鍵約束不等於非空約束+唯一約束,還作為唯一標示。
非空約束
非空約束:如果為一個列添加了非空約束,那麼這個列的值就不能為空,但可以重複。
新增非空約束,例如為password新增非空約束: not null
create table user(
password varchar(50) not null,
...
);
唯一約束
唯一約束:如果為一個列添加了唯一約束,那麼這個列的值就必須是唯一的(即不能重複),但可以為空。
新增唯一約束,例如為username新增唯一約束及非空約束:
unique:代表唯一約束
unique not null:代表 唯一且不為空,它和主鍵約束有區別(主鍵約束還有一個標識的作用)
create table user(
username varchar(50) unique not null,
...
);
外來鍵約束(通常2張或2張以上的表)
外來鍵其實就是用於 通知 資料庫兩張表資料之間對應關係的這樣一個列。
這樣資料庫就會幫我們維護兩張表中資料之間的關係。
如何儲存兩張表之間對應的關係: 可以在其中的一張表中,新增一個列,用於儲存另外一張表的主鍵.
可以不用新增外來鍵:也就是不告訴資料庫dept和emp兩張表之間存在對應關係,資料庫也就不會幫我們去維護這層關係.
可以新增外來鍵: 新增外檢等同於通知資料庫,dept和emp兩張表之間存在對應關係,並且要求資料庫幫我們去維護者層關係.(可以避免資料的完整性和一致性被破壞,你刪除銷售部,趙四和劉能就找不到部門了會報錯,阻止你刪除)
foreign key(dept_id) references dept(id) references:參考
那現在就是想刪除呢? 可以吧趙四和劉能的id改為別的部門的id如3:update emp dept_id=3 where is=4 or id=5;
解釋: 外來鍵列裡面的引數參考部門的主鍵.
(1) 建立表的同時新增外來鍵
create table emp(
id int,
name varchar(50),
dept_id int,
foreign key(dept_id) references dept(id)
);
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-COFgKHDq-1608909624281)(JAVAWEB-NOTE01.assets/6b56c23ba5cf6a63d9f9e8a8b5fd8467.png)]
(1)如果是要表示兩張表的資料之間存在對應關係,只需要在其中的一張表中新增一個列,儲存另外一張表的主鍵,就可以儲存兩張表資料之間的關係。
但是新增的這個列(dept_id)對於資料庫來說就是一個普通列,資料庫不會知道兩張表存在任何關係,因此資料庫也不會幫我們維護這層關係。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-oajvsC6Q-1608909624283)(JAVAWEB-NOTE01.assets/image-20200530160646152.png)]
(2)如果將dept_id列設定為外來鍵,等同於通知資料庫,部門表和員工表之間存在對應關係,dept_id列中的資料要參考部門的主鍵,資料庫一旦知道部門和員工表之間存在關係,就會幫我們維護這層關係。
思考:如果在建立表時沒有指定外來鍵,那麼後期該如何指定外來鍵?以及如何刪除外來鍵?
表關係
常見的表關係分為以下三種:
一對多(多對一)、一對一、多對多
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-xNAULpOK-1608909624286)(JAVAWEB-NOTE01.assets/1e4a36daf517c88d356cbc3c8dbd3ea8.png)]
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-sCUyIAG6-1608909624288)(JAVAWEB-NOTE01.assets/392ee4d4c0f8fdd86adc4b9abc3ad6f5.png)]
多表查詢
– 準備資料: 以下練習將使用db30庫中的表及表記錄,請先進入db30資料庫!!!
連線查詢
– 42.查詢部門和部門對應的員工資訊
select *from dept,emp; -- 就是寫多張表,之間用逗號隔開。
上面的查詢中存在大量錯誤的資料,一般我們不會直接使用這種查詢。
**笛卡爾積查詢:**所謂笛卡爾積查詢就是指,查詢兩張表,其中一張表有m條記錄,另一張表有n條記錄,查詢的結果是m*n條。
雖然笛卡爾積查詢中包含大量錯誤資料,但我們可以通過where子句將錯誤資料剔除,保留下來的就是正確資料。
-- 員工部門編號=部門的編號
select *from dept,emp -- 因為id在部門表和員工表都有,所以加上列名進行區分
where emp.dept_id=dept.id; -- 因為dept_id只存在於emp表中得列,所以可以直接寫 寫dept_id 而id則是既存在emp表又存在dept表,所以dept.id(表名.列名) 用於區分, 不然會報錯模糊不清的。
通過where子句將笛卡爾積查詢中的錯誤資料剔除,保留正確的資料,這就是連線查詢!
上面的查詢可以換成下面的查詢:(,換位inner join where換位on )
select *from dept inner join emp
on emp.dept_id=dept.id; -- 內連線查詢,和上面的查詢結果一樣
左外連線查詢 (以左邊為基準)
– 43.查詢【所有部門】及部門對應的員工,如果某個部門下沒有員工,員工顯示為null
select *from dept left join emp
on emp.dept_id=dept.id;
左外連線查詢:可以將左邊表中的所有記錄都查詢出來,右邊表只顯示和左邊相對應的資料,如果左邊表中某些記錄在右邊沒有對應的資料,右邊顯示為null即可。
( 如果是想查左邊所有表的資料,就用左外連線查詢)
,換位 left join where --on
右外連線查詢 (以右邊為基準)
– 44.查詢【所有員工】及員工所屬部門,如果某個員工沒有所屬部門,部門顯示為null
select *from dept right join emp
on emp.dept_id=dept.id;
右外連線查詢:可以將右邊表中的所有記錄都查詢出來,左邊表只顯示和右邊相對應的資料,如果右邊表中某些記錄在左邊沒有對應的資料,可以顯示為null。
擴充套件:如果想將兩張表中的所有資料都查詢出來(左外+右外並去除重複記錄),可以使用全外連線查詢,但是mysql又不支援全外連線查詢。
select *from dept left join emp on emp.dept_id=dept.id
union
select *from dept right join emp on emp.dept_id=dept.id;
可以使用union將左外連線查詢的結果和右外連線查詢的結果合併在一起,並去除重複的記錄。例如:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-P5k4iyE3-1608909624290)(JAVAWEB-NOTE01.assets/d0c3a3d4ad4f48d4779d1d40cac31755.png)]
需要注意的是:union可以將兩條SQL語句執行的結果合併,但是有前提:
(1**)兩條SQL語句查詢的結果列數必須一致**
(2)兩條SQL語句查詢的結果列名、順序也必須一致
並且union預設就會將兩個查詢中重複的記錄去除(如果不希望去除重複記錄,可以使用union all)
子查詢練習
– 準備資料:以下練習將使用db40庫中的表及表記錄,請先進入db40資料庫!!!
– 45.列出薪資比’王海濤’的薪資高的所有員工,顯示姓名、薪資
-- 求出'王海濤'的薪資
select sal from emp where name='王海濤'; -- 2450
-- 求出比'王海濤'薪資高的所有員工資訊 這樣寫沒有寫死,以後再改工資不用再更改程式碼 像這樣將一條語句作為另一條語句的子句就叫子查詢.
select name,sal from emp
where sal>(select sal from emp where name='王海濤');
– 46.列出與’劉沛霞’從事相同職位的所有員工,顯示姓名、職位。
-- 求出劉培霞從事的職位
select job from emp where name='劉沛霞';
-- 再求出和劉培霞從事相同職位的員工
select name ,job from emp
where job=(select job from emp where name='劉沛霞');
– 47.列出薪資比’大資料部’部門(已知部門編號為30)所有員工薪資都高的員工資訊,顯示員工姓名、薪資和部門名稱。
如果不考慮沒有部門的員工
-- 先連線查詢部門表和員工表
select emp.name ,sal, dept.name from dept,emp
where emp.dept_id=dept.id;
-- 求出'大資料'部門最高的薪資
select max(sal) from emp where dept_id=30;
--列出薪資比'大資料'部門最高薪資還高的員工資訊
select emp.name ,sal, dept.name from dept,emp
where emp.dept_id=dept.id and
sal>(select max(sal) from emp where dept_id=30);
如果加上沒有部門的員工 (考慮韓少雲)
-- 使用外連線查詢部門表和員工表
select emp.name ,sal, dept.name from dept right join emp
on emp.dept_id=dept.id;
-- 求出'大資料'部門最高的薪資
select max(sal) from emp where dept_id=30;
--列出薪資比'大資料'部門最高薪資還高的員工資訊
select emp.name ,sal, dept.name from dept right join emp
on emp.dept_id=dept.id
where sal>(select max(sal) from emp where dept_id=30);
多表查詢練習
– 48.列出在’培優部’任職的員工,假定不知道’培優部’的部門編號,顯示部門名稱,員工名稱。
-- 連線查詢部門表和員工表 多張表查詢 先連線查詢
select dept.name,emp.name from dept,emp
where emp.dept_id=dept.id;
-- 求出部門名稱為'培優部'的員工
select dept.name,emp.name from dept,emp
where emp.dept_id=dept.id and dept.name='培優部';
-- 擴充套件:可以為表明加別名,加了別名後,就需要使用別名替換表名
select d.name,e.name from dept d,emp e
where e.dept_id=d.id and d.name='培優部';
– 49.(自查詢)列出所有員工及其直接上級,顯示員工姓名、上級編號,上級姓名
/* 將emp同時看做員工表和上級表
* emp e1 看做員工表 emp e2 看做上級表
* 查詢的表: emp e1, emp e2
* 查詢的列: e1.name,e2.id, e2.name
* 連線條件: 員工所屬上級編號=上級編號
* e1.topid=e2.id
*/
select e1.name,e2.id, e2.name -- select一般用於查詢表的結構
from emp e1, emp e2 -- from 一般跟來至那個表
where e1.topid=e2.id; -- where 一般用於條件的篩選
– 50.列出最低薪資大於1500的各種職位,顯示職位和該職位的最低薪資
-- 根據職位進行分組,在求出每個職位的最低薪資
select job,min(sal) from emp group by job;
-- 求出最低薪資大於1500的職位有哪些
select job,min(sal) from emp group by job
having min(sal) >1500;
補充內容:where和having子句的區別:
(1)相同點: where和having都可以對記錄進行篩選過濾。
(2)區別:where是在分組之前,對記錄進行篩選過濾,並且where子句中不能使用多行函式以及列別名(但是可以使用表別名)
(3)區別:having是在分組之後,對記錄進行篩選過濾,並且having子句中可以使用多行函式以及列別名、表別名。
– 51.列出在每個部門就職的員工數量、平均工資。顯示部門編號、員工數量,平均薪資。
-- 根據部門分組,統計每個組(每個部門)的人數,平均薪資
select dept_id,count(*),avg(sal)
from emp
group by dept_id;
– 52.查出至少有一個員工的部門,顯示部門編號、部門名稱、部門位置、部門人數。
-- 連線查詢部門表和員工表
select d.id,d.name,d.loc
from dept d,emp e
where d.id=e.dept_id;
-- 根據部門進行分組
select d.id,d.name,d.loc,count(*)
from dept d,emp e
where d.id=e.dept_id
group by d.name
having count(*)>0; -- 這句話加不加都行,因為上面分組已經滿足了這個條件.
– 53.列出受僱日期早於直接上級的所有員工,顯示員工編號、員工姓名、部門名稱。
/* emp e1 員工表, emp e2 上級表
* 查詢的表: emp e1, emp e2, dept d
* 查詢的列: e1.id, e1.name, d.name
* 連線條件: e1.topid=e2.id
* e1.dept_id=d.id
* 篩選條件: e1.hdate < e2.hdate
*/
select e1.id, e1.name, d.name
from emp e1, emp e2, dept d
where e1.topid=e2.id
and e1.dept_id=d.id
and e1.hdate < e2.hdate;
– 補充:查詢員工表中薪資最高的員工資訊
select name,max(sal) from emp; -- 這個查詢的結果是錯誤的
-- 可以按照薪資降序排序,每頁顯示一條,查詢第一頁.
select * from emp order by sal desc limit 0,1;
-- 或則 : 也可以使用子查詢 效率會偏低一些
select max(sal) from emp;-- 求emp表中的最高薪資
select * from emp where sal=(select max(sal) from emp);
資料庫備份與恢復
備份資料庫
在cmd視窗中(未登入的狀態下,即:沒有連線資料庫),可以通過如下命令對指定的資料庫進行備份:
mysqldump -u使用者名稱 -p 資料庫的名字 > 備份檔案的位置
– 注意-p和資料庫的名字有空格 檔案沒有會自動幫你建立
示例1: 對db40
庫中的資料(表,表記錄)進行備份,備份到 d:/db40.sql
檔案中
mysqldump -uroot -p db40 > d:/db40.sql
– 這個沒有分號
鍵入密碼,如果沒有提示,即表示備份成功!
也可以一次性備份所有庫,例如:
對mysql伺服器中所有的資料庫進行備份,備份到 d:/all.sql檔案中
mysqldump -uroot -p --all-database > d:/all.sql
鍵入密碼,如果沒有提示錯誤(警告資訊不是錯誤,可以忽略),即表示備份成功!
恢復資料庫(先備份才能恢復)
1、恢復資料庫方式一:
在cmd視窗中(未登入的狀態下),可以通過如下命令對指定的資料庫進行恢復:
mysql -u使用者名稱 -p 資料庫的名字 < 備份檔案的位置
示例:將d:/db40.sql檔案中的資料恢復到db60庫中
– 在cmd視窗中(已登入的狀態下),先建立db60庫:
create database db60 charset utf8;
– 在cmd視窗中(未登入的狀態下)
mysql -uroot -p db60 < d:/db40.sql
2、恢復資料庫方式二:
在cmd視窗中(已登入的狀態下),可以通過source執行指定位置的SQL檔案:
source sql檔案的位置
示例:將d:/db40.sql檔案中的資料恢復到db80庫中
– 在cmd視窗中(已登入的狀態下),先建立db80庫,進入db80庫:
create database db80 charset utf8;
use db80;
– 再通過source執行指定位置下的sql檔案:
source d:/db40.sql
Navicat軟體的使用
Navicat Premium是一套帶圖形使用者介面的資料庫管理工具,讓你從單一應用程式中同時連線MySQL、MariaDB、MongoDB、SQL Server、Oracle、PostgreSQL 和 SQLite資料庫。使用Navicat可以快速、輕鬆地建立、管理和維護資料庫。
1、使用navicat連線mysql伺服器(使用cmd連線mysql伺服器)
2、檢視所有庫、進入資料庫、建立資料庫、刪除資料庫、修改資料庫
3、建立表、查看錶、修改表、刪除表
4、新增表記錄、查詢表記錄、修改表記錄、刪除表記錄
5、使用navicat書寫SQL語句操作資料庫、表和表記錄
...
嗶哩嗶哩視訊連結:https://www.bilibili.com/video/BV1yA41147Vi/
擴充套件內容
現建立學生表:
use test; -- 進入test庫
drop table if exists stu; -- 刪除學生表(如果存在)
create table stu( -- 建立學生表
id int, -- 學生id
name varchar(20), -- 學生姓名
gender char(1), -- 學生性別
birthday date -- 出生年月
);
修改表—新增列
語法:ALTER TABLE tabname ADD col_name datatype [DEFAULT expr][,ADD col_name datatype…];
1、往stu表中新增score列,double型別
alter table stu add score double;
修改表—修改列
語法:ALTER TABLE tabname MODIFY (col_name datatype [DEFAULT expr][,MODIFY
col_name datatype]…);
1、修改id列,將id設定為主鍵
alter table stu modify id int primary key;
2、修改id列,將id主鍵設定為自動增長
alter table stu modify id int auto_increment;
修改表—刪除列
語法:ALTER TABLE tabname DROP [COLUMN] col_name;
1、刪除stu表中的score列
alter table stu drop score;
新增或刪除主鍵及自增
思考:a) 在建表時,如何為id指定主鍵約束和自增?
b) 建好的表,如何通過修改新增主鍵約束和自增?
c) 如何刪除表中的主鍵約束和自增?
1、建立stu學生表,不新增主鍵自增, 查看錶結果
use mydb1; -- 切換到mydb1庫
drop table if exists stu; -- 刪除stu學生表(如果存在)
create table stu( -- 重建stu學生表,沒有主鍵自增
id int,
name varchar(20),
gender char(1),
birthday date
);
desc stu; -- 查看錶結構
表結構如下: 沒有主鍵約束和自增。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-EydNUR3b-1608909624292)(JAVAWEB-NOTE01.assets/4f7cf015ff7829f26d326b6f443628cc.png)]
2、如果表沒有建立,或者要刪除重建,在建立時可以指定主鍵或主鍵自增
drop table if exists stu; -- 刪除stu表
create table stu( -- 重新建立stu表時,指定主鍵自增
id int primary key auto_increment,
name varchar(20),
gender char(1),
birthday date
);
desc stu; -- 查看錶結構
表結構如下: 已經添加了主鍵約束和自增。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-ft8XZQqv-1608909624294)(JAVAWEB-NOTE01.assets/1606d49b391f6e0d23b526912dbb22cf.png)]
3、如果不想刪除重建表,也可以通過修改表新增主鍵或主鍵自增
再次執行第1步,建立stu學生表,不新增主鍵自增,查看錶結果
– 例如: 將stu學生表中的id設定為主鍵和自動增長
alter table stu modify id int primary key auto_increment;
desc stu; -- 查看錶結構
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-iFqxtrwV-1608909624296)(JAVAWEB-NOTE01.assets/1606d49b391f6e0d23b526912dbb22cf.png)]
如果只新增主鍵約束,不設定自增
alter table stu modify id int **primary key**;
如果已經新增主鍵約束,僅僅設定自增,但需注意:
(1)如果沒有設定主鍵,不可新增自增
(2)只有當主鍵是數值時,才可以新增自增
alter table stu modify id int **auto_increment**;
4、如果想刪除主鍵自增
– 刪除主鍵自增時,要先刪除自增
alter table stu modify id int;
– 再刪除主鍵約束
alter table stu drop primary key;
desc stu; -- 查看錶結構
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-RT3FcaOR-1608909624297)(JAVAWEB-NOTE01.assets/4f7cf015ff7829f26d326b6f443628cc.png)]
新增外來鍵約束
1、新增外來鍵方式一:建表時新增外來鍵
現有部門表如下:
– 建立部門表
create table dept(
id int primary key auto_increment, -- 部門編號
name varchar(20) -- 部門名稱
);
要求建立員工表,並在員工表中新增外來鍵關聯部門主鍵
– 建立員工表
create table emp(
id int primary key auto_increment, -- 員工編號
name varchar(20), -- 員工姓名
dept_id int, -- 部門編號
foreign key(dept_id) references dept(id) -- 指定dept_id為外來鍵
);
2、新增外來鍵方式二:建表後新增外來鍵
現有部門表和員工表:
– 建立部門表
create table dept(
id int primary key auto_increment, -- 部門編號
name varchar(20) -- 部門名稱
);
– 建立員工表
create table emp(
id int primary key auto_increment, -- 員工編號
name varchar(20), -- 員工姓名
dept_id int -- 部門編號
);
– 如果表已存在,可以使用下面這種方式:
alter table emp add constraint fk_dept_id foreign key(dept_id) references dept(id);
其中 fk_dept_id (名字由自己定義),是指外來鍵約束名稱,也可以將【constraint fk_dept_id】省略,MySQL會自動分配一個外來鍵名稱,將來可以通過該名稱刪除外來鍵。
foreign key(dept_id)中的dept_id為外來鍵
刪除外來鍵約束
1、首先通過 “show create table 表名”語法,查詢含有外來鍵表的建表語句,例如:
show create table emp;
顯示結果如下:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-8QFW4Hnl-1608909624299)(JAVAWEB-NOTE01.assets/e5ad1306d0985dadf8ffbbd3eff61174.png)]
其中,emp_ibfk_1是在建立表時,資料庫為外來鍵約束指定的一個名字,刪除這個名字即可刪除外來鍵關係,例如:
alter table emp drop foreign key emp_ibfk_1;
外來鍵刪除成功!
新增外來鍵約束(多對多)
– 現有學生(stu)表和教師(tea)表:
– 建立學生表
create table stu(
stu_id int primary key auto_increment, -- 學生編號
name varchar(20) -- 學生姓名
);
– 建立教師表
create table tea(
tea_id int primary key auto_increment, -- 教師編號
name varchar(20) -- 教師姓名
);
– 新增第三方表(stu_tea)表示學生表和教師表關係
– 建立學生和教師關係表
create table stu_tea(
stu_id int, -- 學生編號
tea_id int, -- 教師編號
primary key(stu_id,tea_id), -- 設定聯合主鍵
foreign key(stu_id) references stu(stu_id), -- 新增外來鍵
foreign key(tea_id) references tea(tea_id) -- 新增外來鍵
);
其中為了防止重複資料,將stu_id和tea_id設定為聯合主鍵。
將stu_id設定為外來鍵,參考stu表中的stu_id列
並將tea_id設定為外來鍵,參考tea表中的tea_id列
級聯更新、級聯刪除
– 建立db20庫、dept表、emp表並插入記錄
– 刪除db20庫(如果存在),並重新建立db20庫
drop database if exists db20;
create database db20 charset utf8;
use db20;
– 建立部門表, 要求id, name欄位
create table dept(
id int primary key auto_increment, -- 部門編號
name varchar(20) -- 部門名稱
);
– 往部門表中插入記錄
insert into dept values(null, '財務部');
insert into dept values(null, '人事部');
insert into dept values(null, '科技部');
insert into dept values(null, '銷售部');
– 建立員工表, 要求id, name, dept_id
create table emp(
id int primary key auto_increment, -- 員工編號
name varchar(20), -- 員工姓名
dept_id int, -- 部門編號
foreign key(dept_id) references dept(id) -- 指定外來鍵
on update cascade -- 級聯更新
on delete cascade -- 級聯刪除
);
insert into emp values(null, '張三', 1);
insert into emp values(null, '李四', 2);
insert into emp values(null, '老王', 3);
insert into emp values(null, '趙六', 4);
insert into emp values(null, '劉能', 4);
級聯更新:主表(dept表)中的主鍵發生更新時(例如將銷售部的id改為40),從表(emp表)中的記錄的外來鍵資料也會跟著該表(即趙六和劉能的部門編號也會更新為40)
級聯刪除:如果不新增級聯刪除,當刪除部門表中的某一個部門時(例如刪除4號部門),若該部門在員工表中有對應的員工(趙六和劉能),刪除會失敗!
若果添加了級聯刪除,當刪除部門表中的某一個部門時,若該部門在員工表中有對應的員工,會在刪除部門的同時,將員工表中對應的員工也刪除!
where中不能使用列別名
SQL語句的書寫順序:
select * | 列名 -- 確定要查詢的列有哪些
from 表名 -- 確定查詢哪張表
where 條件 -- 通過篩選過濾,剔除不符合條件的記錄
group by 分組的列 -- 指定根據哪一列進行分組
having 條件 -- 通過條件對分組後的資料進行篩選過濾
order by 排序的列 -- 指定根據哪一列進行排序
limit (countPage-1)*rowCount, rowCount -- 指定返回第幾頁記錄以及每頁顯示多少條
SQL語句的執行順序:
from 表名 -- 確定查詢哪張表
where 條件 -- 通過篩選過濾,剔除不符合條件的記錄
select * | 列名 列別名 -- 確定要查詢的列有哪些,
group by 分組的列 -- 指定根據哪一列進行分組
having 條件 -- 通過條件對分組後的資料進行篩選過濾
order by 排序的列 -- 指定根據哪一列進行排序
limit (countPage-1)*rowCount, rowCount
**** 關於where中不能使用列別名但是可以使用表別名?**
是因為,表別名是宣告在from中,from先於where執行,先宣告再使用沒有問題,但是列別名是宣告在select中,where先於select執行,如果先使用列別名,再宣告,這樣執行會報錯!!