MySQL筆記

MySQL筆記


一、前期準(zhǔn)備

  1. SQL語句分類
    • DQL - 數(shù)據(jù)查詢語言 --> 查詢語句,select 語句都是DQL

    • DML - 數(shù)據(jù)操作語言 --> insert、delete、update 等等對表數(shù)據(jù)進(jìn)行增刪改

    • DDL - 數(shù)據(jù)定義語言 --> create、 drop、 alter 等等對表結(jié)構(gòu)的增刪改

    • TCL - 事務(wù)控制語言 --> Transaction Commit - 提交事務(wù) Rollback - 回滾事務(wù)

    • DCL - 數(shù)據(jù)控制語言 --> grant - 授權(quán) revoke - 撤銷權(quán)限

  2. MySQL卸載
    • 去安裝目錄找到my.ini文件

    • 復(fù)制文件中配置的路徑:【 datadir="C:/ProgramData/MySQL/MySQL Server 5.5/Data/" 】

    • 控制面板卸載MySQL

    • 去第二步里復(fù)制的路徑中刪除 C:/ProgramData下的MySQL文件夾

  3. 常見的cmd命令
    • 打開服務(wù)窗口 services.msc

    • 打開/關(guān)閉MySQL服務(wù) net start/shut mysql

    • 登錄MySQL mysql -uroot -p密碼

    • 訪問別人的MySQL mysql -h別人IP -uroot -p別人密碼

    • 退出MySQL exit/quit


二、DDL -- 對數(shù)據(jù)庫、表的操作

  1. 操作數(shù)據(jù)庫
    • C(Create):創(chuàng)建
      • create database 數(shù)據(jù)庫名;

      • create database if not exists 數(shù)據(jù)庫名; -- 判斷不存在再創(chuàng)建

      • create database 數(shù)據(jù)庫名 character set 字符集名; -- 創(chuàng)建庫并指定字符集

      • 練習(xí): create database if not exists db0 character set utf8;

    • R(Retrieve):查詢
      • show databases; -- 查詢所有的數(shù)據(jù)庫名

      • show create database 數(shù)據(jù)庫名; -- 查看創(chuàng)建庫的語句

    • U(Update):修改
      • alterdatabase 數(shù)據(jù)庫名 character set 字符集名;
    • D(Delete):刪除
      • drop database 數(shù)據(jù)庫名;

      • drop database if exists 數(shù)據(jù)庫名; -- 先判斷是否存在

    • 使用數(shù)據(jù)庫
      • 查詢當(dāng)前正使用的數(shù)據(jù)庫

        • selsect database();
      • 使用數(shù)據(jù)庫

        • use 數(shù)據(jù)庫名;
  2. 操作表
    • C(Create):創(chuàng)建
      • 語法:create table 表名(列名1 類型1,

        列名2 類型2,

        列名3 類型3);

      • 數(shù)據(jù)庫數(shù)據(jù)類型

        • int -- 整數(shù)類型

          • age int
        • double -- 小數(shù)類型

          • score double(3, 1); -- 最多三位,一位小數(shù)
        • date -- 日期 只包含年月日 yyyy- MM-dd

        • datetime -- 時間戳類型 包含年月日時分秒 yyyy- MM-dd HH:mm:ss

        • timestamp -- 包含年月日時分秒 yyyy- MM-dd HH:mm:ss

          • 如果不給這個字段賦值或賦值為null,則默認(rèn)值為系統(tǒng)當(dāng)前時間
        • varchar -- 字符串

          • name varchar(20);

          • 張三 8個字符 zhangsan 兩個字符

      • 復(fù)制表 -- create table 表名 like 源表名

      • 練習(xí):

      create table t_student(
      id int,
      name varchar(30),
      age int,
      score double(4,1),
      birthday date,
      insert_time timestamp);
      
    • R(Retrieve):查詢
  • show tables; -- 查詢當(dāng)前數(shù)據(jù)庫的所有表

  • desc 表名; -- 查詢表結(jié)構(gòu)

    • U(Update):修改
      • 修改表名

        • alter table 表名 rename to 新表名
      • 修改表字符集

        • alter table 表名 character set 字符集名;
      • 添加一列

        • alter table 表名 add 列名 類型;
      • 修改列名稱、類型

        • alter table 表名 change 列名 新列名 新類型;

        • alter table 表名 modify 列名 新類型;

    • 刪除列

  • alter table 表名 drop 列名;

    • D(Delete):刪除
      • drop table if exists 表名;

三、DML -- 增刪改表中數(shù)據(jù)

  1. 添加數(shù)據(jù)
    • 語法:
      • insert into 表名(列名1, 列名2, 列名3...) values(數(shù)據(jù)1, 數(shù)據(jù)2, 數(shù)據(jù)3...);
    • 注意??!
        1. 前后括號的 列名和值(類型)要一一對應(yīng)

        2. 如果表名后不定義列名,則默認(rèn)給所有列添加值 (也要對應(yīng)上所有坑,不然報錯)

          • insert into stu values(2, 'Jones', 18, 90.7, null,null);
        3. 除了數(shù)值類型,其他的類型都需要是喲個引號括起來【單雙引號都可】

  2. 刪除數(shù)據(jù)
    • 語法:
      • delete from 表名 [where 條件 ];
    • 注意??!
      • 如果不寫條件則會刪除表中所有記錄

      • 如果要刪除所有記錄,有兩種方式:

        • delete from 表名; -- 有多少條記錄都會一條一條刪除掉

        • truncate table 表名; -- 先刪除整張表【包括其數(shù)據(jù)】,然后創(chuàng)建一張一模一樣的空表,效率高

  3. 修改數(shù)據(jù)
    • 語法:

      • update 表名 set 列名1 = 值1, 列名2 = 值2...[where 條件]
    • 注意??!

      • 如果不加任何條件,則會將表中所有記錄全部修改

四、DQL -- 查詢語句

  1. 查詢表中記錄
    1. 語法:
       select 
            字段列表
       from 
            表名列表
       where 
            條件列表
       group by  
            分組字段
       having   
            分組之后補(bǔ)充的條件
       order by 
            排序
       limit 
           分頁查詢
      
    2. 基礎(chǔ)查詢

      • 多個字段的查詢

        • select name, age from stu;

        • 有null參與的任何運算結(jié)果為null 如下:

          • 解決方案:在可能出現(xiàn)問題的計算的地方添加ifnull(表達(dá)式1, 表達(dá)式2)即可

            • 表達(dá)式1 -- 哪個字段需要判斷是否為null

            • 表達(dá)式2 -- 如果該字段值為null,替換為表達(dá)式2值

          • SELECT s.name, s.math, s.english, (ifnull(s.math, 0) + ifnull(s.english, 0)) totalScore FROM stu s ;

      • 去除重復(fù)

        • select distinct address from stu; -- 地址重復(fù)去除
      • 起別名

        • SELECT s.name AS 姓名,(IFNULL(s.math, 0) + IFNULL(s.english, 0)) AS 總分 FROM stu s ; -- as 看省略

    3. 條件查詢
      1. where子句后跟條件

      2. 運算符

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

          • 查詢年齡大于20歲的

            select * from stu where age > 20;

        • beteen...and

          查詢年齡位于20-30歲的
           SELECT * FROM stu WHERE age <= 30 && age >= 20;
           SELECT * FROM stu WHERE age BETWEEN 20 AND 30;  #推薦寫法
          
        • like

          • 模糊查詢

          • 占位符

            • _ 表示單個任意字符

            • % 表示多個任意字符

          • 舉例:

              # 查詢姓馬的記錄  第一個字是“馬”,其余任意多字無所謂
          SELECT s.name, s.math, s.english FROM stu s WHERE s.name LIKE '馬%';
             # 查詢姓名中第二個字是'化'的人
          SELECT * from stu where name like '_化%';  # 第一個任意
             # 查詢姓名有三個字的人
          SELECT * FROM stu WHERE NAME LIKE '___';  # 三個下劃線
             # 查詢姓名中包含“馬”和“德”的人
          SELECT * FROM stu WHERE NAME LIKE "%德%" OR "%馬%";
          
          • is null
            #查詢英語成績?yōu)閚ull的列 與不為null的列
          SELECT s.name FROM stu s WHERE s.english IS NULL;
          SELECT s.name FROM stu s WHERE s.english IS NOT NULL;
          
          • and 或者 &&

          • or 或者 ||

            # 查詢年齡為19 22 25 的
          SELECT * FROM stu WHERE age = 19 or age = 22 or age = 25;
          SELECT * FROM stu WHERE age in(18, 22, 25);  #推薦寫法
          
          • not 或者 !
    4. 排序查詢
      1. 語法:order by 子句

        • order by 排序字段1 排序方式1, 排序字段2 排序方式2...
      2. 排序方式:

        • asc:升序【默認(rèn)】

        • desc :降序

      3. 注意??!如果有多個排序條件,則當(dāng)前邊的條件值一樣時,才會執(zhí)行第二判斷條件

      4. 練習(xí):

            # 按照數(shù)學(xué)成績排名,如果數(shù)學(xué)一樣,則按照英語成績排名
         SELECT * FROM stu ORDER BY math ASC, english ASC; 
             # 先按照前面的升序,如果前面的一樣則再按照后面的升序
        
    5. 聚合函數(shù) -- 將一列數(shù)據(jù)作為一個整體,進(jìn)行縱向的計算
      1. count -- 計算個數(shù)

        • 一般選擇主鍵
      2. max -- 計算最大值

      3. min -- 計算最小值

      4. sum -- 計算和

      5. avg -- 計算平均數(shù)

           # 看下英語成績平均值
          SELECT AVG(IFNULL(english, 0)) FROM stu;</pre>
      
      1. 注意??!聚合函數(shù)計算,是排除null值的

        • 解決方案一:選擇不包含null的列進(jìn)行計算

        • 解決方案二:使用ifnull函數(shù) SELECT COUNT(IFNULL(english, 0)) FROM stu;

    6. 分組查詢 -- 統(tǒng)計某一類具有相同特征的數(shù)據(jù),把他們看做一個整體
      1. 語法:group by分組字段

             # 按照性別分組,看下男女同學(xué)的平均分
          SELECT sex 性別, AVG(IFNULL(math, 0))  數(shù)學(xué)平均分, AVG(IFNULL(english, 0)) 英語平均分 FROM stu GROUP BY sex;
             # 按照性別分組,看下男女同學(xué)的平均分 分?jǐn)?shù)低于70的同學(xué)不參與分組
          SELECT sex, AVG(IFNULL(math, 0)), AVG(IFNULL(english, 0)), COUNT(id) FROM stu WHERE IFNULL(math, 0) > 70 GROUP BY sex;
        
             # 按照性別分組,看下男女同學(xué)的平均分 分?jǐn)?shù)低于70的同學(xué)不參與分組,
             # 且分組后組內(nèi)個數(shù)小于2的不要了
          SELECT sex, AVG(IFNULL(math, 0)), AVG(IFNULL(english, 0)), COUNT(id) FROM stu WHERE IFNULL(math, 0) > 70 GROUP BY sex HAVING COUNT(id) > 2;
        
      2. 注意??!

        • 分組之后查詢的字段只能是分組字段或者聚合函數(shù)了,不能有與個人有關(guān)的字段

        • wherehaving的區(qū)別

          • where在分組之前【order by】進(jìn)行限定,而having在分組之后進(jìn)行限定

          • where后不可以跟聚合函數(shù),而having可以

    7. 分頁查詢
      1. 語法:limit index, n index -- 開始的索引; n -- 每頁查詢的條數(shù)

      2. 公式:【當(dāng)前頁開始索引 = (當(dāng)前頁數(shù) - 1) * 每頁記錄條數(shù)

            # 每頁顯示三條,第一頁
          SELECT * FROM stu LIMIT 0, 3;
            # 第二頁
          SELECT * FROM stu LIMIT 3, 3;
            #  第三頁
          SELECT * FROM stu LIMIT 6, 3; 
            # 每頁開始索引    (當(dāng)前頁數(shù) - 1) * 每頁顯示條數(shù) = 每頁開始索引
        
      3. 分頁操作是一個方言 【在MySQL中分頁是limit,其他數(shù)據(jù)庫有各自額關(guān)鍵字】

  2. 約束
    1. 概念:對表中數(shù)據(jù)進(jìn)行限定,保證數(shù)據(jù)的正確性、有效性與完整性

    2. 約束分類:

      • 主鍵約束:primary key

      • 非空約束:not null

      • 唯一約束:unique

      • 外鍵約束:foreign key

    3. 主鍵 -- 該字段值非空且唯一

      • 注意?。?/p>

          1. 一張表只能有一個字段為主鍵

          2. 主鍵就是表中記錄的唯一標(biāo)識

      • 創(chuàng)建表時添加主鍵

          # 創(chuàng)建一個新表,id是主鍵
         create table stu1(
          id int primary key,
          name varchar(30) not null  #  name字段非空
         ); # 一個表只能有一個主鍵
        
      • 刪除主鍵

        alter table stu1 drop primary key;  #  一個表只有一個主鍵
        
      • 創(chuàng)建表之后添加主鍵

          # 給 id 字段添加約束主鍵
         alter table stu1 modify id int primary key;
        
        • 添加前刪除所有重復(fù)字段
    4. 非空 -- 值不能為null

      • 創(chuàng)建表時添加非空約束

            # 創(chuàng)建一個新表,name字段非空
         create table stu1(
          id int,
          name varchar(30) not null -- name非空
         );
        
      • 刪除已經(jīng)創(chuàng)建的表的非空約束

           # 給name字段添加約束非空
         alter table stu1 modify name varchar(30) not null;
        
    5. 唯一 -- 值不能重復(fù)

      • 創(chuàng)建表時添加

           # 創(chuàng)建一個新表,phoneName唯一
         CREATE TABLE stu1(
          id INT,
          phoneName VARCHAR(20) UNIQUE # phoneName唯一
         );
        
      • 創(chuàng)建表之后添加

           #  給 phoneName 字段添加約束唯一
         alter table stu1 modify phoneName varchar(20) unique;
        
      • 刪除表字段的的唯一約束

            alter table stu1 drop index phoneName;  # 刪除表phoneName字段唯一約束
        
      • 注意??!

        • MySQL中unique限定的值可以有多個null

        • 刪除唯一約束的語法特殊

        • 給已經(jīng)創(chuàng)建的表的某個字段添加唯一約束時,需要刪除掉該字段所有的重復(fù)的值

    6. 自動增長

      • 概念:如果某一字段是數(shù)值類型,使用auto_increment可以實現(xiàn)其自增【一般配合主鍵id一起使用】

      • 創(chuàng)建表時添加自增約束

            # 創(chuàng)建一個新表,id是主鍵,且自增
         create table stu1(
          id int primary key auto_increment,
          name varchar(30) not null -- name字段非空
         );
        
        • 注意!!自增的數(shù)據(jù)只跟上一條記錄有關(guān),如id自增到6,插入數(shù)據(jù)時,指定了id為20 則下一次自增從21開始
      • 刪除自增約束

            # 刪除自增約束
         alter table stu1 modify id int; # id的主鍵約束不會被刪除掉
        
      • 添加自增約束

             # 給 id 字段添加約束自增
         alter table stu1 modify id int auto_increment;
        
    7. 外鍵 -- 添加外鍵前,外鍵表刪除數(shù)據(jù)不會做檢查【比如小李還在A部門,刪除A部門不會做檢查】

      1. 在創(chuàng)建表時??梢蕴砑油怄I
          create table 表名(
          ...
          外鍵列,
          constraint 外鍵名 foreign key (外鍵列名) references 主表名(主表列名)
         );
        
      2. 刪除外鍵
            # 刪除外鍵
         alter table 本表名 drop foreign key 外鍵名稱;
        
      3. 創(chuàng)建表之后,添加外鍵
         alter table 本表名 add constraint 外鍵名 foreign key (要關(guān)聯(lián)的本表列名) references 外鍵表名(要關(guān)聯(lián)的外鍵表列名);
           #  如下
          alter table emp add constraint emp_edp_fk foreign key (dep_id) references dep(id);
        
      4. 添加外鍵,并設(shè)置級聯(lián)更新[ -- 【更改/刪除部門的id時,在員工表里自動更改了對應(yīng)員工的部門號】用的時候謹(jǐn)慎
            # 添加外鍵,并設(shè)置級聯(lián)更新與級聯(lián)刪除
         ALTER TABLE emp ADD CONSTRAINT emp_edp_fk FOREIGN KEY
         (dep_id) REFERENCES dep(id) ON UPDATE CASCADE ON DELETE CASCADE;
        

五、數(shù)據(jù)庫的設(shè)計

  1. 多表之間的關(guān)系
    1. 分類

      • 一對一(了解)

        • 如:人與身份證

        • 一個人只能有一個身份證,一個身份證只能對應(yīng)一個人

      • 一對多(多對一)

        • 如:部門與員工

        • 一個部門可以有多個員工,一個員工只能對應(yīng)一個部門

      • 多對多

        • 如:學(xué)生與課程

        • 一個學(xué)生可以選擇多個課程,一個課程也可以被很多學(xué)生選擇

    2. 如何實現(xiàn)
      • 一對多(多對一)

        • 如:部門與員工

        • MySQL實現(xiàn):

          在多的一方【員工表】建立外鍵,指向一的一方【部門表】的主鍵

          總結(jié) 一對多兩張表,多的一方加外鍵

      • 多對多

        • 如:學(xué)生與課程

        • MySQL實現(xiàn):

          多對多關(guān)系實現(xiàn)需要借助第三張表,此第三話張表至少包含兩個字段,這兩個字段作為第三張表的外鍵,分別指向兩張表的主鍵【選課表】

          總結(jié) 多對多,三張表、關(guān)系表倆外鍵

      • 一對一【了解】

        • 一對一關(guān)系實現(xiàn),在任意一方添加唯一外鍵指向另一方主鍵【直接放一張表吧。。。。】
  2. 范式
    1. 概念:設(shè)計數(shù)據(jù)庫時,遵循不同的規(guī)范要求,設(shè)計出合理的關(guān)系型數(shù)據(jù)庫,這些不同的規(guī)范要求被稱為不同的范式,各種范式呈遞次規(guī)范,越高的范式數(shù)據(jù)庫冗余越小

    2. 分類:(目前關(guān)系型數(shù)據(jù)庫有六種范式)

      • 第一范式(1NF): 任何一張表應(yīng)該有主鍵,且每一個字段原子性不可再分

        • 如下圖的系列還分兩列,且存在問題【比如刪除了張無忌會一起刪除了高等數(shù)學(xué)課程】

      • 第二范式(2NF): 建立在1NF之上 另外要求所有非主鍵字段完全依賴主鍵,不能產(chǎn)生部分依賴 【消除非主字段對主鍵的部分函數(shù)依賴】

        • 幾個概念

          • 函數(shù)依賴:A --> B ,如果通過A列的值可以唯一確定列B的值,則稱B依賴于A

            • 如 學(xué)號 --> 姓名 姓名依賴于學(xué)號

            • (學(xué)號,課程) --> 分?jǐn)?shù) 則分?jǐn)?shù)依賴于屬性組

          • 完全函數(shù)依賴: A --> B 如果A是一個屬性組,則B值的確認(rèn)依賴于A中每一個屬性

            • 如:(學(xué)號,課程) -- > 分?jǐn)?shù) 分?jǐn)?shù)的確定單由一個學(xué)號無法確定,單由課程也無法確定,一個確定的學(xué)號+一個確定的課程確定唯一一個分?jǐn)?shù)
          • 部分函數(shù)依賴: A --> B 如果A是一個屬性組,則B值的確認(rèn)依只需要依賴于A中某一部分屬性

            • 如:(學(xué)號,系名) --> 姓名。我們發(fā)現(xiàn)前面屬性組里,通過一個學(xué)號可以確定一個姓名,不需要系名,用這個屬性組局多余
          • 傳遞依賴:A --> B, B -- > C,如果通過A屬性(組)可以唯一確定B屬性的值,再通過B屬性(組)的值可以唯一確定C屬性(組)的值,則C傳遞依賴于A

        • 如:

          • 圖:

          • 學(xué)號與課程名可以作為主碼【由(學(xué)號, 課程)可以唯一確定一個其他的唯一的值】,而系名與系主任可由學(xué)號直接確定,產(chǎn)生了部分依賴

          • 解決方案:拆分出選課表【學(xué)號、課程、分?jǐn)?shù)】作為主碼,與學(xué)生表【還存在傳遞依賴問題】

      • 第三范式(3NF): 建立在2NF基礎(chǔ)上,所有外鍵字段直接依賴主鍵,不可產(chǎn)生傳遞依賴

        • 如:

          • 圖:

          • 系名依賴于學(xué)號,系主任依賴于系名 則系主任傳遞依賴于學(xué)號 解決:拆分表,把系名與系主任另開為系表

  3. 數(shù)據(jù)庫的備份與還原
    1. 命令行形式

      • 備份:mysqldump -u用戶名 -p密碼 要備份的數(shù)據(jù)庫 > 保存的路徑

        mysqldump -uroot -padmin db1 > D:\JavaSETestDirectory01\MySQLBackup\db1.sql

      • 還原:

          1. 登錄數(shù)據(jù)庫

          2. 創(chuàng)建數(shù)據(jù)庫【還原的數(shù)據(jù)裝在此數(shù)據(jù)庫】

            create database backupdb;

          3. 使用數(shù)據(jù)庫【進(jìn)入這個數(shù)據(jù)庫,把數(shù)據(jù)還原進(jìn)來】

            use backupdb;

          4. 執(zhí)行文件。source 文件路徑

            source D:\JavaSETestDirectory01\MySQLBackup\ddd.sql

    2. 圖形化工具


六、多表查詢

  1. 查詢語法:
    select 列名列表 from 表名列表 where ...

    • 笛卡爾積:兩個集合,其所有情況為兩個集合列的乘積

    • 消除笛卡爾積:下面三種方式

  2. 多表查詢分類:

    1. 內(nèi)連接:

      1. 隱式內(nèi)連接:使用where條件消除無用數(shù)據(jù)
      SELECT 
           e.name,  # 員工表姓名
           e.gender,   # 員工表性別
           d.name  # 部門表名
      FROM
           emp e, dep d
      WHERE
           e.dep_id = d.id;  # 當(dāng)員工的部門id與部門的id相等時才返回結(jié)果
      
      1. 顯示內(nèi)連接:顯示地指定連接方式
      • 語法:
        select 字段列表 from 表1 inner join 表2 on 條件
        
           # 顯示連接  查詢所有的員工信息與對應(yīng)的部門信息
        SELECT  * FROM emp e INNER JOIN dep d ON e.dep_id = d.id;    #  inner可省略
        
      • 可以看出內(nèi)連接,查詢的是兩張表的交集
      1. 內(nèi)連接注意事項:

        1. 從哪些表中查詢數(shù)據(jù)

        2. 條件是什么

        3. 查詢哪些字段

    2. 外連接

      1. 左外連接

        • 語法:
         select 字段列表 from 表1 left outer join 表2 on 條件  # outer可省略
        
        # 查詢所有的員工信息,如果員工有部門,則查詢部門名稱。沒有則不顯示部門名
         SELECT * FROM emp e LEFT OUTER JOIN dep d ON e.`dep_id` = d.`id`;
        
        • 可以看出--左外連接是查詢的左邊的表另外與右邊表的交集
          image
      2. 右外連接

        • 語法:
         select 字段列表 from 表1 right outer join 表2 on 條件  # outer可省略
        
        • 右外連接查詢的就是右邊的表及其交集
    3. 子查詢

      1. 概念:查詢中嵌套查詢,稱嵌套查詢?yōu)樽硬樵?/p>

      2. 案例: -- 查詢工資最高的員工信息

        # 先查詢最高工資是多少
         select * from emp where salary = 9000;   # 帶著最高工資查詢信息
        # 查詢工資最高的員工信息,使用子查詢
         SELECT * FROM emp WHERE salary = (SELECT MAX(salary) FROM emp);
        
      3. 子查詢不同情況

        • 子查詢是單行單列的

          • 子查詢可以作為條件,使用運算符取判斷,運算符【>, <, >=, <=, =】
          # 查詢工資小于平均工資的員工信息
         SELECT * from emp where salary < (SELECT avg(salary) e from emp);
        
        • 子查詢是多行單列的

          • 子查詢作為條件,使用運算符in作為判斷
        # 查詢在開發(fā)部或者市場部工作的員工
        SELECT * FROM emp WHERE dep_id IN (( SELECT id FROM dep WHERE NAME = "開發(fā)部" ), ( SELECT id FROM dep WHERE NAME = "市場部" ));
        
image-20200302190004915

* 子查詢是多行多列的

         # 子查詢可以作為一張臨時表參與查詢
         # 查詢員工入職日期是 2011-11-11 日之后的員工信息和部門信息
         # 使用普通的內(nèi)連接
       SELECT * from emp e, dep d where e.dep_id = d.id and e.join_date > "2011-11-11";
         # 使用子查詢  多行多列
      SELECT * from (select * from emp where emp.join_date > "2011-11-11") t, dep d  where t.dep_id = d.id;
  1. 多表查詢練習(xí):

    1. 查詢所有員工信息。查詢員工編號,員工姓名,工資,職務(wù)名稱,職務(wù)描述

    2. 查詢員工編號,員工姓名,工資,職務(wù)名稱,職務(wù)描述,部門名稱,部門位置

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

    4. 查詢員工姓名,工資,職務(wù)名稱,職務(wù)描述,部門名稱,部門位置,工資等級

    5. 查詢出部門編號、部門名稱、部門位置、部門人數(shù)

    6. 查詢所有員工的姓名及其直接上級的姓名,沒有領(lǐng)導(dǎo)的員工也需要查詢

    7. 答案:

     # 1.  查詢所有員工信息。查詢員工編號,員工姓名,工資,職務(wù)名稱,職務(wù)描述
    select e.id 員工編號, e.ename 員工姓名, e.salary 工資, j.jname 職務(wù)名稱, j.de 職    務(wù)描述 from emp e, job j where e.job_id = j.id;
    
    # 2.  查詢員工編號,員工姓名,工資,職務(wù)名稱,職務(wù)描述,部門名稱,部門位    置
    select e.id, e.ename, e.salary, j.jname, j.de, d.dname, d.loc from emp e, dep d,     job j where e.dep_id = d.id and e.job_id = j.id;
    
    # 3.  查詢員工姓名,工資,工資等級
    SELECT e.ename, e.salary, s.grade from emp e, salarygrade s where e.salary     between s.losalary and s.hissalary;
    
    # 4.  查詢員工姓名,工資,職務(wù)名稱,職務(wù)描述,部門名稱,部門位置,工資等    級
    select e.ename, e.salary, j.jname, j.de, d.dname, d.loc, s.grade from emp e, dep     d, job j, salarygrade s where e.dep_id = d.id and e.job_id = j.id and e.salary     BETWEEN s.losalary and s.hissalary;
    
    # 5.  查詢出部門編號、部門名稱、部門位置、部門人數(shù)
            /*
                分析:
        ·               1. 使用分組查詢,對 emp.dep_id  字段進(jìn)行分組,查詢部    門的id與其對應(yīng)數(shù)量 COUNT(emp.id) 作為臨時表 t
                        2. 把 1 中的表拿出來 子查詢與 dep 表連接查詢部門信息
                    條件:當(dāng)臨時表的id與部門表id相同時
    */
    SELECT
        dep.id 部門編號,
        dep.dname 部門,
        dep.loc 部門位置,
        t.tcount 部門人數(shù)
    FROM
        dep,
        (
            SELECT
            emp.dep_id tid,
            COUNT(id) tcount
        FROM
            emp
        GROUP BY
            dep_id
        ) t
    WHERE
        t.tid = dep.id
    # 6.  查詢所有員工的姓名及其直接上級的姓名,沒有領(lǐng)導(dǎo)的員工也需要查詢
    select t1.t1ename 員工姓名, emp.ename 上級領(lǐng)導(dǎo) from (select ename         t1ename,mgr t1mgr from emp) t1 LEFT OUTER JOIN emp on emp.id = t1.t1mgr; 
        -- 更簡單的,起別名把員工表看做另一張領(lǐng)導(dǎo)表
    SELECT 
            e.ename,
        e.mgr,
        m.id,
        m.ename
    FROM
        emp e LEFT OUTER JOIN emp m 
    ON
        e.mgr = m.id;
    

七、事務(wù)

  1. 事務(wù)介紹
    1. 概念一個包含多個步驟的業(yè)務(wù)操作,被事務(wù)管理,那么這些事務(wù)要么同時成功,要么同時失敗【開啟事務(wù)后中間某一步出現(xiàn)問題就回滾到所有步驟之前,沒有任何異常則提交事務(wù)】

    2. 操作

      1. 開啟事務(wù):start transaction

      2. 回滾:rollback

      3. 提交:commit 【如果手動開啟了事務(wù)但沒有手動提交,事務(wù)會回滾】

    3. MySQL中數(shù)據(jù)庫事務(wù)默認(rèn)自動提交

      • 一條DML(增刪改)語句會自動提交一次事務(wù)

      • 事務(wù)提交的兩種方式:

        • 自動提交 -- MySQL是自動提交的【Oracle數(shù)據(jù)庫時默認(rèn)手動提交的(需要寫commit)】

        • 手動提交 -- 需要手動start開啟事務(wù),然后手動commit提交

      • 修改事務(wù)的提交方式

        • 查看事務(wù)默認(rèn)提交方式:select @@autocommit; -- 1為自動提交 0 為手動提交

          image-20200303135300042.png
        • 修改默認(rèn)提交方式:SET @@autocommit = 0

  2. 事務(wù)的四大特征
    1. 原子性:事務(wù)是不可分割的最小操作單位,要么同時成功,要么同時失敗

    2. 持久性:事務(wù)提交或回滾后,數(shù)據(jù)會持久化保存【關(guān)機(jī),重啟應(yīng)用都已經(jīng)保存】

    3. 隔離性:多個事務(wù)之間相互獨立【期望互不影響】

    4. 一致性:事務(wù)操作前后,事務(wù)的總量不變【轉(zhuǎn)錢前A100,B100。轉(zhuǎn)錢后A20,B180】

  3. 事務(wù)的隔離級別(了解)
    1. 概念:多個事務(wù)之間是隔離的、獨立的。但是如果多個事務(wù)曹組同一批數(shù)據(jù),則會引發(fā)一些問題,設(shè)置不同的隔離級別可以解決這些問題

    2. 存在的問題:

      • 臟讀:一個事務(wù),讀取到另一個事務(wù)匯總沒有提交的數(shù)據(jù)

      • (虛 讀)不可重復(fù)讀:在同一個事務(wù)中,兩次讀取到的數(shù)據(jù)不一樣

      • 幻讀:一個事務(wù)操作(DML)數(shù)據(jù)表中所有記錄,另一個事務(wù)添加了一條數(shù)據(jù),則第一個事務(wù)查詢不到自己的修改

    3. 隔離級別:

      • read uncommitted:讀未提交

        • 產(chǎn)生的問題:臟讀、不可重復(fù)讀、幻讀

          • 左邊事務(wù)更改信息還未提交或者回滾,右邊讀取到更新的信息【比如AB開啟事務(wù),A給B轉(zhuǎn)賬500,但未提交,B可以看到自己的賬戶多了500,但是A此時回滾可以把這500不轉(zhuǎn)過去】
      • read committed :讀已提交【Oracle默認(rèn)】

        • 產(chǎn)生的問題:不可重復(fù)讀、幻讀

          • 左邊事務(wù)提交更新信息,右邊事務(wù)在提交之前可以看到更新的信息,而不是保持不變
      • repeatable read:可重復(fù)讀【MySQL默認(rèn)】

        • 產(chǎn)生的問題:幻讀【左邊事務(wù)提交更新的信息,但右邊事務(wù)未提交之前,右邊事務(wù)讀到的數(shù)據(jù)是不會改變的(實際上已經(jīng)改變了)。只有在右邊事務(wù)提交之后才會看到更新的數(shù)據(jù)信息】
      • serializable:串行化

        • 可以解決所有的問題

        • 一個鎖表的操作,一個事務(wù)在開啟并操作【增刪改查】時,其他任何事物不得操作【比如查詢時會卡住不動】,只有當(dāng)前操作事務(wù)提交/回滾,別的事務(wù)才能操作【效率低】

        注意??!隔離級別從小到大安全性愈高,但是效率愈低

    4. MySQL查詢隔離級別

      • 查詢:select @@tx_isolation

      • 修改:set global transaction isolation level 級別字符串 【級別字符串是上述的read uncommitted等】


八、DCL -- 控制權(quán)限與管理用戶

  1. DBA :數(shù)據(jù)庫管理員 -- 管理用戶,授權(quán)

  2. 管理用戶

    1. 添加用戶:

       # 創(chuàng)建用戶【使用DCL語句】
       # create user "用戶名"@"主機(jī)名" IDENTIFIED by "密碼";
       create user "aaa"@"localhost" IDENTIFIED by "123";  -- 這樣就可以使用  mysql -uaaa -p123訪問這個數(shù)據(jù)庫 
      
    2. 刪除用戶:

       # 刪除用戶
       # drop user "用戶名"@"主機(jī)名":
       drop user "aaa"@"localhost";
      
    3. 修改用戶密碼:

       #可行的
       # set password for "用戶名"@"主機(jī)名" = password("新密碼");
       set password for "aaa"@"localhost" = password("345");
      
      1.          ```
        
         # update user set PASSWORD = PASSWORD("新密碼") where user = "用戶名";
         update user set PASSWORD = PASSWORD("123") where user = "aaa";  #### 實測不行 =.=
        
      2. 如果忘記了自己的登錄密碼... =.=

        1. 停止MySQL服務(wù) cmd --> net stop mysql 需要管理員權(quán)限

        2. 使用無驗證啟動MySQL服務(wù):mysqld --skip-grant- tables

        3. 再新打開一個cmd窗口 輸入mysql 回車登錄

        4. 使用 mysql 表,改密碼

         use mysql;
         set password for "root"@"localhost" = password("新密碼");
             # 或者下面這條命令
         update user set password = password('新密碼') where user = 'root';
        
        1. 關(guān)閉兩個窗口

        2. 打開任務(wù)管理器,手動結(jié)束mysqld.exe進(jìn)程

        3. 啟動mysql服務(wù)。使用新密碼登錄

    4. 查詢用戶:

      1. 切換到mysql數(shù)據(jù)庫,用戶表是mysql下的user

         use mysql;
         show tables;
         select * from user;  #可以發(fā)現(xiàn)有兩個用戶,上面這個是本機(jī)登錄,第二個是%通配符 任意的【遠(yuǎn)程登錄】
        

        image-20200303164817539
        有兩個用戶記錄,上面的是本地主機(jī),下面的是 % 通配符,表示可以在任意主機(jī)使用用戶登錄數(shù)據(jù)庫

  3. 權(quán)限管理(權(quán)限授予、添加)

    1. 查詢權(quán)限

       # 查詢權(quán)限   普通創(chuàng)建的用戶只有登錄的權(quán)限
       #  show grants for '用戶名'@'主機(jī)名';
       SHOW GRANTS FOR 'aaa'@'localhost';
      
    2. 授予權(quán)限

       # 授予權(quán)限  給誰授予哪個數(shù)據(jù)庫的哪個表什么權(quán)限
       # grant 權(quán)限列表 on 數(shù)據(jù)庫名.表名 to '用戶名'@'主機(jī)名';
       GRANT SELECT, UPDATE, DELETE ON db3.emp TO 'aaa'@'localhost';
      

      2.1 授予全部權(quán)限

       # 授予所有權(quán)限,在所有數(shù)據(jù)庫的所有的表上【謹(jǐn)慎使用】
       GRANT SELECT, UPDATE, DELETE ON db3.emp TO 'aaa'@'localhost';            
      
    3. 撤銷權(quán)限

       # 撤銷權(quán)限  從誰撤銷哪個數(shù)據(jù)庫的哪個表什么權(quán)限
       # revoke 權(quán)限列表 on 數(shù)據(jù)庫名.表名 from '用戶名'@'主機(jī)名';
       revoke select on db3.emp from 'aaa'@'localhost'; 
      
      1. 撤銷所有權(quán)限
       revoke  all on *.* from 'aaa'@'localhost';
      
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • DDL1.創(chuàng)建庫、創(chuàng)建表使用關(guān)鍵字create2.刪除庫、刪除表使用關(guān)鍵字drop3.修改庫、修改表使用關(guān)鍵字al...
    王_凱閱讀 420評論 0 0
  • ORACLE自學(xué)教程 --create tabletestone ( id number, --序號usernam...
    落葉寂聊閱讀 1,241評論 0 0
  • 1. 了解SQL 1.1 數(shù)據(jù)庫基礎(chǔ) ? 學(xué)習(xí)到目前這個階段,我們就需要以某種方式與數(shù)據(jù)庫打交道。在深入學(xué)習(xí)MyS...
    鋒享前端閱讀 1,315評論 0 1
  • 1、MySQL啟動和關(guān)閉(安裝及配置請參照百度經(jīng)驗,這里不再記錄。MySQL默認(rèn)端口號:3306;默認(rèn)數(shù)據(jù)類型格式...
    強(qiáng)壯de西蘭花閱讀 758評論 0 1
  • 典型子查詢 一個查詢的輸出是另一個查詢的輸入,也稱為嵌套子查詢 5個關(guān)鍵點:1、在查詢時基于未知時應(yīng)考慮使用子查詢...
    gg大宇閱讀 404評論 0 4

友情鏈接更多精彩內(nèi)容