Mysql的建表規範與注意事項

1、庫名、表名、字段名必須使用小寫字母,「_」分割;庫名、表名、字段名必須不超過12個字符;庫名、表名、字段名見名知意,建議使用名詞而不是動詞。html


2、建議使用InnoDB存儲引擎。mysql

存儲引擎:innoDb支持事物,myisam不支持事物,建議使用innoDb, 5.5之後的默認引擘,支持事務,行級鎖,更好的恢復性,高併發下性能更好,對多核,大內存,ssd等硬件支持更好。程序員

(1) MyISAM表是獨立於操做系統的,這說明能夠輕鬆地將其從Windows服務器移植到Linux服務器;每當咱們創建一個MyISAM引擎的表時,就會在本地磁盤上創建三個文件,文件名就是代表。例如,我創建了一個MyISAM引擎的tb_Demo表,那麼就會生成如下三個文件:sql

1.tb_demo.frm,存儲表定義;數據庫

2.tb_demo.MYD,存儲數據;安全

3.tb_demo.MYI,存儲索引。服務器

MyISAM表沒法處理事務,這就意味着有事務處理需求的表,不能使用MyISAM存儲引擎。MyISAM存儲引擎特別適合在如下幾種狀況下使用:網絡

1.選擇密集型的表。MyISAM存儲引擎在篩選大量數據時很是迅速,這是它最突出的優勢。併發

2.插入密集型的表。MyISAM的併發插入特性容許同時選擇和插入數據。例如:MyISAM存儲引擎很適合管理郵件或Web服務器日誌數據。分佈式

(2) InnoDB是一個健壯的事務型存儲引擎,這種存儲引擎已經被不少互聯網公司使用,爲用戶操做很是大的數據存儲提供了一個強大的解決方案。個人電腦上安裝的MySQL 5.6.13版,InnoDB就是做爲默認的存儲引擎。InnoDB還引入了行級鎖定和外鍵約束,在如下場合下,使用InnoDB是最理想的選擇:

1.更新密集的表。InnoDB存儲引擎特別適合處理多重併發的更新請求。
2.事務。InnoDB存儲引擎是支持事務的標準MySQL存儲引擎。
3.自動災難恢復。與其它存儲引擎不一樣,InnoDB表可以自動從災難中恢復。 4.外鍵約束。MySQL支持外鍵的存儲引擎只有InnoDB。 5.支持自動增長列AUTO_INCREMENT屬性。

通常來講,若是須要事務支持,而且有較高的併發讀取頻率,InnoDB是不錯的選擇。

(3)  MEMORY   :使用MySQL Memory存儲引擎的出發點是速度。

1.目標數據較小,並且被很是頻繁地訪問。在內存中存放數據,因此會形成內存的使用,能夠經過參數max_heap_table_size控制Memory表的大小,設置此參數,就能夠限制Memory表的最大大小。

2.若是數據是臨時的,並且要求必須當即可用,那麼就能夠存放在內存表中。

3.存儲在Memory表中的數據若是忽然丟失,不會對應用服務產生實質的負面影響。

(2) MERGE

MERGE存儲引擎是一組MyISAM表的組合,這些MyISAM表結構必須徹底相同,儘管其使用不如其它引擎突出,可是在某些狀況下很是有用。說白了,Merge表就是幾個相同MyISAM表的聚合器;Merge表中並無數據,對Merge類型的表能夠進行查詢、更新、刪除操做,這些操做其實是對內部的MyISAM表進行操做。Merge存儲引擎的使用場景


3、存儲精確浮點數必須使用DECIMAL替代FLOAT和DOUBLE。

(1) decimal 類型能夠精確地表示很是大或很是精確的小數。大至 1028(正或負)以及有效位數多達 28 位的數字能夠做爲 decimal類型存儲而不失其精確性。該類型對於必須避免舍入錯誤的應用程序(如記帳)頗有用。

一、   decimal   類型是適合財務和貨幣計算的   128   位數據類型。

二、   decimal不是浮點型、decimal不存在精度損失;

三、   decimal所能儲存的數比double大,從double到decimal的類型轉換不會出現任何問題。

四、

float 單精度浮點 32bit,

double 雙精度浮點64bit,

decimal是高精度 128bit,浮點型。

float double 是 基本類型(primitive type),decimal不是。

五、  浮點數運算會有精度損失問題,有精度損失時程序不會報告,要程序員本身注意。

(2)   mysql中的數值類型(不包括整型):

IEEE754浮點數: float  (單精度) , double  或 real  (雙精度)
    定點數: decimal 或 numeric
    單精度浮點數的有效數字二進制是24位,按十進制來講,是8位;雙精度浮點數的有效數字二進制是53位,按十進制來講,是16 位

一個實數的有效數字超過8位,用單精度浮點數來表示的話,就會產生偏差!一樣,若是一個實數的有效數字超過16位,用雙精度浮點數來表示,也會產生偏差

(3)    IEEE754標準的計算機浮點數,在內部是用二進制表示的,但在將一個十進制數轉換爲二進制浮點數時,也會形成偏差,緣由是否是全部的數都能轉換成有限長度的二進制數。

即一個二進制能夠準確轉換成十進制,但一個帶小數的十進制不必定可以準確地用二進制來表示。


4、建議使用INT UNSIGNED存儲IPV4。

(1) 用UNSINGED INT存儲IP地址佔用4字節,CHAR(15)則佔用15字節。另外,計算機處理整數類型比字符串類型快。使用INT UNSIGNED而不是CHAR(15)來存儲IPV4地址,經過MySQL函數inet_ntoa和inet_aton來進行轉化。IPv6地址目前沒有轉化函數,須要使用DECIMAL或兩個BIGINT來存儲。

例如:

SELECT INET_ATON('209.207.224.40');

3520061480

SELECT INET_NTOA(3520061480);

209.207.224.40


5、 整形定義中不添加長度,好比使用INT,而不是INT(4)。

(1) mysql中int數據類型長度最大爲11位,最少爲4位,不夠在前面補空格。

(2) 而mysql中int自己就是4個字節 bigint是8個字節 因此說int(X)的含義就是 int決定數據存儲的字節 X表示指望數據的列寬度

在SQL語句中int表明你要建立字段的類型,int表明整型,11表明字段的長度。

整數列的顯示寬度與mysql須要用多少個字符來顯示該列數值,與該整數須要的存儲空間的大小都沒有關係,好比,無論設定了顯示寬度是多少個字符,bigint都要佔用8個字節。


6、短數據類型,使用TINYINT。

(1) 一樣的字節數,非負存儲的數值範圍更大。如TINYINT有符號爲 -128-127,無符號爲0-255。

一、TINYINT ,字段類型,若是設置爲UNSIGNED類型,只能存儲從0到255的整數,不能用來儲存[負數]。

二、TINYINT 型的字段若是不設置UNSIGNED類型,存儲-128到127的整數。

提示:  一般,爲了節省空間,應該儘量的使用最小的 [整型數據]。一個TINYINT型數據只佔用一個字節,一個INT型數據佔用四個字節。這看起來彷佛差異不大,可是在比較大的表中,字節數的增加是很快的。另外一方面,一旦你已經建立了一個字段,要修改它是很困難的。所以,爲安全起見,你應該預測一下,一個字段所須要存儲的數值最大有多是多大,而後選擇適當的數據類型。

(2)

tinyint 1字節 (-128,127)

smallint 2字節 (-32768,32767)

int 無符號 0-65535

mediumint 3字節 (-8388608,8388607)

int或integer 4字節 (-2147483648,2147483647)


7、不建議使用ENUM類型,使用TINYINT來代替。

詳細講解:

提及這個ENUM, 經查閱各大技術社區的網絡文摘,ENUM確實是mysql裏的一個特點字段,印象裏模糊記得在之前看到一些比較知名的商城系統如shopnc裏面在用它,但也沒細究,多是由於他能夠設置字段的區間範圍,會讓值能夠被數據庫所控制,有枚舉約束的功能(好比,字段只想有0和1,若是用 TINYINT(1),結果就可能出現2,那2就是贓數據了)

但ENUM也有一些比較棘手的問題,好比數據遷移的時候,他幾乎不可能被其餘數據庫所支持,若是enum裏面是字符串,對於其餘數據庫來講就更鬱悶了,還不能設爲tinyint等類型的字段(enum雖然能夠存儲字符串,但對於內部來講,仍是以順序進行索引,好比'a','b','c',咱們也能夠用索引值來獲取值select * from tbl_name whre enum = 2,這與select * from tbl_name where enum = 'b'等義)若是你看明白了這兩句SQL爲何等義,那麼你也就能夠了解爲何不主張用enum字段了。

也就是說,假如一個設計不合理的ENUM字段,給程序員帶來的就徹底是夢魘了,好比一個enum字段的範圍是('0','1','2','3','4','5'),而enum的枚舉值對應的索引是從1開始的,所以,insert into table (enum)values(1),插入的並非1,而是0

另外假如你在設計好enum的枚舉字段範圍並使用了一段時間後,再到字段範圍中加一個枚舉值,而且不是加在最後,那麼也就至關於把原來的範圍都改變了索引值,也就是當你在查詢的時候直接查詢值(並加上單引號),將不會使用enum自身隱藏的索引值來獲取結果了。

若是是純數值型,仍是建議採用tinyint字段吧,畢竟它也只佔一個字節,即便出現贓數據,也能夠被接受,不象enum,若是純數字型範圍,更改了索引,你就不知道你查詢的值是否正確了)


8、儘量不使用TEXT、BLOB類型。

  1. TEXT、BLOB類型會使查詢變慢,若是須要保存超長字符集,建議用varchar(n)類型或將過大字段拆分到其餘表中;

  2. 使用VARBINARY存儲變長字符串,binary儲存定長字符串。由於二進制字節流,不存在編碼問題

    binary(n) :固定長度爲 n 字節,其中 n 值從 1 到 8,000 ,存儲空間爲 n 字節;
    
     varbinary( n | max):可變長度,n 的取值範圍爲 1 至 8,000,max 是指最大存儲空間是 2^31-1 個字節,即最大4GB;
    
     n:在表列定義或變量聲明語句中沒有指定 n,則默認長度爲 1;在CAST 函數中沒有指定 n,則默認長度爲 30;
    
     詳情:::      [http://www.cnblogs.com/ljhdo/p/4530293.html](http://www.cnblogs.com/ljhdo/p/4530293.html)

對比

一、 BLOB是一個二進制大對象,能夠容納可變數量的數據。有4種 BLOB類型:TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB。它們只是可容納值的最大長度不一樣。

有4種TEXT類型:TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT。這些對應4種BLOB類型,有相同的最大長度和存儲需求。

二、 BLOB 列被視爲二進制字符串(字節字符串)。TEXT列被視爲非二進制字符串(字符字符串)。BLOB列沒有字符集,而且排序和比較基於列值字節的數值值。TEXT列有一個字符集,而且根據字符集的 校對規則對值進行排序和比較。

在TEXT或BLOB列的存儲或檢索過程當中,不存在大小寫轉換。

三、 在大多數方面,能夠將BLOB列視爲可以足夠大的VARBINARY列。一樣,能夠將TEXT列視爲VARCHAR列。BLOB和TEXT在如下幾個方面不一樣於VARBINARY和VARCHA

注意事項:

因爲BLOB和TEXT值可能會很是長,使用它們時可能遇到一些約束:

當排序時只使用該列的前max_sort_length個字節。max_sort_length的 默認值是1024;該值能夠在啓動d服務器時使用--max_sort_length選項進行更改。

運行時增長max_sort_length的值能夠在排序或組合時使更多的字節有意義。任何客戶端能夠更改其會話max_sort_length變量的值:


久、禁止在數據庫中使用VARBINARY、BLOB存儲圖片、文件等。

若是要存儲圖片、文件等 採用分佈式文件系統更高效


10、VARCHAR(N),N表示的是字符數不是字節數,好比VARCHAR(255),能夠最大可存儲255個漢字,須要根據實際的寬度來選擇N。

區別:

一、char的總結:

char最大長度是255字符,注意是字符數和字符集不要緊。能夠有默認值,尾部有空格會被截斷。

二、varchar的總結:

varchar的最大長度65535是指能存儲的字節數,其實最多隻能存儲65532個字節,還有3個字節用於存儲長度。注意是字節數這個和字符集有關係。一個漢字字符用utf8佔用3字節,用gbk佔用2字節。存儲的最大字符數因編碼不一樣而不一樣一般是n=65532/3或n=65532/2個字符。能夠有默認值,尾部有空格不會截斷。

二 理論知識

先說明一下 MySQL 從來版本對 varchar 的定義:

4.0版本如下,varchar(50),指的是50字節,若是存放UTF8漢字時,只能存16個(每一箇中文3字節)

5.0版本以上,varchar(50),指的是50字符,不管存放的是數字、字母仍是UTF8中文(每一箇中文3字節),均可以存放50個

存儲限制

須要額外佔用字節存放字符的長度:小於255爲1個字節,大於255則要2個字節

編碼限制

gbk :每一個字符最多佔用2個字節

utf8:每一個字符最多佔用3個字節

utf8mb4 每一個字符最多佔用4個字節,中文佔3個字節,emoji表情符號 佔用4個字節

列長度限制

MySQL定義行的長度不能超過65535,該數值限制了列的數目。好比全部列爲char(128) utf8字符集,最多有65535/(128*3)=170個列。


1、表字符集選擇UTF8。

(1) 使用utf8字符集,若是是漢字,佔3個字節,但ASCII碼字符仍是1個字節。

(2) 統一,不會有轉換產生亂碼風險

(3) 其餘地區的用戶(美國、印度、臺灣)無需安裝簡體中文支持,就能正常看您的文字,而且不會出現亂碼

(4) ISO-8859-1編碼(latin1)使用了單字節內的全部空間,在支持ISO-8859-1的系統中傳輸和存儲其餘任何編碼的字節流都不會被拋棄。即把其餘任何編碼的字節流看成ISO-8859-1編碼看待都沒有問題,保存的是原封不動的字節流。


12、存儲年使用YEAR類型。

**    重點:: mysql的日期與時間類型:分爲time、date、datetime、timestamp、year,**

(1)、類型支持:year 與 year(4),注意無year(2)的定義方式,不然報錯「[Err] 1818 - Supports only YEAR or YEAR(4) column.」

create table if  not exists time(
atime  YEAR                         #year的定義,可寫成year或者year(4)

) engine =innodb charset = utf8;

(2)、插入值,支持整數和字符串,支持 2位數 或者 4位數

00~69  將轉換爲2000~2069之間

70~99  將轉換爲1970~1999之間

#測試year類型insert into time values( 78);    #數據庫中顯示:1978
insert into time values('78'); #數據庫中顯示:1978

insert into time values('1978'); #數據庫中顯示:1978

(3)、注意點

一、 支持插入 數字0 或者 字符串0,實際顯示的數值不一樣

insert into time  values( 0);  #數據庫中顯示:0
insert into time values('0'); #數據庫中顯示:2000

二、year只保存年份,佔用空間小

三、其餘和日期有關的能夠經過整型保存

時間初  : 存9位


十3、存儲日期使用DATE類型。

MySQL日期類型、日期格式、存儲空間、日期範圍比較。

日期類型        存儲空間       日期格式                 日期範圍

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

datetime       8 bytes   YYYY-MM-DD HH:MM:SS   1000-01-01 00:00:00 ~ 9999-12-31 23:59:59

timestamp      4 bytes   YYYY-MM-DD HH:MM:SS   1970-01-01 00:00:01 ~ 2038

date           3 bytes   YYYY-MM-DD            1000-01-01          ~ 9999-12-31

year           1 bytes   YYYY                  1901                ~ 2155


十4、存儲時間(精確到秒)建議使用int/bigint類型,int使用4字節,bigint使用8個字節。

1)int (1) 4個字節存儲,INT的長度是4個字節,存儲空間上比datatime少,int索引存儲空間也相對較小,排序和查詢效率相對較高一點點 (2)可讀性極差,沒法直觀的看到數據,可能讓你很惱火

能夠略微注意2038年問題的陷阱。對於MySQL而言,若是存時間戳請使用timestamp或bigint,而不要使用int。 2)TIMESTAMP

(1)4個字節儲存 (2)值以UTC格式保存 (3)時區轉化 ,存儲時對當前的時區進行轉換,檢索時再轉換回當前的時區。 (4)TIMESTAMP值不能早於1970或晚於2037

3)datetime (1)8個字節儲存 (2)與時區無關 (3)以'YYYY-MM-DD HH:MM:SS'格式檢索和顯示DATETIME值。支持的範圍爲'1000-01-01 00:00:00'到'9999-12-31 23:59:59'a


十5、建議字段定義爲NOT NULL。

**   (1)**空值是不佔用空間的, not null的效率比null高

** (2) ** MySQL中的NULL實際上是佔用空間的  : 打個比方來講,你有一個杯子,空值表明杯子是真空的,NULL表明杯子中裝滿了空氣,雖然杯子看起來都是空的,可是區別是很大的。


十6、表結構變動須要通知DBA審覈。

數據庫管理員 DBA :::Database Administrator

**    (1)** 每次變動不能說變就變了,否則,別人不知道,確定也是按照原來的來,報錯的話,也就很差往下進行了,

每次變動,提早說,都知道,審覈,DBA以爲合理在審覈經過,再把這些變動的,放入一個文件裏,便於

查看,修改了什麼。

平時數據庫得維護,管理,看看這設計得是否合理,不合理的更改,

相關文章
相關標籤/搜索