SQL 創建表是通過SQL CREATE TABLE 語句來實現,該語句是DDL SQL語句。CREATE TABLE語句用於創建用於存儲數據的表。在創建表時,可以為列定義主鍵、惟一鍵和外鍵等完整性約束。完整性約束可以在列級或表級定義。對於不同的RDBMS, CREATE語句的實現和語法是不同的。
CREATE TABLE語句語法
- table_name—是表的名稱
-
column_name1, column_name2 ….-是列的名稱
-
datatype -是列的數據類型,比如char、date、number等
例如:如果要創建employee表,語句應該是這樣的:
在Oracle數據庫中,整數列的數據類型表示為“number”。在Sybase中,它表示為“int”。
Oracle提供了另一種創建表的方法。
在上面的語句中,使用與employee表相同的列數和數據類型創建了temp_employee表。
CREATE TABLE語句例子
比如我們想創建一個球員表,表名為player,里面有兩個字段,一個是player_id,它是int類型,另一個player_name字段是varchar(255)類型。這兩個字段都不為空,且player_id是遞增的。
那么創建的時候就可以寫為:
需要注意的是,語句最后以分號(;)作為結束符,最后一個字段的定義結束后沒有逗號。數據類型中int(11)代表整數類型,顯示長度為11位,括號中的參數11代表的是最大有效顯示長度,與類型包含的數值范圍大小無關。varchar(255)代表的是最大長度為255的可變字符串類型。NOT NULL表明整個字段不能是空值,是一種數據約束。AUTO_INCREMENT代表主鍵自動增長。
實際上,我們通常很少自己寫DDL語句,可以使用一些可視化工具來創建和操作數據庫和數據表。在這里我推薦使用Navicat,它是一個數據庫管理和設計工具,跨平台,支持很多種數據庫管理軟件,比如MySQL、Oracle、MariaDB等。基本上專欄講到的數據庫軟件都可以使用Navicat來管理。
假如還是針對player這張表,我們想設計以下的字段:
其中player_id是數據表player的主鍵,且自動增長,也就是player_id會從1開始,然后每次加1。player_id、team_id、player_name 這三個字段均不為空,height字段可以為空。
按照上面的設計需求,我們可以使用Navicat軟件進行設計,如下所示:
然后,我們還可以對player_name字段進行索引,索引類型為Unique。使用Navicat設置如下:
這樣一張player表就通過可視化工具設計好了。我們可以把這張表導出來,可以看看這張表對應的SQL語句是怎樣的。方法是在Navicat左側用右鍵選中player這張表,然后選擇“轉儲SQL文件”→“僅結構”,這樣就可以看到導出的SQL文件了,代碼如下:
你能看到整個SQL文件中的DDL處理,首先先刪除player表(如果數據庫中存在該表的話),然后再創建player表,里面的數據表和字段都使用了反引號,這是為了避免它們的名稱與MySQL保留字段相同,對數據表和字段名稱都加上了反引號。
其中player_name字段的字符集是utf8,排序規則是utf8_general_ci,代表對大小寫不敏感,如果設置為utf8_bin,代表對大小寫敏感,還有許多其他排序規則這里不進行介紹。
因為player_id設置為了主鍵,因此在DDL中使用PRIMARY KEY進行規定,同時索引方法采用BTREE。
因為我們對player_name字段進行索引,在設置字段索引時,我們可以設置為UNIQUE INDEX(唯一索引),也可以設置為其他索引方式,比如NORMAL INDEX(普通索引),這里我們采用UNIQUE INDEX。唯一索引和普通索引的區別在於它對字段進行了唯一性的約束。在索引方式上,你可以選擇BTREE或者HASH,這里采用了BTREE方法進行索引。我會在后面介紹BTREE和HASH索引方式的區別。
整個數據表的存儲規則采用InnoDB。之前我們簡單介紹過InnoDB,它是MySQL5.5版本之后默認的存儲引擎。同時,我們將字符集設置為utf8,排序規則為utf8_general_ci,行格式為Dynamic,就可以定義數據表的最后約定了:
你能看出可視化工具還是非常方便的,它能直接幫我們將數據庫的結構定義轉化成SQL語言,方便數據庫和數據表結構的導出和導入。不過在使用可視化工具前,你首先需要了解對於DDL的基礎語法,至少能清晰地看出來不同字段的定義規則、索引方法,以及主鍵和外鍵的定義。
數據表的常見約束
當我們創建數據表的時候,還會對字段進行約束,約束的目的在於保證RDBMS里面數據的准確性和一致性。下面,我們來看下常見的約束有哪些。
首先是主鍵約束
主鍵起的作用是唯一標識一條記錄,不能重復,不能為空,即UNIQUE+NOT NULL。一個數據表的主鍵只能有一個。主鍵可以是一個字段,也可以由多個字段復合組成。在上面的例子中,我們就把player_id設置為了主鍵。
其次還有外鍵約束
外鍵確保了表與表之間引用的完整性。一個表中的外鍵對應另一張表的主鍵。外鍵可以是重復的,也可以為空。比如player_id在player表中是主鍵,如果你想設置一個球員比分表即player_score,就可以在player_score中設置player_id為外鍵,關聯到player表中。
除了對鍵進行約束外,還有字段約束。
唯一性約束。
唯一性約束表明了字段在表中的數值是唯一的,即使我們已經有了主鍵,還可以對其他字段進行唯一性約束。比如我們在player表中給player_name設置唯一性約束,就表明任何兩個球員的姓名不能相同。需要注意的是,唯一性約束和普通索引(NORMAL INDEX)之間是有區別的。唯一性約束相當於創建了一個約束和普通索引,目的是保證字段的正確性,而普通索引只是提升數據檢索的速度,並不對字段的唯一性進行約束。
NOT NULL約束。
對字段定義了NOT NULL,即表明該字段不應為空,必須有取值。
DEFAULT,表明了字段的默認值。如果在插入數據的時候,這個字段沒有取值,就設置為默認值。比如我們將身高height字段的取值默認設置為0.00,即DEFAULT 0.00。
CHECK約束
用來檢查特定字段取值范圍的有效性,CHECK約束的結果不能為FALSE,比如我們可以對身高height的數值進行CHECK約束,必須≥0,且<3,即CHECK(height>=0 AND height<3)。
設計數據表的原則
我們在設計數據表的時候,經常會考慮到各種問題,比如:用戶都需要什么數據?需要在數據表中保存哪些數據?哪些數據是經常訪問的數據?如何提升檢索效率?
如何保證數據表中數據的正確性,當插入、刪除、更新的時候該進行怎樣的約束檢查?
如何降低數據表的數據冗余度,保證數據表不會因為用戶量的增長而迅速擴張?
如何讓負責數據庫維護的人員更方便地使用數據庫?
除此以外,我們使用數據庫的應用場景也各不相同,可以說針對不同的情況,設計出來的數據表可能千差萬別。那么有沒有一種設計原則可以讓我們來借鑒呢?這里我整理了一個“三少一多”原則:
1.數據表的個數越少越好
RDBMS的核心在於對實體和聯系的定義,也就是E-R圖(Entity Relationship Diagram),數據表越少,證明實體和聯系設計得越簡潔,既方便理解又方便操作。
2.數據表中的字段個數越少越好
字段個數越多,數據冗余的可能性越大。設置字段個數少的前提是各個字段相互獨立,而不是某個字段的取值可以由其他字段計算出來。當然字段個數少是相對的,我們通常會在數據冗余和檢索效率中進行平衡。
3.數據表中聯合主鍵的字段個數越少越好
設置主鍵是為了確定唯一性,當一個字段無法確定唯一性的時候,就需要采用聯合主鍵的方式(也就是用多個字段來定義一個主鍵)。聯合主鍵中的字段越多,占用的索引空間越大,不僅會加大理解難度,還會增加運行時間和索引空間,因此聯合主鍵的字段個數越少越好。
4.使用主鍵和外鍵越多越好
數據庫的設計實際上就是定義各種表,以及各種字段之間的關系。這些關系越多,證明這些實體之間的冗余度越低,利用度越高。這樣做的好處在於不僅保證了數據表之間的獨立性,還能提升相互之間的關聯使用率。
你應該能看出來“三少一多”原則的核心就是簡單可復用。簡單指的是用更少的表、更少的字段、更少的聯合主鍵字段來完成數據表的設計。可復用則是通過主鍵、外鍵的使用來增強數據表之間的復用率。因為一個主鍵可以理解是一張表的代表。鍵設計得越多,證明它們之間的利用率越高。
極客教程提供了DDL中與表(TABLE)相關的SQL語句: