一蛔屹,數(shù)據(jù)庫設計規(guī)范
1.數(shù)據(jù)庫命名規(guī)范?
? ?采用26個英文字母(區(qū)分大小寫)和0-9的自然數(shù)(經(jīng)常不需要)加上下劃線'_'組成;?
? ?例如:user,?stat,?log,?也可以wifi_user,?wifi_stat,?wifi_log給數(shù)據(jù)庫加個前綴;?
2.數(shù)據(jù)表命名規(guī)范? ?
? ?采用26個英文字母(區(qū)分大小寫)和0-9的自然數(shù)(經(jīng)常不需要)加上下劃線'_'組成;??
? ??命名簡潔明確,多個單詞用下劃線'_'分隔;???
3.數(shù)據(jù)表字段命名規(guī)范??
采用26個英文字母(區(qū)分大小寫)和0-9的自然數(shù)(經(jīng)常不需要)加上下劃線'_'組成;?
命名簡潔明確,多個單詞用下劃線'_'分隔;?
例如:user_login表段?user_id,?user_name,?pass_word,?eamil,?tickit,?status,?mobile,?add_time;? 4.字段類型規(guī)范??
用盡量少的存儲空間來存數(shù)一個字段的數(shù)據(jù);? 例如:能使用int就不要使用varchar升筏、char,能用varchar(16)就不要使用varchar(256);?
IP地址最好使用int類型;?
固定長度的類型最好使用char,例如:郵編;?
能使用tinyint就不要使用smallint,int;?
最好給每個字段一個默認值,最好不能為null;
5.數(shù)據(jù)庫表索引規(guī)范
?命名簡潔明確,例如:user_login表user_name字段的索引應為user_name_index唯一索引;?
6.簡單熟悉數(shù)據(jù)庫范式(三大范式)
第一范式(1NF):字段值具有原子性,不能再分(所有關系型數(shù)據(jù)庫系統(tǒng)都滿足第一范式);? 例如:姓名字段,其中姓和名是一個整體,如果區(qū)分姓和名那么必須設立兩個獨立字段;?
第二范式(2NF):一個表必須有主鍵,即每行數(shù)據(jù)都能被唯一的區(qū)分;
第三范式(3NF):一個表中不能包涵其他相關表中非關鍵字段的信息,即數(shù)據(jù)表不能有沉余字段;?
二.MYSQL數(shù)據(jù)庫設計原則?
1.核心原則
? ? ? ?不在數(shù)據(jù)庫做運算或?qū)憳I(yè)務邏輯(存儲過程,觸發(fā)器);??控制列數(shù)量(字段少而精,字段數(shù)建議在20以內(nèi));??平衡范式與冗余(效率優(yōu)先虑粥;往往犧牲范式) ; 拒絕3B(拒絕大sql語句:big?sql车荔、拒絕大事物:bigtransaction、拒絕大批量:big?batch);???
2.字段類原則
用好數(shù)值類型(用合適的字段類型節(jié)約空間);??
字符轉(zhuǎn)化為數(shù)字(能轉(zhuǎn)化的最好轉(zhuǎn)化,同樣節(jié)約空間兽掰、提高查詢性能);?
避免使用NULL字段(NULL字段很難查詢優(yōu)化竿滨、NULL字段的索引需要額外空間佳恬、NULL字段的復合索引無效);?
少用text類型(盡量使用varchar代替text字段);??
3.索引類原則??
合理使用索引(改善查詢,減慢更新,索引一定不是越多越好);?
字符字段必須建前綴索引;??不在索引做列運算;??
innodb主鍵推薦使用自增列(主鍵建立聚簇索引,主鍵不應該被修改,字符串不應該做主鍵)(理解Innodb的索引保存結構就知道了);? 減少使用外鍵(由程序保證約束);
4.sql類原則?
sql語句盡可能簡單;簡單的事務;???避免使用trig/func(觸發(fā)器于游、函數(shù)不用客戶端程序取而代之);
?不用select?*(消耗cpu,io,內(nèi)存,帶寬,這種程序不具有擴展性);??
條件查詢or改為IN;OR改寫為UNION(mysql的索引合并很弱智);??
?避免負向%;? 如id !=1毁葱;少用連接join;??
===========================================================
三.mysql分區(qū)分表
(1)簡介
mysql數(shù)據(jù)庫中的數(shù)據(jù)是以文件的形式存在磁盤上的,默認放在/mysql/data下面(可以通過my.cnf中的datadir來查看)贰剥。
使用myisam引擎的一張表主要對應著三個文件倾剿,一個是frm存放表結構的,一個是myd存放表數(shù)據(jù)的鸠澈,一個是myi存表索引的柱告。使用innoDB引擎的/mysql/data/數(shù)據(jù)庫名目錄下一張表有一個frm文件存放數(shù)據(jù)結構,其他的數(shù)據(jù)部分全部都存在在/mysql/data目錄下的ibdata文件中笑陈。
(2)分表分區(qū)是什么?
? ??分表是將一個大表按照一定的規(guī)則分解成多張具有獨立存儲空間的實體表,我們可以稱為子表葵袭,每個表都對應三個文件涵妥,MYD數(shù)據(jù)文件,.MYI索引文件坡锡,.frm表結構文件蓬网。這些子表可以分布在同一塊磁盤上,也可以在不同的機器上鹉勒。
????分區(qū)就是把一張表的數(shù)據(jù)分成N多個區(qū)域帆锋,分區(qū)后,表面上還是一張表禽额,但數(shù)據(jù)散列到多個位置根據(jù)數(shù)據(jù)量的大小锯厢,結合實際業(yè)務皮官。
(3)分區(qū)
mysql5.1及以上支持分區(qū)功能?
分區(qū)方式有:range分區(qū),list分區(qū),hash分區(qū),key分區(qū),子分區(qū)实辑。
①range分區(qū)? ? ?
?建表的時候添分區(qū)按照id的范圍
CREATE?TABLE?IF?NOT?EXISTS?`user`?(? ?
id int ........
?)?ENGINE=MyISAM??DEFAULT?CHARSET=utf8?AUTO_INCREMENT=1???-PARTITION?BY?RANGE?(id)?(? ? ?
? ?PARTITION?p0?VALUES?LESS?THAN?(3),? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?PARTITION?p1?VALUES?LESS?THAN?(6),? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?PARTITION?p2?VALUES?LESS?THAN?MAXVALUE,? ? ? ? ? ? ? ? ? ? ? ? ? ??);
對現(xiàn)有的表進行分區(qū)
alter?table?aa?partition?by?RANGE(id)(
PARTITION?p1?VALUES?less?than?(1),? ?
PARTITION?p2?VALUES?less?than?(5),???- PARTITION?p3?VALUES?less?than?MAXVALUE);??
//刪除一個分區(qū)??
?alter?table?aa?drop?partition?p2;??
②list分區(qū)
LIST分區(qū)中每個分區(qū)的定義和選擇是基于某列的值從屬于一個值列表集中的一個值捺氢,而RANGE分 區(qū)是從屬于一個連續(xù)區(qū)間值的集合。如下:
官方文檔規(guī)定??LIST 分區(qū)是剪撬,分區(qū)字段必須包含在主鍵字段內(nèi)
CREATE?TABLE?IF?NOT?EXISTS?`list_part`?(? `id`?int(11)?NOT?NULL COMMENT?'用戶ID',??
`province_id`?int(2)?NOT?NULL?DEFAULT?0?COMMENT?'省',??
)?ENGINE=INNODB??DEFAULT?CHARSET=utf8? AUTO_INCREMENT=1???-PARTITION?BY?LIST?(province_id)?(?
PARTITION?p0?VALUES?IN?(1,2,3,4,5,6,7,8),? ? PARTITION?p1?VALUES?IN?(9,10,11,12,16,21),? PARTITION?p2?VALUES?IN?(13,14,15,19),? ? PARTITION?p3?VALUES?IN?(17,18,20,22,23,24)? ?);??
③hash分區(qū)
HASH分區(qū)主要用來確保數(shù)據(jù)在預先確定數(shù)目的分區(qū)中平均分布摄乒,你所要做的只是基于將要被哈希的列值指定一個列值或表達式,以 及指定被分區(qū)的表將要被分割成的分區(qū)數(shù)量残黑。
CREATE?TABLE?IF?NOT?EXISTS?`hash_part`?(? ? ?`id`?int(11)?NOT?NULL?AUTO_INCREMENT?COMMENT?'評論ID',? ? ?`comment`?varchar(1000)?NOT?NULL?DEFAULT?''?COMMENT?'評論',? ? ? `ip`?varchar(25)?NOT?NULL?DEFAULT?''?COMMENT?'來源IP',? ? ? PRIMARY?KEY?(`id`)? ? )?ENGINE=INNODB??DEFAULT?CHARSET=utf8?AUTO_INCREMENT=1? ? PARTITION?BY?HASH(id)???->?PARTITIONS?3;?
④key分區(qū)
按照KEY進行分區(qū)類似于按照HASH分區(qū)馍佑,除了HASH分區(qū)使用的用 戶定義的表達式,而KEY分區(qū)的 哈希函數(shù)是由MySQL 服務器提供梨水。
CREATE?TABLE?IF?NOT?EXISTS?`key_part`?(? ? ? `news_id`?int(11)?NOT?NULL??COMMENT?'新聞ID',? ? ?`content`?varchar(1000)?NOT?NULL?DEFAULT?''?COMMENT?'新聞內(nèi)容',? ? ? `u_id`?varchar(25)?NOT?NULL?DEFAULT?''?COMMENT?'來源IP',? ? ? `create_time`?DATE?NOT?NULL?DEFAULT?'0000-00-00?00:00:00'?COMMENT?'時間'? ?)?ENGINE=INNODB??DEFAULT?CHARSET=utf8? ? PARTITION?BY?LINEAR?HASH(YEAR(create_time))???
PARTITIONS?3;??
⑤子分區(qū)
子分區(qū)是分區(qū)表中每個分區(qū)的再次分割拭荤,子分區(qū)既可以使用HASH希分區(qū),也可以使用KEY分區(qū)冰木。這 也被稱為復合分區(qū)(composite partitioning)穷劈。
? 1,如果一個分區(qū)中創(chuàng)建了子分區(qū)踊沸,其他分區(qū)也要有子分區(qū)
? 2歇终,如果創(chuàng)建了了分區(qū),每個分區(qū)中的子分區(qū)數(shù)必有相同
? 3逼龟,同一分區(qū)內(nèi)的子分區(qū)评凝,名字不相同,不同分區(qū)內(nèi)的子分區(qū)名子可以相同(5.1.50不適用)
CREATE?TABLE?IF?NOT?EXISTS?`sub_part`?(? ? ?`news_id`?int(11)?NOT?NULL??COMMENT?'新聞ID',? ? ?`content`?varchar(1000)?NOT?NULL?DEFAULT?''?COMMENT?'新聞內(nèi)容',? ? ? `u_id`??int(11)?NOT?NULL?DEFAULT?0s?COMMENT?'來源IP',? ? ? `create_time`?DATE?NOT?NULL?DEFAULT?'0000-00-00?00:00:00'?COMMENT?'時間'? ? )?ENGINE=INNODB??DEFAULT?CHARSET=utf8? ? PARTITION?BY?RANGE(YEAR(create_time))? SUBPARTITION?BY?HASH(TO_DAYS(create_time))(? ? PARTITION?p0?VALUES?LESS?THAN?(1990)(SUBPARTITION?s0,SUBPARTITION?s1,SUBPARTITION?s2),? ? PARTITION?p1?VALUES?LESS?THAN?(2000)(SUBPARTITION?s3,SUBPARTITION?s4,SUBPARTITION?good),? ? PARTITION?p2?VALUES?LESS?THAN?MAXVALUE(SUBPARTITION?tank0,SUBPARTITION?tank1,SUBPARTITION?tank3));?
⑥分區(qū)管理⑦⑧⑨⑩
? ?1腺律,刪除分區(qū)
? ??alter?table?user?drop?partition?p4;??
? ?2奕短,新增分區(qū)
? ? range添加新分區(qū)?
? ? alter?table?user?add?partition(partition?p4?values?less?than?MAXVALUE);
? ??list添加新分區(qū)
? ? alter?table?list_part?add?partition(partition?p4?values?in?(25,26,28));??
? ?hash重新分區(qū)?
? ? alter?table?hash_part?add?partition?partitions?4;??
? ?key重新分區(qū)
? ? alter?table?key_part?add?partition?partitions?4;
?