一, 數(shù)據(jù)庫對象命名規(guī)范
表名,字段名,視圖名,存儲過程名,函數(shù)名,觸發(fā)器名稱統(tǒng)一使用大寫字母命名。使用最接近數(shù)據(jù)庫對象含義的英文單詞,單詞組合,或縮寫來命名,盡可能做得見名知意。
表名: 以T_開頭,比如:T_COMMONCONTENT
字段名:大寫英文單詞或縮寫
視圖名:以V_開頭。
存儲過程名:以P_開頭
函數(shù)名:以F_開頭
觸發(fā)器名:以TR_開頭
索引名: 以IDX_開頭
二, 數(shù)據(jù)庫設(shè)計
2.1 數(shù)據(jù)類型選擇
選擇原則:在滿足需求的前提下,盡可能選擇范圍較小的數(shù)據(jù)類型來定義字段。涉及貨幣的字段都選擇精確度高的decimal定長數(shù)據(jù)類型來表示。按以下優(yōu)先級來選擇數(shù)據(jù)類型:
高優(yōu)先級 低優(yōu)先級
TINYINT--------->BIGINT---àCHAR-----àVARCHAR-------àTEXT-----àLONGTEXT
在滿足業(yè)務(wù)定義需求的前提下,能選擇整型的就用整型,位數(shù)短的用短整型,如果位數(shù)不夠就用長整型,位數(shù)逐步增加。不能用整型的優(yōu)先選用字符型(CHAR),字符型不夠選用變長字符型(VARCHAR),最后才考慮選用文本型(TEXT)。對只有一位長度的字段,比如狀態(tài)值等,統(tǒng)一使用TINYINT類型??傊?,在數(shù)據(jù)類型的選擇上,做到寧短勿長,這樣即能節(jié)省存儲空間,又能提高處理速度。
以下是各種整數(shù)類型的存儲字節(jié)數(shù)和數(shù)值表達范圍:
整數(shù)類型
存儲字節(jié)
數(shù)值表達范圍
tinyint
1
有符號 -128----------127
無符號 0-------------255
smallint
2
有符號 -32768----------32767
無符號 0--------------65535
Mediumint
3
有符號 -8388608--------8388607
無符號 0---------------16777215
Int
4
有符號 -2147483648---------2147483647
有符號 0----------------4294967295
Bigint
8
有符號 -9223372036854775808-------9223372036854775807
無符號 0-----------------18446744073709551616
2.2 數(shù)據(jù)庫設(shè)計
2.2.1 主外鍵定義
每個表都要求定義主鍵和外鍵約束,通過外鍵的定義,可以保障數(shù)據(jù)的一致性和完整性。定義外鍵時,統(tǒng)一采用ON DELETE SET NULL ON UPDATE SET NULL方式。這種方式在刪除被參照表的數(shù)據(jù)時,數(shù)據(jù)庫將自動把參照表中的相關(guān)記錄的相關(guān)字段置空。這樣的好處是,當(dāng)參照表的記錄被刪除時,子表記錄可以完整的保存下來。
定義主鍵健外鍵例子:
CREATE TABLE customerinfo
(
CustomerID INT NOT NULL ,
PRIMARY KEY ( CustomerID )
) TYPE = INNODB;
CREATE TABLE salesinfo
(
SalesID INT NOT NULL,
CustomerID INT NOT NULL,
PRIMARY KEY(CustomerID, SalesID),
FOREIGN KEY (CustomerID) REFERENCES customerinfo
(CustomerID) ON DELETE SET NULL ON UPDATE SET NULL
) TYPE = INNODB;
2.2.2 數(shù)據(jù)表中字段順序
在數(shù)據(jù)表的設(shè)計時統(tǒng)一規(guī)定各字段依以下順序設(shè)置:
主鍵---------->同步字段(version)----------->外鍵--------->其它字段
2.2.3 索引創(chuàng)建問題
索引對大數(shù)據(jù)量表查詢來說,比較重要,過多過少的索引,不合理的索引都會直接影響到SQL的查詢性能,建議到測試時統(tǒng)一由數(shù)據(jù)庫支持人員創(chuàng)建。
2.2.4 表拆分問題
在進行數(shù)據(jù)庫表設(shè)計時,盡可能使SQL查詢的表關(guān)聯(lián)數(shù)不要超過3個,如果表關(guān)連太多,可能需要考慮使用冗余字段來減少表關(guān)聯(lián)的個數(shù)。關(guān)聯(lián)表太多的SQL查詢,很可能效率比較差并且優(yōu)化困難。
如果設(shè)計的表包括大數(shù)據(jù)量的TEXT或BLOB類型字段,盡量把大數(shù)據(jù)量大的TEXT(BLOB)字段拆成單獨的表,避免導(dǎo)致整個表的查詢都慢。
2.2.5 數(shù)據(jù)庫接口定義
表設(shè)計統(tǒng)一采用PowerDesigner工具完成,除設(shè)計本模塊的表外,還需要標(biāo)出外模塊的參照表或有數(shù)據(jù)關(guān)系的表,建議用虛線標(biāo)出外模塊相關(guān)的表。
三, SQL編寫規(guī)范
3.1 SQL簡化和減少數(shù)據(jù)庫查詢次數(shù)
在滿足業(yè)務(wù)需求的前提下,盡可能使編寫的SQL簡單,不要選擇多余的字段和不必要的嵌套查詢,越簡單的SQL,查詢性能可能越好,也越好進行性能優(yōu)化。
比如:
不要用SELECT *:SELECT語句中寫出必要的要選擇的全部列名,增強語句可讀性,避免不必要的選擇;SELECT *增加了對所有字段的依賴,當(dāng)表增加了字段后,有可能發(fā)生錯誤;此外還可能增加了數(shù)據(jù)的流量,查詢了一些實際不需要的字段。
其它SQL查詢也要求選擇真正需要選擇的字段,避免選擇出多余的字段。
另外,盡可能減少數(shù)據(jù)庫操作的次數(shù),建議一次性查出你需要的結(jié)果集,先放到應(yīng)用內(nèi)存中進行遍歷處理。
3.2 索引使用問題
3.2.1 在查詢列上避免使用表達式
在WHERE中,數(shù)據(jù)庫函數(shù)、計算表達式等等,要盡可能將放在等號右邊。否則會使所比較的字段上的索引失效;
SELECT?。?div style="height:15px;">
FROM service_promotion
WHERE TO_CHAR(gmt_modified,’yyyy-mm-dd’)
= ‘20001-09-01’;
而應(yīng)使用:
SELECT *
FROM service_promotion
WHERE gmt_modified
>= DATE_FORMAT('2009-07-26 20:49:33','%Y-%m-%d');
AND gmt_modified
< DATE_FORMAT('2009-07-26 20:49:33','%Y-%m-%d');
3.2.2 查詢條件列類型的隱含轉(zhuǎn)換
盡量注意比較值與查詢列數(shù)據(jù)類型的一致性(int與int比較、char與char比較),避免使用數(shù)據(jù)庫的類型自動轉(zhuǎn)換功能,比如:
SELECT * FROM category
WHERE id = ‘123’;
-- id在表中定義為int類型
3.2.3 Like查詢
在進行模糊查詢時,不要使用WHERE columnname like ‘%字符串%’這樣的查詢形式,這樣的查詢語句不能使用列上所建的索引,當(dāng)數(shù)據(jù)量稍微有點大就會導(dǎo)致有嚴重的性能問題。如果確實有這樣的需求,應(yīng)該考慮用別的方式實現(xiàn)。這個問題需要在表設(shè)計的時候就考慮到。
3.2.4 排序,分組查詢
大量的排序操作將嚴重影響系統(tǒng)性能,所以盡量減少order by和group by排序操作。如果有大數(shù)據(jù)量的表確實存在大范圍的分組查詢求和運算,建議通過建立臨時統(tǒng)計表,通過觸發(fā)器或后臺作業(yè)來完成統(tǒng)計數(shù)據(jù)的計算。對大數(shù)據(jù)量表的排序查詢,除可以在排序列上建立索引外,應(yīng)該盡量通過表設(shè)計加條件減少排序范圍來實現(xiàn)排序操作。
對于進行分組求和操作的SQL,可以通過增加選擇項來避免排序,比如,在sql語句的末尾增加order by null選項避免進行資源消耗量極大的排序操作。
Select id,sum(moneys) from sales2 group by id order by null;
3.2.5 視圖,存儲過程,函數(shù),觸發(fā)器的使用
復(fù)雜,重復(fù)性使用率高的SQL查詢語句,建議定義成視圖(VIEW)來使用,好處是將來可以在數(shù)據(jù)庫后臺進行修改,優(yōu)化等維護,同時也可以簡化應(yīng)用端的代碼編寫。對操作任務(wù)量大,比如定時性的數(shù)據(jù)統(tǒng)計,計算任務(wù),建議編寫成存儲過程,函數(shù)來實現(xiàn)。盡量少用觸發(fā)器,特別是使用帶有大量數(shù)據(jù)操作任務(wù)的觸發(fā)器,那樣的觸發(fā)器會降低表的更新速度。而且大量使用觸發(fā)器會給數(shù)據(jù)庫的維護帶來更大的難度。
3.2.6 使用批操作提高數(shù)據(jù)插入效率
如果數(shù)據(jù)插入量比較大,建議寫成批量操作的形式,將能大大提高數(shù)據(jù)庫插入的效率,比如:
INSERT INTO `T_VISITIP` VALUES
(38094,'10.10.10.0',10,'2007-02- 28'),
(38095,'10.10.10.1',10,'2007-02- 28'),
(38096,'10.10.10.2',10,'2007-02- 28'),
(38097,'10.10.10.3',10,'2007-02- 28') ,
………………………………..;
begin;
INSERT INTO a VALUES (1,23),(2,34),(4,33);
INSERT INTO a VALUES (8,26),(6,29);
………………………
commit;
3.2.7 慎用union或union all
慎用union或union all,特別是合并后再進行排序操作的SQL,碰到數(shù)據(jù)量比較大時,進行優(yōu)化會非常困難。
3.2.8 優(yōu)化嵌套查詢
使用連接(JOIN)來代替子查詢(Sub-Queries) ,在有的情況下可能能大大提高sql執(zhí)行的速度。
子查詢:
SELECT * FROM customerinfo WHERE CustomerID in (SELECT CustomerID FROM salesinfo )
改寫成:
SELECT Ci.* FROM customerinfo ci, salesinfo sf
WHERE ci. CustomerID=sf. CustomerID
四, 數(shù)據(jù)庫有用知識
4.1 中文排序,大小寫字母排序
如果排序時想?yún)^(qū)分大小寫,并按照中文的首字母排序,請這樣定義你的字符字段類型,比如:
CREATE TABLE `test1` (
`a` int(11) default NULL,
`b` varbinary(30) default NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
排序例子:
mysql> select * from test1 order by b;
+------+----------+
| a | b |
+------+----------+
| 1 | 1111 |
| 1 | 22222 |
| 1 | AA |
| 1 | Ab |
| 1 | Az |
| 1 | aA |
| 1 | aa |
| 1 | 阿拉斯加 |
| 1 | 地震 |
| 1 | 丫頭 |
| 1 | 中國 |
+------+----------+
11 rows in set (0.00 sec)
4.2 字符集選擇
Z-SHOP數(shù)據(jù)庫將使用UTF-8多語言字符集,該字符集可以存儲支持多種語言。如果是linux系統(tǒng),可以在mysql配置文件/etc/my.cnf的[mysqld]部分添加
default-character-set=utf8
重啟mysql數(shù)據(jù)庫后,在服務(wù)器上創(chuàng)建的表使用的就是utf8字符集。如果是windows系統(tǒng),mysql的配置文件是my.ini??蛻舳艘话憧梢赃x用gbk字符集就能滿足開發(fā)要求了。
4.3 存儲引擎選擇
Z-SHOP數(shù)據(jù)庫將主要使用INNODB存儲引擎,如果是linux系統(tǒng),可以在mysql配置文件/etc/my.cnf的[mysqld]部分添加
default-storage-engine=innodb
重啟mysql數(shù)據(jù)庫后,在服務(wù)器上創(chuàng)建的表使用的就是innodb存儲引擎。如果是windows系統(tǒng),mysql的配置文件是my.ini。