1. 程式人生 > 其它 >sql語言概述

sql語言概述

技術標籤:常見的sql語句

文章目錄

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;
image-20200316141717739

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執行,如果先使用列別名,再宣告,這樣執行會報錯!!