目錄
表的操作是數據庫中的重要內容,在此總結一下MySql數據庫的表操作。
本文參考書籍《MySql入門很簡單》
1 創建表
創建表的SQL語句格式如下:
CREATE TABLE 表名(屬性名 數據類型 [完整性約束條件],
屬性名 數據類型 [完整性約束條件],
...
屬性名 數據類型 [完整性約束條件]
);
注意創建表的時候要選擇合適的數據類型,而且還可以給字段添加完整性約束條件,比如主鍵、非空鍵等,完整的約束條件如下所示:
約束條件 |
說明 |
PRIMARY KEY |
修飾的屬性爲該表的主鍵,可以區分不同的行記錄 |
FOREIGN KEY |
修飾的屬性爲該表的外鍵,關聯了父表的主鍵 |
NOT NULL |
表示該屬性不能爲空 |
UNIQUE |
表示該屬性的值是唯一的 |
AUTO_INCREMENT |
MySQL特色,表示該屬性是自增的,整數類型 |
DEFAULT |
給屬性設置默認值 |
1.1 設置表的主鍵
接下來我們來創建一個student表:
如下圖所示:
如上所示,創建了一個student表,有兩個屬性,id,設置爲主鍵,name設置爲非空。
同時我們還可以爲表設置多個主鍵,如下,我們創建一個表example0:
如上,通過PRIMARY KEY(屬性名,屬性名,……)的語法格式可以爲表設置多個主鍵。
1.2 設置表的外鍵
外鍵是表的一個特殊字段。如果字段sno是一個表A的屬性,且依賴於B的主鍵。那麼,稱表B爲父表,表A爲子表,sno爲表A的外鍵。那麼就可以通過sno字段將父表和子表建立關聯關係。
外鍵的作用:設置外鍵的作用是建立該表與其父表的關聯關係。當父表中刪除某條信息時,子表中與之對應的信息也必須有相應的改變。
例如,stu_id是student表的主鍵,stu_id是表grade的外鍵。當stu_id爲“123”的同學退學了,需要刪除student表中該 學生的信息,那麼grade表中與該學生對應的信息也應該刪除。這樣保證了數據的完整性和一致性。
在1.1節中,我們創建了一個表example0,其中有stu_id和courese_id,且都爲主鍵。下面我們創建一個表example1,且將外鍵設置爲example0表中的兩個主鍵。
sql語句如下圖:
表example1有三個屬性,id爲主鍵,stu_id和course_id爲外鍵,fk爲外鍵的別名,從上可以發現創建外鍵的語法格式爲:
CONSTRAINT 外鍵別名 FOREIGN KEY(屬性名1,屬性名2,……) REFERENCES 表名(屬性名1,屬性名2,……)
需要注意:子表的外鍵關聯的必須是父表的主鍵,而且數據類型必須保持一致。
除了設置表的主鍵外鍵外,我們還可以設置表的非空約束、表的唯一性約束、屬性值自動、默認值,都非常簡單,應用相應的約束性條件即可。這裏不再舉例。
2 刪除表
刪除表的時候要注意,要刪除的表是一個普通的表還是一個被關聯的表:
刪除普通表可以直接用下面的sql語句來進行刪除:
DROP TABLE 表名;
當我們要刪除一個被關聯的表的時候,上述的方法不再適用,用上述方法刪除父表,會報錯,可以自行嘗試。
我們知道,表的關聯是通過設置外鍵來實現的。但是我們用上述語句直接刪除子表是沒有問題的。因此我們的一種解決方案是先刪除子表,再去刪除父表,但是這樣可會影響其他子表的數據。因此,我們可以先刪除子表的外鍵約束,再去刪除父表,從而不會影響其他表的數據。
刪除表的外鍵約束的時候我們可以使用:ALTER TABLE 表名 DROP FOREIFN KEY 外鍵別名;
舉例:上述中我們建立了兩個表,example0爲父表,example1爲子表:
我們先來直接刪除父表:
可以發現,直接刪除父表會直接報錯。
因此我們先來刪除子表中的外鍵約束,再來刪除父表:
其中fk爲example1中的外鍵別名。再去刪除父表,發現沒有報錯。成功。
注意:刪除子表中的外鍵約束,比如外鍵爲stu_id,刪除之後,與父表的關聯不再存在,但是子表中stu_id屬性還是存在的。
3 查看錶
這裏的查看錶指的是查看錶的結構。
可以使用DESCRIBE 表名進行查看,如下:
可以將,example的屬性信息展示出來。
我們還可以通過語句SHOW CREATE TABLE 表名的方法將展示表的詳細信息,如下:
上圖中通過show create table 語句展示了example1的詳細信息,包括屬性約束條件、主鍵、外鍵、關聯信息、存儲引擎和字符編碼。
4 修改表
修改表主要用到的SQL語句爲ALTER,同時,修改表包含許多個小部分,一一解釋。
4.1 修改表名
修改表名的語法形式如下:
ALTER TABLE 舊錶名 RENAME 新表名;
4.2 修改字段的數據類型
語法形式如下:
ALTER TABLE 表名 MODIFY 屬性名 新屬性類型;
4.3 修改表的字段名
語法形式如下:
ALTER TABLE 表名 CHANGE 舊屬性名 新屬性名 新數據類型;
4.4 增加字段
首先,向表中增加字段的語法格式如下:
ALTER TABLE 表名 ADD 屬性名1 屬性類型 [約束條件] [FIRST |AFTER 屬性名2];
上述加”[]“的爲可選項。
屬性名1爲要添加的字段名,[FIRST|AFTER 屬性名]表示要添加的位置,默認爲末尾,FIRST爲首部添加,AFTER 屬性名2:屬性名2爲表原有的屬性名,表示將新的字段添加在屬性名2之後。
一個實例:
我們現在有一個表example,結構如下:
現在我們在stu_id後面添加一個name屬性:
可以發現,name成功的添加在了stu_id之後。
5 查詢表
表的查詢操作可以說是數據庫操作裏面最重要的操作。
MySql的基本查詢語句如下:
SELECT 屬性列表
FROM 表名
[WHERE 條件表達式1]
[GROUP BY 屬性名1 [HAVING 條件表達式2]]
[ORDER BY 性名2[ASC|DESC]];
其中屬性名爲要查詢的字段名,”條件表達式1”指定查詢條件;“屬性名1“參數按指定該字段中的數據進行分組,”條件表達式2”參數表示滿足該表達式的數據才能進行輸出,“屬性名2“參數指定該字段中的數據進行排序,排序方式由ASC和DESC兩個參數指出,ASC表示升序,DESC表示降序。
接下來詳細介紹一下常用的SQL查詢,在這之前,先來建一張表,在下述難理解的查詢中,用此表舉例。
表名:employee
5.1 帶in子的查詢
語句格式爲
[NOT] IN (元素1,元素2……)
如:select * from user where id in (select stu_id from grade where average>=60.0);
帶in的普通查詢如下所示:
in後面根一跟集合。
5.2 帶BETWEEN AND的範圍查詢
[NOT] BETWEEN 取值1 AND 取值2
如:select * from user where average between 80.0 and 100.0;
5.3 帶like的通配符匹配查詢
[NOT] LIKE '字符串'
注意此處LIKE後面的字符串可以攜帶通配符
% : 表示0個或任意長度的字符串
_ :只能表示單個字符
如:select * from news where content like “%亞運會%”;
5.4 空值查詢
IS [NOT] NULL;
如:select * from user where b.id is NULL;
5.5 帶AND的多條件查詢
條件表達式1 AND 條件表達式2 [... AND 條件表達式n]
如:select * from user where average between 80.0 and 100.0 and user.sex=’男’;
5.6 帶OR的多條件插查詢
條件表達式1 OR 條件表達式2 [... OR 條件表達式n]
如:select * from user where grade.math>80.0 or grade.english>80.0;
5.7 去重複查詢
SELECT DISTINCT 屬性名
如:select distinct name from user ;
5.8 對結果排序
ORDER BY 屬性名 [ASC | DESC]
如:select * from user where average between 80.0 and 100.0 order by average desc;
5.9 分組查詢
GROUP BY 屬性名 [HAVING 條件表達式]
對於分組排序,用前面提到的employee來進行示例。
分組查詢可以將查詢結果的按照某個字段或者多個字段來進行分組。字段中值相等的爲一組。
當單獨使用GROUP BY來分組的時侯,查詢結果只顯示一個分組的一條記錄。
因此,GRUOP BY一般會與GROUP_CONCAT()函數、集合函數、HAVING等一起使用。
與GROUP_CONCAT()一起使用:
GROUP_CONCAT 會將每個分組中的指定字段顯示出來,如下:
與集合函數一起使用:
當使用GROUP_BY的時候,我們可以通過集合函數來計算組中的總記錄、最大值、最小值等。
與關鍵字HAVING一起使用:
這個理解起來也比較直觀,如下:
5.10 union合併查詢
SELECT expression1, expression2, ... expression_n
FROM tables[WHERE conditions]
UNION [ALL | DISTINCT]
注意:union默認去重,不用修飾distinct,all表示顯示所有重複值
SELECT expression1, expression2, ... expression_n
FROM tables[WHERE conditions];
如:SELECT country FROM Websites UNION ALL SELECT country FROM apps ORDER BY country;
5.11 LIMIT分頁查詢
limt查詢會查找固定數量的數據。不指定初始位置是個數是LIMIT 記錄數;指定初始位置格式是LIMIT 初始位置, 記錄數。
5.12 內連接查詢和外連接查詢
內連接查詢:
SELECT a.屬性名1,a.屬性名2,...,b,屬性名1,b.屬性名2... FROM table_name1 a, table_name2 b on a.id = b.id where a.屬性名 滿足某些條件;
內連接查詢是一種常用的連接查詢。內連接查詢可以查詢兩個或者兩個以上的表。
如下我們建立一個新表:
然後使用內連接查詢(對錶deparment和employee):
外連接查詢:
外連接查詢也可以查詢兩個或者兩個以上的表。包括左查詢和右查詢,語法如下:
左連接查詢:
查詢結果共顯示了四條記錄。這四條條記錄的數據是從employee表和department表中取出來的。因爲employee表和department表中都包含d_id值爲1001he 1002的記錄,所以這些記錄都能查出來。因爲department表中沒有d_id等於1004記錄,所以該記錄只能從表employee中取出來,而對應的需要從deparment表中取出來的值都是空值。
右連接查詢:
查詢結果也顯示了4條記錄。因爲employee表和department表中都包含了d_id值爲1001和1002的記錄,所以這些記錄能查出來。但是查詢結果中比內查詢多出1003的記錄。因爲employee表中沒有d_id等於1003的記錄,所以該記錄只能從department表中取除了相應的值。而對應的需要從employee表中取出的值都是空值。
通過上述例子,想必都可以明白左連接查詢和有鏈接查詢的不同。
我們一般都會用連接查詢代替in子查詢進行多表聯合查詢,子查詢的效率遠不及連接查詢效率高!
6 設置表的字符編碼
有時候MySQL中的表需要存儲中文,需要設置表的字符編碼爲utf8,否則默認的字符編碼有可能不能正確處理中文,那麼在MySQL中,如何設置表的字符編碼呢?如下:
通過命令查看MySQL表的字符編碼,如下:
mysql> show variables like 'charac%';
+--------------------------+---------------------------------------------------------+
| Variable_name | Value |
+--------------------------+---------------------------------------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 需要設置! |
| character_set_system | utf8 |
| character_sets_dir | C:\Program Files\MySQL\MySQL Server 5.7\share\charsets\ |
+--------------------------+---------------------------------------------------------+
如下設置:
mysql> set character_set_server=utf8;
Query OK, 0 rows affected (0.00 sec)
字符編碼設置utf8成功,MySQL的status運行狀態和運行參數都是通過全局變量來控制的,用show status和show variables兩個命令可以查看這些信息,用set可以設置這些信息,改變配置。