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