DDL是DBMS的核心組件,是SQL的重要組成部分. DDL的正確性和穩定性是整個SQL髮型的重要基礎.數據庫
DDL的英文是Data Definition Language,也就是數據定義語言.定義了數據庫的結構和數據表的結構.經常使用的功能急救室增刪改,對應的命令分別是CREATE、DROP和ALTER.併發
CREATE DATABASE nba; // 建立名爲nba的數據庫 DROP DATABASE nba; // 刪除名爲nba的數據庫
CREATE TABLE table_name; // 建立表,table_name指表名
建立表的結構呢? 舉個實際的例子, 咱們建立一個球員表, 表名爲player, 裏面有兩個字段, 一個是player_id, 它是int類型,另外一個是player_name字段是varchar(255)類型, 兩個字段都不能爲空, 而且player_id是遞增的.數據庫設計
接下來建立表的語句這麼就是:高併發
CREATE TABLE player( player_id int(11) NOT NULL AUTO_INCREMENT, player_name varchar(255) NOT NULL );
注意的是每一個字段定義的語句最後使用 , 做爲結束符, 最後一個字段的定義結束以後沒有逗號的 , 而且語句最後是以 ; 結尾的. 數據類型中int(11)表明整數類型, 顯示長度是11位, 括號中的參數11表明的是最大有效顯示長度, 與類型包含的數值大小無關. varchar(255)表明的是最大長度爲255的可變字符串類型. NOT NULL表名整個字段不能爲空值,是一種數據約束. AUTO_INCREMENT表明主鍵自動增加.(通常狀況下使用可視化工具類建立和操做數據庫和數據庫表,好比Navicat)工具
接下來針對player表,設計下面字段:
性能
其中player_id是數據表player的主鍵, 且自動增加, 也就是player_id會從1開始, 而後每次加一, 沒必要爲它賦值. player_id、team_id、player_name這三個字段均不爲空, height字段能夠爲空.學習
使用Navicat工具建立表並導出的SQL文件以下所示:設計
DROP TABLE IF EXISTS `player`; CREATE TABLE `player`( `player_id` int(11) NOT NULL AUTO_INCREMENT, `team_id` int(11) NOT NULL, `team_name` varchar(255) CHARACTER SET utf8 collate utf8_general_ci NOT NULL , `height` float(3,2) NULL DEFAULT0.00, PRIMARY KEY(`player_id`) USING BTREE, UNIQUE INDEX `player_name`(`player_name`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
能夠看到整個SQL文件中的DDL處理, 首先刪除player表(若是數據庫中存在該表的話), 而後再建立player表, 裏面的字段名和表名都使用了反引號,這是爲了不名稱與MYSQL保留字段相同,對數據庫表和字段名都加上反引號.code
其中player_name字段的字符集是utf8, 排序規則是utf8_general_ci, 表明對大小寫不敏感, 若是設置爲utf8_bin, 表示對大小寫敏感.blog
由於player_id設置爲了主鍵, 因此在DDL中使用PRIMARY KEY進行規定,同時索引方法採用BTREE.
對player_name字段進行索引, 在設置索引時, 能夠設置UNIQUE INDEX(惟一索引), 也能夠設置爲其它索引方式, 好比NORMAL INDEX(普通索引), 這裏咱們採用UNIQUE INDEX. 惟一索引和普通索引的區別在於對字段進行了惟一性約束. 在索引方式上, 能夠選擇BTREE和HASH, 這裏採用BTREE方法進行索引.
整個數據表的存儲規則採用InnoDB, 是MYSQL5.5以後的默認存儲引擎, 將字符集設置爲utf8, 排序規則設置爲utf8_general_ci, 行格式爲Dynamic, 就能夠定義數據表的最後約定了:
ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
建立完表以後, 能夠對錶結構進行修改, 使用DDL命令來完成.
ALTER TABLE player ADD (age int(11));
ALTER TABLE player RENAME COLUMN age to player_age;
ALTER TABLE player MODIFT (player_age float(3,1));
ALTER TABLE player DROP CLOUMN player_age;
在建立數據表的時候, 會對字段進行約束, 約束的目的在於保證RDBMS裏面的數據的準確性和一致性.
主鍵起的做用是惟一標識一條記錄, 不能重複, 不能爲空, 即UNIQUE + NOT NULL. 一個數據表的主鍵只能有一個. 可是主鍵能夠是一個字段, 也能夠是多個字段符合組成. 上面的player_id就是主鍵.
外鍵起的做用是確保表與表之間引用的完整性. 一個表中的外鍵對應了另一張表中的主鍵. 外鍵能夠重複而且能夠爲空. 好比player_id是player表的主鍵,若是想設置一個球員比分表player_score, 能夠再player_score中設置player_id爲外鍵,關聯到player表.
惟一約束就是代表字段在表中的數值惟一, 主要是對除主鍵之外的其餘字段(主鍵自帶數值惟一BUFF). 上面對player_name進行了惟一性約束,也就是說球員的姓名不能相同. 注意的是惟一性約束和普通索引(NORMAL INDEX)之間的區別: 惟一性約束至關於建立了一個約束和普通索引, 目的是保證字段的正確性, 而普通索引只是提高數據檢索的速度, 並不對字段的惟一性進行約束.
對字段定義了NOT NULL, 代表字段不能爲空, 必須有取值.
代表字段的默認值, 若是在插入數據的時候該字段沒有取值, 就設置爲默認值.
用來檢查特定字段取值範圍的有效性, CHECK約束的結果不能爲FALSE.
"三少一多的原則":
RDBMS的核心在於對實體和聯繫的定義, 也就是E-R圖(Entity Relation Diagram), 數據表越少, 說明實體和聯繫設計得越簡潔, 即方便理解有方便操做.
字段個數越多, 數據冗餘的可能性越大. 設置字段個數少的前提是各個字段相互獨立, 而不是某個字段的取值能夠由其它字段計算出來. 固然字段個數少是相對的, 一般會在數據冗餘和檢索效率中進行平衡.
設置主鍵是爲了肯定惟一性, 當一個字段沒法肯定惟一性, 就須要採用聯合主鍵的方式. 聯合主鍵中的字段越多, 佔用的因此索引空間越大, 會加大理解難度, 會增長運行時間和索引空間.
數據庫的設計實際上就是定義各類表, 一級各類字段間的關係, 關係越多, 證實實體之間的冗餘度越低, 利用度越高, 這樣作的好處在於不只保證數據表之間的獨立性, 還能提高相互之間的關聯使用率. (不過在我如今的公司, 基本上沒有使用外鍵, 不知道是由於影響效率仍是什麼, 外鍵的意義起不到做用)
做者的意思是大型項目中後期,能夠採用業務層來實現,取消外鍵提升效率。不過在SQL學習之初,包括在系統最初設計的時候,仍是建議你採用規範的數據庫設計,也就是採用外鍵來對數據表進行約束。由於這樣能夠創建一個強一致性,可靠性高的數據庫結構,也不須要在業務層來實現過多的檢查。固然在項目後期,業務量增大的狀況下,你須要更多考慮到數據庫性能問題,能夠取消外鍵的約束,轉移到業務層來實現。並且在大型互聯網項目中,考慮到分庫分表的狀況,也會下降外鍵的使用。
建議是 不過在SQL學習,以及項目早期,仍是建議你使用外鍵。在項目後期,你能夠分析有哪些外鍵形成了過多的性能消耗。通常遵循2/8原則,會有20%的外鍵形成80%的資源效率,你能夠只把這20%的外鍵進行開放,採用業務層邏輯來進行實現,固然你須要保證業務層的實現沒有錯誤。不一樣階段,考慮的問題不一樣。當用戶和業務量增大的時候,對於大型互聯網應用,也會經過減小外鍵的使用,來減低死鎖發生的機率,提升併發處理能力。