一、數據庫基礎知識
1.1 Whats's 數據庫
-
數據庫(Database,DB):將大量數據保存起來,通過計算機加工而成的可以進行高效訪問的數據集合。如:大型-銀行存儲的信息,小型-電話簿。
-
數據庫管理系統(Batabase Management System,DBMS):用來管理數據庫的計算機系統。
-
關系型數據庫(Relational Database,RDB):目前應用最廣泛的數據庫。
-
結構化查詢語言(Structured Query Language,SQL):專門用於操作 RDB。
-
常見的 5 種關系型數據庫管理系統(Relational Database Management System,RDBMS):
①Oracle Database:甲骨文公司
②SQL Server:微軟公司
③DB2:IBM 公司
④PostgreSQL:開源
⑤MySQL:開源
1.2 數據庫結構
- 服務器:用於接收並處理其它程序發出的請求的程序(軟件),或者是安裝此類程序的設備(計算機)。
- 客戶端:向服務器發出請求的程序(軟件),或者是安裝此類程序的設備(計算機)。
-
表(table):類似 Excel,由行和列組成的二維表。
-
字段:表的列(垂直方向)。
-
記錄:表的行(水平方向)。【注意】關系數據庫必須以行為單位進行數據讀寫。
-
單元格:行列交匯處。【注意】與 Excel 不同,一個單元格只能輸入一個數據。
二、SQL基礎知識
SQL(Structured Query Language)是結構化查詢語言的簡稱,它是一種數據庫查詢和程序涉及語言,同時也是目前使用最廣泛的關系型數據庫操作語言。
-
SQL 語句:用關鍵字、表名和列名等組合而成的一條語句。
-
3 種 SQL 語句種類:
(1)DDL(Data Definition Language,數據定義語言):創建、刪除或修改數據庫以及數據庫中的表等對象。
①CREATE:創建數據庫和表等對象
②DROP:刪除數據庫和表等對象
③ALTER:修改數據庫和表等對象
(2)DML(Data Manipulation Language,數據操作語言):查詢或修改表中的記錄。
①SELECT:查詢表中的數據
②INSERT:向表中插入數據
③UPDATE:修改表中的數據
④DELETE:刪除表中的數據
(3)DCL(Data Control Language,數據控制語言):確認或取消對數據庫中的數據變更的執行操作,以及對用戶的操作數據庫中的對象權限進行設定。
①COMMIT:確認對數據庫中的數據進行的變更
②ROLLBACK:取消對數據庫中的數據進行的變更
③GRANT:賦予用戶的操作權限
④REVOKE:取消用戶的操作權限
三、創建數據庫與表
1. 創建數據庫
語法:CREATE DATABASE <數據庫名稱>
-- 創建數據庫 CREATE DATABASE student; -- 查看建庫語句 show create database student; -- 刪除數據庫 drop database student;
2. 創建數據表
語法:
CREATE TABLE <表名>
(
<列名1> <數據類型> <約束>,
<列名1> <數據類型> <約束>,
...
<表約束1>,
<表約束2>,
...
)# 建立一張用來存儲學生信息的表 # 字段包含學號、姓名、性別、年齡、入學日期、班級等信息 create table student( num int , name varchar(5), sex char(1), age int, entersate date, class varchar(10), )
3.命名規則
①只能使用半角英文字母、數字、下划線(_)作為數據庫、表和列的名稱;
②規范要求命名以半角英文字符開頭;
③名稱不能重復。
4.數據類型的指定:聲明該列的數據類型,是一種約束。
5.數據類型介紹
①INTEGER:整型,意味不能存儲小數;
②CHAR:字符串型,如 CHAR(10)和 CHAR(100)中的括號表名該列可以存儲的字符串的最大長度。它是“定長字符串”,如 CHAR(8) 表示在列中插入 'abc' 時會自動保存成 'abc '(后面5個半角空格)的形式;
③VARCHAR:字符串型,類似 CHAR,不同的是它是 “可變長字符串”,如 VARCHAR(8) 在插入 'abc',保存的就是字符串 'abc';
④DATE:日期類型;
... ...
6.約束
①非空約束:NULL 是空白(無記錄)的意思的關鍵字,NOT NULL 表示必須輸入的約束。
②主鍵約束:主鍵是可以確定一行數據的列,一般通過它取特定行的數據,它是唯一的,不允許重復。
7.新增表記錄
INSERT INTO `student`(`num`,`name`,`sex`,`age`,`enterdate`,`class`) VALUES (1,'Emily','女',20,'2022-9-7','Python班級1');
8.修改和刪除記錄
# 更新表記錄
update student set enterdate='2021-9-7' where num=1;
# 刪除記錄
delete from student where num=1;
# 刪除全部記錄
delete from student;
9.更新和刪除表
刪除表(被刪除的表無法恢復)
語法:DROP TABLE <表名>
DROP TABLE student;
更新表
添加列
語法:ALTER TABLE <表名> ADD <列名> <類型>;
ALTER TABLE student ADD E-mail VARCHAR(100); -- 在 student 中添加名為 E-mail 類型為 VARCHAR(100) 的列
刪除列
語法:ALTER TABLE <表名> DROP COLUMN <列名>;
ALTER TABLE student DROP COLUMN E-mail; -- 刪除 student 表中名為 E-mail 的列
修改字段名
語法:ALTER TABLE <表名>change <老字段><新字段>數據類型(修改后的長度)
四、查詢數據庫表
1.查詢指定列:select 關鍵字
語法:
select <列名>, ..... -- 希望查詢的列的名稱from <表名> -- 指定選取數據的表
-- 從 student中取 3 列 SELECT num, name, sex -- 列的順序可以任意指定,逗號(“,”)分隔,查詢結果的順序和 SELECT 子句中的順序相同 FROM student;
2.查詢表的所有列:星號(*)
語法:
select * -- 星號(*)代表所有列
from <表名>
3.為列設定別名:AS 關鍵字
SELECT num AS "學號", name AS "姓名"FROM student; -- 不用 AS 關鍵字也可以
4.從結果中刪除重復行:DISTINCT
(1)SELECT DISTINCT class FROM student;
(2)DISTINCT 對 NULL 類型的處理:存在多條 NULL 值的行時,會結合為一條 NULL 數據。
5.篩選記錄:WHERE
WHERE 子句中可以指定“某一列的值和這個字符串相等”或者“某一列的值大於這個數字”等條件,找出只符合該條件的記錄。
語法:
select <列名>,
from <表名>
where <條件表達式>
-- where子句 + 關系運算符 select * from emp where deptno = 10; -- where子句 + 邏輯運算符:and select * from emp where sal >1500 and sal < 3000; -- where子句 + 邏輯運算符:or select * from emp where deptno = 10 or deptno = 20; -- 模糊查詢-- 查詢名字中帶A的員工 select * from emp where ename like '%A%'; -- 任意一個字符 select * from emp where ename like '_A%'; -- 關於null的判斷 select * from emp where comm is null; select * from emp where comm is not null;
五、數據更新
1.插入數據
INSERT 語句的基本語法
--語法:--INSERT INTO <表名>(列1, 列2, ...) VALUES (值1, 值2, ...)
2.刪除數據
2 種 刪除數據的方法:
(1)DROP TABLE 語句:刪除表
(2)DELETE 語句:刪除表的數據
--語法--DELETE FROM <表名>;
指定刪除對象的 DELETE 語句
--語法--DELETE FROM <表名>--WHERE <條件>;
3.更新數據
UPDATE 子句的基本語法
--語法--UPDATE <表名>-- SET <列名> = <表達式>
指定條件的 UPDATE 語句
--語法--UPDATE <表名>-- SET <列名> = <表達式>--WHERE <條件>;
使用 NULL 進行更新
--示例UPDATE dbo.Shohin SET torokubi = NULLWHERE shohin_id = '008';
多列更新
--示例UPDATE dbo.Shohin SET hanbai_tanka = hanbai_tanka * 10, --逗號分割 shiire_tanka = shiire_tanka / 2WHERE shohin_bunrui = '廚房用具'
六、多表查詢
1、笛卡爾積
概念:表示兩個表中的每一行任意組合的結果
例如:
有兩個表,左表有m條數據記錄,x個字段,右表有n條數據記錄,y個字段,則執行交叉連接后將返回m*n條數據記錄,x+y個字段
2、多表查詢
- 先確定數據要用到哪些表。
- 將多個表先通過笛卡爾積變成一個表。
- 然后去除不符合邏輯的數據(根據兩個表的關系去掉)。
- 最后當做是一個虛擬表一樣來加上條件即可。
3、自然連接(natural join)
自然連接是一種特殊的等值連接,他要求兩個關系表中進行比較的必須是相同的屬性列,無須添加連接條件,並且在結果中消除重復的屬性
SQL語句
Select …… from 表1 natural join 表2;
4、內連接(innner join)
內連接基本與自然連接相同,不同之處在於自然連接要求是同名屬性列的比較,而內連接則不要求兩屬性列名相同,可以使用using或on來指定某兩列字段相同的連接條件
SQL語句
Select …… from 表1 inner join 表 2 on 表1.A=表2.E;Select …… from 表1 inner join 表 2 using(A); --using缺點:關聯的字段,必須是同名的
5、外連接
外連接有三種方式:左連接、右連接、全連接
外連接除了顯示匹配的數據之外,還可以顯示不匹配的數據
自然連接時某一些屬性不同則會導致這些元組會被舍棄,那么如何去保存這些被丟失的數據呢?外連接就解決了相應的問題。
5.1 左連接(left outer join)
左連接是在兩表進行自然連接,只把左邊那個表要舍棄的保留在結果集中,右表對應的列上顯示NULL
SQL語句
Select …… from 表1 left outer join 表2 on 表1.C=表2.C;Select …… from 表1 left join 表2 on 表1.C=表2.C; --outer可以省略不寫
5.2 右連接(right outer join)
右連接是在兩表進行自然連接,只把右邊那個表要舍棄的保留在結果集中,左表對應的列上顯示NULL
SQL語句
Select …… from 表1 right outer join 表2 on 表1.C=表2.C;Select …… from 表1 right join 表2 on 表1.C=表2.C; --outer可以省略不寫
5.3、全連接(full join)
全連接是在兩表進行自然連接,把左表和右表要舍棄的都保留在結果集中,相對應的列上顯示NULL
SQL語句
Select …… from 表1 full outer join 表2 on 表1.C=表2.C;Select …… from 表1 full join 表2 on 表1.C=表2.C; --outer可以省略不寫
注意:這個語法在mysql中不支持,在oracle中支持
要解決上述問題可以使用左連接與右連接的並集
Select …… from 表1 left join 表2 on 表1.C=表2.Cunion -- 並集Select …… from 表1 right join 表2 on 表1.C=表2.C;
注意:mysql中對集合的操作支持比較弱,只支持並集操作,交集、差集不支持(oracle中支持)
6、練習
- 准備表和數據
CREATE TABLE dept (deptno int NOT NULL,dname varchar(14),loc varchar(13),PRIMARY KEY (deptno))ENGINE = InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;CREATE TABLE emp (empno int NOT NULL,ename varchar(10),job varchar(9),mgr int,hiredate date,sal double(7,2),comm double(7,2),deptno int,PRIMARY KEY (empno),CONSTRAINT fk_deptno FOREIGN KEY (deptno) REFERENCES dept (deptno))ENGINE = InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;CREATE TABLE salgrade (grade int NOT NULL, losal double(7,2), hisal double(7,2),PRIMARY KEY (grade))ENGINE = InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; INSERT INTO DEPT VALUES ('10', '教研部', '北京');INSERT INTO DEPT VALUES ('20', '學工部', '上海');INSERT INTO DEPT VALUES ('30', '銷售部', '深圳');INSERT INTO DEPT VALUES ('40', '財務部', '廣州');INSERT INTO DEPT VALUES ('50', '董事會', '成都');INSERT INTO EMP VALUES (1001,'SMITH','文員',1013,'2021-12-17',800,NULL,20); INSERT INTO EMP VALUES (1002,'ALLEN','銷售員',1006,'2021-02-20',1600,300,30);INSERT INTO EMP VALUES (1003,'WARD','銷售員',1006,'2021-02-22',1250,500,30); INSERT INTO EMP VALUES (1004,'JONES','經理',1009,'2021-04-02',2975,NULL,20); INSERT INTO EMP VALUES (1005,'MARTIN','銷售員',1006,'2021-09-28',1250,1400,30); INSERT INTO EMP VALUES (1006,'BLAKE','經理',1009,'2021-05-01',2850,NULL,30); INSERT INTO EMP VALUES (1007,'CLARK','經理',1009,'2021-06-09',2450,NULL,10); INSERT INTO EMP VALUES (1008,'SCOTT','分析師',1004,'2021-07-13',3000,NULL,20); INSERT INTO EMP VALUES (1009,'KING','董事長',NULL,'2021-11-07',5000,NULL,10); INSERT INTO EMP VALUES (1010,'TURNER','銷售員',1006,'2021-09-08',1500,0,30); INSERT INTO EMP VALUES (1011,'ADAMS','文員',1008,'2021-07-13',1100,NULL,20); INSERT INTO EMP VALUES (1012,'JAMES','文員',1008,'2021-12-03',950,NULL,30); INSERT INTO EMP VALUES (1013,'FORD','分析師',1004,'2021-12-03',3000,NULL,20); INSERT INTO EMP VALUES (1014,'MILLER','文員',1008,'2021-01-23',1300,NULL,10);INSERT INTO EMP VALUES (1015,'Emily','保潔員',1001,'2021-01-23',1300,NULL,10);INSERT INTO SALGRADE VALUES (1,700,1200); INSERT INTO SALGRADE VALUES (2,1201,1400); INSERT INTO SALGRADE VALUES (3,1401,2000); INSERT INTO SALGRADE VALUES (4,2001,3000); INSERT INTO SALGRADE VALUES (5,3001,9999);
- 查出至少有一個員工的部門。顯示部門編號、部門名稱、部門位置、部門人數
SELECT d.deptno,d.dname,d.loc,e1.`count(*)`FROM dept d INNER JOIN (SELECT deptno,COUNT(*) FROM emp GROUP BY deptno) e1ON d.deptno=e1.deptno;
- 列出所有員工的姓名以及直接上級
SELECT e1.ename,e2.ename 上級 FROM emp e1 LEFT JOIN emp e2 ON e1.mgr=e2.empno;
- 列出工資比 ALLEN 高的所有員工
SELECT * FROM emp WHERE sal >(SELECT sal FROM emp WHERE ename = 'ALLEN');
- 列出受雇日期早於直接上級的所有員工的編號、姓名、部門名稱
SELECT e1.empno, e1.ename, d.dname from emp e1 left join emp e2 on e1.mgr = e2.empnoleft join dept d on e1.empno = d.empno where e1.hiredate < e2.hiredata;SELECT e1.empno, e1.ename, d.dname FROM emp e1, emp e2, dept d WHERE e1.mgr=e2.empno AND e1.hiredate<e2.hiredate AND e1.deptno=d.deptno;
- 列出部門名稱和這些部門的員工信息,同時列出那些沒有員工的部門
SELECT * from emp e RIGHT JOIN dept d on e.deptno = d.deptno;