DDL:運算元據庫

Lynne0224發表於2024-08-30

DDL:運算元據庫、表

  1. 運算元據庫:CRUD

    1. C(Create):建立
      • 建立資料庫:
        • create database 資料庫名稱;
      • 建立資料庫,判斷不存在,再建立:
        • create database if not exists 資料庫名稱;
      • 建立資料庫,並指定字符集
        • create database 資料庫名稱 character set 字符集名;
      • 練習: 建立db4資料庫,判斷是否存在,並制定字符集為gbk
        • create database if not exists db4 character set gbk;
    2. R(Retrieve):查詢
      • 查詢所有資料庫的名稱:
        • show databases;
      • 查詢某個資料庫的字符集:查詢某個資料庫的建立語句
        • show create database 資料庫名稱;
    3. U(Update):修改
      • 修改資料庫的字符集
        • alter database 資料庫名稱 character set 字符集名稱;
    4. D(Delete):刪除
      • 刪除資料庫
        • drop database 資料庫名稱;
      • 判斷資料庫存在,存在再刪除
        • drop database if exists 資料庫名稱;
    5. 使用資料庫
      • 查詢當前正在使用的資料庫名稱
        • select database();
      • 使用資料庫
        • use 資料庫名稱;
  2. 操作表

    1. C(Create):建立

      1. 語法:
        create table 表名(
        列名1 資料型別1,
        列名2 資料型別2,
        ....
        列名n 資料型別n
        );
        • 注意:最後一列,不需要加逗號(,)
        • 資料庫型別:
          1. int:整數型別
            • age int,
          2. double:小數型別
            • score double(5,2)
          3. date:日期,只包含年月日,yyyy-MM-dd
          4. datetime:日期,包含年月日時分秒 yyyy-MM-dd HH:mm:ss
          5. timestamp:時間錯型別 包含年月日時分秒 yyyy-MM-dd HH:mm:ss
            • 如果將來不給這個欄位賦值,或賦值為null,則預設使用當前的系統時間,來自動賦值
          6. varchar:字串
            • name varchar(20):姓名最大20個字元
            • zhangsan 8個字元 張三 2個字元
      • 建立表
        create table student(
        id int,
        name varchar(32),
        age int ,
        score double(4,1),
        birthday date,
        insert_time timestamp
        );
      • 複製表:
        • create table 表名 like 被複制的表名;
    2. R(Retrieve):查詢

      • 查詢某個資料庫中所有的表名稱
        • show tables;
      • 查詢表結構
        • desc 表名;
    3. U(Update):修改

      1. 修改表名
        alter table 表名 rename to 新的表名;
      2. 修改表的字符集
        alter table 表名 character set 字符集名稱;
      3. 新增一列
        alter table 表名 add 列名 資料型別;
      4. 修改列名稱 型別
        alter table 表名 change 列名 新列別 新資料型別;
        alter table 表名 modify 列名 新資料型別;
      5. 刪除列
        alter table 表名 drop 列名;
    4. D(Delete):刪除

      • drop table 表名;
      • drop table if exists 表名 ;

客戶端圖形化工具:SQLYog

DML:增刪改表中資料

  1. 新增資料:
    • 語法:
      • insert into 表名(列名1,列名2,...列名n) values(值1,值2,...值n);
    • 注意:
      1. 列名和值要一一對應。
      2. 如果表名後,不定義列名,則預設給所有列新增值
        insert into 表名 values(值1,值2,...值n);
      3. 除了數字型別,其他型別需要使用引號(單雙都可以)引起來
  2. 刪除資料:
    • 語法:
      • delete from 表名 [where 條件]
    • 注意:
      1. 如果不加條件,則刪除表中所有記錄。
      2. 如果要刪除所有記錄
        1. delete from 表名; -- 不推薦使用。有多少條記錄就會執行多少次刪除操作
        2. TRUNCATE TABLE 表名; -- 推薦使用,效率更高 先刪除表,然後再建立一張一樣的表。
  3. 修改資料:
    • 語法:
      • update 表名 set 列名1 = 值1, 列名2 = 值2,... [where 條件];
    • 注意:
      1. 如果不加任何條件,則會將表中所有記錄全部修改。

DQL:查詢表中的記錄

  • select * from 表名;
  1. 語法:
    select
    欄位列表
    from
    表名列表
    where
    條件列表
    group by
    分組欄位
    having
    分組之後的條件
    order by
    排序
    limit
    分頁限定

  2. 基礎查詢

    1. 多個欄位的查詢
      select 欄位名1,欄位名2... from 表名;
      • 注意:
        • 如果查詢所有欄位,則可以使用*來替代欄位列表。
    2. 去除重複:
      • distinct
    3. 計算列
      • 一般可以使用四則運算計算一些列的值。(一般只會進行數值型的計算)
      • ifnull(表示式1,表示式2):null參與的運算,計算結果都為null
        • 表示式1:哪個欄位需要判斷是否為null
        • 如果該欄位為null後的替換值。
    4. 起別名:
      • as:as也可以省略
  3. 條件查詢

    1. where子句後跟條件

    2. 運算子

      • 、< 、<= 、>= 、= 、<>

      • BETWEEN...AND

      • IN( 集合)

      • LIKE:模糊查詢

      • 佔位符:

        • _:單個任意字元
        • %:多個任意字元
      • IS NULL

      • and 或 &&

      • or 或 ||

      • not 或 !

-- 查詢年齡大於20歲

SELECT * FROM student WHERE age > 20;

SELECT * FROM student WHERE age >= 20;

-- 查詢年齡等於20歲
SELECT * FROM student WHERE age = 20;

-- 查詢年齡不等於20歲
SELECT * FROM student WHERE age != 20;
SELECT * FROM student WHERE age <> 20;

-- 查詢年齡大於等於20 小於等於30

SELECT * FROM student WHERE age >= 20 && age <=30;
SELECT * FROM student WHERE age >= 20 AND age <=30;
SELECT * FROM student WHERE age BETWEEN 20 AND 30;

-- 查詢年齡22歲,18歲,25歲的資訊
SELECT * FROM student WHERE age = 22 OR age = 18 OR age = 25
SELECT * FROM student WHERE age IN (22,18,25);

-- 查詢英語成績為null
SELECT * FROM student WHERE english = NULL; -- 不對的。null值不能使用 = (!=) 判斷

SELECT * FROM student WHERE english IS NULL;

-- 查詢英語成績不為null
SELECT * FROM student WHERE english IS NOT NULL;

-- 查詢姓馬的有哪些? like
SELECT * FROM student WHERE NAME LIKE '馬%';
-- 查詢姓名第二個字是化的人
SELECT * FROM student WHERE NAME LIKE "_化%";

-- 查詢姓名是3個字的人
SELECT * FROM student WHERE NAME LIKE '___';

-- 查詢姓名中包含德的人
SELECT * FROM student WHERE NAME LIKE '%德%';

DQL:查詢語句

  1. 排序查詢

    • 語法:order by 子句
      • order by 排序欄位1 排序方式1 , 排序欄位2 排序方式2...
    • 排序方式:
      • ASC:升序,預設的。
      • DESC:降序。
    • 注意:
      • 如果有多個排序條件,則當前邊的條件值一樣時,才會判斷第二條件。
  2. 聚合函式:將一列資料作為一個整體,進行縱向的計算。

    1. count:計算個數
      1. 一般選擇非空的列:主鍵
      2. count(*)
    2. max:計算最大值
    3. min:計算最小值
    4. sum:計算和
    5. avg:計算平均值
    • 注意:聚合函式的計算,排除null值。
      解決方案:
      1. 選擇不包含非空的列進行計算
      2. IFNULL函式
  3. 分組查詢:

    1. 語法:group by 分組欄位;

    2. 注意:

      1. 分組之後查詢的欄位:分組欄位、聚合函式
      2. where 和 having 的區別?
        1. where 在分組之前進行限定,如果不滿足條件,則不參與分組。having在分組之後進行限定,如果不滿足結果,則不會被查詢出來
        2. where 後不可以跟聚合函式,having可以進行聚合函式的判斷。

      -- 按照性別分組。分別查詢男、女同學的平均分

      SELECT sex , AVG(math) FROM student GROUP BY sex;

      -- 按照性別分組。分別查詢男、女同學的平均分,人數

      SELECT sex , AVG(math),COUNT(id) FROM student GROUP BY sex;

      -- 按照性別分組。分別查詢男、女同學的平均分,人數 要求:分數低於70分的人,不參與分組
      SELECT sex , AVG(math),COUNT(id) FROM student WHERE math > 70 GROUP BY sex;

      -- 按照性別分組。分別查詢男、女同學的平均分,人數 要求:分數低於70分的人,不參與分組,分組之後。人數要大於2個人
      SELECT sex , AVG(math),COUNT(id) FROM student WHERE math > 70 GROUP BY sex HAVING COUNT(id) > 2;

      SELECT sex , AVG(math),COUNT(id) 人數 FROM student WHERE math > 70 GROUP BY sex HAVING 人數 > 2;

  1. 分頁查詢

    1. 語法:limit 開始的索引,每頁查詢的條數;

    2. 公式:開始的索引 = (當前的頁碼 - 1) * 每頁顯示的條數
      -- 每頁顯示3條記錄

      SELECT * FROM student LIMIT 0,3; -- 第1頁

      SELECT * FROM student LIMIT 3,3; -- 第2頁

    SELECT * FROM student LIMIT 6,3; -- 第3頁

  2. limit 是一個MySQL"方言"

約束

  • 概念: 對錶中的資料進行限定,保證資料的正確性、有效性和完整性。

  • 分類:

    1. 主鍵約束:primary key
    2. 非空約束:not null
    3. 唯一約束:unique
    4. 外來鍵約束:foreign key
  • 非空約束:not null,值不能為null

    1. 建立表時新增約束
      CREATE TABLE stu(
      id INT,
      NAME VARCHAR(20) NOT NULL -- name為非空
      );
    2. 建立表完後,新增非空約束
      ALTER TABLE stu MODIFY NAME VARCHAR(20) NOT NULL;
    3. 刪除name的非空約束
      ALTER TABLE stu MODIFY NAME VARCHAR(20);
  • 唯一約束:unique,值不能重複

    1. 建立表時,新增唯一約束
      CREATE TABLE stu(
      id INT,
      phone_number VARCHAR(20) UNIQUE -- 新增了唯一約束

      );

      • 注意mysql中,唯一約束限定的列的值可以有多個null
    2. 刪除唯一約束

      ALTER TABLE stu DROP INDEX phone_number;

    3. 在建立表後,新增唯一約束
      ALTER TABLE stu MODIFY phone_number VARCHAR(20) UNIQUE;

  • 主鍵約束:primary key。

    1. 注意:

      1. 含義:非空且唯一
      2. 一張表只能有一個欄位為主鍵
      3. 主鍵就是表中記錄的唯一標識
    2. 在建立表時,新增主鍵約束
      create table stu(
      id int primary key,-- 給id新增主鍵約束
      name varchar(20)
      );

    3. 刪除主鍵
      -- 錯誤 alter table stu modify id int ;
      ALTER TABLE stu DROP PRIMARY KEY;

    4. 建立完表後,新增主鍵
      ALTER TABLE stu MODIFY id INT PRIMARY KEY;

    5. 自動增長:

      1. 概念:如果某一列是數值型別的,使用 auto_increment 可以來完成值得自動增長

      2. 在建立表時,新增主鍵約束,並且完成主鍵自增長
        create table stu(
        id int primary key auto_increment,-- 給id新增主鍵約束
        name varchar(20)
        );

      3. 刪除自動增長
        ALTER TABLE stu MODIFY id INT;

      4. 新增自動增長
        ALTER TABLE stu MODIFY id INT AUTO_INCREMENT;

  • 外來鍵約束:foreign key,讓表於表產生關係,從而保證資料的正確性。

    1. 在建立表時,可以新增外來鍵

      • 語法:
        create table 表名(
        ....
        外來鍵列
        constraint 外來鍵名稱 foreign key (外來鍵列名稱) references 主表名稱(主表列名稱)
        );
    2. 刪除外來鍵
      ALTER TABLE 表名 DROP FOREIGN KEY 外來鍵名稱;

    3. 建立表之後,新增外來鍵
      ALTER TABLE 表名 ADD CONSTRAINT 外來鍵名稱 FOREIGN KEY (外來鍵欄位名稱) REFERENCES 主表名稱(主表列名稱);

    4. 級聯操作

      1. 新增級聯操作
        語法:ALTER TABLE 表名 ADD CONSTRAINT 外來鍵名稱
        FOREIGN KEY (外來鍵欄位名稱) REFERENCES 主表名稱(主表列名稱) ON UPDATE CASCADE ON DELETE CASCADE ;
      2. 分類:
        1. 級聯更新:ON UPDATE CASCADE
        2. 級聯刪除:ON DELETE CASCADE

資料庫的設計

  1. 多表之間的關係

    1. 分類:

      1. 一對一(瞭解):
        • 如:人和身份證
        • 分析:一個人只有一個身份證,一個身份證只能對應一個人
      2. 一對多(多對一):
        • 如:部門和員工
        • 分析:一個部門有多個員工,一個員工只能對應一個部門
      3. 多對多:
        • 如:學生和課程
        • 分析:一個學生可以選擇很多門課程,一個課程也可以被很多學生選擇
    2. 實現關係:

      1. 一對多(多對一):
        • 如:部門和員工
        • 實現方式:在多的一方建立外來鍵,指向一的一方的主鍵。
      2. 多對多:
        • 如:學生和課程
        • 實現方式:多對多關係實現需要藉助第三張中間表。中間表至少包含兩個欄位,這兩個欄位作為第三張表的外來鍵,分別指向兩張表的主鍵
      3. 一對一(瞭解):
        • 如:人和身份證
        • 實現方式:一對一關係實現,可以在任意一方新增唯一外來鍵指向另一方的主鍵。
    3. 案例
      -- 建立旅遊線路分類表 tab_category
      -- cid 旅遊線路分類主鍵,自動增長
      -- cname 旅遊線路分類名稱非空,唯一,字串 100
      CREATE TABLE tab_category (
      cid INT PRIMARY KEY AUTO_INCREMENT,
      cname VARCHAR(100) NOT NULL UNIQUE
      );

      -- 建立旅遊線路表 tab_route
      /*
      rid 旅遊線路主鍵,自動增長
      rname 旅遊線路名稱非空,唯一,字串 100
      price 價格
      rdate 上架時間,日期型別
      cid 外來鍵,所屬分類
      */
      CREATE TABLE tab_route(
      rid INT PRIMARY KEY AUTO_INCREMENT,
      rname VARCHAR(100) NOT NULL UNIQUE,
      price DOUBLE,
      rdate DATE,
      cid INT,
      FOREIGN KEY (cid) REFERENCES tab_category(cid)
      );

      /*建立使用者表 tab_user
      uid 使用者主鍵,自增長
      username 使用者名稱長度 100,唯一,非空
      password 密碼長度 30,非空
      name 真實姓名長度 100
      birthday 生日
      sex 性別,定長字串 1
      telephone 手機號,字串 11
      email 郵箱,字串長度 100
      */
      CREATE TABLE tab_user (
      uid INT PRIMARY KEY AUTO_INCREMENT,
      username VARCHAR(100) UNIQUE NOT NULL,
      PASSWORD VARCHAR(30) NOT NULL,
      NAME VARCHAR(100),
      birthday DATE,
      sex CHAR(1) DEFAULT '男',
      telephone VARCHAR(11),
      email VARCHAR(100)
      );

      /*
      建立收藏表 tab_favorite
      rid 旅遊線路 id,外來鍵
      date 收藏時間
      uid 使用者 id,外來鍵
      rid 和 uid 不能重複,設定複合主鍵,同一個使用者不能收藏同一個線路兩次
      */
      CREATE TABLE tab_favorite (
      rid INT, -- 線路id
      DATE DATETIME,
      uid INT, -- 使用者id
      -- 建立複合主鍵
      PRIMARY KEY(rid,uid), -- 聯合主鍵
      FOREIGN KEY (rid) REFERENCES tab_route(rid),
      FOREIGN KEY(uid) REFERENCES tab_user(uid)
      );

  2. 資料庫設計的正規化

    • 概念:設計資料庫時,需要遵循的一些規範。要遵循後邊的正規化要求,必須先遵循前邊的所有正規化要求

      設計關聯式資料庫時,遵從不同的規範要求,設計出合理的關係型資料庫,這些不同的規範要求被稱為不同的正規化,各種正規化呈遞次規範,越高的正規化資料庫冗餘越小。
      目前關聯式資料庫有六種正規化:第一正規化(1NF)、第二正規化(2NF)、第三正規化(3NF)、巴斯-科德正規化(BCNF)、第四正規化(4NF)和第五正規化(5NF,又稱完美正規化)。

    • 分類:

      1. 第一正規化(1NF):每一列都是不可分割的原子資料項
      2. 第二正規化(2NF):在1NF的基礎上,非碼屬性必須完全依賴於碼(在1NF基礎上消除非主屬性對主碼的部分函式依賴)
        • 幾個概念:
          1. 函式依賴:A-->B,如果透過A屬性(屬性組)的值,可以確定唯一B屬性的值。則稱B依賴於A
            例如:學號-->姓名。 (學號,課程名稱) --> 分數
          2. 完全函式依賴:A-->B, 如果A是一個屬性組,則B屬性值得確定需要依賴於A屬性組中所有的屬性值。
            例如:(學號,課程名稱) --> 分數
          3. 部分函式依賴:A-->B, 如果A是一個屬性組,則B屬性值得確定只需要依賴於A屬性組中某一些值即可。
            例如:(學號,課程名稱) -- > 姓名
          4. 傳遞函式依賴:A-->B, B -- >C . 如果透過A屬性(屬性組)的值,可以確定唯一B屬性的值,在透過B屬性(屬性組)的值可以確定唯一C屬性的值,則稱 C 傳遞函式依賴於A
            例如:學號-->系名,系名-->系主任
          5. 碼:如果在一張表中,一個屬性或屬性組,被其他所有屬性所完全依賴,則稱這個屬性(屬性組)為該表的碼
            例如:該表中碼為:(學號,課程名稱)
            • 主屬性:碼屬性組中的所有屬性
            • 非主屬性:除過碼屬性組的屬性
      3. 第三正規化(3NF):在2NF基礎上,任何非主屬性不依賴於其它非主屬性(在2NF基礎上消除傳遞依賴)

資料庫的備份和還原

命令列:
* 語法:
* 備份: mysqldump -u使用者名稱 -p密碼 資料庫名稱 > 儲存的路徑
* 還原:
1. 登入資料庫
2. 建立資料庫
3. 使用資料庫
4. 執行檔案。source 檔案路徑

圖形化介面:

  • 備份:選中要備份的資料庫,右鍵->備份/匯出
  • 還原:右鍵->執行SQL指令碼...

  • 建立部門表

    CREATE TABLE dept(
    id INT PRIMARY KEY AUTO_INCREMENT,
    NAME VARCHAR(20)
    );
    INSERT INTO dept (NAME) VALUES ('開發部'),('市場部'),('財務部');

    建立員工表

    CREATE TABLE emp (
    id INT PRIMARY KEY AUTO_INCREMENT,
    NAME VARCHAR(10),
    gender CHAR(1), -- 性別
    salary DOUBLE, -- 工資
    join_date DATE, -- 入職日期
    dept_id INT,
    FOREIGN KEY (dept_id) REFERENCES dept(id) -- 外來鍵,關聯部門表(部門表的主鍵)
    );
    INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('孫悟空','男',7200,'2013-02-24',1);
    INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('豬八戒','男',3600,'2010-12-02',2);
    INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('唐僧','男',9000,'2008-08-08',2);
    INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('白骨精','女',5000,'2015-10-07',3);
    INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('蜘蛛精','女',4500,'2011-03-14',1);

  • 笛卡爾積:

    • 有兩個集合A,B .取這兩個集合的所有組成情況。
    • 要完成多表查詢,需要消除無用的資料
  • 多表查詢的分類:

    1. 內連線查詢:

      1. 隱式內連線:使用where條件消除無用資料

        • 例子:
          -- 查詢所有員工資訊和對應的部門資訊

        SELECT * FROM emp,dept WHERE emp.dept_id = dept.id;

        -- 查詢員工表的名稱,性別。部門表的名稱
        SELECT emp.name,emp.gender,dept.name FROM emp,dept WHERE emp.dept_id = dept.id;

        SELECT
        t1.name, -- 員工表的姓名
        t1.gender,-- 員工表的性別
        t2.name -- 部門表的名稱
        FROM
        emp t1,
        dept t2
        WHERE
        t1.dept_id = t2.id;

	2. 顯式內連線:
		* 語法: select 欄位列表 from 表名1 [inner] join 表名2 on 條件
		* 例如:
			* SELECT * FROM emp INNER JOIN dept ON emp.`dept_id` = dept.`id`;	
			* SELECT * FROM emp JOIN dept ON emp.`dept_id` = dept.`id`;	

	3. 內連線查詢:
		1. 從哪些表中查詢資料
		2. 條件是什麼
		3. 查詢哪些欄位
2. 外連結查詢:
	1. 左外連線:
		* 語法:select 欄位列表 from 表1 left [outer] join 表2 on 條件;
		* 查詢的是左表所有資料以及其交集部分。
		* 例子:
			-- 查詢所有員工資訊,如果員工有部門,則查詢部門名稱,沒有部門,則不顯示部門名稱
			SELECT 	t1.*,t2.`name` FROM emp t1 LEFT JOIN dept t2 ON t1.`dept_id` = t2.`id`;
	2. 右外連線:
		* 語法:select 欄位列表 from 表1 right [outer] join 表2 on 條件;
		* 查詢的是右表所有資料以及其交集部分。
		* 例子:
			SELECT 	* FROM dept t2 RIGHT JOIN emp t1 ON t1.`dept_id` = t2.`id`;
3. 子查詢:
	* 概念:查詢中巢狀查詢,稱巢狀查詢為子查詢。
		-- 查詢工資最高的員工資訊
		-- 1 查詢最高的工資是多少 9000
		SELECT MAX(salary) FROM emp;
		
		-- 2 查詢員工資訊,並且工資等於9000的
		SELECT * FROM emp WHERE emp.`salary` = 9000;
		
		-- 一條sql就完成這個操作。子查詢
		SELECT * FROM emp WHERE emp.`salary` = (SELECT MAX(salary) FROM emp);

	* 子查詢不同情況
		1. 子查詢的結果是單行單列的:
			* 子查詢可以作為條件,使用運算子去判斷。 運算子: > >= < <= =
			* 
			-- 查詢員工工資小於平均工資的人
			SELECT * FROM emp WHERE emp.salary < (SELECT AVG(salary) FROM emp);
		2. 子查詢的結果是多行單列的:
			* 子查詢可以作為條件,使用運算子in來判斷
			-- 查詢'財務部'和'市場部'所有的員工資訊
			SELECT id FROM dept WHERE NAME = '財務部' OR NAME = '市場部';
			SELECT * FROM emp WHERE dept_id = 3 OR dept_id = 2;
			-- 子查詢
			SELECT * FROM emp WHERE dept_id IN (SELECT id FROM dept WHERE NAME = '財務部' OR NAME = '市場部');

		3. 子查詢的結果是多行多列的:
			* 子查詢可以作為一張虛擬表參與查詢
			-- 查詢員工入職日期是2011-11-11日之後的員工資訊和部門資訊
			-- 子查詢
			SELECT * FROM dept t1 ,(SELECT * FROM emp WHERE emp.`join_date` > '2011-11-11') t2
			WHERE t1.id = t2.dept_id;
			
			-- 普通內連線
			SELECT * FROM emp t1,dept t2 WHERE t1.`dept_id` = t2.`id` AND t1.`join_date` >  '2011-11-11'

* 多表查詢練習

		-- 部門表
		CREATE TABLE dept (
		  id INT PRIMARY KEY PRIMARY KEY, -- 部門id
		  dname VARCHAR(50), -- 部門名稱
		  loc VARCHAR(50) -- 部門所在地
		);
		
		-- 新增4個部門
		INSERT INTO dept(id,dname,loc) VALUES 
		(10,'教研部','北京'),
		(20,'學工部','上海'),
		(30,'銷售部','廣州'),
		(40,'財務部','深圳');



​ -- 職務表,職務名稱,職務描述
​ CREATE TABLE job (
​ id INT PRIMARY KEY,
​ jname VARCHAR(20),
​ description VARCHAR(50)
​ );

​ -- 新增4個職務
​ INSERT INTO job (id, jname, description) VALUES
​ (1, '董事長', '管理整個公司,接單'),
​ (2, '經理', '管理部門員工'),
​ (3, '銷售員', '向客人推銷產品'),
​ (4, '文員', '使用辦公軟體');



​ -- 員工表
​ CREATE TABLE emp (
​ id INT PRIMARY KEY, -- 員工id
​ ename VARCHAR(50), -- 員工姓名
​ job_id INT, -- 職務id
​ mgr INT , -- 上級領導
​ joindate DATE, -- 入職日期
​ salary DECIMAL(7,2), -- 工資
​ bonus DECIMAL(7,2), -- 獎金
​ dept_id INT, -- 所在部門編號
​ CONSTRAINT emp_jobid_ref_job_id_fk FOREIGN KEY (job_id) REFERENCES job (id),
​ CONSTRAINT emp_deptid_ref_dept_id_fk FOREIGN KEY (dept_id) REFERENCES dept (id)
​ );

​ -- 新增員工
​ INSERT INTO emp(id,ename,job_id,mgr,joindate,salary,bonus,dept_id) VALUES
​ (1001,'孫悟空',4,1004,'2000-12-17','8000.00',NULL,20),
​ (1002,'盧俊義',3,1006,'2001-02-20','16000.00','3000.00',30),
​ (1003,'林沖',3,1006,'2001-02-22','12500.00','5000.00',30),
​ (1004,'唐僧',2,1009,'2001-04-02','29750.00',NULL,20),
​ (1005,'李逵',4,1006,'2001-09-28','12500.00','14000.00',30),
​ (1006,'宋江',2,1009,'2001-05-01','28500.00',NULL,30),
​ (1007,'劉備',2,1009,'2001-09-01','24500.00',NULL,10),
​ (1008,'豬八戒',4,1004,'2007-04-19','30000.00',NULL,20),
​ (1009,'羅貫中',1,NULL,'2001-11-17','50000.00',NULL,10),
​ (1010,'吳用',3,1006,'2001-09-08','15000.00','0.00',30),
​ (1011,'沙僧',4,1004,'2007-05-23','11000.00',NULL,20),
​ (1012,'李逵',4,1006,'2001-12-03','9500.00',NULL,30),
​ (1013,'小白龍',4,1004,'2001-12-03','30000.00',NULL,20),
​ (1014,'關羽',4,1007,'2002-01-23','13000.00',NULL,10);



​ -- 工資等級表
​ CREATE TABLE salarygrade (
​ grade INT PRIMARY KEY, -- 級別
​ losalary INT, -- 最低工資
​ hisalary INT -- 最高工資
​ );

​ -- 新增5個工資等級
​ INSERT INTO salarygrade(grade,losalary,hisalary) VALUES
​ (1,7000,12000),
​ (2,12010,14000),
​ (3,14010,20000),
​ (4,20010,30000),
​ (5,30010,99990);

​ -- 需求:

​ -- 1.查詢所有員工資訊。查詢員工編號,員工姓名,工資,職務名稱,職務描述
​ /*
​ 分析:
​ 1.員工編號,員工姓名,工資,需要查詢emp表 職務名稱,職務描述 需要查詢job表
​ 2.查詢條件 emp.job_id = job.id

​ */
​ SELECT
​ t1.id, -- 員工編號
​ t1.ename, -- 員工姓名
​ t1.salary,-- 工資
​ t2.jname, -- 職務名稱
​ t2.description -- 職務描述
​ FROM
​ emp t1, job t2
​ WHERE
​ t1.job_id = t2.id;



​ -- 2.查詢員工編號,員工姓名,工資,職務名稱,職務描述,部門名稱,部門位置
​ /*
​ 分析:
​ 1. 員工編號,員工姓名,工資 emp 職務名稱,職務描述 job 部門名稱,部門位置 dept
​ 2. 條件: emp.job_id = job.id and emp.dept_id = dept.id
/

​ SELECT
​ t1.id, -- 員工編號
​ t1.ename, -- 員工姓名
​ t1.salary,-- 工資
​ t2.jname, -- 職務名稱
​ t2.description, -- 職務描述
​ t3.dname, -- 部門名稱
​ t3.loc -- 部門位置
​ FROM
​ emp t1, job t2,dept t3
​ WHERE
​ t1.job_id = t2.id AND t1.dept_id = t3.id;

​ -- 3.查詢員工姓名,工資,工資等級
​ /

​ 分析:
​ 1.員工姓名,工資 emp 工資等級 salarygrade
​ 2.條件 emp.salary >= salarygrade.losalary and emp.salary <= salarygrade.hisalary
​ emp.salary BETWEEN salarygrade.losalary and salarygrade.hisalary
/
​ SELECT
​ t1.ename ,
​ t1.salary,
​ t2.

​ FROM emp t1, salarygrade t2
​ WHERE t1.salary BETWEEN t2.losalary AND t2.hisalary;



​ -- 4.查詢員工姓名,工資,職務名稱,職務描述,部門名稱,部門位置,工資等級
​ /*
​ 分析:
​ 1. 員工姓名,工資 emp , 職務名稱,職務描述 job 部門名稱,部門位置,dept 工資等級 salarygrade
​ 2. 條件: emp.job_id = job.id and emp.dept_id = dept.id and emp.salary BETWEEN salarygrade.losalary and salarygrade.hisalary

​ */
​ SELECT
​ t1.ename,
​ t1.salary,
​ t2.jname,
​ t2.description,
​ t3.dname,
​ t3.loc,
​ t4.grade
​ FROM
​ emp t1,job t2,dept t3,salarygrade t4
​ WHERE
​ t1.job_id = t2.id
​ AND t1.dept_id = t3.id
​ AND t1.salary BETWEEN t4.losalary AND t4.hisalary;



​ -- 5.查詢出部門編號、部門名稱、部門位置、部門人數

​ /*
​ 分析:
​ 1.部門編號、部門名稱、部門位置 dept 表。 部門人數 emp表
​ 2.使用分組查詢。按照emp.dept_id完成分組,查詢count(id)
​ 3.使用子查詢將第2步的查詢結果和dept表進行關聯查詢

​ */
​ SELECT
​ t1.id,t1.dname,t1.loc , t2.total
​ FROM
​ dept t1,
​ (SELECT
​ dept_id,COUNT(id) total
​ FROM
​ emp
​ GROUP BY dept_id) t2
​ WHERE t1.id = t2.dept_id;


​ -- 6.查詢所有員工的姓名及其直接上級的姓名,沒有領導的員工也需要查詢

​ /*
​ 分析:
​ 1.姓名 emp, 直接上級的姓名 emp
​ * emp表的id 和 mgr 是自關聯
​ 2.條件 emp.id = emp.mgr
​ 3.查詢左表的所有資料,和 交集資料
​ * 使用左外連線查詢

/
​ /

​ select
​ t1.ename,
​ t1.mgr,
​ t2.id,
​ t2.ename
​ from emp t1, emp t2
​ where t1.mgr = t2.id;

​ */

​ SELECT
​ t1.ename,
​ t1.mgr,
​ t2.id,
​ t2.ename
​ FROM emp t1
​ LEFT JOIN emp t2
​ ON t1.mgr = t2.id;

DCL:

  • SQL分類:

    1. DDL:運算元據庫和表
    2. DML:增刪改表中資料
    3. DQL:查詢表中資料
    4. DCL:管理使用者,授權
  • DBA:資料庫管理員

  • DCL:管理使用者,授權

    1. 管理使用者

      1. 新增使用者:

        • 語法:CREATE USER '使用者名稱'@'主機名' IDENTIFIED BY '密碼';
      2. 刪除使用者:

        • 語法:DROP USER '使用者名稱'@'主機名';
      3. 修改使用者密碼:

        UPDATE USER SET PASSWORD = PASSWORD('新密碼') WHERE USER = '使用者名稱';
        UPDATE USER SET PASSWORD = PASSWORD('abc') WHERE USER = 'lisi';

    SET PASSWORD FOR '使用者名稱'@'主機名' = PASSWORD('新密碼');
    SET PASSWORD FOR 'root'@'localhost' = PASSWORD('123');

    	* mysql中忘記了root使用者的密碼?
    1. cmd -- > net stop mysql 停止mysql服務
    			* 需要管理員執行該cmd
    
    		2. 使用無驗證方式啟動mysql服務: mysqld --skip-grant-tables
    		3. 開啟新的cmd視窗,直接輸入mysql命令,敲回車。就可以登入成功
    		4. use mysql;
    		5. update user set password = password('你的新密碼') where user = 'root';
    		6. 關閉兩個視窗
    		7. 開啟工作管理員,手動結束mysqld.exe 的程序
    		8. 啟動mysql服務
    		9. 使用新密碼登入。
    4. 查詢使用者:
    	-- 1. 切換到mysql資料庫
    	USE myql;
    	-- 2. 查詢user表
    	SELECT * FROM USER;
    
    	* 萬用字元: % 表示可以在任意主機使用使用者登入資料庫
    
    1. 許可權管理:

      1. 查詢許可權:
        -- 查詢許可權
        SHOW GRANTS FOR '使用者名稱'@'主機名';
        SHOW GRANTS FOR 'lisi'@'%';

      2. 授予許可權:
        -- 授予許可權
        grant 許可權列表 on 資料庫名.表名 to '使用者名稱'@'主機名';
        -- 給張三使用者授予所有許可權,在任意資料庫任意表上

        GRANT ALL ON . TO 'zhangsan'@'localhost';

    2. 撤銷許可權:
      -- 撤銷許可權:
      revoke 許可權列表 on 資料庫名.表名 from '使用者名稱'@'主機名';
      REVOKE UPDATE ON db3.account FROM 'lisi'@'%';

相關文章