1. 程式人生 > >mysql設計與開發

mysql設計與開發

垂直 sin n) 文件 聚集索引 基準 values prim 存在

架構設計
表結構設計
索引
sql語句
1.表結構設計的核心思想是什麽?
容量評估,性能優化,硬件升級,垂直拆分,水平拆分

2.有個大表為了一個查詢(一天就查2次),領導要你建索引(索引空間大小有500G),
你怎麽考慮,是建還是不建?建索引時要考慮哪些因素?

3.執行計劃中有 filesort 就會進行磁盤文件排序嗎(詳細說明)?
Using filesort:當我們的Query 中包含ORDER BY 操作,而且無法利用索引完成排序操
作的時候,MySQL Query Optimizer 不得不選擇相應的排序算法來實現。

數據庫的範式
1NF):數據庫表中的字段都是單一屬性的,不可再分,這個單一屬性由基本類型構成,包括整型、實數、字符型、邏輯型、日期型等
2NF):數據庫表中不存在非關鍵字段 對任一候選關鍵字段 的部分 函數依賴
選課關系表為SelectCourse(學號, 姓名, 年齡, 課程名稱, 成績, 學分)
(學號, 課程名稱) → (姓名, 年齡, 成績, 學分)
3NF):在第二範式的基礎上,數據表中如果不存在非關鍵字段 對任一候選關鍵字段 的傳遞 函數依賴 則符合第三範式。
所謂傳遞函數依賴,指的是如 果存在"A → B → C"的決定關系,則C傳遞函數依賴於A
學生關系表為Student(學號, 姓名, 年齡, 所在學院, 學院地點, 學院電話),關鍵字為單一關鍵字"學號"
(學號) → (所在學院) → (學院地點, 學院電話)即存在非關鍵字段"學院地點"、"學院電話"對關鍵字段"學號"的傳遞函數依賴

在商業環境中,絕大多數超越第3範式的設計都是不切實際的。 由範式的進階來看,越高等級的範式所產生的表越多,
而在應用程序使用的過程中越多的表Join和查詢造成的性能損耗的問題,甚至很多情況下為了兼顧性能和開發我們甚至要做一下反範式的操作

1 表字段類型選擇
tinyint,int,bigint
decimal(m,n)
datetime,timestamp
varcahr(n)
utf8
表容量評估,數據歸檔評估

架構設計
讀寫分離,schema解耦,冷熱數據分表

表結構設計:INNODB,auto increment primary key,comment
原則:只增不減,自增主鍵,主鍵不應該被修改,不用字符串做主鍵,拆開寬表
varchar(500),控制單表數據量,越短越好
控制列數量
表字段數少而精
IO高效、全表遍歷、表修復快、 提高並發、 alter table快
單表多少字段合適


單表1G體積500W行評估
順序讀1G文件需要N秒
單行不超過200Byte
單表不超50個純INT字段
單表不超20個CHAR(10)個字段
單表字段數上限控制在20-50個
update_time timestamp not null default current_timestamp on update current_timestamp
default 0,不使用default null
default ‘‘
不使用text,blob
索引字段定義not null
禁用外鍵
數字型VS字符型索引:更高效、查詢更快、占用空間更小
示例:
mysql> create table yhq_t11(id int unsigned);
mysql> insert into yhq_t11 values (INET_ATON(‘127.0.0.1‘));
mysql> select * from yhq_t11;
| id |
+------------+
| 2130706433 |
mysql> SELECT INET_NTOA(id) from yhq_t11;
| INET_NTOA(id) |
存儲精確浮點數必須使用DECIMAL
替代FLOAT和DOUBLE
盡可能不要使用TEXT、 BLOB
1) 索引排序問題,只能使用max_sort_length的長度或者手工指定ORDER BY SUBSTRING(column,
length)的長度來排序
2) Memory引擘不支持text,blog類型,會在磁盤上生成臨時表
3) 可能浪費更多的空間
4) 可能無法使用adaptive hash index
5) 導致使用where沒有索引的語句變慢
6) Varchar的性能會比text高很多
為什麽不要default NULL
索引不會包括NULL值。影響索引的統計信息,影響優化器的判斷。
復合索引中只要有一列含有NULL值,那麽這一列對於此復合索引就是無效的, NULL字段很難查詢優化
(NULL字段無法索引) 。
a)如果null字段被索引,需要額外的1字節作為判斷是否為NULL的標誌位“需要mysql內部進行特殊處理)
b)使索引,索引統計,值的比較變得更復雜
c)可用0,” 代替
d)如果是索引字段,一定要定義為not null
不在數據庫裏存圖片

索引
1.唯一鍵不和主鍵重復。
2.不要修改聚焦索引。
3.使用EXPLAIN判斷SQL語句是否合理使用索引,盡量避免extra列出現: Using File Sort, UsingTemporary。
4.索引不是越多越好,盡量合並索引,合理創建聯合索引(避免冗余)。
5.合理利用覆蓋索引,結合核心SQL優先考慮覆蓋索引。
6.不要修改聚集索引(主鍵)
7.不要給選擇性低的字段建單列索引, MySQL對索引的過濾性有要求,如果過濾性太低, MySQL會放棄使用
例如:不要給“性別”列創建索引。
8.不要使用外鍵約束
9.字符類型字段盡量使用前綴索引, 太長的索引不僅影響寫入性能,而且使用性能也差
10.能不加的索引盡量不要加
綜合評估數據密度和數據分布
最好不超過字段數20%

sql語句
慎用count(*)
Count(*)的資源開銷大,盡量不用少用!
實時統計:用memcache,雙向更新,零晨跑基準
非實時統計:盡量用單獨統計表,定期重算
select /*+first_rows(1)*/ count(*) from t1 where rownum<2;
比如,有些應用,只是想看看我表裏是否有數據,或者滿足某個條件的,是否有數據。
first_rows來作。
sql語句盡可能簡單
拒絕大SQL,拆解成多條簡單SQL
減少鎖時間
用上更多CPU
簡單SQL緩存命中率更高
INSERT語句使用batch提交
降低CUP,不在數據庫做運算
select id*16 from yhq_t1;
上面的語句放在MySQL不起眼,不是很明顯,這些運算沒必要放在數據庫裏,數據庫盡量做到簡
單,數據庫就檢索數據,對這些數據的加工就放在應用層。
讓數據庫多做她擅長的事:
1)盡量不在數據庫做運算
2)復雜運算移動程序端CPU
3)盡可能簡單應用MySQL

必須使用綁定變量, 避免常量的直接引用
頻繁的硬解析會影響數據庫性能
ibatis中,所有的 ##都是綁定變量

mysql設計與開發