关于数据库的理解
當前數據庫分為關系型數據庫和非關系型數據庫
關系型數據庫
關系型數據庫:指采用了關系模型來組織數據的數據庫。
關系模型指的就是二維表格模型,而一個關系型數據庫就是由二維表及其之間的聯系所組成的一個數據組織。
關系模型中常用的概念:
關系:一張二維表,每個關系都具有一個關系名,也就是表名
元組:二維表中的一行,在數據庫中被稱為記錄
屬性:二維表中的一列,在數據庫中被稱為字段
域:屬性的取值范圍,也就是數據庫中某一列的取值限制
關鍵字:一組可以唯一標識元組的屬性,數據庫中常稱為主鍵,由一個或多個列組成
關系模式:指對關系的描述。其格式為:關系名(屬性1,屬性2, ... ... ,屬性N),在數據庫中成為表結構
關系型數據庫的優點:
1.容易理解:二維表結構是非常貼近邏輯世界的一個概念,關系模型相對網狀、層次等其他模型來說更容易理解
2.使用方便:通用的SQL語言使得操作關系型數據庫非常方便
3.易于維護:豐富的完整性(實體完整性、參照完整性和用戶定義的完整性)大大減低了數據冗余和數據不一致的概率
關系型數據庫存在的問題
1.網站的用戶并發性非常高,往往達到每秒上萬次讀寫請求,對于傳統關系型數據庫來說,硬盤I/O是一個很大的瓶頸
2.網站每天產生的數據量是巨大的,對于關系型數據庫來說,在一張包含海量數據的表中查詢,效率是非常低的
3.在基于web的結構當中,數據庫是最難進行橫向擴展的,當一個應用系統的用戶量和訪問量與日俱增的時候,數據庫卻沒有辦法像web server和app server那樣簡單的通過添加更多的硬件和服務節點來擴展性能和負載能力。當需要對數據庫系統進行升級和擴展時,往往需要停機維護和數據遷移。
4.性能欠佳:在關系型數據庫中,導致性能欠佳的最主要原因是多表的關聯查詢,以及復雜的數據分析類型的復雜SQL報表查詢。為了保證數據庫的ACID特性,必須盡量按照其要求的范式進行設計,關系型數據庫中的表都是存儲一個格式化的數據結構。
數據庫事務必須具備ACID特性,ACID分別是Atomic原子性,Consistency一致性,
Isolation隔離性,Durability持久性。
當今十大主流的關系型數據庫
Oracle,Microsoft SQL Server,MySQL,PostgreSQL,DB2,
Microsoft Access, SQLite,Teradata,MariaDB(MySQL的一個分支),SAP
非關系型數據庫
非關系型數據庫:指非關系型的,分布式的,且一般不保證遵循ACID原則的數據存儲系統。
非關系型數據庫結構
非關系型數據庫以鍵值對存儲,且結構不固定,每一個元組可以有不一樣的字段,每個元組可以根據需要增加一些自己的鍵值對,不局限于固定的結構,可以減少一些時間和空間的開銷。
優點
1.用戶可以根據需要去添加自己需要的字段,為了獲取用戶的不同信息,不像關系型數據庫中,要對多表進行關聯查詢。僅需要根據id取出相應的value就可以完成查詢。
2.適用于SNS(Social Networking Services)中,例如facebook,微博。系統的升級,功能的增加,往往意味著數據結構巨大變動,這一點關系型數據庫難以應付,需要新的結構化數據存儲。由于不可能用一種數據結構化存儲應付所有的新的需求,因此,非關系型數據庫嚴格上不是一種數據庫,應該是一種數據結構化存儲方法的集合。
不足:
只適合存儲一些較為簡單的數據,對于需要進行較復雜查詢的數據,關系型數據庫顯的更為合適。不適合持久存儲海量數據
非關系型數據庫的分類
非關系型數據庫都是針對某些特定的應用需求出現的,因此,對于該類應用,具有極高的性能。依據結構化方法以及應用場合的不同,主要分為以下幾類:
面向高性能并發讀寫的key-value數據庫:
key-value數據庫的主要特點是具有極高的并發讀寫性能
Key-value數據庫是一種以鍵值對存儲數據的一種數據庫,類似Java中的map。可以將整個數據庫理解為一個大的map,每個鍵都會對應一個唯一的值。
主流代表為Redis, Amazon DynamoDB, Memcached,
Microsoft Azure Cosmos DB和Hazelcast
面向海量數據訪問的面向文檔數據庫:
這類數據庫的主要特點是在海量的數據中可以快速的查詢數據
文檔存儲通常使用內部表示法,可以直接在應用程序中處理,主要是JSON。JSON文檔也可以作為純文本存儲在鍵值存儲或關系數據庫系統中。
主流代表為MongoDB,Amazon DynamoDB,Couchbase,
Microsoft Azure Cosmos DB和CouchDB
面向搜索數據內容的搜索引擎:
搜索引擎是專門用于搜索數據內容的NoSQL數據庫管理系統。
主要是用于對海量數據進行近實時的處理和分析處理,可用于機器學習和數據挖掘
主流代表為Elasticsearch,Splunk,Solr,MarkLogic和Sphinx
面向可擴展性的分布式數據庫:
這類數據庫的主要特點是具有很強的可拓展性
普通的關系型數據庫都是以行為單位來存儲數據的,擅長以行為單位的讀入處理,比如特定條件數據的獲取。因此,關系型數據庫也被成為面向行的數據庫。相反,面向列的數據庫是以列為單位來存儲數據的,擅長以列為單位讀入數據。
這類數據庫想解決的問題就是傳統數據庫存在可擴展性上的缺陷,這類數據庫可以適應數據量的增加以及數據結構的變化,將數據存儲在記錄中,能夠容納大量動態列。由于列名和記錄鍵不是固定的,并且由于記錄可能有數十億列,因此可擴展性存儲可以看作是二維鍵值存儲。
主流代表為Cassandra,HBase,Microsoft Azure Cosmos DB,
Datastax Enterprise和Accumulo
CAP理論
NoSQL的基本需求就是支持分布式存儲,嚴格一致性與可用性需要互相取舍
CAP理論:一個分布式系統不可能同時滿足C(一致性)、A(可用性)、P(分區容錯性)三個基本需求,并且最多只能滿足其中的兩項。對于一個分布式系統來說,分區容錯是基本需求,否則不能稱之為分布式系統,因此需要在C和A之間尋求平衡
C(Consistency)一致性
一致性是指更新操作成功并返回客戶端完成后,所有節點在同一時間的數據完全一致。與ACID的C完全不同
A(Availability)可用性
可用性是指服務一直可用,而且是正常響應時間。
P(Partition tolerance)分區容錯性
分區容錯性是指分布式系統在遇到某節點或網絡分區故障的時候,仍然能夠對外提供滿足一致性和可用性的服務。
關系型與非關系型數據庫的比較
1.成本:Nosql數據庫簡單易部署,基本都是開源軟件,不需要像使用Oracle那樣花費大量成本購買使用,相比關系型數據庫價格便宜。
2.查詢速度:Nosql數據庫將數據存儲于緩存之中,而且不需要經過SQL層的解析,關系型數據庫將數據存儲在硬盤中,自然查詢速度遠不及Nosql數據庫。
3.存儲數據的格式:Nosql的存儲格式是key,value形式、文檔形式、圖片形式等等,所以可以存儲基礎類型以及對象或者是集合等各種格式,而數據庫則只支持基礎類型。
4.擴展性:關系型數據庫有類似join這樣的多表查詢機制的限制導致擴展很艱難。Nosql基于鍵值對,數據之間沒有耦合性,所以非常容易水平擴展。
5.持久存儲:Nosql不使用于持久存儲,海量數據的持久存儲,還是需要關系型數據庫
6.數據一致性:非關系型數據庫一般強調的是數據最終一致性,不像關系型數據庫一樣強調數據的強一致性,從非關系型數據庫中讀到的有可能還是處于一個中間態的數據,
Nosql不提供對事務的處理。
1.數據庫啟動
命令:mysql -uroot -proot
(注:-u后是你的數據庫名-p后是你的數據庫密碼;具體內容以你的設置為本)
?2.對數據庫的操作(DOS窗口/可視化的工具)
(1)操作庫的命令
查看所有的庫: show databases ;
創建庫: create database 庫名;
刪除庫: drop database 庫名;
(2)操作表的命令
使用庫:use? 庫名;
查看表: show tables;
創建表: create table 表名(字段名 字段類型(長度) , 2 , 3 , 4 , 5…);
刪除表: drop table 表名;
修改表: alter table 表名 add column 字段名 字段類型(長度)
描述表:desc 表名;
(3)對表中內容操作的命令
查詢: select * from 表名 ;
創建: insert into 表名 values(字段1的值,字段2的值,字段3的值,字段4的值)
修改: update 表名 set 字段名=新值(where)
刪除: delete from 表名(where)
一,字段約束
–1,概述
常見的約束: 主鍵約束 , 非空約束 , 唯一約束
–2,主鍵約束
表設計的原則是,表里必須有主鍵.作為每條記錄的唯一標識.
當表里的字段加了主鍵約束時,效果是,字段的值必須唯一且不能為null
通常會使用自增策略,是指主鍵的值從此不必我們設計,交給了數據庫來管理
–3,非空約束
#非空約束:字段的值不能是null CREATE TABLE c( id INT PRIMARY KEY AUTO_INCREMENT,#主鍵約束 PASSWORD VARCHAR(20) NOT NULL #非空約束,值不能是null ) #c表里有兩個字段,那就必須賦兩個值, #只是第一個是id的值不必維護 INSERT INTO c VALUES(NULL,'123456') #INSERT INTO c VALUES(NULL,null),第二個必須不為null–4,唯一約束
#唯一約束:值不能相同 CREATE TABLE e( id INT PRIMARY KEY AUTO_INCREMENT,#主鍵約束 NAME VARCHAR(20) UNIQUE NOT NULL #唯一約束,值不能重復 )二,基本函數
–1,概述
Mysql數據庫提供了豐富的函數,
常見的: lower upper length concat substr replace ifnull round/ceil/floor
–2,測試
#只查指定列的值
#UPPER全轉大寫 LOWER全轉小寫
SELECT ename,UPPER(ename),LOWER(ename) FROM emp
`dept`#length求長度(一個字母算一個字符,一個漢字算三個字符)
SELECT LENGTH(ename),ename,LENGTH(job),job FROM emp
#concat(1,2,3)拼接字符串-1是字段名2和3都是要拼的內容
SELECT ename,CONCAT(ename,'hello',100) FROM emp#查部門名稱
#substr(1,2,3)截取字符串-1是字段名2是開始位置3是總長度
SELECT dname,SUBSTR(dname,2),SUBSTR(dname,2,3) FROM dept
#replace(1,2,3)替換-1是字段名2是要被替換的3是新的數據
SELECT dname,REPLACE(dname,'o','666') FROM dept
#ifnull(1,2)判斷是否為null,如果是null就替換成0-1是字段名2是要替換的值
SELECT comm,IFNULL(comm,0) FROM emp
SELECT *,sal+IFNULL(comm,0) FROM emp#round四舍五入/ceil向上取整/floor向下取整
SELECT comm,ROUND(comm),CEIL(comm),FLOOR(comm) FROM emp
#now/CURDATE/CURTIME
SELECT NOW() #年月日 時分秒
SELECT CURDATE()#年月日
SELECT CURTIME()#時分秒
#year/month/day/hour/minute/second
SELECT YEAR('2000-07-27')
SELECT YEAR(NOW()),MONTH(NOW()),DAY(NOW())
SELECT HOUR(NOW()),MINUTE(NOW()),SECOND(NOW())
三,條件查詢
–1,where like
#查詢部門地址
SELECT loc FROM dept
#DISTINCT用來給結果去重distinct
SELECT DISTINCT loc FROM dept#where滿足條件的才查出來
#查詢deptno等于1的部門記錄
SELECT * FROM dept WHERE deptno=1
#查詢地址在一區的部門記錄
SELECT * FROM dept WHERE loc='一區'
#查詢地址在二區的部門名稱
SELECT dname FROM dept WHERE loc='二區'
#根據名稱查詢部門記錄
SELECT * FROM dept WHERE dname='research'
#根據名稱和地址 查詢部門記錄
SELECT * FROM dept
#WHERE loc='二區' and dname='research2'#并且關系
WHERE loc='二區' OR dname='research2'#或者關系SELECT * FROM dept
WHERE 1=1#查詢工資>8000的員工信息
SELECT * FROM emp WHERE sal>8000
#查詢工資是8000的或者工資是3000的員工信息
SELECT * FROM emp WHERE
# sal=8000 or sal=3000
sal IN (3000,8000) #作用意義同上SELECT * FROM emp WHERE
empno IN (100,300,500)#like 像,模糊查詢,通常配合%作為占位符
#查詢名字里包含a的員工信息
SELECT * FROM emp WHERE
#ename like '%a%' #包含a,動態匹配0~n個字符
ename LIKE 'l%' #以l開頭,動態匹配0~n個字符
–2,null limit order by等
#查詢工資>8000的員工信息 SELECT * FROM emp WHERE sal>8000 #查詢工資是8000的或者工資是3000的員工信息 SELECT * FROM emp WHERE # sal=8000 or sal=3000 sal IN (3000,8000) #作用意義同上SELECT * FROM emp WHERE empno IN (100,300,500)#like 像,模糊查詢,通常配合%作為占位符 #查詢名字里包含a的員工信息 SELECT * FROM emp WHERE #ename like '%a%' #包含a,動態匹配0~n個字符 ename LIKE 'l%' #以l開頭,動態匹配0~n個字符#查詢mgr是null的員工信息 SELECT * FROM emp WHERE mgr IS NULL #是null #WHERE mgr IS not NULL #不是null#查詢sal在3000到10000內的員工信息 SELECT * FROM emp WHERE #sal > 3000 and sal< 10000 sal BETWEEN 3000 AND 10000 #包含[3000,10000]#查詢2017年到2019年入職的員工信息 SELECT * FROM emp WHERE YEAR(hiredate) BETWEEN 2017 AND 2019 #包含#limit分頁 SELECT * FROM emp LIMIT 3 #只查前三條 #第1個數字是開始位置(從n+1條數據開始)第2個是總條數 SELECT * FROM emp LIMIT 0,3 SELECT * FROM emp LIMIT 2,2 #order by 排序 SELECT * FROM emp ORDER BY sal ASC #默認ASC,升序 SELECT * FROM emp ORDER BY sal DESC #倒序 SELECT * FROM emp ORDER BY hiredate #按照日期的數字升序 SELECT * FROM emp ORDER BY ename #a-z升序 SELECT * FROM emp ORDER BY job #拿著每個漢字對應的數字(查u8) ,升序排序四,統計案例
#統計2019年入職的員工 SELECT * FROM emp WHERE #year(hiredate)=2019 hiredate>'2019-1-1' AND hiredate<'2019-12-12' #統計2017年以前入職的員工 SELECT * FROM emp WHERE YEAR(hiredate)<2017 #統計2015~2017年入職的員工 SELECT * FROM emp WHERE YEAR(hiredate) BETWEEN 2015 AND 2017 #統計員工入職了幾年 SELECT *,YEAR(NOW())-YEAR(hiredate) FROM emp五,聚合函數
–1,概述
把一列的值全都取出來,聚合起來,分析最大值,最小值,平均值,求和,求個數 常見的聚合函數:
max? ?min? ?avg? ?sum? count
–2,測試
#聚合函數:把查出來的列聚合起來分析數據 #求最高薪max SELECT sal FROM emp ORDER BY sal DESC LIMIT 1 SELECT MAX(sal) FROM emp #獲取sal這列里的最大值 #求最低薪min SELECT sal FROM emp ORDER BY sal LIMIT 1 SELECT MIN(sal) MIN FROM emp #求和sum SELECT SUM(sal) FROM emp #求平均數avg SELECT AVG(sal) FROM emp SELECT MAX(sal),MIN(sal),SUM(sal),AVG(sal) FROM emp #求總個數count SELECT COUNT(comm) FROM emp#不統計comm字段值是null的-低效 SELECT COUNT(*) FROM emp#都統計 SELECT COUNT(1) FROM emp#都統計-高效 #統計工資>8000的人數 SELECT COUNT(1) FROM emp WHERE sal>8000 #統計2019年入職的人數 SELECT COUNT(1) FROM emp WHERE YEAR(hiredate)=2019六,分組
–1,測試
#什么時候必須分組?當查詢結果中出現了聚合列和非聚合列時
#按照什么分組合理?通常按照非聚合列分組
#什么是聚合列非聚合列?使用了聚合函數max min sum avg count的就是聚合列
#統計每個部門的平均薪資
SELECT deptno,AVG(sal) FROM emp
GROUP BY deptno #按照部門編號分組
#統計每個崗位的最高薪資
SELECT MAX(sal),job FROM emp
GROUP BY job#按照崗位分組
#統計每年的入職人數
#count是聚合函數,year只是普通函數
SELECT COUNT(1),YEAR(hiredate) FROM emp
GROUP BY YEAR(hiredate)#按照非聚合列分組#having的作用:用來對分組后的數據,進一步過濾
#統計每個部門的平均薪資,只要>10000的記錄
SELECT deptno,AVG(sal) FROM emp
GROUP BY deptno
HAVING AVG(sal)>10000
#統計每個崗位的最高薪資,只要>8000的記錄
SELECT job,MAX(sal) FROM emp
#先過濾再分組高效,但是where里不能用聚合函數
#where MAX(sal)>8000 #會報錯
GROUP BY job
HAVING MAX(sal)>8000
ORDER BY MAX(sal) #升序排序#統計每年的入職人數,只要人數>1的記錄
SELECT COUNT(1),YEAR(hiredate) FROM emp
GROUP BY YEAR(hiredate)
HAVING COUNT(1) > 1
#不能改成where,后面出現了聚合函數#統計每年的入職人數,只要2017年以后的記錄
SELECT COUNT(1),YEAR(hiredate) FROM emp
WHERE YEAR(hiredate) > 2017 #高效,只是where里不能出現聚合函數
GROUP BY YEAR(hiredate)
#having YEAR(hiredate)> 2017
#having里使用的過濾條件必須是查到的結果
七,事務
-1,概述
保證SQL語句,要么全執行成功,要么全失敗
有四個特征ACID:
A是原子性: 是指多條SQL是一個原子,密不可分.如果都正確,就操作了數據.如果有錯誤的都會發生回滾,回到事務執行之前.
C是一致性: 保證了數據的一致性和完整性.
I是隔離性: 保證多線程并發時的數據安全,多個操作之間是被隔離的.
D是持久性: 是指對數據CDU的影響是持久生效的.
隔離級別:讀未提交 讀已提交 可重復讀 串行化
從前往后,性能越來越差,安全性越來越高.MySQL默認是可重復讀
?
-2,測試
先開啟事務,然后執行一批SQL,再結束事務
?
八,字段約束
–1,默認約束和檢查約束
#默認約束:給指定字段設置默認值
CREATE TABLE f(
id INT PRIMARY KEY AUTO_INCREMENT,#主鍵,自動遞增
sex VARCHAR(10) DEFAULT '男' #設置默認值
)#檢查約束:給指定字段設置合法值的檢查規則
CREATE TABLE g(
id INT PRIMARY KEY AUTO_INCREMENT,#主鍵,自動遞增
age INT,
CHECK(age>0 AND age<200)#設置檢查
)
–2,外鍵約束
#默認約束:給指定字段設置默認值 CREATE TABLE f( id INT PRIMARY KEY AUTO_INCREMENT,#主鍵,自動遞增 sex VARCHAR(10) DEFAULT '男' #設置默認值 )#檢查約束:給指定字段設置合法值的檢查規則 CREATE TABLE g( id INT PRIMARY KEY AUTO_INCREMENT,#主鍵,自動遞增 age INT, CHECK(age>0 AND age<200)#設置檢查 )#外鍵:通過指定的SQL語句描述了兩張表的關系 #約束:子表添加記錄時id必須在取自主表#刪除主表記錄時,必須沒有被子表使用著 #怎么確定誰是子表誰是主表?子表中有外鍵的SQL CREATE TABLE tb_user( id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(10), sex VARCHAR(10) ) CREATE TABLE tb_user_address( user_id INT PRIMARY KEY AUTO_INCREMENT, address VARCHAR(20), #表明和哪張表的哪個字段有關系 #foreign key(本表的主鍵) references 關聯表(主鍵) FOREIGN KEY(user_id) REFERENCES tb_user(id) )九,索引
一、索引
MySQL索引的建立對于MySQL的高效運行是很重要的,索引可以大大提高MySQL的檢索速度。
打個比方,如果合理的設計且使用索引的MySQL是一輛蘭博基尼的話,那么沒有設計和使用索引的MySQL就是一個人力三輪車。
索引分單列索引和組合索引。單列索引,即一個索引只包含單個列,一個表可以有多個單列索引,但這不是組合索引。組合索引,即一個索引包含多個列。
創建索引時,你需要確保該索引是應用在 SQL 查詢語句的條件(一般作為 WHERE 子句的條件)。
實際上,索引也是一張表,該表保存了主鍵與索引字段,并指向實體表的記錄。
上面都在說使用索引的好處,但過多的使用索引將會造成濫用。因此索引也會有它的缺點:雖然索引大大提高了查詢速度,同時卻會降低更新表的速度,如對表進行INSERT、UPDATE和DELETE。因為更新表時,MySQL不僅要保存數據,還要保存一下索引文件。
建立索引會占用磁盤空間的索引文件。
二、索引類型
Mysql目前主要有以下幾種索引類型:FULLTEXT,HASH,BTREE,RTREE。
1. FULLTEXT
即為全文索引,目前只有MyISAM引擎支持。其可以在CREATE TABLE ,ALTER TABLE ,CREATE INDEX 使用,不過目前只有 CHAR、VARCHAR ,TEXT 列上可以創建全文索引。
全文索引并不是和MyISAM一起誕生的,它的出現是為了解決WHERE name LIKE “%word%"這類針對文本的模糊查詢效率較低的問題。
2. HASH
由于HASH的唯一(幾乎100%的唯一)及類似鍵值對的形式,很適合作為索引。
HASH索引可以一次定位,不需要像樹形索引那樣逐層查找,因此具有極高的效率。但是,這種高效是有條件的,即只在“=”和“in”條件下高效,對于范圍查詢、排序及組合索引仍然效率不高。
3. BTREE
BTREE索引就是一種將索引值按一定的算法,存入一個樹形的數據結構中(二叉樹),每次查詢都是從樹的入口root開始,依次遍歷node,獲取leaf。這是MySQL里默認和最常用的索引類型。
4. RTREE
RTREE在MySQL很少使用,僅支持geometry數據類型,支持該類型的存儲引擎只有MyISAM、BDb、InnoDb、NDb、Archive幾種。
相對于BTREE,RTREE的優勢在于范圍查找。
ps. 此段詳細內容見此片博文:Mysql幾種索引類型的區別及適用情況
三、索引種類
普通索引:僅加速查詢(MySQL中基本索引類型,沒有什么限制,允許在定義索引的列中插入重復值和空值,純粹為了查詢數據更快一點。)
唯一索引:加速查詢 + 列值唯一(可以有null)
主鍵索引:加速查詢 + 列值唯一(不可以有null)+ 表中只有一個。
組合索引:多列值組成一個索引,專門用于組合搜索,其效率大于索引合并。(在表中的多個字段組合上創建的索引,只有在查詢條件中使用了這些字段的左邊字段時,索引才會被使用,使用組合索引時遵循最左前綴集合。例如,這里由id、name和age3個字段構成的索引,索引行中就按id/name/age的順序存放,索引可以索引下面字段組合(id,name,age)、(id,name)或者(id)。如果要查詢的字段不構成索引最左面的前綴,那么就不會是用索引,比如,age或者(name,age)組合就不會使用索引查詢)
全文索引:只有在MyISAM引擎上才能使用,只能在CHAR,VARCHAR,TEXT類型字段上使用全文索引,介紹了要求,說說什么是全文索引,就是在一堆文字中,通過其中的某個關鍵字等,就能找到該字段所屬的記錄行,比如有"你是個大煞筆,二貨 ..." 通過大煞筆,可能就可以找到該條記錄。這里說的是可能,因為全文索引的使用涉及了很多細節,我們只需要知道這個大概意思。
ps:索引合并,使用多個單列索引組合搜索;
覆蓋索引,select的數據列只用從索引中就能夠取得,不必讀取數據行,換句話說查詢列要被所建的索引覆蓋。
聚集(clustered)索引:也叫聚簇索引,是指數據行的物理順序與列值(一般是主鍵的那一列)的邏輯順序相同,一個表中只能擁有一個聚集索引。MySQL中一般默認主鍵為聚集索引。
非聚集(unclustered)索引:該索引中索引的邏輯順序與磁盤上行的物理存儲順序不同,一個表中可以擁有多個非聚集索引。其實按照定義,除了聚集索引以外的索引都是非聚集索引,只是人們想細分一下非聚集索引,分成普通索引,唯一索引,全文索引。
好處: 大大的提高了SQL的查詢效率
壞處: 索引本身也是一張表,表里的數據和真正的表里的數據是重復的,浪費了空間.
操作索引的命令:
查看索引:SHOW INDEX FROM emp
#索引的分類:單值/唯一/復合 #1.創建 單值索引:一個索引包含了一個列 CREATE INDEX job_index ON emp(job) #創建 唯一索引 #alter table emp add unique(deptno)報錯,deptno的值重復啦 ALTER TABLE emp ADD UNIQUE(ename) #創建 復合索引:最左特性 ALTER TABLE emp ADD INDEX many_index(ename,job,hiredate)#2.查看索引 SHOW INDEX FROM emp#3.使用索引 EXPLAIN #用來觀察SQL的執行計劃,主要看有沒有用索引 #(觀察兩列的結果:key和possible_keys) SELECT * FROM emp WHERE job='經理'#背后會用job索引EXPLAIN SELECT * FROM emp WHERE empno=100#背后會用主鍵索引EXPLAIN SELECT * FROM emp WHERE ename='jack'#背后會用唯一索引 SELECT * FROM emp WHERE ename='jack' AND job='經理'#復合索引生效 SELECT * FROM emp WHERE hiredate='2010-1-1'#復合索引失效 SELECT * FROM emp WHERE job='經理' AND hiredate='2010-1-1'#復合索引失效十,關聯查詢
–1,測試
#多表聯查:一張表已經無法滿足業務需求,需要聯合查詢多張表
#方式1:笛卡爾積
SELECT * FROM dept,emp #查出了所有數據
SELECT * FROM dept,emp#表名.字段名
WHERE dept.deptno=emp.deptno#兩張表的關聯關系
AND dept.dname='accounting'#方式2:連接查詢join#inner join/left join/right join
#工作中,常用的是: 小表 left join 大表,小表驅動大表
SELECT * FROM emp
#inner join dept #兩邊都滿足的交集
LEFT JOIN dept #左邊的所有和右邊滿足了的
#right JOIN dept #右邊的所有和左邊滿足了的
ON dept.deptno=emp.deptno #描述字段
WHERE dept.dname='accounting' #具體過濾條件#方式3:子查詢:把上次的查詢結果作為條件再次查詢
#1.根據部門名稱查部門編號dept
SELECT deptno FROM dept WHERE dname='accounting'
#2.把查到的編號作為條件,查員工信息emp
SELECT * FROM emp WHERE deptno=1
#查詢部門名稱是accounting的所有信息
SELECT * FROM emp WHERE deptno=(SELECT deptno FROM dept WHERE dname='accounting'
)
總結
- 上一篇: 分享一下我的小说史
- 下一篇: linux cmake编译源码,linu