日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

MySQL数据库学习教程,从0到入门

發布時間:2023/12/31 数据库 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MySQL数据库学习教程,从0到入门 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

mysql day01課堂筆記

1、什么是數據庫?什么是數據庫管理系統?什么是SQL?他們之間的關系是什么?

數據庫:英文單詞DataBase,簡稱DB。按照一定格式存儲數據的一些文件的組合。顧名思義:存儲數據的倉庫,實際上就是一堆文件。這些文件中存儲了具有特定格式的數據。數據庫管理系統:DataBaseManagement,簡稱DBMS。數據庫管理系統是專門用來管理數據庫中數據的,數據庫管理系統可以對數據庫當中的數據進行增刪改查。常見的數據庫管理系統:MySQL、Oracle、MS SqlServer、DB2、sybase等....SQL:結構化查詢語言程序員需要學習SQL語句,程序員通過編寫SQL語句,然后DBMS負責執行SQL語句,最終來完成數據庫中數據的增刪改查操作。SQL是一套標準,程序員主要學習的就是SQL語句,這個SQL在mysql中可以使用,同時在Oracle中也可以使用,在DB2中也可以使用。三者之間的關系?DBMS--執行--> SQL --操作--> DB先安裝數據庫管理系統MySQL,然后學習SQL語句怎么寫,編寫SQL語句之后,DBMS 對SQL語句進行執行,最終來完成數據庫的數據管理。

2、安裝MySQL數據庫管理系統。
第一步:先安裝,選擇“經典版”
第二步:需要進行MySQL數據庫實例配置。

注意:一路下一步就行了!!!!!需要注意的事項?端口號:端口號port是任何一個軟件/應用都會有的,端口號是應用的唯一代表。端口號通常和IP地址在一塊,IP地址用來定位計算機的,端口號port是用來定位計算機上某個服務的/某個應用的!在同一臺計算機上,端口號不能重復。具有唯一性。mysql數據庫啟動的時候,這個服務占有的默認端口號是3306這是大家都知道的事兒。記住。字符編碼方式?設置mysql數據庫的字符編碼方式為 UTF8一定要注意:先選中第3個單選按鈕,然后再選擇utf8字符集。服務名稱?默認是:MySQL不用改。選擇配置環境變量path:如果沒有選擇怎么辦?你可以手動配置path=其它路徑;C:\Program Files (x86)\MySQL\MySQL Server 5.5\binmysql超級管理員用戶名不能改,一定是:root你需要設置mysql數據庫超級管理員的密碼。我們設置為123456設置密碼的同時,可以激活root賬戶遠程訪問。激活:表示root賬號可以在外地登錄。不激活:表示root賬號只能在本機上使用。我這里選擇激活了!

3、MySQL數據庫的完美卸載!
第一步:雙擊安裝包進行卸載刪除。
第二步:刪除目錄:
把C:\ProgramData下面的MySQL目錄干掉。
把C:\Program Files (x86)下面的MySQL目錄干掉。

這樣就卸載結束了!

4、看一下計算機上的服務,找一找MySQL的服務在哪里?
計算機–>右鍵–>管理–>服務和應用程序–>服務–>找mysql服務
MySQL的服務,默認是“啟動”的狀態,只有啟動了mysql才能用。
默認情況下是“自動”啟動,自動啟動表示下一次重啟操作系統的時候
自動啟動該服務。

可以在服務上點擊右鍵:啟動重啟服務停止服務...還可以改變服務的默認配置:服務上點擊右鍵,屬性,然后可以選擇啟動方式:自動(延遲啟動)自動手動禁用

5、在windows操作系統當中,怎么使用命令來啟動和關閉mysql服務呢?
語法:
net stop 服務名稱;
net start 服務名稱;

其它服務的啟停都可以采用以上的命令。

6、mysql安裝了,服務啟動了,怎么使用客戶端登錄mysql數據庫呢?
使用bin目錄下的mysql.exe命令來連接mysql數據庫服務器

本地登錄(顯示編寫密碼的形式):C:\Users\Administrator>mysql -uroot -p123456Welcome to the MySQL monitor. Commands end with ; or \g.Your MySQL connection id is 1Server version: 5.5.36 MySQL Community Server (GPL)Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.Oracle is a registered trademark of Oracle Corporation and/or itsaffiliates. Other names may be trademarks of their respectiveowners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql>本地登錄(隱藏密碼的形式):C:\Users\Administrator>mysql -uroot -pEnter password: ******Welcome to the MySQL monitor. Commands end with ; or \g.Your MySQL connection id is 2Server version: 5.5.36 MySQL Community Server (GPL)Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.Oracle is a registered trademark of Oracle Corporation and/or itsaffiliates. Other names may be trademarks of their respectiveowners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql>

7、mysql常用命令:

退出mysql :exit查看mysql中有哪些數據庫?show databases; 注意:以分號結尾,分號是英文的分號。mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | test | +--------------------+ mysql默認自帶了4個數據庫。怎么選擇使用某個數據庫呢?mysql> use test;Database changed表示正在使用一個名字叫做test的數據庫。怎么創建數據庫呢?mysql> create database bjpowernode;Query OK, 1 row affected (0.00 sec)mysql> show databases;+--------------------+| Database |+--------------------+| information_schema || bjpowernode || mysql || performance_schema || test |+--------------------+查看某個數據庫下有哪些表?mysql> show tables;注意:以上的命令不區分大小寫,都行。查看mysql數據庫的版本號: mysql> select version();+-----------+| version() |+-----------+| 5.5.36 |+-----------+查看當前使用的是哪個數據庫? mysql> select database(); +-------------+ | database() | +-------------+ | bjpowernode | +-------------+mysql> show -> databases -> ; +--------------------+ | Database | +--------------------+ | information_schema | | bjpowernode | | mysql | | performance_schema | | test | +--------------------+注意:mysql是不見“;”不執行,“;”表示結束!mysql> show -> -> -> -> -> -> -> -> -> \c mysql> \c用來終止一條命令的輸入。

8、數據庫當中最基本的單元是表:table

什么是表table?為什么用表來存儲數據呢?姓名 性別 年齡(列:字段) ---------------------------張三 男 20 ------->行(記錄)李四 女 21 ------->行(記錄)王五 男 22 ------->行(記錄)數據庫當中是以表格的形式表示數據的。 因為表比較直觀。任何一張表都有行和列:行(row):被稱為數據/記錄。列(column):被稱為字段。姓名字段、性別字段、年齡字段。了解一下:每一個字段都有:字段名、數據類型、約束等屬性。字段名可以理解,是一個普通的名字,見名知意就行。數據類型:字符串,數字,日期等,后期講。約束:約束也有很多,其中一個叫做唯一性約束,這種約束添加之后,該字段中的數據不能重復。

9、關于SQL語句的分類?

SQL語句有很多,最好進行分門別類,這樣更容易記憶。分為:DQL:數據查詢語言(凡是帶有select關鍵字的都是查詢語句)select...DML:數據操作語言(凡是對表當中的數據進行增刪改的都是DML)insert delete updateinsert 增delete 刪update 改這個主要是操作表中的數據data。DDL:數據定義語言凡是帶有create、drop、alter的都是DDL。DDL主要操作的是表的結構。不是表中的數據。create:新建,等同于增drop:刪除alter:修改這個增刪改和DML不同,這個主要是對表結構進行操作。TCL:不是王牌電視。是事務控制語言包括:事務提交:commit;事務回滾:rollback;DCL:是數據控制語言。例如:授權grant、撤銷權限revoke....

10、導入一下提前準備好的數據:
bjpowernode.sql 這個文件中是我提前為大家練習準備的數據庫表。
怎么將sql文件中的數據導入呢?
mysql> source D:\course\03-MySQL\document\bjpowernode.sql

注意:路徑中不要有中文!!!!

11、關于導入的這幾張表?
mysql> show tables;
±----------------------+
| Tables_in_bjpowernode |
±----------------------+
| dept |
| emp |
| salgrade |
±----------------------+

dept是部門表 emp是員工表 salgrade 是工資等級表怎么查看表中的數據呢?select * from 表名; //統一執行這個SQL語句。mysql> select * from emp; // 從emp表查詢所有數據。 +-------+--------+-----------+------+------------+---------+---------+--------+ | EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO | +-------+--------+-----------+------+------------+---------+---------+--------+ | 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 | | 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 | | 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 | | 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 | | 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 | | 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 | | 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 | | 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 | | 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 | | 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 | | 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | NULL | 20 | | 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | NULL | 30 | | 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 | | 7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1300.00 | NULL | 10 | +-------+--------+-----------+------+------------+---------+---------+--------+mysql> select * from dept; +--------+------------+----------+ | DEPTNO | DNAME | LOC | +--------+------------+----------+ | 10 | ACCOUNTING | NEW YORK | | 20 | RESEARCH | DALLAS | | 30 | SALES | CHICAGO | | 40 | OPERATIONS | BOSTON | +--------+------------+----------+mysql> select * from salgrade; +-------+-------+-------+ | GRADE | LOSAL | HISAL | +-------+-------+-------+ | 1 | 700 | 1200 | | 2 | 1201 | 1400 | | 3 | 1401 | 2000 | | 4 | 2001 | 3000 | | 5 | 3001 | 9999 | +-------+-------+-------+

12、不看表中的數據,只看表的結構,有一個命令:
desc 表名;
mysql> desc dept;
±-------±------------±-----±----±--------±------+
| Field | Type | Null | Key | Default | Extra |
±-------±------------±-----±----±--------±------+
| DEPTNO | int(2) | NO | PRI | NULL | |部門編號
| DNAME | varchar(14) | YES | | NULL | |部門名字
| LOC | varchar(13) | YES | | NULL | |地理位置
±-------±------------±-----±----±--------±------+
mysql> desc emp;
±---------±------------±-----±----±--------±------+
| Field | Type | Null | Key | Default | Extra |
±---------±------------±-----±----±--------±------+
| EMPNO | int(4) | NO | PRI | NULL | |員工編號
| ENAME | varchar(10) | YES | | NULL | |員工姓名
| JOB | varchar(9) | YES | | NULL | |工作崗位
| MGR | int(4) | YES | | NULL | |上級編號
| HIREDATE | date | YES | | NULL | |入職日期
| SAL | double(7,2) | YES | | NULL | |工資
| COMM | double(7,2) | YES | | NULL | |補助
| DEPTNO | int(2) | YES | | NULL | |部門編號
±---------±------------±-----±----±--------±------+
mysql> desc salgrade;
±------±--------±-----±----±--------±------+
| Field | Type | Null | Key | Default | Extra |
±------±--------±-----±----±--------±------+
| GRADE | int(11) | YES | | NULL | |工資等級
| LOSAL | int(11) | YES | | NULL | |最低工資
| HISAL | int(11) | YES | | NULL | |最高工資
±------±--------±-----±----±--------±------+

describe縮寫為:desc
mysql> describe dept;
±-------±------------±-----±----±--------±------+
| Field | Type | Null | Key | Default | Extra |
±-------±------------±-----±----±--------±------+
| DEPTNO | int(2) | NO | PRI | NULL | |
| DNAME | varchar(14) | YES | | NULL | |
| LOC | varchar(13) | YES | | NULL | |
±-------±------------±-----±----±--------±------+

13、簡單查詢
13.1、查詢一個字段?
select 字段名 from 表名;
其中要注意:
select和from都是關鍵字。
字段名和表名都是標識符。

強調:對于SQL語句來說,是通用的,所有的SQL語句以“;”結尾。另外SQL語句不區分大小寫,都行。查詢部門名字?mysql> select dname from dept;+------------+| dname |+------------+| ACCOUNTING || RESEARCH || SALES || OPERATIONS |+------------+4 rows in set (0.00 sec)mysql> SELECT DNAME FROM DEPT;+------------+| DNAME |+------------+| ACCOUNTING || RESEARCH || SALES || OPERATIONS |+------------+4 rows in set (0.00 sec)13.2、查詢兩個字段,或者多個字段怎么辦?使用逗號隔開“,”查詢部門編號和部門名?select deptno,dname from dept;+--------+------------+| deptno | dname |+--------+------------+| 10 | ACCOUNTING || 20 | RESEARCH || 30 | SALES || 40 | OPERATIONS |+--------+------------+13.3、查詢所有字段怎么辦?第一種方式:可以把每個字段都寫上select a,b,c,d,e,f... from tablename;第二種方式:可以使用*select * from dept;+--------+------------+----------+| DEPTNO | DNAME | LOC |+--------+------------+----------+| 10 | ACCOUNTING | NEW YORK || 20 | RESEARCH | DALLAS || 30 | SALES | CHICAGO || 40 | OPERATIONS | BOSTON |+--------+------------+----------+這種方式的缺點:1、效率低2、可讀性差。在實際開發中不建議,可以自己玩沒問題。你可以在DOS命令窗口中想快速的看一看全表數據可以采用這種方式。13.4、給查詢的列起別名?mysql> select deptno,dname as deptname from dept;+--------+------------+| deptno | deptname |+--------+------------+| 10 | ACCOUNTING || 20 | RESEARCH || 30 | SALES || 40 | OPERATIONS |+--------+------------+使用as關鍵字起別名。注意:只是將顯示的查詢結果列名顯示為deptname,原表列名還是叫:dname記住:select語句是永遠都不會進行修改操作的。(因為只負責查詢)as關鍵字可以省略嗎?可以的mysql> select deptno,dname deptname from dept;假設起別名的時候,別名里面有空格,怎么辦?mysql> select deptno,dname dept name from dept;DBMS看到這樣的語句,進行SQL語句的編譯,不符合語法,編譯報錯。怎么解決?select deptno,dname 'dept name' from dept; //加單引號select deptno,dname "dept name" from dept; //加雙引號+--------+------------+| deptno | dept name |+--------+------------+| 10 | ACCOUNTING || 20 | RESEARCH || 30 | SALES || 40 | OPERATIONS |+--------+------------+注意:在所有的數據庫當中,字符串統一使用單引號括起來,單引號是標準,雙引號在oracle數據庫中用不了。但是在mysql中可以使用。再次強調:數據庫中的字符串都是采用單引號括起來。這是標準的。雙引號不標準。13.5、計算員工年薪?sal * 12mysql> select ename,sal from emp;+--------+---------+| ename | sal |+--------+---------+| SMITH | 800.00 || ALLEN | 1600.00 || WARD | 1250.00 || JONES | 2975.00 || MARTIN | 1250.00 || BLAKE | 2850.00 || CLARK | 2450.00 || SCOTT | 3000.00 || KING | 5000.00 || TURNER | 1500.00 || ADAMS | 1100.00 || JAMES | 950.00 || FORD | 3000.00 || MILLER | 1300.00 |+--------+---------+mysql> select ename,sal*12 from emp; // 結論:字段可以使用數學表達式!+--------+----------+| ename | sal*12 |+--------+----------+| SMITH | 9600.00 || ALLEN | 19200.00 || WARD | 15000.00 || JONES | 35700.00 || MARTIN | 15000.00 || BLAKE | 34200.00 || CLARK | 29400.00 || SCOTT | 36000.00 || KING | 60000.00 || TURNER | 18000.00 || ADAMS | 13200.00 || JAMES | 11400.00 || FORD | 36000.00 || MILLER | 15600.00 |+--------+----------+mysql> select ename,sal*12 as yearsal from emp; //起別名+--------+----------+| ename | yearsal |+--------+----------+| SMITH | 9600.00 || ALLEN | 19200.00 || WARD | 15000.00 || JONES | 35700.00 || MARTIN | 15000.00 || BLAKE | 34200.00 || CLARK | 29400.00 || SCOTT | 36000.00 || KING | 60000.00 || TURNER | 18000.00 || ADAMS | 13200.00 || JAMES | 11400.00 || FORD | 36000.00 || MILLER | 15600.00 |+--------+----------+mysql> select ename,sal*12 as '年薪' from emp; //別名是中文,用單引號括起來。+--------+----------+| ename | 年薪 |+--------+----------+| SMITH | 9600.00 || ALLEN | 19200.00 || WARD | 15000.00 || JONES | 35700.00 || MARTIN | 15000.00 || BLAKE | 34200.00 || CLARK | 29400.00 || SCOTT | 36000.00 || KING | 60000.00 || TURNER | 18000.00 || ADAMS | 13200.00 || JAMES | 11400.00 || FORD | 36000.00 || MILLER | 15600.00 |+--------+----------+

14、條件查詢

14.1、什么是條件查詢?
不是將表中所有數據都查出來。是查詢出來符合條件的。
語法格式:
select
字段1,字段2,字段3…
from
表名
where
條件;

14.2、都有哪些條件?

= 等于 查詢薪資等于800的員工姓名和編號?select empno,ename from emp where sal = 800; 查詢SMITH的編號和薪資?select empno,sal from emp where ename = 'SMITH'; //字符串使用單引號<>或!= 不等于 查詢薪資不等于800的員工姓名和編號?select empno,ename from emp where sal != 800;select empno,ename from emp where sal <> 800; // 小于號和大于號組成的不等號< 小于 查詢薪資小于2000的員工姓名和編號?mysql> select empno,ename,sal from emp where sal < 2000;+-------+--------+---------+| empno | ename | sal |+-------+--------+---------+| 7369 | SMITH | 800.00 || 7499 | ALLEN | 1600.00 || 7521 | WARD | 1250.00 || 7654 | MARTIN | 1250.00 || 7844 | TURNER | 1500.00 || 7876 | ADAMS | 1100.00 || 7900 | JAMES | 950.00 || 7934 | MILLER | 1300.00 |+-------+--------+---------+<= 小于等于 查詢薪資小于等于3000的員工姓名和編號?select empno,ename,sal from emp where sal <= 3000;> 大于 查詢薪資大于3000的員工姓名和編號?select empno,ename,sal from emp where sal > 3000;>= 大于等于 查詢薪資大于等于3000的員工姓名和編號?select empno,ename,sal from emp where sal >= 3000;between … and …. 兩個值之間, 等同于 >= and <= 查詢薪資在2450和3000之間的員工信息?包括2450和3000第一種方式:>= and <= (and是并且的意思。)select empno,ename,sal from emp where sal >= 2450 and sal <= 3000;+-------+-------+---------+| empno | ename | sal |+-------+-------+---------+| 7566 | JONES | 2975.00 || 7698 | BLAKE | 2850.00 || 7782 | CLARK | 2450.00 || 7788 | SCOTT | 3000.00 || 7902 | FORD | 3000.00 |+-------+-------+---------+第二種方式:between … and …select empno,ename,sal from emp where sal between 2450 and 3000;注意:使用between and的時候,必須遵循左小右大。between and是閉區間,包括兩端的值。is null 為 null(is not null 不為空) 查詢哪些員工的津貼/補助為null?mysql> select empno,ename,sal,comm from emp where comm = null;Empty set (0.00 sec)mysql> select empno,ename,sal,comm from emp where comm is null;+-------+--------+---------+------+| empno | ename | sal | comm |+-------+--------+---------+------+| 7369 | SMITH | 800.00 | NULL || 7566 | JONES | 2975.00 | NULL || 7698 | BLAKE | 2850.00 | NULL || 7782 | CLARK | 2450.00 | NULL || 7788 | SCOTT | 3000.00 | NULL || 7839 | KING | 5000.00 | NULL || 7876 | ADAMS | 1100.00 | NULL || 7900 | JAMES | 950.00 | NULL || 7902 | FORD | 3000.00 | NULL || 7934 | MILLER | 1300.00 | NULL |+-------+--------+---------+------+10 rows in set (0.00 sec)注意:在數據庫當中null不能使用等號進行衡量。需要使用is null因為數據庫中的null代表什么也沒有,它不是一個值,所以不能使用等號衡量。查詢哪些員工的津貼/補助不為null?select empno,ename,sal,comm from emp where comm is not null;+-------+--------+---------+---------+| empno | ename | sal | comm |+-------+--------+---------+---------+| 7499 | ALLEN | 1600.00 | 300.00 || 7521 | WARD | 1250.00 | 500.00 || 7654 | MARTIN | 1250.00 | 1400.00 || 7844 | TURNER | 1500.00 | 0.00 |+-------+--------+---------+---------+and 并且 查詢工作崗位是MANAGER并且工資大于2500的員工信息?select empno,ename,job,sal from emp where job = 'MANAGER' and sal > 2500;+-------+-------+---------+---------+| empno | ename | job | sal |+-------+-------+---------+---------+| 7566 | JONES | MANAGER | 2975.00 || 7698 | BLAKE | MANAGER | 2850.00 |+-------+-------+---------+---------+or 或者 查詢工作崗位是MANAGER和SALESMAN的員工?select empno,ename,job from emp where job = 'MANAGER';select empno,ename,job from emp where job = 'SALESMAN';select empno,ename,jobfromempwhere job = 'MANAGER' or job = 'SALESMAN';+-------+--------+----------+| empno | ename | job |+-------+--------+----------+| 7499 | ALLEN | SALESMAN || 7521 | WARD | SALESMAN || 7566 | JONES | MANAGER || 7654 | MARTIN | SALESMAN || 7698 | BLAKE | MANAGER || 7782 | CLARK | MANAGER || 7844 | TURNER | SALESMAN |+-------+--------+----------+and和or同時出現的話,有優先級問題嗎? 查詢工資大于2500,并且部門編號為10或20部門的員工?select *fromempwheresal > 2500 and deptno = 10 or deptno = 20;分析以上語句的問題?and優先級比or高。以上語句會先執行and,然后執行or。以上這個語句表示什么含義?找出工資大于2500并且部門編號為10的員工,或者20部門所有員工找出來。select *fromempwheresal > 2500 and (deptno = 10 or deptno = 20);and和or同時出現,and優先級較高。如果想讓or先執行,需要加“小括號”以后在開發中,如果不確定優先級,就加小括號就行了。in 包含,相當于多個 or (not in 不在這個范圍中)查詢工作崗位是MANAGER和SALESMAN的員工?select empno,ename,job from emp where job = 'MANAGER' or job = 'SALESMAN';select empno,ename,job from emp where job in('MANAGER', 'SALESMAN');+-------+--------+----------+| empno | ename | job |+-------+--------+----------+| 7499 | ALLEN | SALESMAN || 7521 | WARD | SALESMAN || 7566 | JONES | MANAGER || 7654 | MARTIN | SALESMAN || 7698 | BLAKE | MANAGER || 7782 | CLARK | MANAGER || 7844 | TURNER | SALESMAN |+-------+--------+----------+注意:in不是一個區間。in后面跟的是具體的值。查詢薪資是800和5000的員工信息?select ename,sal from emp where sal = 800 or sal = 5000;select ename,sal from emp where sal in(800, 5000); //這個不是表示800到5000都找出來。+-------+---------+| ename | sal |+-------+---------+| SMITH | 800.00 || KING | 5000.00 |+-------+---------+select ename,sal from emp where sal in(800, 5000, 3000);// not in 表示不在這幾個值當中的數據。select ename,sal from emp where sal not in(800, 5000, 3000);+--------+---------+| ename | sal |+--------+---------+| ALLEN | 1600.00 || WARD | 1250.00 || JONES | 2975.00 || MARTIN | 1250.00 || BLAKE | 2850.00 || CLARK | 2450.00 || TURNER | 1500.00 || ADAMS | 1100.00 || JAMES | 950.00 || MILLER | 1300.00 |+--------+---------+not 可以取非,主要用在 is 或 in 中is nullis not nullinnot inlike 稱為模糊查詢,支持%或下劃線匹配%匹配任意多個字符下劃線:任意一個字符。(%是一個特殊的符號,_ 也是一個特殊符號)找出名字中含有O的?mysql> select ename from emp where ename like '%O%';+-------+| ename |+-------+| JONES || SCOTT || FORD |+-------+找出名字以T結尾的?select ename from emp where ename like '%T';找出名字以K開始的?select ename from emp where ename like 'K%';找出第二個字每是A的?select ename from emp where ename like '_A%';找出第三個字母是R的?select ename from emp where ename like '__R%';t_student學生表name字段----------------------zhangsanlisiwangwuzhaoliujack_son找出名字中有“_”的?select name from t_student where name like '%_%'; //這樣不行。mysql> select name from t_student where name like '%\_%'; // \轉義字符。+----------+| name |+----------+| jack_son |+----------+

15、排序

15.1、查詢所有員工薪資,排序?
select
ename,sal
from
emp
order by
sal; // 默認是升序!!!

+--------+---------+ | ename | sal | +--------+---------+ | SMITH | 800.00 | | JAMES | 950.00 | | ADAMS | 1100.00 | | WARD | 1250.00 | | MARTIN | 1250.00 | | MILLER | 1300.00 | | TURNER | 1500.00 | | ALLEN | 1600.00 | | CLARK | 2450.00 | | BLAKE | 2850.00 | | JONES | 2975.00 | | FORD | 3000.00 | | SCOTT | 3000.00 | | KING | 5000.00 | +--------+---------+

15.2、怎么降序?

指定降序: select ename,sal fromemp order bysal desc;

±-------±--------+
| ename | sal |
±-------±--------+
| KING | 5000.00 |
| SCOTT | 3000.00 |
| FORD | 3000.00 |
| JONES | 2975.00 |
| BLAKE | 2850.00 |
| CLARK | 2450.00 |
| ALLEN | 1600.00 |
| TURNER | 1500.00 |
| MILLER | 1300.00 |
| MARTIN | 1250.00 |
| WARD | 1250.00 |
| ADAMS | 1100.00 |
| JAMES | 950.00 |
| SMITH | 800.00 |
±-------±--------+

指定升序? select ename,sal fromemp order bysal asc;

±-------±--------+
| ename | sal |
±-------±--------+
| SMITH | 800.00 |
| JAMES | 950.00 |
| ADAMS | 1100.00 |
| WARD | 1250.00 |
| MARTIN | 1250.00 |
| MILLER | 1300.00 |
| TURNER | 1500.00 |
| ALLEN | 1600.00 |
| CLARK | 2450.00 |
| BLAKE | 2850.00 |
| JONES | 2975.00 |
| FORD | 3000.00 |
| SCOTT | 3000.00 |
| KING | 5000.00 |
±-------±--------+

15.3、可以兩個字段排序嗎?或者說按照多個字段排序?
查詢員工名字和薪資,要求按照薪資升序,如果薪資一樣的話,
再按照名字升序排列。
select
ename,sal
from
emp
order by
sal asc, ename asc; // sal在前,起主導,只有sal相等的時候,才會考慮啟用ename排序。

+--------+---------+ | ename | sal | +--------+---------+ | SMITH | 800.00 | | JAMES | 950.00 | | ADAMS | 1100.00 | | MARTIN | 1250.00 | | WARD | 1250.00 | | MILLER | 1300.00 | | TURNER | 1500.00 | | ALLEN | 1600.00 | | CLARK | 2450.00 | | BLAKE | 2850.00 | | JONES | 2975.00 | | FORD | 3000.00 | | SCOTT | 3000.00 | | KING | 5000.00 | +--------+---------+

15.4、了解:根據字段的位置也可以排序
select ename,sal from emp order by 2; // 2表示第二列。第二列是sal
按照查詢結果的第2列sal排序。

了解一下,不建議在開發中這樣寫,因為不健壯。 因為列的順序很容易發生改變,列順序修改之后,2就廢了。

16、綜合一點的案例:
找出工資在1250到3000之間的員工信息,要求按照薪資降序排列。
select
ename,sal
from
emp
where
sal between 1250 and 3000
order by
sal desc;

±-------±--------+
| ename | sal |
±-------±--------+
| FORD | 3000.00 |
| SCOTT | 3000.00 |
| JONES | 2975.00 |
| BLAKE | 2850.00 |
| CLARK | 2450.00 |
| ALLEN | 1600.00 |
| TURNER | 1500.00 |
| MILLER | 1300.00 |
| MARTIN | 1250.00 |
| WARD | 1250.00 |
±-------±--------+

關鍵字順序不能變:select...from...where...order by...以上語句的執行順序必須掌握:第一步:from第二步:where第三步:select第四步:order by(排序總是在最后執行!)

17、數據處理函數

17.1、數據處理函數又被稱為單行處理函數

單行處理函數的特點:一個輸入對應一個輸出。和單行處理函數相對的是:多行處理函數。(多行處理函數特點:多個輸入,對應1個輸出!)

17.2、單行處理函數常見的有哪些?

lower 轉換小寫mysql> select lower(ename) as ename from emp;+--------+| ename |+--------+| smith || allen || ward || jones || martin || blake || clark || scott || king || turner || adams || james || ford || miller |+--------+14個輸入,最后還是14個輸出。這是單行處理函數的特點。upper 轉換大寫mysql> select * from t_student;+----------+| name |+----------+| zhangsan || lisi || wangwu || jack_son |+----------+mysql> select upper(name) as name from t_student;+----------+| name |+----------+| ZHANGSAN || LISI || WANGWU || JACK_SON |+----------+substr 取子串(substr( 被截取的字符串, 起始下標,截取的長度))select substr(ename, 1, 1) as ename from emp;注意:起始下標從1開始,沒有0.找出員工名字第一個字母是A的員工信息?第一種方式:模糊查詢select ename from emp where ename like 'A%';第二種方式:substr函數select ename from emp where substr(ename,1,1) = 'A';首字母大寫?select name from t_student;select upper(substr(name,1,1)) from t_student;select substr(name,2,length(name) - 1) from t_student;select concat(upper(substr(name,1,1)),substr(name,2,length(name) - 1)) as result from t_student;+----------+| result |+----------+| Zhangsan || Lisi || Wangwu || Jack_son |+----------+concat函數進行字符串的拼接select concat(empno,ename) from emp;+---------------------+| concat(empno,ename) |+---------------------+| 7369SMITH || 7499ALLEN || 7521WARD || 7566JONES || 7654MARTIN || 7698BLAKE || 7782CLARK || 7788SCOTT || 7839KING || 7844TURNER || 7876ADAMS || 7900JAMES || 7902FORD || 7934MILLER |+---------------------+length 取長度select length(ename) enamelength from emp;+-------------+| enamelength |+-------------+| 5 || 5 || 4 || 5 || 6 || 5 || 5 || 5 || 4 || 6 || 5 || 5 || 4 || 6 |+-------------+trim 去空格mysql> select * from emp where ename = ' KING';Empty set (0.00 sec)mysql> select * from emp where ename = trim(' KING');+-------+-------+-----------+------+------------+---------+------+--------+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |+-------+-------+-----------+------+------------+---------+------+--------+| 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 |+-------+-------+-----------+------+------------+---------+------+--------+str_to_date 將字符串轉換成日期 date_format 格式化日期 format 設置千分位case..when..then..when..then..else..end當員工的工作崗位是MANAGER的時候,工資上調10%,當工作崗位是SALESMAN的時候,工資上調50%,其它正常。(注意:不修改數據庫,只是將查詢結果顯示為工資上調)select ename,job, sal as oldsal,(case job when 'MANAGER' then sal*1.1 when 'SALESMAN' then sal*1.5 else sal end) as newsal from emp;+--------+-----------+---------+---------+| ename | job | oldsal | newsal |+--------+-----------+---------+---------+| SMITH | CLERK | 800.00 | 800.00 || ALLEN | SALESMAN | 1600.00 | 2400.00 || WARD | SALESMAN | 1250.00 | 1875.00 || JONES | MANAGER | 2975.00 | 3272.50 || MARTIN | SALESMAN | 1250.00 | 1875.00 || BLAKE | MANAGER | 2850.00 | 3135.00 || CLARK | MANAGER | 2450.00 | 2695.00 || SCOTT | ANALYST | 3000.00 | 3000.00 || KING | PRESIDENT | 5000.00 | 5000.00 || TURNER | SALESMAN | 1500.00 | 2250.00 || ADAMS | CLERK | 1100.00 | 1100.00 || JAMES | CLERK | 950.00 | 950.00 || FORD | ANALYST | 3000.00 | 3000.00 || MILLER | CLERK | 1300.00 | 1300.00 |+--------+-----------+---------+---------+round 四舍五入select 字段 from 表名;select ename from emp;select 'abc' from emp; // select后面直接跟“字面量/字面值”mysql> select 'abc' as bieming from emp;+---------+| bieming |+---------+| abc || abc || abc || abc || abc || abc || abc || abc || abc || abc || abc || abc || abc || abc |+---------+mysql> select abc from emp;ERROR 1054 (42S22): Unknown column 'abc' in 'field list'這樣肯定報錯,因為會把abc當做一個字段的名字,去emp表中找abc字段去了。select 1000 as num from emp; // 1000 也是被當做一個字面量/字面值。+------+| num |+------+| 1000 || 1000 || 1000 || 1000 || 1000 || 1000 || 1000 || 1000 || 1000 || 1000 || 1000 || 1000 || 1000 || 1000 |+------+結論:select后面可以跟某個表的字段名(可以等同看做變量名),也可以跟字面量/字面值(數據)。select 21000 as num from dept;+-------+| num |+-------+| 21000 || 21000 || 21000 || 21000 |+-------+mysql> select round(1236.567, 0) as result from emp; //保留整數位。+--------+| result |+--------+| 1237 || 1237 || 1237 || 1237 || 1237 || 1237 || 1237 || 1237 || 1237 || 1237 || 1237 || 1237 || 1237 || 1237 |+--------+select round(1236.567, 1) as result from emp; //保留1個小數select round(1236.567, 2) as result from emp; //保留2個小數select round(1236.567, -1) as result from emp; // 保留到十位。+--------+| result |+--------+| 1240 || 1240 || 1240 || 1240 || 1240 || 1240 || 1240 || 1240 || 1240 || 1240 || 1240 || 1240 || 1240 || 1240 |+--------+select round(1236.567, -2) as result from emp;+--------+| result |+--------+| 1200 || 1200 || 1200 || 1200 || 1200 || 1200 || 1200 || 1200 || 1200 || 1200 || 1200 || 1200 || 1200 || 1200 |+--------+rand() 生成隨機數mysql> select round(rand()*100,0) from emp; // 100以內的隨機數+---------------------+| round(rand()*100,0) |+---------------------+| 76 || 29 || 15 || 88 || 95 || 9 || 63 || 89 || 54 || 3 || 54 || 61 || 42 || 28 |+---------------------+ifnull 可以將 null 轉換成一個具體值ifnull是空處理函數。專門處理空的。在所有數據庫當中,只要有NULL參與的數學運算,最終結果就是NULL。mysql> select ename, sal + comm as salcomm from emp;+--------+---------+| ename | salcomm |+--------+---------+| SMITH | NULL || ALLEN | 1900.00 || WARD | 1750.00 || JONES | NULL || MARTIN | 2650.00 || BLAKE | NULL || CLARK | NULL || SCOTT | NULL || KING | NULL || TURNER | 1500.00 || ADAMS | NULL || JAMES | NULL || FORD | NULL || MILLER | NULL |+--------+---------+計算每個員工的年薪?年薪 = (月薪 + 月補助) * 12select ename, (sal + comm) * 12 as yearsal from emp;+--------+----------+| ename | yearsal |+--------+----------+| SMITH | NULL || ALLEN | 22800.00 || WARD | 21000.00 || JONES | NULL || MARTIN | 31800.00 || BLAKE | NULL || CLARK | NULL || SCOTT | NULL || KING | NULL || TURNER | 18000.00 || ADAMS | NULL || JAMES | NULL || FORD | NULL || MILLER | NULL |+--------+----------+注意:NULL只要參與運算,最終結果一定是NULL。為了避免這個現象,需要使用ifnull函數。ifnull函數用法:ifnull(數據, 被當做哪個值)如果“數據”為NULL的時候,把這個數據結構當做哪個值。補助為NULL的時候,將補助當做0select ename, (sal + ifnull(comm, 0)) * 12 as yearsal from emp;+--------+----------+| ename | yearsal |+--------+----------+| SMITH | 9600.00 || ALLEN | 22800.00 || WARD | 21000.00 || JONES | 35700.00 || MARTIN | 31800.00 || BLAKE | 34200.00 || CLARK | 29400.00 || SCOTT | 36000.00 || KING | 60000.00 || TURNER | 18000.00 || ADAMS | 13200.00 || JAMES | 11400.00 || FORD | 36000.00 || MILLER | 15600.00 |+--------+----------+

18、分組函數(多行處理函數)

多行處理函數的特點:輸入多行,最終輸出一行。5個:count 計數sum 求和avg 平均值max 最大值min 最小值注意:分組函數在使用的時候必須先進行分組,然后才能用。如果你沒有對數據進行分組,整張表默認為一組。找出最高工資?mysql> select max(sal) from emp;+----------+| max(sal) |+----------+| 5000.00 |+----------+找出最低工資?mysql> select min(sal) from emp;+----------+| min(sal) |+----------+| 800.00 |+----------+計算工資和:mysql> select sum(sal) from emp;+----------+| sum(sal) |+----------+| 29025.00 |+----------+計算平均工資:mysql> select avg(sal) from emp;+-------------+| avg(sal) |+-------------+| 2073.214286 |+-------------+14個工資全部加起來,然后除以14。計算員工數量?mysql> select count(ename) from emp;+--------------+| count(ename) |+--------------+| 14 |+--------------+分組函數在使用的時候需要注意哪些?第一點:分組函數自動忽略NULL,你不需要提前對NULL進行處理。mysql> select sum(comm) from emp;+-----------+| sum(comm) |+-----------+| 2200.00 |+-----------+mysql> select count(comm) from emp;+-------------+| count(comm) |+-------------+| 4 |+-------------+mysql> select avg(comm) from emp;+------------+| avg(comm) |+------------+| 550.000000 |+------------+第二點:分組函數中count(*)和count(具體字段)有什么區別?mysql> select count(*) from emp;+----------+| count(*) |+----------+| 14 |+----------+mysql> select count(comm) from emp;+-------------+| count(comm) |+-------------+| 4 |+-------------+count(具體字段):表示統計該字段下所有不為NULL的元素的總數。count(*):統計表當中的總行數。(只要有一行數據count則++)因為每一行記錄不可能都為NULL,一行數據中有一列不為NULL,則這行數據就是有效的。第三點:分組函數不能夠直接使用在where子句中。找出比最低工資高的員工信息。select ename,sal from emp where sal > min(sal);表面上沒問題,運行一下?ERROR 1111 (HY000): Invalid use of group function?????????????????????????????????????????????????????????????????????說完分組查詢(group by)之后就明白了了。第四點:所有的分組函數可以組合起來一起用。select sum(sal),min(sal),max(sal),avg(sal),count(*) from emp;+----------+----------+----------+-------------+----------+| sum(sal) | min(sal) | max(sal) | avg(sal) | count(*) |+----------+----------+----------+-------------+----------+| 29025.00 | 800.00 | 5000.00 | 2073.214286 | 14 |+----------+----------+----------+-------------+----------+

19、分組查詢(非常重要:五顆星*****)

19.1、什么是分組查詢?在實際的應用中,可能有這樣的需求,需要先進行分組,然后對每一組的數據進行操作。這個時候我們需要使用分組查詢,怎么進行分組查詢呢?select...from...group by...計算每個部門的工資和?計算每個工作崗位的平均薪資?找出每個工作崗位的最高薪資?....19.2、將之前的關鍵字全部組合在一起,來看一下他們的執行順序?select...from...where...group by...order by...以上關鍵字的順序不能顛倒,需要記憶。執行順序是什么?1. from2. where3. group by4. select5. order by為什么分組函數不能直接使用在where后面?select ename,sal from emp where sal > min(sal);//報錯。因為分組函數在使用的時候必須先分組之后才能使用。where執行的時候,還沒有分組。所以where后面不能出現分組函數。select sum(sal) from emp; 這個沒有分組,為啥sum()函數可以用呢?因為select在group by之后執行。19.3、找出每個工作崗位的工資和?實現思路:按照工作崗位分組,然后對工資求和。select job,sum(sal)fromempgroup byjob;+-----------+----------+| job | sum(sal) |+-----------+----------+| ANALYST | 6000.00 || CLERK | 4150.00 || MANAGER | 8275.00 || PRESIDENT | 5000.00 || SALESMAN | 5600.00 |+-----------+----------+以上這個語句的執行順序?先從emp表中查詢數據。根據job字段進行分組。然后對每一組的數據進行sum(sal)select ename,job,sum(sal) from emp group by job;+-------+-----------+----------+| ename | job | sum(sal) |+-------+-----------+----------+| SCOTT | ANALYST | 6000.00 || SMITH | CLERK | 4150.00 || JONES | MANAGER | 8275.00 || KING | PRESIDENT | 5000.00 || ALLEN | SALESMAN | 5600.00 |+-------+-----------+----------+以上語句在mysql中可以執行,但是毫無意義。以上語句在oracle中執行報錯。oracle的語法比mysql的語法嚴格。(mysql的語法相對來說松散一些!)重點結論:在一條select語句當中,如果有group by語句的話,select后面只能跟:參加分組的字段,以及分組函數。其它的一律不能跟。19.4、找出每個部門的最高薪資實現思路是什么?按照部門編號分組,求每一組的最大值。select后面添加ename字段沒有意義,另外oracle會報錯。mysql> select ename,deptno,max(sal) from emp group by deptno;+-------+--------+----------+| ename | deptno | max(sal) |+-------+--------+----------+| CLARK | 10 | 5000.00 || SMITH | 20 | 3000.00 || ALLEN | 30 | 2850.00 |+-------+--------+----------+mysql> select deptno,max(sal) from emp group by deptno;+--------+----------+| deptno | max(sal) |+--------+----------+| 10 | 5000.00 || 20 | 3000.00 || 30 | 2850.00 |+--------+----------+19.5、找出“每個部門,不同工作崗位”的最高薪資?+--------+-----------+---------+--------+| ename | job | sal | deptno |+--------+-----------+---------+--------+| MILLER | CLERK | 1300.00 | 10 || KING | PRESIDENT | 5000.00 | 10 || CLARK | MANAGER | 2450.00 | 10 || FORD | ANALYST | 3000.00 | 20 || ADAMS | CLERK | 1100.00 | 20 || SCOTT | ANALYST | 3000.00 | 20 || JONES | MANAGER | 2975.00 | 20 || SMITH | CLERK | 800.00 | 20 || BLAKE | MANAGER | 2850.00 | 30 || MARTIN | SALESMAN | 1250.00 | 30 || ALLEN | SALESMAN | 1600.00 | 30 || TURNER | SALESMAN | 1500.00 | 30 || WARD | SALESMAN | 1250.00 | 30 || JAMES | CLERK | 950.00 | 30 |+--------+-----------+---------+--------+技巧:兩個字段聯合成1個字段看。(兩個字段聯合分組)select deptno, job, max(sal)fromempgroup bydeptno, job;+--------+-----------+----------+| deptno | job | max(sal) |+--------+-----------+----------+| 10 | CLERK | 1300.00 || 10 | MANAGER | 2450.00 || 10 | PRESIDENT | 5000.00 || 20 | ANALYST | 3000.00 || 20 | CLERK | 1100.00 || 20 | MANAGER | 2975.00 || 30 | CLERK | 950.00 || 30 | MANAGER | 2850.00 || 30 | SALESMAN | 1600.00 |+--------+-----------+----------+19.6、使用having可以對分完組之后的數據進一步過濾。 having不能單獨使用,having不能代替where,having必須 和group by聯合使用。找出每個部門最高薪資,要求顯示最高薪資大于3000的?第一步:找出每個部門最高薪資按照部門編號分組,求每一組最大值。select deptno,max(sal) from emp group by deptno;+--------+----------+| deptno | max(sal) |+--------+----------+| 10 | 5000.00 || 20 | 3000.00 || 30 | 2850.00 |+--------+----------+第二步:要求顯示最高薪資大于3000select deptno,max(sal) from emp group by deptnohavingmax(sal) > 3000;+--------+----------+| deptno | max(sal) |+--------+----------+| 10 | 5000.00 |+--------+----------+思考一個問題:以上的sql語句執行效率是不是低?比較低,實際上可以這樣考慮:先將大于3000的都找出來,然后再分組。select deptno,max(sal)fromempwheresal > 3000group bydeptno;+--------+----------+| deptno | max(sal) |+--------+----------+| 10 | 5000.00 |+--------+----------+優化策略:where和having,優先選擇where,where實在完成不了了,再選擇having。19.7、where沒辦法的????找出每個部門平均薪資,要求顯示平均薪資高于2500的。第一步:找出每個部門平均薪資select deptno,avg(sal) from emp group by deptno;+--------+-------------+| deptno | avg(sal) |+--------+-------------+| 10 | 2916.666667 || 20 | 2175.000000 || 30 | 1566.666667 |+--------+-------------+第二步:要求顯示平均薪資高于2500的select deptno,avg(sal) from emp group by deptnohavingavg(sal) > 2500;+--------+-------------+| deptno | avg(sal) |+--------+-------------+| 10 | 2916.666667 |+--------+-------------+

20、大總結(單表的查詢學完了)
select

from

where

group by

having

order by

以上關鍵字只能按照這個順序來,不能顛倒。執行順序?1. from2. where3. group by4. having5. select6. order by從某張表中查詢數據, 先經過where條件篩選出有價值的數據。 對這些有價值的數據進行分組。 分組之后可以使用having繼續篩選。 select查詢出來。 最后排序輸出!找出每個崗位的平均薪資,要求顯示平均薪資大于1500的,除MANAGER崗位之外, 要求按照平均薪資降序排。select job, avg(sal) as avgsalfromempwherejob <> 'MANAGER'group byjobhavingavg(sal) > 1500order byavgsal desc;+-----------+-------------+| job | avgsal |+-----------+-------------+| PRESIDENT | 5000.000000 || ANALYST | 3000.000000 |+-----------+-------------+

Second day
mysql day02課堂筆記

1、把查詢結果去除重復記錄【distinct】
注意:原表數據不會被修改,只是查詢結果去重。
去重需要使用一個關鍵字:distinct

mysql> select distinct job from emp; +-----------+ | job | +-----------+ | CLERK | | SALESMAN | | MANAGER | | ANALYST | | PRESIDENT | +-----------+// 這樣編寫是錯誤的,語法錯誤。 // distinct只能出現在所有字段的最前方。 mysql> select ename,distinct job from emp;// distinct出現在job,deptno兩個字段之前,表示兩個字段聯合起來去重。 mysql> select distinct job,deptno from emp; +-----------+--------+ | job | deptno | +-----------+--------+ | CLERK | 20 | | SALESMAN | 30 | | MANAGER | 20 | | MANAGER | 30 | | MANAGER | 10 | | ANALYST | 20 | | PRESIDENT | 10 | | CLERK | 30 | | CLERK | 10 | +-----------+--------+統計一下工作崗位的數量?select count(distinct job) from emp;+---------------------+| count(distinct job) |+---------------------+| 5 |+---------------------+

2、連接查詢

2.1、什么是連接查詢?
從一張表中單獨查詢,稱為單表查詢。
emp表和dept表聯合起來查詢數據,從emp表中取員工名字,從dept表中取部門名字。
這種跨表查詢,多張表聯合起來查詢數據,被稱為連接查詢。

2.2、連接查詢的分類?

根據語法的年代分類:SQL92:1992年的時候出現的語法SQL99:1999年的時候出現的語法我們這里重點學習SQL99.(這個過程中簡單演示一個SQL92的例子)根據表連接的方式分類:內連接:等值連接非等值連接自連接外連接:左外連接(左連接)右外連接(右連接)全連接(不講)

2.3、當兩張表進行連接查詢時,沒有任何條件的限制會發生什么現象?

案例:查詢每個員工所在部門名稱?mysql> select ename,deptno from emp;+--------+--------+| ename | deptno |+--------+--------+| SMITH | 20 || ALLEN | 30 || WARD | 30 || JONES | 20 || MARTIN | 30 || BLAKE | 30 || CLARK | 10 || SCOTT | 20 || KING | 10 || TURNER | 30 || ADAMS | 20 || JAMES | 30 || FORD | 20 || MILLER | 10 |+--------+--------+mysql> select * from dept;+--------+------------+----------+| DEPTNO | DNAME | LOC |+--------+------------+----------+| 10 | ACCOUNTING | NEW YORK || 20 | RESEARCH | DALLAS || 30 | SALES | CHICAGO || 40 | OPERATIONS | BOSTON |+--------+------------+----------+兩張表連接沒有任何條件限制:select ename,dname from emp, dept;+--------+------------+| ename | dname |+--------+------------+| SMITH | ACCOUNTING || SMITH | RESEARCH || SMITH | SALES || SMITH | OPERATIONS || ALLEN | ACCOUNTING || ALLEN | RESEARCH || ALLEN | SALES || ALLEN | OPERATIONS |...56 rows in set (0.00 sec)14 * 4 = 56當兩張表進行連接查詢,沒有任何條件限制的時候,最終查詢結果條數,是兩張表條數的乘積,這種現象被稱為:笛卡爾積現象。(笛卡爾發現的,這是一個數學現象。)

2.4、怎么避免笛卡爾積現象?
連接時加條件,滿足這個條件的記錄被篩選出來!
select
ename,dname
from
emp, dept
where
emp.deptno = dept.deptno;

select emp.ename,dept.dname from emp, dept whereemp.deptno = dept.deptno;// 表起別名。很重要。效率問題。 select e.ename,d.dname from emp e, dept d wheree.deptno = d.deptno; //SQL92語法。+--------+------------+ | ename | dname | +--------+------------+ | CLARK | ACCOUNTING | | KING | ACCOUNTING | | MILLER | ACCOUNTING | | SMITH | RESEARCH | | JONES | RESEARCH | | SCOTT | RESEARCH | | ADAMS | RESEARCH | | FORD | RESEARCH | | ALLEN | SALES | | WARD | SALES | | MARTIN | SALES | | BLAKE | SALES | | TURNER | SALES | | JAMES | SALES | +--------+------------+思考:最終查詢的結果條數是14條,但是匹配的過程中,匹配的次數減少了嗎?還是56次,只不過進行了四選一。次數沒有減少。注意:通過笛卡爾積現象得出,表的連接次數越多效率越低,盡量避免表的 連接次數。

2.5、內連接之等值連接。

案例:查詢每個員工所在部門名稱,顯示員工名和部門名?
emp e和dept d表進行連接。條件是:e.deptno = d.deptno

SQL92語法:
select
e.ename,d.dname
from
emp e, dept d
where
e.deptno = d.deptno;

sql92的缺點:結構不清晰,表的連接條件,和后期進一步篩選的條件,都放到了where后面。

SQL99語法:
select
e.ename,d.dname
from
emp e
join
dept d
on
e.deptno = d.deptno;

//inner可以省略(帶著inner可讀性更好!!!一眼就能看出來是內連接) select e.ename,d.dname fromemp e inner joindept d one.deptno = d.deptno; // 條件是等量關系,所以被稱為等值連接。sql99優點:表連接的條件是獨立的,連接之后,如果還需要進一步篩選,再往后繼續添加whereSQL99語法:select ...fromajoinbona和b的連接條件where篩選條件

2.6、內連接之非等值連接

案例:找出每個員工的薪資等級,要求顯示員工名、薪資、薪資等級?
mysql> select * from emp; e
±------±-------±----------±-----±-----------±--------±--------±-------+
| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
±------±-------±----------±-----±-----------±--------±--------±-------+
| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 |
| 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 |
| 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 |
| 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 |

mysql> select * from salgrade; s
±------±------±------+
| GRADE | LOSAL | HISAL |
±------±------±------+
| 1 | 700 | 1200 |
| 2 | 1201 | 1400 |
| 3 | 1401 | 2000 |
| 4 | 2001 | 3000 |
| 5 | 3001 | 9999 |
±------±------±------+

select
e.ename, e.sal, s.grade
from
emp e
join
salgrade s
on
e.sal between s.losal and s.hisal; // 條件不是一個等量關系,稱為非等值連接。

select
e.ename, e.sal, s.grade
from
emp e
inner join
salgrade s
on
e.sal between s.losal and s.hisal;

±-------±--------±------+
| ename | sal | grade |
±-------±--------±------+
| SMITH | 800.00 | 1 |
| ALLEN | 1600.00 | 3 |
| WARD | 1250.00 | 2 |
| JONES | 2975.00 | 4 |
| MARTIN | 1250.00 | 2 |
| BLAKE | 2850.00 | 4 |
| CLARK | 2450.00 | 4 |
| SCOTT | 3000.00 | 4 |
| KING | 5000.00 | 5 |
| TURNER | 1500.00 | 3 |
| ADAMS | 1100.00 | 1 |
| JAMES | 950.00 | 1 |
| FORD | 3000.00 | 4 |
| MILLER | 1300.00 | 2 |
±-------±--------±------+

2.7、內連接之自連接
案例:查詢員工的上級領導,要求顯示員工名和對應的領導名?

mysql> select empno,ename,mgr from emp;
±------±-------±-----+
| empno | ename | mgr |
±------±-------±-----+
| 7369 | SMITH | 7902 |
| 7499 | ALLEN | 7698 |
| 7521 | WARD | 7698 |
| 7566 | JONES | 7839 |
| 7654 | MARTIN | 7698 |
| 7698 | BLAKE | 7839 |
| 7782 | CLARK | 7839 |
| 7788 | SCOTT | 7566 |
| 7839 | KING | NULL |
| 7844 | TURNER | 7698 |
| 7876 | ADAMS | 7788 |
| 7900 | JAMES | 7698 |
| 7902 | FORD | 7566 |
| 7934 | MILLER | 7782 |
±------±-------±-----+

技巧:一張表看成兩張表。
emp a 員工表
±------±-------±-----+
| empno | ename | mgr |
±------±-------±-----+
| 7369 | SMITH | 7902 |
| 7499 | ALLEN | 7698 |
| 7521 | WARD | 7698 |
| 7566 | JONES | 7839 |
| 7654 | MARTIN | 7698 |
| 7698 | BLAKE | 7839 |
| 7782 | CLARK | 7839 |
| 7788 | SCOTT | 7566 |
| 7839 | KING | NULL |
| 7844 | TURNER | 7698 |
| 7876 | ADAMS | 7788 |
| 7900 | JAMES | 7698 |
| 7902 | FORD | 7566 |
| 7934 | MILLER | 7782 |
±------±-------±-----+

emp b 領導表
±------±-------±-----+
| empno | ename | mgr |
±------±-------±-----+
| 7369 | SMITH | 7902 |
| 7499 | ALLEN | 7698 |
| 7521 | WARD | 7698 |
| 7566 | JONES | 7839 |
| 7654 | MARTIN | 7698 |
| 7698 | BLAKE | 7839 |
| 7782 | CLARK | 7839 |
| 7788 | SCOTT | 7566 |
| 7839 | KING | NULL |
| 7844 | TURNER | 7698 |
| 7876 | ADAMS | 7788 |
| 7900 | JAMES | 7698 |
| 7902 | FORD | 7566 |
| 7934 | MILLER | 7782 |
±------±-------±-----+

select
a.ename as ‘員工名’, b.ename as ‘領導名’
from
emp a
join
emp b
on
a.mgr = b.empno; //員工的領導編號 = 領導的員工編號

±-------±-------+
| 員工名 | 領導名|
±-------±-------+
| SMITH | FORD |
| ALLEN | BLAKE |
| WARD | BLAKE |
| JONES | KING |
| MARTIN | BLAKE |
| BLAKE | KING |
| CLARK | KING |
| SCOTT | JONES |
| TURNER | BLAKE |
| ADAMS | SCOTT |
| JAMES | BLAKE |
| FORD | JONES |
| MILLER | CLARK |
±-------±-------+
13條記錄,沒有KING。《內連接》

以上就是內連接中的:自連接,技巧:一張表看做兩張表。

2.8、外連接

mysql> select * from emp; e
±------±-------±----------±-----±-----------±--------±--------±-------+
| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
±------±-------±----------±-----±-----------±--------±--------±-------+
| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 |
| 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 |
| 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 |
| 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 |
| 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 |
| 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 |
| 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 |
| 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 |
| 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 |
| 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 |
| 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | NULL | 20 |
| 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | NULL | 30 |
| 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 |
| 7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1300.00 | NULL | 10 |
±------±-------±----------±-----±-----------±--------±--------±-------+

mysql> select * from dept; d
±-------±-----------±---------+
| DEPTNO | DNAME | LOC |
±-------±-----------±---------+
| 10 | ACCOUNTING | NEW YORK |
| 20 | RESEARCH | DALLAS |
| 30 | SALES | CHICAGO |
| 40 | OPERATIONS | BOSTON |
±-------±-----------±---------+

內連接:(A和B連接,AB兩張表沒有主次關系。平等的。)
select
e.ename,d.dname
from
emp e
join
dept d
on
e.deptno = d.deptno; //內連接的特點:完成能夠匹配上這個條件的數據查詢出來。

±-------±-----------+
| ename | dname |
±-------±-----------+
| CLARK | ACCOUNTING |
| KING | ACCOUNTING |
| MILLER | ACCOUNTING |
| SMITH | RESEARCH |
| JONES | RESEARCH |
| SCOTT | RESEARCH |
| ADAMS | RESEARCH |
| FORD | RESEARCH |
| ALLEN | SALES |
| WARD | SALES |
| MARTIN | SALES |
| BLAKE | SALES |
| TURNER | SALES |
| JAMES | SALES |
±-------±-----------+

外連接(右外連接):
select
e.ename,d.dname
from
emp e
right join
dept d
on
e.deptno = d.deptno;

// outer是可以省略的,帶著可讀性強。
select
e.ename,d.dname
from
emp e
right outer join
dept d
on
e.deptno = d.deptno;

right代表什么:表示將join關鍵字右邊的這張表看成主表,主要是為了將
這張表的數據全部查詢出來,捎帶著關聯查詢左邊的表。
在外連接當中,兩張表連接,產生了主次關系。

外連接(左外連接):
select
e.ename,d.dname
from
dept d
left join
emp e
on
e.deptno = d.deptno;

// outer是可以省略的,帶著可讀性強。
select
e.ename,d.dname
from
dept d
left outer join
emp e
on
e.deptno = d.deptno;

帶有right的是右外連接,又叫做右連接。
帶有left的是左外連接,又叫做左連接。
任何一個右連接都有左連接的寫法。
任何一個左連接都有右連接的寫法。

±-------±-----------+
| ename | dname |
±-------±-----------+
| CLARK | ACCOUNTING |
| KING | ACCOUNTING |
| MILLER | ACCOUNTING |
| SMITH | RESEARCH |
| JONES | RESEARCH |
| SCOTT | RESEARCH |
| ADAMS | RESEARCH |
| FORD | RESEARCH |
| ALLEN | SALES |
| WARD | SALES |
| MARTIN | SALES |
| BLAKE | SALES |
| TURNER | SALES |
| JAMES | SALES |
| NULL | OPERATIONS |
±-------±-----------+

思考:外連接的查詢結果條數一定是 >= 內連接的查詢結果條數?
正確。

案例:查詢每個員工的上級領導,要求顯示所有員工的名字和領導名?
select
a.ename as ‘員工名’, b.ename as ‘領導名’
from
emp a
left join
emp b
on
a.mgr = b.empno;

+--------+--------+ | 員工名 | 領導名 | +--------+--------+ | SMITH | FORD | | ALLEN | BLAKE | | WARD | BLAKE | | JONES | KING | | MARTIN | BLAKE | | BLAKE | KING | | CLARK | KING | | SCOTT | JONES | | KING | NULL | | TURNER | BLAKE | | ADAMS | SCOTT | | JAMES | BLAKE | | FORD | JONES | | MILLER | CLARK | +--------+--------+

2.9、三張表,四張表怎么連接?
語法:
select

from
a
join
b
on
a和b的連接條件
join
c
on
a和c的連接條件
right join
d
on
a和d的連接條件

一條SQL中內連接和外連接可以混合。都可以出現!案例:找出每個員工的部門名稱以及工資等級, 要求顯示員工名、部門名、薪資、薪資等級?select e.ename,e.sal,d.dname,s.grade fromemp e joindept d on e.deptno = d.deptno joinsalgrade s one.sal between s.losal and s.hisal;+--------+---------+------------+-------+ | ename | sal | dname | grade | +--------+---------+------------+-------+ | SMITH | 800.00 | RESEARCH | 1 | | ALLEN | 1600.00 | SALES | 3 | | WARD | 1250.00 | SALES | 2 | | JONES | 2975.00 | RESEARCH | 4 | | MARTIN | 1250.00 | SALES | 2 | | BLAKE | 2850.00 | SALES | 4 | | CLARK | 2450.00 | ACCOUNTING | 4 | | SCOTT | 3000.00 | RESEARCH | 4 | | KING | 5000.00 | ACCOUNTING | 5 | | TURNER | 1500.00 | SALES | 3 | | ADAMS | 1100.00 | RESEARCH | 1 | | JAMES | 950.00 | SALES | 1 | | FORD | 3000.00 | RESEARCH | 4 | | MILLER | 1300.00 | ACCOUNTING | 2 | +--------+---------+------------+-------+案例:找出每個員工的部門名稱以及工資等級,還有上級領導, 要求顯示員工名、領導名、部門名、薪資、薪資等級?select e.ename,e.sal,d.dname,s.grade,l.ename fromemp e joindept d on e.deptno = d.deptno joinsalgrade s one.sal between s.losal and s.hisal left joinemp l one.mgr = l.empno;+--------+---------+------------+-------+-------+ | ename | sal | dname | grade | ename | +--------+---------+------------+-------+-------+ | SMITH | 800.00 | RESEARCH | 1 | FORD | | ALLEN | 1600.00 | SALES | 3 | BLAKE | | WARD | 1250.00 | SALES | 2 | BLAKE | | JONES | 2975.00 | RESEARCH | 4 | KING | | MARTIN | 1250.00 | SALES | 2 | BLAKE | | BLAKE | 2850.00 | SALES | 4 | KING | | CLARK | 2450.00 | ACCOUNTING | 4 | KING | | SCOTT | 3000.00 | RESEARCH | 4 | JONES | | KING | 5000.00 | ACCOUNTING | 5 | NULL | | TURNER | 1500.00 | SALES | 3 | BLAKE | | ADAMS | 1100.00 | RESEARCH | 1 | SCOTT | | JAMES | 950.00 | SALES | 1 | BLAKE | | FORD | 3000.00 | RESEARCH | 4 | JONES | | MILLER | 1300.00 | ACCOUNTING | 2 | CLARK | +--------+---------+------------+-------+-------+

3、子查詢?

3.1、什么是子查詢?
select語句中嵌套select語句,被嵌套的select語句稱為子查詢。

3.2、子查詢都可以出現在哪里呢?
select
…(select).
from
…(select).
where
…(select).

3.3、where子句中的子查詢

案例:找出比最低工資高的員工姓名和工資?select ename,salfromemp wheresal > min(sal);ERROR 1111 (HY000): Invalid use of group functionwhere子句中不能直接使用分組函數。實現思路:第一步:查詢最低工資是多少select min(sal) from emp;+----------+| min(sal) |+----------+| 800.00 |+----------+第二步:找出>800的select ename,sal from emp where sal > 800;第三步:合并select ename,sal from emp where sal > (select min(sal) from emp);+--------+---------+| ename | sal |+--------+---------+| ALLEN | 1600.00 || WARD | 1250.00 || JONES | 2975.00 || MARTIN | 1250.00 || BLAKE | 2850.00 || CLARK | 2450.00 || SCOTT | 3000.00 || KING | 5000.00 || TURNER | 1500.00 || ADAMS | 1100.00 || JAMES | 950.00 || FORD | 3000.00 || MILLER | 1300.00 |+--------+---------+

3.4、from子句中的子查詢
注意:from后面的子查詢,可以將子查詢的查詢結果當做一張臨時表。(技巧)

案例:找出每個崗位的平均工資的薪資等級。第一步:找出每個崗位的平均工資(按照崗位分組求平均值)select job,avg(sal) from emp group by job;+-----------+-------------+| job | avgsal |+-----------+-------------+| ANALYST | 3000.000000 || CLERK | 1037.500000 || MANAGER | 2758.333333 || PRESIDENT | 5000.000000 || SALESMAN | 1400.000000 |+-----------+-------------+t表第二步:克服心理障礙,把以上的查詢結果就當做一張真實存在的表t。 mysql> select * from salgrade; s表 +-------+-------+-------+ | GRADE | LOSAL | HISAL | +-------+-------+-------+ | 1 | 700 | 1200 | | 2 | 1201 | 1400 | | 3 | 1401 | 2000 | | 4 | 2001 | 3000 | | 5 | 3001 | 9999 | +-------+-------+-------+ t表和s表進行表連接,條件:t表avg(sal) between s.losal and s.hisal;select t.*, s.gradefrom(select job,avg(sal) as avgsal from emp group by job) tjoinsalgrade sont.avgsal between s.losal and s.hisal;+-----------+-------------+-------+| job | avgsal | grade |+-----------+-------------+-------+| CLERK | 1037.500000 | 1 || SALESMAN | 1400.000000 | 2 || ANALYST | 3000.000000 | 4 || MANAGER | 2758.333333 | 4 || PRESIDENT | 5000.000000 | 5 |+-----------+-------------+-------+

3.5、select后面出現的子查詢(這個內容不需要掌握,了解即可!!!)

案例:找出每個員工的部門名稱,要求顯示員工名,部門名?
select
e.ename,e.deptno,(select d.dname from dept d where e.deptno = d.deptno) as dname
from
emp e;

+--------+--------+------------+ | ename | deptno | dname | +--------+--------+------------+ | SMITH | 20 | RESEARCH | | ALLEN | 30 | SALES | | WARD | 30 | SALES | | JONES | 20 | RESEARCH | | MARTIN | 30 | SALES | | BLAKE | 30 | SALES | | CLARK | 10 | ACCOUNTING | | SCOTT | 20 | RESEARCH | | KING | 10 | ACCOUNTING | | TURNER | 30 | SALES | | ADAMS | 20 | RESEARCH | | JAMES | 30 | SALES | | FORD | 20 | RESEARCH | | MILLER | 10 | ACCOUNTING | +--------+--------+------------+//錯誤:ERROR 1242 (21000): Subquery returns more than 1 row select e.ename,e.deptno,(select dname from dept) as dname fromemp e;注意:對于select后面的子查詢來說,這個子查詢只能一次返回1條結果, 多于1條,就報錯了。!

4、union合并查詢結果集

案例:查詢工作崗位是MANAGER和SALESMAN的員工?
select ename,job from emp where job = ‘MANAGER’ or job = ‘SALESMAN’;
select ename,job from emp where job in(‘MANAGER’,‘SALESMAN’);
±-------±---------+
| ename | job |
±-------±---------+
| ALLEN | SALESMAN |
| WARD | SALESMAN |
| JONES | MANAGER |
| MARTIN | SALESMAN |
| BLAKE | MANAGER |
| CLARK | MANAGER |
| TURNER | SALESMAN |
±-------±---------+

select ename,job from emp where job = 'MANAGER' union select ename,job from emp where job = 'SALESMAN';+--------+----------+ | ename | job | +--------+----------+ | JONES | MANAGER | | BLAKE | MANAGER | | CLARK | MANAGER | | ALLEN | SALESMAN | | WARD | SALESMAN | | MARTIN | SALESMAN | | TURNER | SALESMAN | +--------+----------+union的效率要高一些。對于表連接來說,每連接一次新表, 則匹配的次數滿足笛卡爾積,成倍的翻。。。 但是union可以減少匹配的次數。在減少匹配次數的情況下, 還可以完成兩個結果集的拼接。a 連接 b 連接 c a 10條記錄 b 10條記錄 c 10條記錄 匹配次數是:1000a 連接 b一個結果:10 * 10 --> 100次 a 連接 c一個結果:10 * 10 --> 100次 使用union的話是:100次 + 100次 = 200次。(union把乘法變成了加法運算)

union在使用的時候有注意事項嗎?

//錯誤的:union在進行結果集合并的時候,要求兩個結果集的列數相同。 select ename,job from emp where job = 'MANAGER' union select ename from emp where job = 'SALESMAN';// MYSQL可以,oracle語法嚴格 ,不可以,報錯。要求:結果集合并時列和列的數據類型也要一致。 select ename,job from emp where job = 'MANAGER' union select ename,sal from emp where job = 'SALESMAN'; +--------+---------+ | ename | job | +--------+---------+ | JONES | MANAGER | | BLAKE | MANAGER | | CLARK | MANAGER | | ALLEN | 1600 | | WARD | 1250 | | MARTIN | 1250 | | TURNER | 1500 | +--------+---------+

5、limit(非常重要)

5.1、limit作用:將查詢結果集的一部分取出來。通常使用在分頁查詢當中。
百度默認:一頁顯示10條記錄。
分頁的作用是為了提高用戶的體驗,因為一次全部都查出來,用戶體驗差。
可以一頁一頁翻頁看。

5.2、limit怎么用呢?

完整用法:limit startIndex, lengthstartIndex是起始下標,length是長度。起始下標從0開始。缺省用法:limit 5; 這是取前5.按照薪資降序,取出排名在前5名的員工? select ename,sal fromemp order by sal desc limit 5; //取前5select ename,sal fromemp order by sal desc limit 0,5;+-------+---------+ | ename | sal | +-------+---------+ | KING | 5000.00 | | SCOTT | 3000.00 | | FORD | 3000.00 | | JONES | 2975.00 | | BLAKE | 2850.00 | +-------+---------+

5.3、注意:mysql當中limit在order by之后執行!!!!!!

5.4、取出工資排名在[3-5]名的員工?
select
ename,sal
from
emp
order by
sal desc
limit
2, 3;

2表示起始位置從下標2開始,就是第三條記錄。 3表示長度。+-------+---------+ | ename | sal | +-------+---------+ | FORD | 3000.00 | | JONES | 2975.00 | | BLAKE | 2850.00 | +-------+---------+

5.5、取出工資排名在[5-9]名的員工?
select
ename,sal
from
emp
order by
sal desc
limit
4, 5;

+--------+---------+ | ename | sal | +--------+---------+ | BLAKE | 2850.00 | | CLARK | 2450.00 | | ALLEN | 1600.00 | | TURNER | 1500.00 | | MILLER | 1300.00 | +--------+---------+

5.6、分頁

每頁顯示3條記錄
第1頁:limit 0,3 [0 1 2]
第2頁:limit 3,3 [3 4 5]
第3頁:limit 6,3 [6 7 8]
第4頁:limit 9,3 [9 10 11]

每頁顯示pageSize條記錄
第pageNo頁:limit (pageNo - 1) * pageSize , pageSize

public static void main(String[] args){// 用戶提交過來一個頁碼,以及每頁顯示的記錄條數int pageNo = 5; //第5頁int pageSize = 10; //每頁顯示10條int startIndex = (pageNo - 1) * pageSize;String sql = "select ...limit " + startIndex + ", " + pageSize; }

記公式:
limit (pageNo-1)*pageSize , pageSize

6、關于DQL語句的大總結:
select

from

where

group by

having

order by

limit

執行順序?1.from2.where3.group by4.having5.select6.order by7.limit..

7、表的創建(建表)

7.1、建表的語法格式:(建表屬于DDL語句,DDL包括:create drop alter)

create table 表名(字段名1 數據類型, 字段名2 數據類型, 字段名3 數據類型);create table 表名(字段名1 數據類型, 字段名2 數據類型, 字段名3 數據類型 );表名:建議以t_ 或者 tbl_開始,可讀性強。見名知意。 字段名:見名知意。 表名和字段名都屬于標識符。

7.2、關于mysql中的數據類型?

很多數據類型,我們只需要掌握一些常見的數據類型即可。varchar(最長255)可變長度的字符串比較智能,節省空間。會根據實際的數據長度動態分配空間。優點:節省空間缺點:需要動態分配空間,速度慢。char(最長255)定長字符串不管實際的數據長度是多少。分配固定長度的空間去存儲數據。使用不恰當的時候,可能會導致空間的浪費。優點:不需要動態分配空間,速度快。缺點:使用不當可能會導致空間的浪費。varchar和char我們應該怎么選擇?性別字段你選什么?因為性別是固定長度的字符串,所以選擇char。姓名字段你選什么?每一個人的名字長度不同,所以選擇varchar。int(最長11)數字中的整數型。等同于java的int。bigint數字中的長整型。等同于java中的long。float 單精度浮點型數據double雙精度浮點型數據date短日期類型datetime長日期類型clob字符大對象最多可以存儲4G的字符串。比如:存儲一篇文章,存儲一個說明。超過255個字符的都要采用CLOB字符大對象來存儲。Character Large OBject:CLOBblob二進制大對象Binary Large OBject專門用來存儲圖片、聲音、視頻等流媒體數據。往BLOB類型的字段上插入數據的時候,例如插入一個圖片、視頻等,你需要使用IO流才行。t_movie 電影表(專門存儲電影信息的)編號 名字 故事情節 上映日期 時長 海報 類型 no(bigint) name(varchar) history(clob) playtime(date) time(double) image(blob) type(char) ------------------------------------------------------------------------------------------------------------------ 10000 哪吒 ........... 2019-10-11 2.5 .... '1' 10001 林正英之娘娘 ........... 2019-11-11 1.5 .... '2' ....

7.3、創建一個學生表?
學號、姓名、年齡、性別、郵箱地址
create table t_student(
no int,
name varchar(32),
sex char(1),
age int(3),
email varchar(255)
);

刪除表:drop table t_student; // 當這張表不存在的時候會報錯!// 如果這張表存在的話,刪除drop table if exists t_student;

7.4、插入數據insert (DML)

語法格式:insert into 表名(字段名1,字段名2,字段名3...) values(值1,值2,值3);注意:字段名和值要一一對應。什么是一一對應?數量要對應。數據類型要對應。insert into t_student(no,name,sex,age,email) values(1,'zhangsan','m',20,'zhangsan@123.com'); insert into t_student(email,name,sex,age,no) values('lisi@123.com','lisi','f',20,2);insert into t_student(no) values(3);+------+----------+------+------+------------------+ | no | name | sex | age | email | +------+----------+------+------+------------------+ | 1 | zhangsan | m | 20 | zhangsan@123.com | | 2 | lisi | f | 20 | lisi@123.com | | 3 | NULL | NULL | NULL | NULL | +------+----------+------+------+------------------+ insert into t_student(name) values('wangwu'); +------+----------+------+------+------------------+ | no | name | sex | age | email | +------+----------+------+------+------------------+ | 1 | zhangsan | m | 20 | zhangsan@123.com | | 2 | lisi | f | 20 | lisi@123.com | | 3 | NULL | NULL | NULL | NULL | | NULL | wangwu | NULL | NULL | NULL | +------+----------+------+------+------------------+ 注意:insert語句但凡是執行成功了,那么必然會多一條記錄。 沒有給其它字段指定值的話,默認值是NULL。drop table if exists t_student; create table t_student(no int,name varchar(32),sex char(1) default 'm',age int(3),email varchar(255) );+-------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+--------------+------+-----+---------+-------+ | no | int(11) | YES | | NULL | | | name | varchar(32) | YES | | NULL | | | sex | char(1) | YES | | m | | | age | int(3) | YES | | NULL | | | email | varchar(255) | YES | | NULL | | +-------+--------------+------+-----+---------+-------+ insert into t_student(no) values(1); mysql> select * from t_student; +------+------+------+------+-------+ | no | name | sex | age | email | +------+------+------+------+-------+ | 1 | NULL | m | NULL | NULL | +------+------+------+------+-------+insert語句中的“字段名”可以省略嗎?可以insert into t_student values(2); //錯誤的// 注意:前面的字段名省略的話,等于都寫上了!所以值也要都寫上!insert into t_student values(2, 'lisi', 'f', 20, 'lisi@123.com');+------+------+------+------+--------------+| no | name | sex | age | email |+------+------+------+------+--------------+| 1 | NULL | m | NULL | NULL || 2 | lisi | f | 20 | lisi@123.com |+------+------+------+------+--------------+

7.5、insert插入日期

數字格式化:formatselect ename,sal from emp;+--------+---------+| ename | sal |+--------+---------+| SMITH | 800.00 || ALLEN | 1600.00 || WARD | 1250.00 || JONES | 2975.00 || MARTIN | 1250.00 || BLAKE | 2850.00 || CLARK | 2450.00 || SCOTT | 3000.00 || KING | 5000.00 || TURNER | 1500.00 || ADAMS | 1100.00 || JAMES | 950.00 || FORD | 3000.00 || MILLER | 1300.00 |+--------+---------+格式化數字:format(數字, '格式')select ename,format(sal, '$999,999') as sal from emp;+--------+-------+| ename | sal |+--------+-------+| SMITH | 800 || ALLEN | 1,600 || WARD | 1,250 || JONES | 2,975 || MARTIN | 1,250 || BLAKE | 2,850 || CLARK | 2,450 || SCOTT | 3,000 || KING | 5,000 || TURNER | 1,500 || ADAMS | 1,100 || JAMES | 950 || FORD | 3,000 || MILLER | 1,300 |+--------+-------+str_to_date:將字符串varchar類型轉換成date類型 date_format:將date類型轉換成具有一定格式的varchar字符串類型。drop table if exists t_user; create table t_user(id int,name varchar(32),birth date // 生日也可以使用date日期類型 );create table t_user(id int,name varchar(32),birth char(10) // 生日可以使用字符串,沒問題。 );生日:1990-10-11 (10個字符)注意:數據庫中的有一條命名規范:所有的標識符都是全部小寫,單詞和單詞之間使用下劃線進行銜接。mysql> desc t_user; +-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | id | int(11) | YES | | NULL | | | name | varchar(32) | YES | | NULL | | | birth | date | YES | | NULL | | +-------+-------------+------+-----+---------+-------+插入數據?insert into t_user(id,name,birth) values(1, 'zhangsan', '01-10-1990'); // 1990年10月1日出問題了:原因是類型不匹配。數據庫birth是date類型,這里給了一個字符串varchar。怎么辦?可以使用str_to_date函數進行類型轉換。str_to_date函數可以將字符串轉換成日期類型date?語法格式:str_to_date('字符串日期', '日期格式')mysql的日期格式:%Y 年%m 月%d 日%h 時%i 分%s 秒insert into t_user(id,name,birth) values(1, 'zhangsan', str_to_date('01-10-1990','%d-%m-%Y'));str_to_date函數可以把字符串varchar轉換成日期date類型數據,通常使用在插入insert方面,因為插入的時候需要一個日期類型的數據,需要通過該函數將字符串轉換成date。好消息?如果你提供的日期字符串是這個格式,str_to_date函數就不需要了!!!%Y-%m-%dinsert into t_user(id,name,birth) values(2, 'lisi', '1990-10-01');查詢的時候可以以某個特定的日期格式展示嗎?date_format這個函數可以將日期類型轉換成特定格式的字符串。select id,name,date_format(birth, '%m/%d/%Y') as birth from t_user;+------+----------+------------+| id | name | birth |+------+----------+------------+| 1 | zhangsan | 10/01/1990 || 2 | lisi | 10/01/1990 |+------+----------+------------+date_format函數怎么用?date_format(日期類型數據, '日期格式')這個函數通常使用在查詢日期方面。設置展示的日期格式。mysql> select id,name,birth from t_user;+------+----------+------------+| id | name | birth |+------+----------+------------+| 1 | zhangsan | 1990-10-01 || 2 | lisi | 1990-10-01 |+------+----------+------------+以上的SQL語句實際上是進行了默認的日期格式化,自動將數據庫中的date類型轉換成varchar類型。并且采用的格式是mysql默認的日期格式:'%Y-%m-%d'select id,name,date_format(birth,'%Y/%m/%d') as birth from t_user;java中的日期格式?yyyy-MM-dd HH:mm:ss SSS

7.6、date和datetime兩個類型的區別?
date是短日期:只包括年月日信息。
datetime是長日期:包括年月日時分秒信息。

drop table if exists t_user; create table t_user(id int,name varchar(32),birth date,create_time datetime );id是整數 name是字符串 birth是短日期 create_time是這條記錄的創建時間:長日期類型mysql短日期默認格式:%Y-%m-%d mysql長日期默認格式:%Y-%m-%d %h:%i:%sinsert into t_user(id,name,birth,create_time) values(1,'zhangsan','1990-10-01','2020-03-18 15:49:50');在mysql當中怎么獲取系統當前時間?now() 函數,并且獲取的時間帶有:時分秒信息!!!!是datetime類型的。insert into t_user(id,name,birth,create_time) values(2,'lisi','1991-10-01',now());

7.7、修改update(DML)

語法格式:
update 表名 set 字段名1=值1,字段名2=值2,字段名3=值3… where 條件;

注意:沒有條件限制會導致所有數據全部更新。update t_user set name = 'jack', birth = '2000-10-11' where id = 2; +------+----------+------------+---------------------+ | id | name | birth | create_time | +------+----------+------------+---------------------+ | 1 | zhangsan | 1990-10-01 | 2020-03-18 15:49:50 | | 2 | jack | 2000-10-11 | 2020-03-18 15:51:23 | +------+----------+------------+---------------------+update t_user set name = 'jack', birth = '2000-10-11', create_time = now() where id = 2;更新所有?update t_user set name = 'abc';

7.8、刪除數據 delete (DML)
語法格式?
delete from 表名 where 條件;

注意:沒有條件,整張表的數據會全部刪除!delete from t_user where id = 2;insert into t_user(id) values(2);delete from t_user; // 刪除所有!

mysql day03課堂筆記

1、查詢每一個員工的所在部門名稱?要求顯示員工名和部門名。

mysql> select * from emp;
±------±-------±----------±-----±-----------±--------±--------±-------+
| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
±------±-------±----------±-----±-----------±--------±--------±-------+
| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 |
| 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 |
| 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 |
| 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 |
| 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 |
| 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 |
| 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 |
| 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 |
| 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 |
| 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 |
| 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | NULL | 20 |
| 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | NULL | 30 |
| 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 |
| 7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1300.00 | NULL | 10 |
±------±-------±----------±-----±-----------±--------±--------±-------+

mysql> select * from dept;
±-------±-----------±---------+
| DEPTNO | DNAME | LOC |
±-------±-----------±---------+
| 10 | ACCOUNTING | NEW YORK |
| 20 | RESEARCH | DALLAS |
| 30 | SALES | CHICAGO |
| 40 | OPERATIONS | BOSTON |
±-------±-----------±---------+

從emp表中取ename,從dept表中取dname,沒有條件限制最終查詢結果是?

ENAME DNAME

SMITH ACCOUNTING 無效記錄
SMITH RESEARCH 有效記錄
SMITH SALES 無效記錄
SMITH OPERATIONS 無效記錄

ALLEN ACCOUNTING
ALLEN RESEARCH
ALLEN SALES
ALLEN OPERATIONS


56條記錄。

加個條件是為了達到4選1,也是為了數據的有效性。

select e.ename,d.dname fromemp e joindept d one.deptno = d.deptno;加條件只是為了避免笛卡爾積現象,只是為了查詢出有效的組合記錄。 匹配的次數一次都沒有少,還是56次。

2、insert語句可以一次插入多條記錄嗎?【掌握】
可以的!
mysql> desc t_user;
±------------±------------±-----±----±--------±------+
| Field | Type | Null | Key | Default | Extra |
±------------±------------±-----±----±--------±------+
| id | int(11) | YES | | NULL | |
| name | varchar(32) | YES | | NULL | |
| birth | date | YES | | NULL | |
| create_time | datetime | YES | | NULL | |
±------------±------------±-----±----±--------±------+

一次可以插入多條記錄:insert into t_user(id,name,birth,create_time) values(1,'zs','1980-10-11',now()), (2,'lisi','1981-10-11',now()),(3,'wangwu','1982-10-11',now());語法:insert into t_user(字段名1,字段名2) values(),(),(),();mysql> select * from t_user; +------+--------+------------+---------------------+ | id | name | birth | create_time | +------+--------+------------+---------------------+ | 1 | zs | 1980-10-11 | 2020-03-19 09:37:01 | | 2 | lisi | 1981-10-11 | 2020-03-19 09:37:01 | | 3 | wangwu | 1982-10-11 | 2020-03-19 09:37:01 | +------+--------+------------+---------------------+

3、快速創建表?【了解內容】

mysql> create table emp2 as select * from emp;原理:將一個查詢結果當做一張表新建!!!!!這個可以完成表的快速復制!!!!表創建出來,同時表中的數據也存在了!!!create table mytable as select empno,ename from emp where job = 'MANAGER';

4、將查詢結果插入到一張表當中?insert相關的!!!【了解內容】
create table dept_bak as select * from dept;
mysql> select * from dept_bak;
±-------±-----------±---------+
| DEPTNO | DNAME | LOC |
±-------±-----------±---------+
| 10 | ACCOUNTING | NEW YORK |
| 20 | RESEARCH | DALLAS |
| 30 | SALES | CHICAGO |
| 40 | OPERATIONS | BOSTON |
±-------±-----------±---------+

insert into dept_bak select * from dept; //很少用!mysql> select * from dept_bak; +--------+------------+----------+ | DEPTNO | DNAME | LOC | +--------+------------+----------+ | 10 | ACCOUNTING | NEW YORK | | 20 | RESEARCH | DALLAS | | 30 | SALES | CHICAGO | | 40 | OPERATIONS | BOSTON | | 10 | ACCOUNTING | NEW YORK | | 20 | RESEARCH | DALLAS | | 30 | SALES | CHICAGO | | 40 | OPERATIONS | BOSTON | +--------+------------+----------+

5、快速刪除表中的數據?【truncate比較重要,必須掌握】

//刪除dept_bak表中的數據 delete from dept_bak; //這種刪除數據的方式比較慢。mysql> select * from dept_bak; Empty set (0.00 sec)delete語句刪除數據的原理?(delete屬于DML語句!!!)表中的數據被刪除了,但是這個數據在硬盤上的真實存儲空間不會被釋放!!!這種刪除缺點是:刪除效率比較低。這種刪除優點是:支持回滾,后悔了可以再恢復數據!!!truncate語句刪除數據的原理?這種刪除效率比較高,表被一次截斷,物理刪除。這種刪除缺點:不支持回滾。這種刪除優點:快速。用法:truncate table dept_bak; (這種操作屬于DDL操作。)大表非常大,上億條記錄????刪除的時候,使用delete,也許需要執行1個小時才能刪除完!效率較低。可以選擇使用truncate刪除表中的數據。只需要不到1秒鐘的時間就刪除結束。效率較高。但是使用truncate之前,必須仔細詢問客戶是否真的要刪除,并警告刪除之后不可恢復!truncate是刪除表中的數據,表還在!刪除表操作?drop table 表名; // 這不是刪除表中的數據,這是把表刪除。

6、對表結構的增刪改?

什么是對表結構的修改?添加一個字段,刪除一個字段,修改一個字段!!!對表結構的修改需要使用:alter 屬于DDL語句DDL包括:create drop alter第一:在實際的開發中,需求一旦確定之后,表一旦設計好之后,很少的 進行表結構的修改。因為開發進行中的時候,修改表結構,成本比較高。 修改表的結構,對應的java代碼就需要進行大量的修改。成本是比較高的。 這個責任應該由設計人員來承擔!第二:由于修改表結構的操作很少,所以我們不需要掌握,如果有一天 真的要修改表結構,你可以使用工具!!!!修改表結構的操作是不需要寫到java程序中的。實際上也不是java程序員的范疇。

7、約束(非常重要,五顆星*****)

7.1、什么是約束?
約束對應的英語單詞:constraint
在創建表的時候,我們可以給表中的字段加上一些約束,來保證這個表中數據的
完整性、有效性!!!

約束的作用就是為了保證:表中的數據有效!!

7.2、約束包括哪些?
非空約束:not null
唯一性約束: unique
主鍵約束: primary key (簡稱PK)
外鍵約束:foreign key(簡稱FK)
檢查約束:check(mysql不支持,oracle支持)

我們這里重點學習四個約束:not nulluniqueprimary keyforeign key

7.3、非空約束:not null

非空約束not null約束的字段不能為NULL。 drop table if exists t_vip; create table t_vip(id int,name varchar(255) not null // not null只有列級約束,沒有表級約束! ); insert into t_vip(id,name) values(1,'zhangsan'); insert into t_vip(id,name) values(2,'lisi');insert into t_vip(id) values(3); ERROR 1364 (HY000): Field 'name' doesn't have a default value小插曲:xxxx.sql這種文件被稱為sql腳本文件。sql腳本文件中編寫了大量的sql語句。我們執行sql腳本文件的時候,該文件中所有的sql語句會全部執行!批量的執行SQL語句,可以使用sql腳本文件。在mysql當中怎么執行sql腳本呢?mysql> source D:\course\03-MySQL\document\vip.sql你在實際的工作中,第一天到了公司,項目經理會給你一個xxx.sql文件,你執行這個腳本文件,你電腦上的數據庫數據就有了!

7.4、唯一性約束: unique

唯一性約束unique約束的字段不能重復,但是可以為NULL。 drop table if exists t_vip; create table t_vip(id int,name varchar(255) unique,email varchar(255) ); insert into t_vip(id,name,email) values(1,'zhangsan','zhangsan@123.com'); insert into t_vip(id,name,email) values(2,'lisi','lisi@123.com'); insert into t_vip(id,name,email) values(3,'wangwu','wangwu@123.com'); select * from t_vip;insert into t_vip(id,name,email) values(4,'wangwu','wangwu@sina.com'); ERROR 1062 (23000): Duplicate entry 'wangwu' for key 'name'insert into t_vip(id) values(4); insert into t_vip(id) values(5); +------+----------+------------------+ | id | name | email | +------+----------+------------------+ | 1 | zhangsan | zhangsan@123.com | | 2 | lisi | lisi@123.com | | 3 | wangwu | wangwu@123.com | | 4 | NULL | NULL | | 5 | NULL | NULL | +------+----------+------------------+ name字段雖然被unique約束了,但是可以為NULL。新需求:name和email兩個字段聯合起來具有唯一性!!!!drop table if exists t_vip;create table t_vip(id int,name varchar(255) unique, // 約束直接添加到列后面的,叫做列級約束。email varchar(255) unique);這張表這樣創建是不符合我以上“新需求”的。這樣創建表示:name具有唯一性,email具有唯一性。各自唯一。以下這樣的數據是符合我“新需求”的。但如果采用以上方式創建表的話,肯定創建失敗,因為'zhangsan'和'zhangsan'重復了。insert into t_vip(id,name,email) values(1,'zhangsan','zhangsan@123.com');insert into t_vip(id,name,email) values(2,'zhangsan','zhangsan@sina.com');怎么創建這樣的表,才能符合新需求呢?drop table if exists t_vip;create table t_vip(id int,name varchar(255),email varchar(255),unique(name,email) // 約束沒有添加在列的后面,這種約束被稱為表級約束。);insert into t_vip(id,name,email) values(1,'zhangsan','zhangsan@123.com');insert into t_vip(id,name,email) values(2,'zhangsan','zhangsan@sina.com');select * from t_vip;name和email兩個字段聯合起來唯一!!!insert into t_vip(id,name,email) values(3,'zhangsan','zhangsan@sina.com');ERROR 1062 (23000): Duplicate entry 'zhangsan-zhangsan@sina.com' for key 'name'什么時候使用表級約束呢?需要給多個字段聯合起來添加某一個約束的時候,需要使用表級約束。unique 和not null可以聯合嗎?drop table if exists t_vip;create table t_vip(id int,name varchar(255) not null unique);mysql> desc t_vip;+-------+--------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+-------+--------------+------+-----+---------+-------+| id | int(11) | YES | | NULL | || name | varchar(255) | NO | PRI | NULL | |+-------+--------------+------+-----+---------+-------+在mysql當中,如果一個字段同時被not null和unique約束的話,該字段自動變成主鍵字段。(注意:oracle中不一樣!)insert into t_vip(id,name) values(1,'zhangsan');insert into t_vip(id,name) values(2,'zhangsan'); //錯誤了:name不能重復insert into t_vip(id) values(2); //錯誤了:name不能為NULL。

7.5、主鍵約束(primary key,簡稱PK)非常重要五顆星*****

主鍵約束的相關術語?主鍵約束:就是一種約束。主鍵字段:該字段上添加了主鍵約束,這樣的字段叫做:主鍵字段主鍵值:主鍵字段中的每一個值都叫做:主鍵值。什么是主鍵?有啥用?主鍵值是每一行記錄的唯一標識。主鍵值是每一行記錄的身份證號!!!記住:任何一張表都應該有主鍵,沒有主鍵,表無效!!主鍵的特征:not null + unique(主鍵值不能是NULL,同時也不能重復!)怎么給一張表添加主鍵約束呢?drop table if exists t_vip;// 1個字段做主鍵,叫做:單一主鍵create table t_vip(id int primary key, //列級約束name varchar(255));insert into t_vip(id,name) values(1,'zhangsan');insert into t_vip(id,name) values(2,'lisi');//錯誤:不能重復insert into t_vip(id,name) values(2,'wangwu');ERROR 1062 (23000): Duplicate entry '2' for key 'PRIMARY'//錯誤:不能為NULLinsert into t_vip(name) values('zhaoliu');ERROR 1364 (HY000): Field 'id' doesn't have a default value可以這樣添加主鍵嗎,使用表級約束?drop table if exists t_vip;create table t_vip(id int,name varchar(255),primary key(id) // 表級約束);insert into t_vip(id,name) values(1,'zhangsan');//錯誤insert into t_vip(id,name) values(1,'lisi');ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'表級約束主要是給多個字段聯合起來添加約束?drop table if exists t_vip;// id和name聯合起來做主鍵:復合主鍵!!!!create table t_vip(id int,name varchar(255),email varchar(255),primary key(id,name));insert into t_vip(id,name,email) values(1,'zhangsan','zhangsan@123.com');insert into t_vip(id,name,email) values(1,'lisi','lisi@123.com');//錯誤:不能重復insert into t_vip(id,name,email) values(1,'lisi','lisi@123.com');ERROR 1062 (23000): Duplicate entry '1-lisi' for key 'PRIMARY'在實際開發中不建議使用:復合主鍵。建議使用單一主鍵!因為主鍵值存在的意義就是這行記錄的身份證號,只要意義達到即可,單一主鍵可以做到。復合主鍵比較復雜,不建議使用!!!一個表中主鍵約束能加兩個嗎?drop table if exists t_vip;create table t_vip(id int primary key,name varchar(255) primary key);ERROR 1068 (42000): Multiple primary key defined結論:一張表,主鍵約束只能添加1個。(主鍵只能有1個。)主鍵值建議使用:intbigintchar等類型。不建議使用:varchar來做主鍵。主鍵值一般都是數字,一般都是定長的!主鍵除了:單一主鍵和復合主鍵之外,還可以這樣進行分類?自然主鍵:主鍵值是一個自然數,和業務沒關系。業務主鍵:主鍵值和業務緊密關聯,例如拿銀行卡賬號做主鍵值。這就是業務主鍵!在實際開發中使用業務主鍵多,還是使用自然主鍵多一些?自然主鍵使用比較多,因為主鍵只要做到不重復就行,不需要有意義。業務主鍵不好,因為主鍵一旦和業務掛鉤,那么當業務發生變動的時候,可能會影響到主鍵值,所以業務主鍵不建議使用。盡量使用自然主鍵。在mysql當中,有一種機制,可以幫助我們自動維護一個主鍵值?drop table if exists t_vip;create table t_vip(id int primary key auto_increment, //auto_increment表示自增,從1開始,以1遞增!name varchar(255));insert into t_vip(name) values('zhangsan');insert into t_vip(name) values('zhangsan');insert into t_vip(name) values('zhangsan');insert into t_vip(name) values('zhangsan');insert into t_vip(name) values('zhangsan');insert into t_vip(name) values('zhangsan');insert into t_vip(name) values('zhangsan');insert into t_vip(name) values('zhangsan');select * from t_vip;+----+----------+| id | name |+----+----------+| 1 | zhangsan || 2 | zhangsan || 3 | zhangsan || 4 | zhangsan || 5 | zhangsan || 6 | zhangsan || 7 | zhangsan || 8 | zhangsan |+----+----------+

7.6、外鍵約束(foreign key,簡稱FK)非常重要五顆星*****

外鍵約束涉及到的相關術語:外鍵約束:一種約束(foreign key)外鍵字段:該字段上添加了外鍵約束外鍵值:外鍵字段當中的每一個值。業務背景:請設計數據庫表,來描述“班級和學生”的信息?第一種方案:班級和學生存儲在一張表中???t_studentno(pk) name classno classname----------------------------------------------------------------------------------1 jack 100 北京市大興區亦莊鎮第二中學高三1班2 lucy 100 北京市大興區亦莊鎮第二中學高三1班3 lilei 100 北京市大興區亦莊鎮第二中學高三1班4 hanmeimei 100 北京市大興區亦莊鎮第二中學高三1班5 zhangsan 101 北京市大興區亦莊鎮第二中學高三2班6 lisi 101 北京市大興區亦莊鎮第二中學高三2班7 wangwu 101 北京市大興區亦莊鎮第二中學高三2班8 zhaoliu 101 北京市大興區亦莊鎮第二中學高三2班分析以上方案的缺點:數據冗余,空間浪費!!!!這個設計是比較失敗的!第二種方案:班級一張表、學生一張表??t_class 班級表classno(pk) classname------------------------------------------------------100 北京市大興區亦莊鎮第二中學高三1班101 北京市大興區亦莊鎮第二中學高三1班t_student 學生表no(pk) name cno(FK引用t_class這張表的classno)----------------------------------------------------------------1 jack 1002 lucy 1003 lilei 1004 hanmeimei 1005 zhangsan 1016 lisi 1017 wangwu 1018 zhaoliu 101當cno字段沒有任何約束的時候,可能會導致數據無效。可能出現一個102,但是102班級不存在。所以為了保證cno字段中的值都是100和101,需要給cno字段添加外鍵約束。那么:cno字段就是外鍵字段。cno字段中的每一個值都是外鍵值。注意:t_class是父表t_student是子表刪除表的順序?先刪子,再刪父。創建表的順序?先創建父,再創建子。刪除數據的順序?先刪子,再刪父。插入數據的順序?先插入父,再插入子。思考:子表中的外鍵引用的父表中的某個字段,被引用的這個字段必須是主鍵嗎?不一定是主鍵,但至少具有unique約束。測試:外鍵可以為NULL嗎?外鍵值可以為NULL。

8、存儲引擎(了解內容)

8.1、什么是存儲引擎,有什么用呢?
存儲引擎是MySQL中特有的一個術語,其它數據庫中沒有。(Oracle中有,但是不叫這個名字)
存儲引擎這個名字高端大氣上檔次。
實際上存儲引擎是一個表存儲/組織數據的方式。
不同的存儲引擎,表存儲數據的方式不同。

8.2、怎么給表添加/指定“存儲引擎”呢?
show create table t_student;

可以在建表的時候給表指定存儲引擎。 CREATE TABLE `t_student` (`no` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(255) DEFAULT NULL,`cno` int(11) DEFAULT NULL,PRIMARY KEY (`no`),KEY `cno` (`cno`),CONSTRAINT `t_student_ibfk_1` FOREIGN KEY (`cno`) REFERENCES `t_class` (`classno`) ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8在建表的時候可以在最后小括號的")"的右邊使用:ENGINE來指定存儲引擎。CHARSET來指定這張表的字符編碼方式。結論:mysql默認的存儲引擎是:InnoDBmysql默認的字符編碼方式是:utf8建表時指定存儲引擎,以及字符編碼方式。 create table t_product(id int primary key,name varchar(255) )engine=InnoDB default charset=gbk;

8.3、怎么查看mysql支持哪些存儲引擎呢?

mysql> select version();
±----------+
| version() |
±----------+
| 5.5.36 |
±----------+

命令: show engines \G

*************************** 1. row ***************************
Engine: FEDERATED
Support: NO
Comment: Federated MySQL storage engine
Transactions: NULL
XA: NULL
Savepoints: NULL
*************************** 2. row ***************************
Engine: MRG_MYISAM
Support: YES
Comment: Collection of identical MyISAM tables
Transactions: NO
XA: NO
Savepoints: NO
*************************** 3. row ***************************
Engine: MyISAM
Support: YES
Comment: MyISAM storage engine
Transactions: NO
XA: NO
Savepoints: NO
*************************** 4. row ***************************
Engine: BLACKHOLE
Support: YES
Comment: /dev/null storage engine (anything you write to it disappears
Transactions: NO
XA: NO
Savepoints: NO
*************************** 5. row ***************************
Engine: CSV
Support: YES
Comment: CSV storage engine
Transactions: NO
XA: NO
Savepoints: NO
*************************** 6. row ***************************
Engine: MEMORY
Support: YES
Comment: Hash based, stored in memory, useful for temporary tables
Transactions: NO
XA: NO
Savepoints: NO
*************************** 7. row ***************************
Engine: ARCHIVE
Support: YES
Comment: Archive storage engine
Transactions: NO
XA: NO
Savepoints: NO
*************************** 8. row ***************************
Engine: InnoDB
Support: DEFAULT
Comment: Supports transactions, row-level locking, and foreign keys
Transactions: YES
XA: YES
Savepoints: YES
*************************** 9. row ***************************
Engine: PERFORMANCE_SCHEMA
Support: YES
Comment: Performance Schema
Transactions: NO
XA: NO
Savepoints: NO

mysql支持九大存儲引擎,當前5.5.36支持8個。版本不同支持情況不同。

8.4、關于mysql常用的存儲引擎介紹一下

MyISAM存儲引擎?
它管理的表具有以下特征:
使用三個文件表示每個表:
格式文件 — 存儲表結構的定義(mytable.frm)
數據文件 — 存儲表行的內容(mytable.MYD)
索引文件 — 存儲表上索引(mytable.MYI):索引是一本書的目錄,縮小掃描范圍,提高查詢效率的一種機制。
可被轉換為壓縮、只讀表來節省空間

提示一下:對于一張表來說,只要是主鍵,或者加有unique約束的字段上會自動創建索引。MyISAM存儲引擎特點:可被轉換為壓縮、只讀表來節省空間這是這種存儲引擎的優勢!!!!MyISAM不支持事務機制,安全性低。

InnoDB存儲引擎?
這是mysql默認的存儲引擎,同時也是一個重量級的存儲引擎。
InnoDB支持事務,支持數據庫崩潰后自動恢復機制。
InnoDB存儲引擎最主要的特點是:非常安全。

它管理的表具有下列主要特征:– 每個 InnoDB 表在數據庫目錄中以.frm 格式文件表示– InnoDB 表空間 tablespace 被用于存儲表的內容(表空間是一個邏輯名稱。表空間存儲數據+索引。)– 提供一組用來記錄事務性活動的日志文件– 用 COMMIT(提交)、SAVEPOINT 及ROLLBACK(回滾)支持事務處理– 提供全 ACID 兼容– 在 MySQL 服務器崩潰后提供自動恢復– 多版本(MVCC)和行級鎖定– 支持外鍵及引用的完整性,包括級聯刪除和更新InnoDB最大的特點就是支持事務:以保證數據的安全。效率不是很高,并且也不能壓縮,不能轉換為只讀,不能很好的節省存儲空間。

MEMORY存儲引擎?
使用 MEMORY 存儲引擎的表,其數據存儲在內存中,且行的長度固定,
這兩個特點使得 MEMORY 存儲引擎非常快。

MEMORY 存儲引擎管理的表具有下列特征:– 在數據庫目錄內,每個表均以.frm 格式的文件表示。– 表數據及索引被存儲在內存中。(目的就是快,查詢快!)– 表級鎖機制。– 不能包含 TEXT 或 BLOB 字段。MEMORY 存儲引擎以前被稱為HEAP 引擎。MEMORY引擎優點:查詢效率是最高的。不需要和硬盤交互。 MEMORY引擎缺點:不安全,關機之后數據消失。因為數據和索引都是在內存當中。

9、事務(重點:五顆星*****,必須理解,必須掌握)

9.1、什么是事務?

一個事務其實就是一個完整的業務邏輯。 是一個最小的工作單元。不可再分。什么是一個完整的業務邏輯?假設轉賬,從A賬戶向B賬戶中轉賬10000.將A賬戶的錢減去10000(update語句)將B賬戶的錢加上10000(update語句)這就是一個完整的業務邏輯。以上的操作是一個最小的工作單元,要么同時成功,要么同時失敗,不可再分。這兩個update語句要求必須同時成功或者同時失敗,這樣才能保證錢是正確的。

9.2、只有DML語句才會有事務這一說,其它語句和事務無關!!!
insert
delete
update
只有以上的三個語句和事務有關系,其它都沒有關系。

因為 只有以上的三個語句是數據庫表中數據進行增、刪、改的。 只要你的操作一旦涉及到數據的增、刪、改,那么就一定要考慮安全問題。數據安全第一位!!!

9.3、假設所有的業務,只要一條DML語句就能完成,還有必要存在事務機制嗎?
正是因為做某件事的時候,需要多條DML語句共同聯合起來才能完成,
所以需要事務的存在。如果任何一件復雜的事兒都能一條DML語句搞定,
那么事務則沒有存在的價值了。

到底什么是事務呢?說到底,說到本質上,一個事務其實就是多條DML語句同時成功,或者同時失敗!事務:就是批量的DML語句同時成功,或者同時失敗!

9.4、事務是怎么做到多條DML語句同時成功和同時失敗的呢?

InnoDB存儲引擎:提供一組用來記錄事務性活動的日志文件事務開啟了: insert insert insert delete update update update 事務結束了!在事務的執行過程中,每一條DML的操作都會記錄到“事務性活動的日志文件”中。 在事務的執行過程中,我們可以提交事務,也可以回滾事務。提交事務?清空事務性活動的日志文件,將數據全部徹底持久化到數據庫表中。提交事務標志著,事務的結束。并且是一種全部成功的結束。回滾事務?將之前所有的DML操作全部撤銷,并且清空事務性活動的日志文件回滾事務標志著,事務的結束。并且是一種全部失敗的結束。

9.5、怎么提交事務,怎么回滾事務?
提交事務:commit; 語句
回滾事務:rollback; 語句(回滾永遠都是只能回滾到上一次的提交點!)

事務對應的英語單詞是:transaction測試一下,在mysql當中默認的事務行為是怎樣的?mysql默認情況下是支持自動提交事務的。(自動提交)什么是自動提交?每執行一條DML語句,則提交一次!這種自動提交實際上是不符合我們的開發習慣,因為一個業務通常是需要多條DML語句共同執行才能完成的,為了保證數據的安全,必須要求同時成功之后再提交,所以不能執行一條就提交一條。怎么將mysql的自動提交機制關閉掉呢?先執行這個命令:start transaction;演示事務:---------------------------------回滾事務----------------------------------------mysql> use bjpowernode;Database changedmysql> select * from dept_bak;Empty set (0.00 sec)mysql> start transaction;Query OK, 0 rows affected (0.00 sec)mysql> insert into dept_bak values(10,'abc', 'tj');Query OK, 1 row affected (0.00 sec)mysql> insert into dept_bak values(10,'abc', 'tj');Query OK, 1 row affected (0.00 sec)mysql> select * from dept_bak;+--------+-------+------+| DEPTNO | DNAME | LOC |+--------+-------+------+| 10 | abc | tj || 10 | abc | tj |+--------+-------+------+2 rows in set (0.00 sec)mysql> rollback;Query OK, 0 rows affected (0.00 sec)mysql> select * from dept_bak;Empty set (0.00 sec)---------------------------------提交事務----------------------------------------mysql> use bjpowernode;Database changedmysql> select * from dept_bak;+--------+-------+------+| DEPTNO | DNAME | LOC |+--------+-------+------+| 10 | abc | bj |+--------+-------+------+1 row in set (0.00 sec)mysql> start transaction;Query OK, 0 rows affected (0.00 sec)mysql> insert into dept_bak values(20,'abcQuery OK, 1 row affected (0.00 sec)mysql> insert into dept_bak values(20,'abcQuery OK, 1 row affected (0.00 sec)mysql> insert into dept_bak values(20,'abcQuery OK, 1 row affected (0.00 sec)mysql> commit;Query OK, 0 rows affected (0.01 sec)mysql> select * from dept_bak;+--------+-------+------+| DEPTNO | DNAME | LOC |+--------+-------+------+| 10 | abc | bj || 20 | abc | tj || 20 | abc | tj || 20 | abc | tj |+--------+-------+------+4 rows in set (0.00 sec)mysql> rollback;Query OK, 0 rows affected (0.00 sec)mysql> select * from dept_bak;+--------+-------+------+| DEPTNO | DNAME | LOC |+--------+-------+------+| 10 | abc | bj || 20 | abc | tj || 20 | abc | tj || 20 | abc | tj |+--------+-------+------+4 rows in set (0.00 sec)

9.6、事務包括4個特性?

A:原子性說明事務是最小的工作單元。不可再分。C:一致性所有事務要求,在同一個事務當中,所有操作必須同時成功,或者同時失敗,以保證數據的一致性。I:隔離性A事務和B事務之間具有一定的隔離。教室A和教室B之間有一道墻,這道墻就是隔離性。A事務在操作一張表的時候,另一個事務B也操作這張表會那樣???D:持久性事務最終結束的一個保障。事務提交,就相當于將沒有保存到硬盤上的數據保存到硬盤上!

9.7、重點研究一下事務的隔離性!!!

A教室和B教室中間有一道墻,這道墻可以很厚,也可以很薄。這就是事務的隔離級別。 這道墻越厚,表示隔離級別就越高。事務和事務之間的隔離級別有哪些呢?4個級別讀未提交:read uncommitted(最低的隔離級別)《沒有提交就讀到了》什么是讀未提交?事務A可以讀取到事務B未提交的數據。這種隔離級別存在的問題就是:臟讀現象!(Dirty Read)我們稱讀到了臟數據。這種隔離級別一般都是理論上的,大多數的數據庫隔離級別都是二檔起步!讀已提交:read committed《提交之后才能讀到》什么是讀已提交?事務A只能讀取到事務B提交之后的數據。這種隔離級別解決了什么問題?解決了臟讀的現象。這種隔離級別存在什么問題?不可重復讀取數據。什么是不可重復讀取數據呢?在事務開啟之后,第一次讀到的數據是3條,當前事務還沒有結束,可能第二次再讀取的時候,讀到的數據是4條,3不等于4稱為不可重復讀取。這種隔離級別是比較真實的數據,每一次讀到的數據是絕對的真實。oracle數據庫默認的隔離級別是:read committed可重復讀:repeatable read《提交之后也讀不到,永遠讀取的都是剛開啟事務時的數據》什么是可重復讀取?事務A開啟之后,不管是多久,每一次在事務A中讀取到的數據都是一致的。即使事務B將數據已經修改,并且提交了,事務A讀取到的數據還是沒有發生改變,這就是可重復讀。可重復讀解決了什么問題?解決了不可重復讀取數據。可重復讀存在的問題是什么?可以會出現幻影讀。每一次讀取到的數據都是幻象。不夠真實!早晨9點開始開啟了事務,只要事務不結束,到晚上9點,讀到的數據還是那樣!讀到的是假象。不夠絕對的真實。mysql中默認的事務隔離級別就是這個!!!!!!!!!!!序列化/串行化:serializable(最高的隔離級別)這是最高隔離級別,效率最低。解決了所有的問題。這種隔離級別表示事務排隊,不能并發!synchronized,線程同步(事務同步)每一次讀取到的數據都是最真實的,并且效率是最低的。

9.8、驗證各種隔離級別

查看隔離級別:SELECT @@tx_isolation
±----------------+
| @@tx_isolation |
±----------------+
| REPEATABLE-READ |
±----------------+
mysql默認的隔離級別

被測試的表t_user
驗證:read uncommited
mysql> set global transaction isolation level read uncommitted;
事務A 事務B

use bjpowernode;
use bjpowernode;
start transaction;
select * from t_user;
start transaction;
insert into t_user values(‘zhangsan’);
select * from t_user;

驗證:read commited
mysql> set global transaction isolation level read committed;
事務A 事務B

use bjpowernode;
use bjpowernode;
start transaction;
start transaction;
select * from t_user;
insert into t_user values(‘zhangsan’);
select * from t_user;
commit;
select * from t_user;

驗證:repeatable read
mysql> set global transaction isolation level repeatable read;
事務A 事務B

use bjpowernode;
use bjpowernode;
start transaction;
start transaction;
select * from t_user;
insert into t_user values(‘lisi’);
insert into t_user values(‘wangwu’);
commit;
select * from t_user;

驗證:serializable
mysql> set global transaction isolation level serializable;
事務A 事務B

use bjpowernode;
use bjpowernode;
start transaction;
start transaction;
select * from t_user;
insert into t_user values(‘abc’);
select * from t_user;

mysql day04課堂筆記

1、索引(index)

1.1、什么是索引?
索引是在數據庫表的字段上添加的,是為了提高查詢效率存在的一種機制。
一張表的一個字段可以添加一個索引,當然,多個字段聯合起來也可以添加索引。
索引相當于一本書的目錄,是為了縮小掃描范圍而存在的一種機制。

對于一本字典來說,查找某個漢字有兩種方式:第一種方式:一頁一頁挨著找,直到找到為止,這種查找方式屬于全字典掃描。效率比較低。第二種方式:先通過目錄(索引)去定位一個大概的位置,然后直接定位到這個位置,做局域性掃描,縮小掃描的范圍,快速的查找。這種查找方式屬于通過索引檢索,效率較高。t_user id(idIndex) name(nameIndex) email(emailIndex) address (emailAddressIndex) ---------------------------------------------------------------------------------- 1 zhangsan... 2 lisi 3 wangwu 4 zhaoliu 5 hanmeimei 6 jackselect * from t_user where name = 'jack';以上的這條SQL語句會去name字段上掃描,為什么?因為查詢條件是:name='jack'如果name字段上沒有添加索引(目錄),或者說沒有給name字段創建索引, MySQL會進行全掃描,會將name字段上的每一個值都比對一遍。效率比較低。MySQL在查詢方面主要就是兩種方式:第一種方式:全表掃描第二種方式:根據索引檢索。注意:在實際中,漢語字典前面的目錄是排序的,按照a b c d e f....排序,為什么排序呢?因為只有排序了才會有區間查找這一說!(縮小掃描范圍其實就是掃描某個區間罷了!)在mysql數據庫當中索引也是需要排序的,并且這個所以的排序和TreeSet數據結構相同。TreeSet(TreeMap)底層是一個自平衡的二叉樹!在mysql當中索引是一個B-Tree數據結構。遵循左小又大原則存放。采用中序遍歷方式遍歷取數據。

1.2、索引的實現原理?

假設有一張用戶表:t_userid(PK) name 每一行記錄在硬盤上都有物理存儲編號 ---------------------------------------------------------------------------------- 100 zhangsan 0x1111 120 lisi 0x2222 99 wangwu 0x8888 88 zhaoliu 0x9999 101 jack 0x6666 55 lucy 0x5555 130 tom 0x7777提醒1:在任何數據庫當中主鍵上都會自動添加索引對象,id字段上自動有索引, 因為id是PK。另外在mysql當中,一個字段上如果有unique約束的話,也會自動 創建索引對象。提醒2:在任何數據庫當中,任何一張表的任何一條記錄在硬盤存儲上都有 一個硬盤的物理存儲編號。提醒3:在mysql當中,索引是一個單獨的對象,不同的存儲引擎以不同的形式 存在,在MyISAM存儲引擎中,索引存儲在一個.MYI文件中。在InnoDB存儲引擎中 索引存儲在一個邏輯名稱叫做tablespace的當中。在MEMORY存儲引擎當中索引 被存儲在內存當中。不管索引存儲在哪里,索引在mysql當中都是一個樹的形式 存在。(自平衡二叉樹:B-Tree)

1.3、在mysql當中,主鍵上,以及unique字段上都會自動添加索引的!!!!
什么條件下,我們會考慮給字段添加索引呢?
條件1:數據量龐大(到底有多么龐大算龐大,這個需要測試,因為每一個硬件環境不同)
條件2:該字段經常出現在where的后面,以條件的形式存在,也就是說這個字段總是被掃描。
條件3:該字段很少的DML(insert delete update)操作。(因為DML之后,索引需要重新排序。)

建議不要隨意添加索引,因為索引也是需要維護的,太多的話反而會降低系統的性能。 建議通過主鍵查詢,建議通過unique約束的字段進行查詢,效率是比較高的。

1.4、索引怎么創建?怎么刪除?語法是什么?

創建索引:mysql> create index emp_ename_index on emp(ename);給emp表的ename字段添加索引,起名:emp_ename_index刪除索引:mysql> drop index emp_ename_index on emp;將emp表上的emp_ename_index索引對象刪除。

1.5、在mysql當中,怎么查看一個SQL語句是否使用了索引進行檢索?

mysql> explain select * from emp where ename = 'KING'; +----+-------------+-------+------+---------------+------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+------+------+-------------+ | 1 | SIMPLE | emp | ALL | NULL | NULL | NULL | NULL | 14 | Using where | +----+-------------+-------+------+---------------+------+---------+------+------+-------------+ 掃描14條記錄:說明沒有使用索引。type=ALLmysql> create index emp_ename_index on emp(ename);mysql> explain select * from emp where ename = 'KING'; +----+-------------+-------+------+-----------------+-----------------+---------+-------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+-----------------+-----------------+---------+-------+------+-------------+ | 1 | SIMPLE | emp | ref | emp_ename_index | emp_ename_index | 33 | const | 1 | Using where | +----+-------------+-------+------+-----------------+-----------------+---------+-------+------+-------------+

1.6、索引有失效的時候,什么時候索引失效呢?

失效的第1種情況:select * from emp where ename like '%T';ename上即使添加了索引,也不會走索引,為什么?原因是因為模糊匹配當中以“%”開頭了!盡量避免模糊查詢的時候以“%”開始。這是一種優化的手段/策略。mysql> explain select * from emp where ename like '%T';+----+-------------+-------+------+---------------+------+---------+------+------+-------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+-------+------+---------------+------+---------+------+------+-------------+| 1 | SIMPLE | emp | ALL | NULL | NULL | NULL | NULL | 14 | Using where |+----+-------------+-------+------+---------------+------+---------+------+------+-------------+失效的第2種情況:使用or的時候會失效,如果使用or那么要求or兩邊的條件字段都要有索引,才會走索引,如果其中一邊有一個字段沒有索引,那么另一個字段上的索引也會實現。所以這就是為什么不建議使用or的原因。mysql> explain select * from emp where ename = 'KING' or job = 'MANAGER';+----+-------------+-------+------+-----------------+------+---------+------+------+-------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+-------+------+-----------------+------+---------+------+------+-------------+| 1 | SIMPLE | emp | ALL | emp_ename_index | NULL | NULL | NULL | 14 | Using where |+----+-------------+-------+------+-----------------+------+---------+------+------+-------------+失效的第3種情況:使用復合索引的時候,沒有使用左側的列查找,索引失效什么是復合索引?兩個字段,或者更多的字段聯合起來添加一個索引,叫做復合索引。create index emp_job_sal_index on emp(job,sal);mysql> explain select * from emp where job = 'MANAGER';+----+-------------+-------+------+-------------------+-------------------+---------+-------+------+-------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+-------+------+-------------------+-------------------+---------+-------+------+-------------+| 1 | SIMPLE | emp | ref | emp_job_sal_index | emp_job_sal_index | 30 | const | 3 | Using where |+----+-------------+-------+------+-------------------+-------------------+---------+-------+------+-------------+mysql> explain select * from emp where sal = 800;+----+-------------+-------+------+---------------+------+---------+------+------+-------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+-------+------+---------------+------+---------+------+------+-------------+| 1 | SIMPLE | emp | ALL | NULL | NULL | NULL | NULL | 14 | Using where |+----+-------------+-------+------+---------------+------+---------+------+------+-------------+失效的第4種情況:在where當中索引列參加了運算,索引失效。mysql> create index emp_sal_index on emp(sal);explain select * from emp where sal = 800;+----+-------------+-------+------+---------------+---------------+---------+-------+------+-------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+-------+------+---------------+---------------+---------+-------+------+-------------+| 1 | SIMPLE | emp | ref | emp_sal_index | emp_sal_index | 9 | const | 1 | Using where |+----+-------------+-------+------+---------------+---------------+---------+-------+------+-------------+mysql> explain select * from emp where sal+1 = 800;+----+-------------+-------+------+---------------+------+---------+------+------+-------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+-------+------+---------------+------+---------+------+------+-------------+| 1 | SIMPLE | emp | ALL | NULL | NULL | NULL | NULL | 14 | Using where |+----+-------------+-------+------+---------------+------+---------+------+------+-------------+失效的第5種情況:在where當中索引列使用了函數explain select * from emp where lower(ename) = 'smith';+----+-------------+-------+------+---------------+------+---------+------+------+-------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+-------+------+---------------+------+---------+------+------+-------------+| 1 | SIMPLE | emp | ALL | NULL | NULL | NULL | NULL | 14 | Using where |+----+-------------+-------+------+---------------+------+---------+------+------+-------------+失效的第6... 失效的第7...

1.7、索引是各種數據庫進行優化的重要手段。優化的時候優先考慮的因素就是索引。
索引在數據庫當中分了很多類?
單一索引:一個字段上添加索引。
復合索引:兩個字段或者更多的字段上添加索引。

主鍵索引:主鍵上添加索引。 唯一性索引:具有unique約束的字段上添加索引。 .....注意:唯一性比較弱的字段上添加索引用處不大。

2、視圖(view)

2.1、什么是視圖?
view:站在不同的角度去看待同一份數據。

2.2、怎么創建視圖對象?怎么刪除視圖對象?

表復制: mysql> create table dept2 as select * from dept;dept2表中的數據: mysql> select * from dept2; +--------+------------+----------+ | DEPTNO | DNAME | LOC | +--------+------------+----------+ | 10 | ACCOUNTING | NEW YORK | | 20 | RESEARCH | DALLAS | | 30 | SALES | CHICAGO | | 40 | OPERATIONS | BOSTON | +--------+------------+----------+創建視圖對象:create view dept2_view as select * from dept2;刪除視圖對象:drop view dept2_view;注意:只有DQL語句才能以view的形式創建。create view view_name as 這里的語句必須是DQL語句;

2.3、用視圖做什么?

我們可以面向視圖對象進行增刪改查,對視圖對象的增刪改查,會導致 原表被操作!(視圖的特點:通過對視圖的操作,會影響到原表數據。)//面向視圖查詢 select * from dept2_view; // 面向視圖插入 insert into dept2_view(deptno,dname,loc) values(60,'SALES', 'BEIJING');// 查詢原表數據 mysql> select * from dept2; +--------+------------+----------+ | DEPTNO | DNAME | LOC | +--------+------------+----------+ | 10 | ACCOUNTING | NEW YORK | | 20 | RESEARCH | DALLAS | | 30 | SALES | CHICAGO | | 40 | OPERATIONS | BOSTON | | 60 | SALES | BEIJING | +--------+------------+----------+// 面向視圖刪除 mysql> delete from dept2_view;// 查詢原表數據 mysql> select * from dept2; Empty set (0.00 sec)// 創建視圖對象 create view emp_dept_view asselect e.ename,e.sal,d.dnamefromemp ejoindept done.deptno = d.deptno;// 查詢視圖對象 mysql> select * from emp_dept_view; +--------+---------+------------+ | ename | sal | dname | +--------+---------+------------+ | CLARK | 2450.00 | ACCOUNTING | | KING | 5000.00 | ACCOUNTING | | MILLER | 1300.00 | ACCOUNTING | | SMITH | 800.00 | RESEARCH | | JONES | 2975.00 | RESEARCH | | SCOTT | 3000.00 | RESEARCH | | ADAMS | 1100.00 | RESEARCH | | FORD | 3000.00 | RESEARCH | | ALLEN | 1600.00 | SALES | | WARD | 1250.00 | SALES | | MARTIN | 1250.00 | SALES | | BLAKE | 2850.00 | SALES | | TURNER | 1500.00 | SALES | | JAMES | 950.00 | SALES | +--------+---------+------------+// 面向視圖更新 update emp_dept_view set sal = 1000 where dname = 'ACCOUNTING';// 原表數據被更新 mysql> select * from emp; +-------+--------+-----------+------+------------+---------+---------+--------+ | EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO | +-------+--------+-----------+------+------------+---------+---------+--------+ | 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 | | 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 | | 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 | | 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 | | 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 | | 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 | | 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 1000.00 | NULL | 10 | | 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 | | 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 1000.00 | NULL | 10 | | 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 | | 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | NULL | 20 | | 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | NULL | 30 | | 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 | | 7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1000.00 | NULL | 10 | +-------+--------+-----------+------+------------+---------+---------+--------+

2.4、視圖對象在實際開發中到底有什么用?《方便,簡化開發,利于維護》

create view emp_dept_viewasselect e.ename,e.sal,d.dnamefromemp ejoindept done.deptno = d.deptno;假設有一條非常復雜的SQL語句,而這條SQL語句需要在不同的位置上反復使用。每一次使用這個sql語句的時候都需要重新編寫,很長,很麻煩,怎么辦?可以把這條復雜的SQL語句以視圖對象的形式新建。在需要編寫這條SQL語句的位置直接使用視圖對象,可以大大簡化開發。并且利于后期的維護,因為修改的時候也只需要修改一個位置就行,只需要修改視圖對象所映射的SQL語句。我們以后面向視圖開發的時候,使用視圖的時候可以像使用table一樣。可以對視圖進行增刪改查等操作。視圖不是在內存當中,視圖對象也是存儲在硬盤上的,不會消失。再提醒一下:視圖對應的語句只能是DQL語句。但是視圖對象創建完成之后,可以對視圖進行增刪改查等操作。小插曲:增刪改查,又叫做:CRUD。CRUD是在公司中程序員之間溝通的術語。一般我們很少說增刪改查。一般都說CRUD。C:Create(增)R:Retrive(查:檢索)U:Update(改)D:Delete(刪)

3、DBA常用命令?

重點掌握:數據的導入和導出(數據的備份)其它命令了解一下即可。(這個培訓日志文檔留著,以后忘了,可以打開文檔復制粘貼。)數據導出?注意:在windows的dos命令窗口中:mysqldump bjpowernode>D:\bjpowernode.sql -uroot -p123456可以導出指定的表嗎?mysqldump bjpowernode emp>D:\bjpowernode.sql -uroot -p123456數據導入?注意:需要先登錄到mysql數據庫服務器上。然后創建數據庫:create database bjpowernode;使用數據庫:use bjpowernode然后初始化數據庫:source D:\bjpowernode.sql

4、數據庫設計三范式

4.1、什么是數據庫設計范式?
數據庫表的設計依據。教你怎么進行數據庫表的設計。

4.2、數據庫設計范式共有?
3個。
第一范式:要求任何一張表必須有主鍵,每一個字段原子性不可再分。

第二范式:建立在第一范式的基礎之上,要求所有非主鍵字段完全依賴主鍵, 不要產生部分依賴。第三范式:建立在第二范式的基礎之上,要求所有非主鍵字段直接依賴主鍵, 不要產生傳遞依賴。聲明:三范式是面試官經常問的,所以一定要熟記在心!設計數據庫表的時候,按照以上的范式進行,可以避免表中數據的冗余,空間的浪費。

4.3、第一范式
最核心,最重要的范式,所有表的設計都需要滿足。
必須有主鍵,并且每一個字段都是原子性不可再分。

學生編號 學生姓名 聯系方式 ------------------------------------------ 1001 張三 zs@gmail.com,1359999999 1002 李四 ls@gmail.com,13699999999 1001 王五 ww@163.net,13488888888以上是學生表,滿足第一范式嗎?不滿足,第一:沒有主鍵。第二:聯系方式可以分為郵箱地址和電話學生編號(pk) 學生姓名 郵箱地址 聯系電話 ---------------------------------------------------- 1001 張三 zs@gmail.com 1359999999 1002 李四 ls@gmail.com 13699999999 1003 王五 ww@163.net 13488888888

4.4、第二范式:
建立在第一范式的基礎之上,
要求所有非主鍵字段必須完全依賴主鍵,不要產生部分依賴。

學生編號 學生姓名 教師編號 教師姓名 ---------------------------------------------------- 1001 張三 001 王老師 1002 李四 002 趙老師 1003 王五 001 王老師 1001 張三 002 趙老師這張表描述了學生和老師的關系:(1個學生可能有多個老師,1個老師有多個學生) 這是非常典型的:多對多關系!分析以上的表是否滿足第一范式?不滿足第一范式。怎么滿足第一范式呢?修改學生編號+教師編號(pk) 學生姓名 教師姓名 ---------------------------------------------------- 1001 001 張三 王老師 1002 002 李四 趙老師 1003 001 王五 王老師 1001 002 張三 趙老師學生編號 教師編號,兩個字段聯合做主鍵,復合主鍵(PK: 學生編號+教師編號) 經過修改之后,以上的表滿足了第一范式。但是滿足第二范式嗎?不滿足,“張三”依賴1001,“王老師”依賴001,顯然產生了部分依賴。產生部分依賴有什么缺點?數據冗余了。空間浪費了。“張三”重復了,“王老師”重復了。為了讓以上的表滿足第二范式,你需要這樣設計:使用三張表來表示多對多的關系!!!!學生表學生編號(pk) 學生名字------------------------------------1001 張三1002 李四1003 王五教師表教師編號(pk) 教師姓名--------------------------------------001 王老師002 趙老師學生教師關系表id(pk) 學生編號(fk) 教師編號(fk)------------------------------------------------------1 1001 0012 1002 0023 1003 0014 1001 002背口訣:多對多怎么設計?多對多,三張表,關系表兩個外鍵!!!!!!!!!!!!!!!

4.5、第三范式
第三范式建立在第二范式的基礎之上
要求所有非主鍵字典必須直接依賴主鍵,不要產生傳遞依賴。

學生編號(PK) 學生姓名 班級編號 班級名稱 ---------------------------------------------------------1001 張三 01 一年一班1002 李四 02 一年二班1003 王五 03 一年三班1004 趙六 03 一年三班以上表的設計是描述:班級和學生的關系。很顯然是1對多關系! 一個教室中有多個學生。分析以上表是否滿足第一范式?滿足第一范式,有主鍵。分析以上表是否滿足第二范式?滿足第二范式,因為主鍵不是復合主鍵,沒有產生部分依賴。主鍵是單一主鍵。分析以上表是否滿足第三范式?第三范式要求:不要產生傳遞依賴!一年一班依賴01,01依賴1001,產生了傳遞依賴。不符合第三范式的要求。產生了數據的冗余。那么應該怎么設計一對多呢?班級表:一班級編號(pk) 班級名稱----------------------------------------01 一年一班02 一年二班03 一年三班學生表:多學生編號(PK) 學生姓名 班級編號(fk)-------------------------------------------1001 張三 01 1002 李四 02 1003 王五 03 1004 趙六 03 背口訣:一對多,兩張表,多的表加外鍵!!!!!!!!!!!!

4.6、總結表的設計?

一對多:一對多,兩張表,多的表加外鍵!!!!!!!!!!!!多對多:多對多,三張表,關系表兩個外鍵!!!!!!!!!!!!!!!一對一:一對一放到一張表中不就行了嗎?為啥還要拆分表?在實際的開發中,可能存在一張表字段太多,太龐大。這個時候要拆分表。一對一怎么設計?沒有拆分表之前:一張表t_userid login_name login_pwd real_name email address........---------------------------------------------------------------------------1 zhangsan 123 張三 zhangsan@xxx2 lisi 123 李四 lisi@xxx...這種龐大的表建議拆分為兩張:t_login 登錄信息表id(pk) login_name login_pwd ---------------------------------1 zhangsan 123 2 lisi 123 t_user 用戶詳細信息表id(pk) real_name email address........ login_id(fk+unique)-----------------------------------------------------------------------------------------100 張三 zhangsan@xxx 1200 李四 lisi@xxx 2口訣:一對一,外鍵唯一!!!!!!!!!!

4.7、囑咐一句話:

數據庫設計三范式是理論上的。實踐和理論有的時候有偏差。最終的目的都是為了滿足客戶的需求,有的時候會拿冗余換執行速度。因為在sql當中,表和表之間連接次數越多,效率越低。(笛卡爾積)有的時候可能會存在冗余,但是為了減少表的連接次數,這樣做也是合理的, 并且對于開發人員來說,sql語句的編寫難度也會降低。面試的時候把這句話說上:他就不會認為你是初級程序員了!

總結

以上是生活随笔為你收集整理的MySQL数据库学习教程,从0到入门的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。