一:數(shù)據(jù)庫基礎(chǔ)知識(shí)

Innodb引擎

Innodb引擎提供了對(duì)數(shù)據(jù)庫ACID事務(wù)的支持,并且實(shí)現(xiàn)了SQL標(biāo)準(zhǔn)的四種隔離級(jí)別,關(guān)于數(shù)據(jù)庫事務(wù)與其隔離級(jí)別的內(nèi)容請(qǐng)見數(shù)據(jù)庫事務(wù)與其隔離級(jí)別這篇文章。該引擎還提供了行級(jí)鎖和外鍵約束,它的設(shè)計(jì)目標(biāo)是處理大容量數(shù)據(jù)庫系統(tǒng),它本身其實(shí)就是基于MySQL后臺(tái)的完整數(shù)據(jù)庫系統(tǒng),MySQL運(yùn)行時(shí)Innodb會(huì)在內(nèi)存中建立緩沖池,用于緩沖數(shù)據(jù)和索引。但是該引擎不支持FULLTEXT類型的索引,而且它沒有保存表的行數(shù),當(dāng)SELECT COUNT(*) FROM TABLE時(shí)需要掃描全表。當(dāng)需要使用數(shù)據(jù)庫事務(wù)時(shí),該引擎當(dāng)然是首選。由于鎖的粒度更小,寫操作不會(huì)鎖定全表,所以在并發(fā)較高時(shí),使用Innodb引擎會(huì)提升效率。但是使用行級(jí)鎖也不是絕對(duì)的,如果在執(zhí)行一個(gè)SQL語句時(shí)MySQL不能確定要掃描的范圍,InnoDB表同樣會(huì)鎖全表。

MyIASM引擎

MyIASM是MySQL默認(rèn)的引擎,但是它沒有提供對(duì)數(shù)據(jù)庫事務(wù)的支持,也不支持行級(jí)鎖和外鍵,因此當(dāng)INSERT(插入)或UPDATE(更新)數(shù)據(jù)時(shí)即寫操作需要鎖定整個(gè)表,效率便會(huì)低一些。不過和Innodb不同,MyIASM中存儲(chǔ)了表的行數(shù),于是SELECT COUNT(*) FROM TABLE時(shí)只需要直接讀取已經(jīng)保存好的值而不需要進(jìn)行全表掃描。如果表的讀操作遠(yuǎn)遠(yuǎn)多于寫操作且不需要數(shù)據(jù)庫事務(wù)的支持,那么MyIASM也是很好的選擇。

唯一索引(聚集索引)

單個(gè)表只能有一個(gè)唯一索引,索引列的值必須唯一,但允許有空值。如果是組合索引,則列值的組合必須唯一。數(shù)據(jù)存儲(chǔ)結(jié)構(gòu)和索引存儲(chǔ)結(jié)構(gòu)順序一致。(一般主鍵為唯一索引)

創(chuàng)建單列索引:CREATE UNIQUE  INDEX indexName ON tableName(tableColumns(length));如果是CHAR,VARCHAR類型,length可以小于字段實(shí)際長(zhǎng)度;如果是BLOB 和 TEXT 類型,必須指定length。

創(chuàng)建組合索引:CREATE UNIQUE  INDEX indexName ON tableName( `column1`, `column2`, `column3` );

刪除索引:DROP INDEX indexName;

非聚集索引

單個(gè)表可以有多個(gè)非聚集索引,可以是單列也可以是組合索引,數(shù)據(jù)存儲(chǔ)結(jié)構(gòu)和索引存儲(chǔ)結(jié)構(gòu)順序無關(guān)。

創(chuàng)建單列索引:CREATE INDEX indexName ON tableName(tableColumns(length));如果是CHAR,VARCHAR類型,length可以小于字段實(shí)際長(zhǎng)度;如果是BLOB 和 TEXT 類型,必須指定length。

創(chuàng)建組合索引:CREATE INDEX indexName ON tableName( `column1`, `column2`, `column3` );

刪除索引:DROP INDEX indexName;

組合索引

創(chuàng)建組合索引:CREATE INDEX indexName ON tableName( `column1`, `column2`, `column3` );

對(duì)于復(fù)合索引:Mysql從左到右的使用索引中的字段,一個(gè)查詢可以只使用索引中的一部份,但只能是最左側(cè)部分。

例如索引是key index (a,b,c). 可以支持a | a,b| a,b,c 3種組合進(jìn)行查找,但不支持 b|c|b,c進(jìn)行查找 ,當(dāng)最左側(cè)字段是常量引用時(shí),索引就十分有效。(組合索引最多2-3列)

視圖與存儲(chǔ)過程

這兩塊的內(nèi)容可以更具具體的業(yè)務(wù)需要進(jìn)行建立,一般對(duì)于查詢較多的相似組合的表,或者需要隱藏原表信息的可以合并提供查詢視圖,對(duì)于復(fù)雜業(yè)務(wù)和需要特殊效率的業(yè)務(wù)可以提供存儲(chǔ)過程。

常用函數(shù)

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

以下內(nèi)容來自請(qǐng)去這里查看更詳細(xì)  http://www.jb51.net/article/40179.htm 

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

1、聚合函數(shù)(常用于GROUP BY從句的SELECT查詢中)
AVG(col)返回指定列的平均值
COUNT(col)返回指定列中非NULL值的個(gè)數(shù)
MIN(col)返回指定列的最小值
MAX(col)返回指定列的最大值
SUM(col)返回指定列的所有值之和
GROUP_CONCAT(col) 返回由屬于一組的列值連接組合而成的結(jié)果

2、字符串函數(shù)
CONCAT(s1,s2...,sn)將s1,s2...,sn連接成字符串
CONCAT_WS(sep,s1,s2...,sn)將s1,s2...,sn連接成字符串,并用sep字符間隔
LCASE(str)或LOWER(str) 返回將字符串str中所有字符改變?yōu)樾懞蟮慕Y(jié)果
REVERSE(str) 返回顛倒字符串str的結(jié)果

3、日期和時(shí)間函數(shù)
CURDATE()或CURRENT_DATE() 返回當(dāng)前的日期
CURTIME()或CURRENT_TIME() 返回當(dāng)前的時(shí)間
DATE_ADD(date,INTERVAL int keyword)返回日期date加上間隔時(shí)間int的結(jié)果(int必須按照關(guān)鍵字進(jìn)行格式化),如:SELECTDATE_ADD(CURRENT_DATE,INTERVAL 6 MONTH);
DATE_FORMAT(date,fmt)  依照指定的fmt格式格式化日期date值
DATE_SUB(date,INTERVAL int keyword)返回日期date加上間隔時(shí)間int的結(jié)果(int必須按照關(guān)鍵字進(jìn)行格式化),如:SELECTDATE_SUB(CURRENT_DATE,INTERVAL 6 MONTH);
DAYOFWEEK(date)   返回date所代表的一星期中的第幾天(1~7)
DAYOFMONTH(date)  返回date是一個(gè)月的第幾天(1~31)
DAYOFYEAR(date)   返回date是一年的第幾天(1~366)
DAYNAME(date)   返回date的星期名,如:SELECT DAYNAME(CURRENT_DATE);
FROM_UNIXTIME(ts,fmt)  根據(jù)指定的fmt格式,格式化UNIX時(shí)間戳ts
HOUR(time)   返回time的小時(shí)值(0~23)
MINUTE(time)   返回time的分鐘值(0~59)
MONTH(date)   返回date的月份值(1~12)
MONTHNAME(date)   返回date的月份名,如:SELECT MONTHNAME(CURRENT_DATE);
NOW()    返回當(dāng)前的日期和時(shí)間
QUARTER(date)   返回date在一年中的季度(1~4),如SELECT QUARTER(CURRENT_DATE);
WEEK(date)   返回日期date為一年中第幾周(0~53)
YEAR(date)   返回日期date的年份(1000~9999)

4、控制流函數(shù)
MySQL有4個(gè)函數(shù)是用來進(jìn)行條件操作的,這些函數(shù)可以實(shí)現(xiàn)SQL的條件邏輯,允許開發(fā)者將一些應(yīng)用程序業(yè)務(wù)邏輯轉(zhuǎn)換到數(shù)據(jù)庫后臺(tái)。

MySQL控制流函數(shù):
CASE WHEN[test1] THEN [result1]...ELSE [default] END如果testN是真,則返回resultN,否則返回default
CASE [test] WHEN[val1] THEN [result]...ELSE [default]END  如果test和valN相等,則返回resultN,否則返回default
IF(test,t,f)   如果test是真,返回t;否則返回f
IFNULL(arg1,arg2) 如果arg1不是空,返回arg1,否則返回arg2
NULLIF(arg1,arg2) 如果arg1=arg2返回NULL;否則返回arg1
這些函數(shù)的第一個(gè)是IFNULL(),它有兩個(gè)參數(shù),并且對(duì)第一個(gè)參數(shù)進(jìn)行判斷。如果第一個(gè)參數(shù)不是NULL,函數(shù)就會(huì)向調(diào)用者返回第一個(gè)參數(shù);如果是NULL,將返回第二個(gè)參數(shù)。

代碼如下:

SELECT CASE 'green'
     WHEN 'red' THEN 'stop'
     WHEN 'green' THEN 'go' END;
SELECT CASE 9 WHEN 1 THEN 'a' WHEN 2 THEN 'b' ELSE 'N/A' END;
SELECT CASE WHEN (2+2)=4 THEN 'OK' WHEN(2+2)<>4 THEN 'not OK' END ASSTATUS;
SELECT Name,IF((IsActive = 1),'已激活','未激活') AS RESULT FROMUserLoginInfo;
SELECT fname,lname,(math+sci+lit) AS total,
CASE WHEN (math+sci+lit) < 50 THEN 'D'
WHEN (math+sci+lit) BETWEEN 50 AND 150 THEN 'C'
WHEN (math+sci+lit) BETWEEN 151 AND 250 THEN 'B'
ELSE 'A' END
AS grade FROM marks;
SELECT IF(ENCRYPT('sue','ts')=upass,'allow','deny') AS LoginResultFROM users WHERE uname = 'sue';#一個(gè)登陸驗(yàn)證

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

二:數(shù)據(jù)庫設(shè)計(jì)

在官方學(xué)習(xí)的時(shí)候這部分是要符合三范式規(guī)則的,但是這種規(guī)則下對(duì)于大多數(shù)的數(shù)據(jù)業(yè)務(wù)來說都是在理論上太完整,不太實(shí)用,所以可以學(xué)習(xí)這種設(shè)計(jì)的思想,但是適不適用可以按照自己的業(yè)務(wù)規(guī)劃。

在設(shè)計(jì)數(shù)據(jù)庫的過程主要可以參考以下幾個(gè)方向(個(gè)人總結(jié)):

1.首先分析自己的業(yè)務(wù),抽象好數(shù)據(jù)對(duì)象以及對(duì)象之間的關(guān)聯(lián)關(guān)系。

2.對(duì)于通用的一些數(shù)據(jù)字段可以抽象總結(jié)出來,比如創(chuàng)建時(shí)間,更新時(shí)間,操作者。。。這些通用的字段。

3.針對(duì)自己的業(yè)務(wù)主要分析查詢的部分,對(duì)于重復(fù)查詢較多,修改機(jī)會(huì)較少的字段可以適當(dāng)?shù)脑诙鄠€(gè)表中進(jìn)行冗余,以提高查詢和簡(jiǎn)化sql代碼的復(fù)雜度。

4.在建表時(shí)可以考慮后期業(yè)務(wù)的擴(kuò)展性,但是不必強(qiáng)制流出字段等,因?yàn)闃I(yè)務(wù)變化比較平凡,過多的預(yù)留會(huì)讓表看起來非?;靵y。

5.當(dāng)業(yè)務(wù)擴(kuò)展性和項(xiàng)目需求有沖突時(shí)可以優(yōu)先考慮項(xiàng)目需求,至于擴(kuò)展性可看業(yè)務(wù)發(fā)展再定,甚至修改。(個(gè)人觀點(diǎn),可不理會(huì))

6.做好字段說明,備注。

三:sql優(yōu)化(只是優(yōu)化的方向和原則)

1.級(jí)聯(lián)查詢優(yōu)化,多個(gè)單標(biāo)查詢的優(yōu)化,可以考慮用多表級(jí)聯(lián)查詢優(yōu)化。

2.考慮索引使用情況優(yōu)化,對(duì)于破壞索引,未使用索引的sql,可以考慮建立索引或者使現(xiàn)有索引生效方面優(yōu)化。

3.對(duì)于大數(shù)據(jù)量分頁的優(yōu)化。

4.通過分析業(yè)務(wù),用更多的條件確定更少的列。

 四:數(shù)據(jù)庫架構(gòu)

1.對(duì)于大數(shù)據(jù)和有讀寫壓力的業(yè)務(wù)可以考慮從幾個(gè)方向去設(shè)計(jì)   

表分區(qū)http://www.cnblogs.com/freeton/p/4265228.html  這個(gè)網(wǎng)址寫的不錯(cuò),值得瀏覽下。

分表存儲(chǔ):按業(yè)務(wù)需求可以有水平分表和垂直分表兩種不同的技術(shù)。

        水平分表是按照一定的規(guī)則將一個(gè)大的表格水平分割到不同的子表中,所以每個(gè)表格的列都是相同的。

     垂直分表是將一個(gè)大的表格按照不同的業(yè)務(wù)需求把不同的列分割到不同的子表中,以某一個(gè)相同的屬性(例ID)關(guān)聯(lián)起來。

     對(duì)于分表后的查詢可以按照業(yè)務(wù)先進(jìn)行邏輯判斷,然后定位到某個(gè)子表。對(duì)于一些統(tǒng)計(jì)功能,則循環(huán)所有子表,合并。

分庫技術(shù):就是采用不同的數(shù)據(jù)庫部署數(shù)據(jù)庫集群,可以搜搜MyCat中間件。

讀寫分離http://blog.csdn.net/zoomyj/article/details/50610349  這片文章寫了好多 有興趣的可以多了解下,作為一個(gè)了解和積累。

 

總結(jié):零零散散寫了一些,這里寫的主要是一些方向性的東西,可能沒有具體的一些實(shí)現(xiàn)或者是代碼。所以只是一個(gè)指引,希望能幫助大家在這些方面去學(xué)習(xí),去積累。也有一些東西是網(wǎng)絡(luò)摘抄的,只要是好的就學(xué)習(xí)吧。

以上內(nèi)適用一到三年java開發(fā)面試,個(gè)人見解,值得參考,覺得適用的順手推薦下,讓更多的人看到

最后分享一個(gè)不錯(cuò)的雞湯給想要干事的朋友們,祝大家成功!http://www.iheima.com/zixun/2017/0628/163820.shtml

http://www.cnblogs.com/web-jiagou/p/6746940.html