Mysql基礎、表設計、sql優化

1、基礎知識
SQL分爲數據操作語言(DML)(數據操作語言)與數據定義語言(DDL)(數據定義語言),SQL對大小寫不敏感。 在MS Access 和 SQL Server 2000中,每條SQL語句之後無需使用分號。
DDL語法:
一、Mysql常用基本數據類型
【1】TINYINT(表示的範圍是0-255之間的數字,存儲大小爲1個字節)
【2】INT/INTEGER(從 -2^31 到 2^31 - 1的整型數據,存儲大小爲4個字節,1個字節8位,最大有效顯
示寬度是255【int(11)夠用】,顯示寬度與存儲大小或類型包含的值的範圍無關)
【3】FLOAT(單精度 4個字節)
【4】DOUBLE(雙精度 8字節)
【5】DATE(YYYY-MM-DD 3個字節)
【6】TIME(HH:MM:SS 3個字節)
【7】YEAR(YYYY 1個字節)
【8】DATETIME(YYYY-MM-DD HH:MM:SS 8字節)
【9】TIMESTAMP(YYYYMMDD HHMMSS 4字節)
【10】VARCHAR(varchar (m)定義的列的長度爲可變長字符串,M取值可以爲0~65535之間,有65535字節的最大限制)
【11】TEXT(最大能達到4G)
二、建數據庫表
CREATE TABLE IF NOT EXISTS runoob_tbl( runoob_id INT UNSIGNED AUTO_INCREMENT, // AUTO_INCREMENT定義列爲自增的屬性,一般用於主鍵,數值會自動加1
runoob_title VARCHAR(100) NOT NULL, //不想字段爲 NULL可設置字段的屬性爲 NOTNULL,在操作數據庫時如果輸入該字段數據爲NULL,則報錯
runoob_author VARCHAR(40) NOT NULL, submission_date DATE, PRIMARY KEY ( runoob_id ) //PRIMARY KEY關鍵字用於定義列爲主鍵。 您可以使用多列來定義主鍵,列間以逗號分隔。
)ENGINE=InnoDB DEFAULT CHARSET=utf8;// ENGINE 設置存儲引擎,CHARSET 設置編碼
三、刪除數據庫
DROP TABLE table_name ;
DML語法:
【1】查詢:Select 列名 from 表 where 列 運算符 值 and 列 運算符 and (列 運算符 值 or 列 運算符) order by 列值 desc(降序)/ asc(降序), 列值 desc/asc //and、or混用時,使用圓括號來組成複雜的表達式
Select distinct 列名 from 表 //返回這個列裏面唯一不同的值
【2】新增:Insert into 表 (列,列)values (值,值)
【3】更新:Update 表 set 列=值,列=值 where 列=值 and列=值
【4】刪除:Delete from 表 where 列=值
高級教程
Top
Select * from 表 limit number(mysql)
Select * from 表 where rownum <= number(oracle)
Select top number| percent * from 表
Like
Select * from 表 where 列 like(not like) ‘%%’ (%代替一個字符_僅代替一個字符)
In
Select * from 表 where 列 in(v1, v2, v3)
UNION
SELECT expression1, expression2, … expression_n FROM tables [WHERE conditions] UNION [ALL | DISTINCT]
SELECT expression1, expression2, … expression_n FROM tables [WHERE conditions];
用於連接兩個以上的 SELECT 語句的結果組合到一個結果集合中,多個 SELECT 語句會刪除重複的數據。
DISTINCT: 可選,刪除結果集中重複的數據。默認情況下 UNION 操作符已經刪除了重複數據,所以 DISTINCT 修飾符對結果沒啥影響。
ALL: 可選,返回所有結果集,包含重複數據。
Group By WITH ROLLUP
SELECT coalesce(name, ‘總數’), SUM(singin) as singin_count FROM employee_tbl GROUP BY name WITH ROLLUP;
//WITH ROLLUP 可以實現在分組統計數據基礎上再進行相同的統計(SUM,AVG,COUNT…)
| 小麗 | 2 | | 小明 | 7 | | 小王 | 7 | | 總數 | 16 |
INNER JOIN(內連接或等值連接)
SELECT a.runoob_id, a.runoob_author, b.runoob_count FROM runoob_tbl a INNER JOIN tcount_tbl b ON a.runoob_author = b.runoob_author;
等價於SELECT a.runoob_id, a.runoob_author, b.runoob_count FROM runoob_tbl a, tcount_tbl b WHERE a.runoob_author = b.runoob_author;
獲取兩個表中字段匹配關係的記錄(也可以省略 INNER 使用 JOIN,效果一樣)
LEFT JOIN(左連接)
SELECT a.runoob_id, a.runoob_author, b.runoob_count FROM runoob_tbl a LEFT JOIN tcount_tbl b ON a.runoob_author = b.runoob_author;
會讀取左邊數據表的全部數據,即便右邊表無對應數據。
RIGHT JOIN(右連接): 與 LEFT JOIN 相反,用於獲取右表所有記錄,即使左表沒有對應匹配的記錄。
IS NULL:當列的值是 NULL,此運算符返回 true。 IS NOT NULL:當列的值不爲 NULL, 運算符返回 true。 <=>:比較操作符(不同於 = 運算符),當比較的的兩個值相等或者都爲 NULL 時返回 true。 關於 NULL 的條件比較運算是比較特殊的,不能使用 = NULL 或 != NULL 在列中查找 NULL 值,使用 IS NULL 和 IS NOT NULL 運算符。在 MySQL 中,NULL 值與任何其它值的比較(即使是 NULL)永遠返回 NULL,即 NULL = NULL 返回 NULL 。 select * , columnName1+ifnull(columnName2,0) from tableName;
columnName1,columnName2 爲 int 型,當 columnName2 中,有值爲 null 時,columnName1+columnName2=null, ifnull(columnName2,0) 把 columnName2 中 null 值轉爲 0。
REGEXP正則表達式匹配
SELECT name FROM person_tbl WHERE name REGEXP ‘^st’;詳見正則表達式表
2、表設計原則
第一範式:所有屬性都不能再分解爲更基本的數據單位
第二範式:實體值的惟一性
第三範式:關聯表要減少冗餘,兩個表字段不重複
(1)字段的寬度儘量小,儘量把字段設置爲NOT NULL
(2)數值類型數據被處理起來的速度要比文本類型快得多,如“省份” “性別”可以設置爲ENUM類型
(3)儘可能的使用 varchar/nvarchar 代替 char/nchar ,因爲首先變長字段存儲空間小,可以節省存儲空間,其次對於查詢來說,在一個相對較小的字段內搜索效率顯然要高些。
(4)索引應建立在那些將用於JOIN,WHERE判斷和ORDERBY排序的字段上。儘量不要對數據庫中某個含有大量重複值的字段建立索引。索引並不是越多越好,索引固然可以提高相應的 select 的效率,但同時也降低了 insert 及 update 的效率,因爲 insert 或 update 時有可能會重建索引,所以怎樣建索引需要慎重考慮,視具體情況而定。一個表的索引數最好不要超過6個,若太多則應考慮一些不常使用到的列上建的索引是否有必要。
索引是幫助Mysql高效獲取數據排好序的數據結構,數據結構有二叉樹、紅黑樹、B-Tree、Hash表
Mysql用最多的存儲引擎是InnoDB、MySIAM,存儲引擎是形容表
Innodb索引:表數據文件本身按B+Tree組織的一個索引結構文件,葉子節點包含了完整的數據記錄(索引與數據不分離:聚集索引),InnoDB表必須有主鍵,並且推薦使用整型的自增主鍵(如果沒有,會找一列或者給你增加一個主鍵),非主鍵索引結構葉子節點存儲的是主鍵值(一致性和節省存儲空間)
MySIAM索引:索引文件與數據文件分離(非聚集索引)
B+Tree(B-Tree的變種)
(1)非葉子節點不存儲data,只存儲索引(冗餘),可以放更多的索引
(2)葉子節點包含所有的索引字段
(3)葉子節點用指針鏈接,提高區間訪問的性能
Hash表:沒辦法滿足範圍查找,統計查詢不需要範圍查詢,這種情況下用hash
聯合索引的底層存儲結構?(待整理)
3、Sql優化
(1)任何地方都不要使用 select * from t ,用具體的字段列表代替“
”,不要返回用不到的任何字段。
(2)where 子句中避免使用!=或<>、避免對字段進行null值判斷(可以設置默認值0)、避免使用or(可以使用union all )、like可能導致索引失效(like ‘%1999-12-15%’; 不會觸發,like ‘%1999-12-15’; 不會觸發,like ‘1999-12-15%’; 會觸發)、in 和 not in 也會導致索引失效(between>in>or,exists 可以代替 in),否則引擎將放棄使用索引全表掃描。
(3)where 子句中應儘量避免對字段進行表達式操作、應儘量避免對字段進行函數操作、子句中的“=”左邊避免進行函數、算術運算或其他表達式運算。
(4)使用JOIN來代替子查詢。
(5)如果該索引是複合索引,在使用索引字段作爲條件時,那麼必須使用到該索引中的第一個字段作爲條件時才能保證系統使用該索引。
(6)使用聯合(UNION)來代替手動創建的臨時表,避免頻繁創建和刪除臨時表,以減少系統表資源的消耗。臨時表並不是不可使用,如當需要重複引用大型表或常用表中的某個數據集時,適當地使用它們可以使某些例程更有效,但是,對於一次性事件,最好使用導出表。在新建臨時表時,如果一次性插入數據量很大,那麼可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果數據量不大,爲了緩和系統表的資源,應先create table,然後insert。如果使用到了臨時表,在存儲過程的最後務必將所有的臨時表顯式刪除,先 truncate table,然後 drop table,這樣可以避免系統表的較長時間鎖定。
(7)儘量避免使用遊標,因爲遊標的效率較差,如果遊標操作的數據超過1萬行,那麼就應該考慮改寫。使用基於遊標的方法或臨時表方法之前,應先尋找基於集的解決方案來解決問題,基於集的方法通常更有效。與臨時表一樣,遊標並不是不可使用。對小型數據集使用 FAST_FORWARD 遊標通常要優於其他逐行處理方法,尤其是在必須引用幾個表才能獲得所需的數據時。在結果集中包括“合計”的例程通常要比使用遊標執行的速度快。如果開發時間允許,基於遊標的方法和基於集的方法都可以嘗試一下,看哪一種方法的效果更好。
(8)在所有的存儲過程和觸發器的開始處設置 SET NOCOUNT ON ,在結束時設置 SET NOCOUNT OFF 。無需在執行存儲過程和觸發器的每個語句後向客戶端發送 DONE_IN_PROC 消息。
(9)儘量避免向客戶端返回大數據量,若數據量過大,應該考慮相應需求是否合理,儘量避免大事務操作,提高系統併發能力。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章