MySQL入門系列:數據庫和表的基本操做

標籤: MySQL入門mysql


上集回顧

MySQL使用表來存放數據,表的每一列都須要存放特定格式的數據,因此MySQL爲不一樣的格式的數據定義了不一樣的類型,咱們介紹了各類數值、字符串、時間和二進制類型的含義以及要求的存儲空間。本集來看一下在MySQL中關於數據庫和表的各類操做。程序員

命令使用注意事項

咱們知道MySQL的基本運行過程就是:經過客戶端程序發送命令給服務器程序,服務器程序按照接收的命令去操做實際的數據。在咱們使用黑框框啓動了MySQL客戶端程序以後,界面上會一直顯示一行mysql>的提示符,你能夠在它後邊輸入咱們的命令而後按一下回車鍵,在書寫命令的時候須要注意下邊這幾點:sql

  1. 命令結束符號。數據庫

    在書寫完一個命令以後須要如下邊這幾個符號之一結尾:bash

    • ;
    • \g
    • \G

    好比說咱們執行一個簡單的查詢當前時間的命令:服務器

    mysql> SELECT NOW();
    +---------------------+
    | NOW()               |
    +---------------------+
    | 2018-02-06 17:50:55 |
    +---------------------+
    1 row in set (0.00 sec)
    
    mysql>
    複製代碼

    其中的SELECT意味着這是一個查詢命令,NOW()MySQL內置的函數,用於返回當前時間。不過咱們如今並非深究具體的某個命令是什麼意思,只是想介紹一下書寫命令時須要注意的一些事情。結果中1 row in set (0.00 sec)的意思是結果只有1行數據,用時0.00秒。使用\g能夠起到同樣的效果:函數

    mysql> SELECT NOW()\g
    +---------------------+
    | NOW()               |
    +---------------------+
    | 2018-02-06 17:50:55 |
    +---------------------+
    1 row in set (0.00 sec)
    
    mysql>
    複製代碼

    \G有一點特殊,它並不以表格的形式返回查詢數據,而是以垂直的形式展示查詢數據:學習

    mysql> SELECT NOW()\G
    *************************** 1. row ***************************
    NOW(): 2018-02-06 17:51:51
    1 row in set (0.00 sec)
    
    mysql>
    複製代碼

    若是查詢結果很是長的話,使用\G可讓咱們看清結果。若是顯式格式沒啥問題,那咱們平時都使用分號;做爲命令結束符了~測試

  2. 命令能夠隨意換行。優化

    並非按了回車鍵就提交命令了,只要按回車鍵的時候輸入的語句裏沒有;\g或者\G就算是語句沒結束。好比上邊查詢當前時間的命令還能夠這麼寫:

    mysql> SELECT
        -> NOW()
        -> ;
    +---------------------+
    | NOW()               |
    +---------------------+
    | 2018-02-06 17:57:15 |
    +---------------------+
    1 row in set (0.00 sec)
    
    mysql>
    複製代碼
  3. 能夠一次提交多個命令

    咱們能夠在一條語句裏寫多個命令(命令之間用上面說的結束符分隔),好比這樣:

    mysql> SELECT NOW(); SELECT NOW(); SELECT NOW();
    +---------------------+
    | NOW()               |
    +---------------------+
    | 2018-02-06 18:00:05 |
    +---------------------+
    1 row in set (0.00 sec)
    
    +---------------------+
    | NOW()               |
    +---------------------+
    | 2018-02-06 18:00:05 |
    +---------------------+
    1 row in set (0.00 sec)
    
    +---------------------+
    | NOW()               |
    +---------------------+
    | 2018-02-06 18:00:05 |
    +---------------------+
    1 row in set (0.00 sec)
    
    mysql>
    複製代碼

    連着輸入了3個查詢當前時間的命令,只要沒按回車鍵,就不會提交命令。

    小貼士: 後邊咱們還會介紹把命令都寫在文件裏,而後再批量執行文件中的命令,那個感受更爽!

  4. 使用\c清除本次操做。

    若是你想放棄本次編寫的命令,可使用\c來清除,好比這樣:

    mysql> SELECT NOW()\c
    mysql>
    複製代碼

    若是不使用\c,那客戶端會覺得這是一個多行命令,還在一直傻傻的等你輸入命令~

  5. 大小寫問題。

    MySQL默認對命令的大小寫並無限制,也就是說咱們這樣查詢當前時間也是能夠的:

    mysql> select now();
    +---------------------+
    | now()               |
    +---------------------+
    | 2018-02-06 18:23:01 |
    +---------------------+
    1 row in set (0.00 sec)
    
    mysql>
    複製代碼

    不過按照習俗,這些命令、函數什麼的都是要大寫的,而一些名稱類的東西,好比數據庫名,表名、列名啥的都是要小寫的,更多具體的書寫規範等咱們遇着再詳細介紹。

  6. 字符串的表示。

    在命令裏有時會使用到字符串,咱們可使用單引號''或者雙引號""把字符串內容引發來,好比這樣:

    mysql> SELECT 'aaa';
    +-----+
    | aaa |
    +-----+
    | aaa |
    +-----+
    1 row in set (0.00 sec)
    
    mysql>
    複製代碼

    這個語句只是簡單的把字符串'aaa'又輸出來了而已。可是必定要在字符串內容上加上引號,否則的話MySQL服務器會把它看成列名,好比這樣就會返回一個錯誤:

    mysql> SELECT aaa;
    ERROR 1054 (42S22): Unknown column 'aaa' in 'field list'
    mysql>
    複製代碼

    可是MySQL中有一種叫ANSI_QUOTES的模式,若是開啓了這種模式,雙引號就有其餘特殊的用途了,可能你並不能看懂我在說什麼,可是這都不重要,重要的是建議你最好使用單引號來表示字符串~

當一條命令發送給了MySQL服務器以後,服務器處理完後就會給你發送回來響應的結果,而後顯示到界面上。而後你就能夠接着輸入下一條命令了。

數據庫相關操做

MySQL中把某種類型的表的集合稱爲一個數據庫MySQL服務器管理着若干個數據庫,每一個數據庫下均可以有若干個表,畫個圖就是這樣:

image_1c4jjlck0101k1lbq100u1ggd4ml46.png-75.7kB

展現數據庫

在咱們剛剛安裝好MySQL的時候,它已經內建了許多數據庫和表了,咱們可使用下邊這個命令來看一下都有哪些數據庫:

SHOW DATABASES;
複製代碼

我本身的電腦上安裝的MySQL版本是5.7.21,看一下在這個版本里內建了哪些數據庫(啓動客戶端軟件,用你的用戶名和密碼登陸後輸入命令):

mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.01 sec)

mysql>
複製代碼

能夠看到,這一版本的MySQL已經爲咱們內建了4個數據庫,這些數據庫都是給MySQL本身使用的,若是咱們想使用MySQL存放本身的數據的話,首先須要建立一個屬於本身的數據庫。

建立數據庫

建立數據庫的語法賊簡單:

CREATE DATABASE 數據庫名;
複製代碼

來實際操做一下:

mysql> CREATE DATABASE xiaohaizi;
Query OK, 1 row affected (0.00 sec)

mysql>
複製代碼

我把個人名字xiaohaizi做爲了數據庫名稱,敲完命令回車以後提示了一個Query OK, 1 row affected (0.00 sec)說明數據庫建立成功了。而後咱們再用SHOW DATABASES的命令查看一下如今有哪些數據庫:

mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| xiaohaizi          |
+--------------------+
5 rows in set (0.00 sec)

mysql>
複製代碼

看到咱們本身建立的數據庫xiaohaizi就已經在列表裏了。

IF NOT EXISTS

咱們在一個數據庫已經存在的狀況下再使用CREATE DATABASE去建立這個數據庫會產生錯誤:

mysql> CREATE DATABASE xiaohaizi;
ERROR 1007 (HY000): Can't create database 'xiaohaizi'; database exists mysql> 複製代碼

執行結果提示了一個ERROR,意思是數據庫xiaohaizi已經存在!因此若是咱們並不清楚數據庫是否存在,可使用下邊的語句來建立數據庫:

CREATE DATABASE IF NOT EXISTS 數據庫名;
複製代碼

這個命令的意思是若是指定的數據庫不存在的話就建立它,不然什麼都不作。咱們試一試:

mysql> CREATE DATABASE IF NOT EXISTS xiaohaizi;
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql>
複製代碼

能夠看到語句執行成功了,報的ERROR錯誤也沒有了,只是結果中有1個warning而已。這個warning只是MySQL善意的提醒咱們數據庫xiaohaizi不存在而已,並不會影響語句的執行。

小貼士: 前邊說過MySQL的命令能夠多條一塊兒執行,能夠在黑框框中一次輸入多個命令,也能夠把好多命令放到一個文件中執行。若是某一條命令的執行結果是產生了一個`ERROR`,MySQL會中止執行該命令以後的命令,可是若是僅僅是在執行結果中有`warning`的話,是不會中斷執行的。

切換當前數據庫

對於每個鏈接到MySQL服務器的客戶端,都有一個當前數據庫的概念,咱們建立的表默認都會被放到當前數據庫中,切換當前數據庫的命令也賊簡單:

USE 數據庫名稱;
複製代碼

因此在介紹建立表以前,咱們應該把當前數據庫切換到剛剛建立的數據庫xiaohaizi上:

mysql> USE xiaohaizi;
Database changed
mysql>
複製代碼

看到顯示了Database changed說明當前數據庫已經切換成功了。須要注意的是,在退出當前客戶端以後,也就是你輸入了exit或者quit命令以後或者直接把當前的黑框框頁面關掉,當你再次調用mysql -h 主機名 -u 用戶名 -p 密碼的時候,至關於從新開啓了一個客戶端,須要從新調用USE 數據庫名稱的命令來選擇一下當前數據庫。

刪除數據庫

若是你建立的數據庫沒用了,咱們還能夠把它刪掉,語法以下:

DROP DATABASE 數據庫名;
複製代碼

在真實的工做環境裏,在刪除數據庫以前你須要先拿體溫計量量是否是發高燒了,而後再找至少兩我的核實一下本身是否是發燒了,而後你纔敢執行刪除數據庫的命令。刪除數據庫意味着裏邊的表就都被刪除了,也就意味着你的數據都沒了,因此是個極其危險的操做,使用時須要極其謹慎。不過咱們這是學習環境,並且剛剛建立了xiaohaizi數據庫,什麼表都沒往裏頭放,刪了就刪了吧:

mysql> DROP DATABASE xiaohaizi;
Query OK, 0 rows affected (0.01 sec)

mysql>
複製代碼

而後看一下如今還有哪些數據庫:

mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.01 sec)

mysql>
複製代碼

能夠看到咱們前邊建立的xiaohaizi數據庫就沒有啦。

IF EXISTS

若是某個數據庫並不存在,咱們仍舊調用DROP TABLE語句去刪除它,會報錯的:

mysql> DROP DATABASE xiaohaizi;
ERROR 1008 (HY000): Can't drop database 'xiaohaizi'; database doesn't exist
mysql>
複製代碼

若是想避免這種報錯,可使用這種形式的語句來刪除數據庫:

DROP DATABASE IF EXISTS 表名;
複製代碼

再次刪除一下xiaohaizi

mysql> DROP DATABASE IF EXISTS xiaohaizi;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql>
複製代碼

這回就不會報錯啦!演示完刪除數據庫的流程以後仍是把xiaohaizi數據庫建立出來而且切換到當前數據庫吧,畢竟咱們以後還要在這個數據庫裏建立各類表呢~

表的操做

數據庫建好以後,咱們就能夠接着建立真正存儲數據的表了。建立表的時候首先須要描述清楚這個表長什麼樣,它有哪些列,這些列都是用來存什麼類型的數據等等,這個對錶的描述稱爲表的模式(scheme)。有了表的模式以後,咱們就能夠着手把數據塞到這個表裏了。表中的每一行也叫作一條記錄,每一列也叫作一個字段

建立表

基本語法

建立一個表須要至少要完成下列事情:

  1. 給表起個名。
  2. 給表定義一些列,而且給這些列都起個名。
  3. 每個列都須要定義一種數據類型,來規範它能存儲的數據。
  4. 若是有須要的話,能夠給這些列定義一些列的屬性,好比不準爲空,設置默認值等等,這些屬性也叫作列的約束性條件,具體有哪些列的屬性咱們稍後會詳細嘮叨。

MySQL中建立表的基本語法就是這樣的:

CREATE TABLE 表名 (
    列名1    列的類型    [列的屬性],
    列名2    列的類型    [列的屬性],
    ...
    列名n    列的類型    [列的屬性]
);
複製代碼

也就是說,咱們在CREATE TABLE後寫清楚咱們定義的表的表名,而後在小括號()中定義上這個表的各個列的信息,包括列的列名、類型,若是有須要的話也能夠定義這個列的屬性,其中列的屬性用中括號[]引發來的意思是可選的,也就是說能夠有也能夠沒有,列名、列的類型、列的屬性之間用空白字符分開就好,而後各個列的信息之間用逗號,分隔開。

小貼士: 咱們也能夠把這個建立表的語句都放在一行裏(把換行刪掉),分紅多行而且加上縮進僅僅是爲了美觀而已~

廢話很少說,趕忙建立一個超級簡單的表瞅瞅:

CREATE TABLE first_table (
    first_column INT,
    second_column VARCHAR(100)
);
複製代碼

咱們新建立的這個表的名字叫作first_table,它有兩個列,第一個列的列名是first_column,列的類型是INT,意味着只能存放整數型數據,第二個列的列名是second_column,列的類型是VARCHAR(100),意味着這個列能夠存放長度不超過100個字符的字符串。咱們在客戶端執行一下這個語句(當前數據庫是xiaohaizi):

mysql> CREATE TABLE first_table (
    ->     first_column INT,
    ->     second_column VARCHAR(100)
    -> );
Query OK, 0 rows affected (0.02 sec)

mysql>
複製代碼

輸出Query OK, 0 rows affected (0.02 sec)意味着建立成功了,而且耗時0.02秒。

有了建立first_table的經驗,咱們就能夠着手用MySQL把以前提到的學生基本信息表和成績表給建立出來了,先把學生信息表搬下來看看:

**學生基本信息表**
學號 姓名 性別 身份證號 學院 專業 入學時間
20180101 杜子騰 158177199901044792 計算機學院 計算機科學與工程 2018/9/1
20180102 杜琦燕 151008199801178529 計算機學院 計算機科學與工程 2018/9/1
20180103 範統 17156319980116959X 計算機學院 軟件工程 2018/9/1
20180104 史珍香 141992199701078600 計算機學院 軟件工程 2018/9/1

很顯然,這個表有學號姓名性別身份證號學院專業入學時間這幾個列,其中的學號是整數類型的,入學時間是日期類型的,因爲身份證號是固定的18位,咱們能夠把身份證號這一列定義成固定長度的字符串類型,性別一列只能填,因此咱們這裏把它定義爲ENUM類型的,其他各個字段都是可變的字符串類型的。看一下建立學生基本信息表的語句:

CREATE TABLE student_info (
    number INT,
    name VARCHAR(5),
    sex ENUM('男', '女'),
    id_number CHAR(18),
    department VARCHAR(30),
    major VARCHAR(30),
    enrollment_time DATE
);
複製代碼

而後再看一下學生成績表:

學生成績表
學號 科目 成績
20180101 母豬的產後護理 78
20180101 論薩達姆的戰爭準備 88
20180102 母豬的產後護理 100
20180102 論薩達姆的戰爭準備 98
20180103 母豬的產後護理 59
20180103 論薩達姆的戰爭準備 61
20180104 母豬的產後護理 55
20180104 論薩達姆的戰爭準備 46

這個表有學號科目成績這幾個列,學號成績是整數類型的,科目是字符串類型的,因此咱們建立一下這個表:

CREATE TABLE student_score (
    number INT,
    subject VARCHAR(30),
    score TINYINT
);
複製代碼

趕忙到你的客戶端裏填寫建立這兩個表的命令吧~

展現當前數據庫中的表

咱們剛纔在xiaohaizi數據庫裏建立了幾個表,那咱們怎麼查看xiaohaizi數據庫下都有哪些表呢?MySQL提供了這樣的一個命令:

SHOW TABLES;
複製代碼

該命令會展現出當前數據庫中都有哪些表,咱們執行一下:

mysql> show tables;
+---------------------+
| Tables_in_xiaohaizi |
+---------------------+
| first_table         |
| student_info        |
| student_score       |
+---------------------+
3 rows in set (0.01 sec)

mysql>
複製代碼

咱們剛纔建立的表就都被展現出來了。

IF NOT EXISTS

和重複建立數據庫同樣,若是建立一個已經存在的表的話是會報錯的,咱們來試試重複建立一下first_table表:

mysql> CREATE TABLE first_table (
    ->     first_column INT,
    ->     second_column VARCHAR(100)
    -> );
ERROR 1050 (42S01): Table 'first_table' already exists
mysql>
複製代碼

執行結果提示了一個ERROR,意思是first_table已經存在!因此若是想要避免這種尷尬,咱們能夠在建立表的時候使用這種形式:

CREATE TABLE IF NOT EXISTS 表名(
    各個列信息的定義 ...
);
複製代碼

加入了IF NOT EXISTS的語句表示若是指定的表名不存在則建立這個表,若是不存在那就什麼都不作。咱們使用這種IF NOT EXISTS的語法再來建立一遍first_table表:

mysql> CREATE TABLE IF NOT EXISTS first_table (
    ->     first_column INT,
    ->     second_column VARCHAR(100)
    -> );
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql>
複製代碼

能夠看到語句執行成功了,報的ERROR錯誤也沒有了,只是結果中有1個warning而已。

簡單的表操做語句

在建立完表以後,咱們只是建立了一個殼子,裏邊什麼數據都沒有。使用表的目的固然是存儲數據啦,下邊咱們來看幾個簡單的查詢與插入語句,更多關於表中數據的操做語句咱們以後會詳細嘮叨的。

簡單的查詢語句

若是咱們想查看某個表裏已經存儲了哪些數據,能夠用下邊這個語句:

SELECT * FROM 表名;
複製代碼

好比咱們想看看前邊建立的first_table表中有哪些數據,能夠這麼寫:

mysql> SELECT * FROM first_table;
Empty set (0.01 sec)

mysql>
複製代碼

很遺憾,咱們歷來沒有向表中插入過數據,因此查詢結果顯示的是Empty set,表示什麼都沒查出來~

簡單插入語句

MySQL插入數據的時候是以行爲單位的,語法格式以下:

INSERT INTO 表名(列1, 列2, ...) VALUES(列1的值,列2的值, ...);
複製代碼

也就是說咱們能夠在表名後邊的括號中指定要插入數據的列,而後在VALUES後邊的括號中按指定的列順序填入對應的值,咱們來爲first_table表插入第一行數據:

mysql> INSERT INTO first_table(first_column, second_column) VALUES(1, 'aaa');
Query OK, 1 row affected (0.00 sec)

mysql>
複製代碼

這個語句的意思就是咱們要向first_table表中插入一行數據,first_column列的值是1second_column列的值是'aaa'。看一下如今表中的數據:

mysql> SELECT * FROM first_table;
+--------------+---------------+
| first_column | second_column |
+--------------+---------------+
|            1 | aaa           |
+--------------+---------------+
1 row in set (0.00 sec)

mysql>
複製代碼

第一行數據就插入成功了!

咱們也能夠只指定部分的列,沒有顯式指定的列的值將被設置爲NULL,意思是尚未指定值,好比這樣寫:

mysql> INSERT INTO first_table(first_column) VALUES(2);
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO first_table(second_column) VALUES('ccc');
Query OK, 1 row affected (0.00 sec)

mysql>
複製代碼

第一條插入語句咱們只指定了first_column列的值是2,而沒有指定second_column的值,因此second_column的值就是NULL;第二條插入語句咱們只指定了second_column的值是'ccc',而沒有指定first_column的值,因此first_column的值就是NULL,也表示沒有數據~ 看一下如今表中的數據:

mysql> SELECT * FROM first_table;
+--------------+---------------+
| first_column | second_column |
+--------------+---------------+
|            1 | aaa           |
|            2 | NULL          |
|         NULL | ccc           |
+--------------+---------------+
3 rows in set (0.00 sec)

mysql>
複製代碼
批量插入

每插入一行數據寫一條語句也不是不行,可是對人來講太煩了,並且每插入一行數據提交一個請求給服務器遠沒有一次把全部插入的數據提交給服務器效率高,因此MySQL爲咱們提供了批量插入的語句:

INSERT INTO 表名(列1,列2, ...) VAULES(列1的值,列2的值, ...), (列1的值,列2的值, ...), (列1的值,列2的值, ...), ...;
複製代碼

也就是在原來的單條插入語句後邊多寫幾項插入行的內容,用逗號分隔開就行了,舉個例子:

mysql> INSERT INTO first_table(first_column, second_column) VALUES(4, 'ddd'), (5, 'eee'), (6, 'fff');
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM first_table;
+--------------+---------------+
| first_column | second_column |
+--------------+---------------+
|            1 | aaa           |
|            2 | NULL          |
|         NULL | ccc           |
|            4 | ddd           |
|            5 | eee           |
|            6 | fff           |
+--------------+---------------+
6 rows in set (0.01 sec)

mysql>
複製代碼

能夠看到3行記錄就插入成功了!

刪除表

若是一個表不用了,就能夠刪掉了,在真實環境中刪除表必定要慎重謹慎,失去了的就再也回不來了~ 看一下刪除的語法:

DROP TABLE 表1, 表2, ..., 表n;
複製代碼

也就是說咱們能夠同時刪除多個表。咱們如今把first_table表給刪掉看看:

mysql> DROP TABLE first_table;
Query OK, 0 rows affected (0.01 sec)

mysql> SHOW TABLES;
+---------------------+
| Tables_in_xiaohaizi |
+---------------------+
| student_info        |
| student_score       |
+---------------------+
2 rows in set (0.00 sec)

mysql>
複製代碼

能夠看到如今數據庫xiaohaizi中沒有了first_table表,說明刪除成功了!

IF EXISTS

若是咱們嘗試刪除某個不存在的表的話會報錯:

mysql> DROP TABLE first_table;
ERROR 1051 (42S02): Unknown table 'xiaohaizi.first_table'
mysql>
複製代碼

提示咱們要刪除的表並不存在,若是想避免報錯,可使用這種刪除語法:

DROP TABLE IF EXISTS 表名;
複製代碼

而後再刪除一下不存在的first_table表:

mysql> DROP TABLE IF EXISTS first_table;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql>
複製代碼

這樣就不報錯了~

約束性條件(列的屬性)

對於某些列來講,可能有一些特殊含義或者用法,咱們把這些特殊的含義或用法稱爲列的屬性,也能夠稱爲列的約束性條件,在建立表的時候能夠顯式的定義出來。下邊咱們看都有哪些約束性條件以及怎麼在建立表的時候把它們定義出來。

默認值

前邊介紹INSERT語句的時候說過,若是在指定的插入列中省略了某些列,那這些列的值將被設置爲NULL,也就是列的默認值爲NULL,表示沒有設置值。咱們在建立表的時候也能夠指定一些有意義的默認值,指定方式以下:

列名 列的類型 DEFAULT 默認值
複製代碼

好比咱們把first_tablesecond_column列的默認值指定爲'abc',建立一下這個表:

mysql> CREATE TABLE first_table (
    ->     first_column INT,
    ->     second_column VARCHAR(100) DEFAULT 'abc'
    -> );
Query OK, 0 rows affected (0.02 sec)

mysql>
複製代碼

而後插入一條數據後看看默認值是否是起了做用:

mysql> INSERT INTO first_table(first_column) VALUES(1);
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * FROM first_table;
+--------------+---------------+
| first_column | second_column |
+--------------+---------------+
|            1 | abc           |
+--------------+---------------+
1 row in set (0.00 sec)

mysql>
複製代碼

咱們的插入語句並無指定second_column的值,可是能夠看到插入結果是按照咱們規定的默認值'abc'來設置的。

若是咱們不設置默認值,其實就至關於指定的默認值爲NULL,好比first_table表並無設置first_column列的默認值,那它的默認值就是NULL,也就是說上邊的表定義語句和下邊這個是等價的:

CREATE TABLE first_table (
    first_column INT DEFAULT NULL,
    second_column VARCHAR(100) DEFAULT 'abc'
);
複製代碼

非空約束

對於某些列,咱們要求它們是必填的,也就是不容許存放NULL值,咱們用這樣的語法來定義這個列:

列名 列的類型 NOT NULL
複製代碼

好比咱們把first_tablefirst_column列定義爲NOT NULL。固然,咱們在從新定義表以前須要把原來的表刪掉:

mysql> DROP TABLE first_table;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE first_table (
    ->     first_column INT NOT NULL,
    ->     second_column VARCHAR(100) DEFAULT 'abc'
    -> );
Query OK, 0 rows affected (0.02 sec)

mysql>
複製代碼

這樣的話,咱們就不能再往這個字段裏插入NULL值了,好比這樣:

mysql> INSERT INTO first_table(first_column, second_column) VALUES(NULL, 'aaa');
ERROR 1048 (23000): Column 'first_column' cannot be null
mysql>
複製代碼

能夠看到,彈出了錯誤提示。

一旦對某個列定義了NOT NULL屬性,那這個列的默認值就不爲NULL了。上邊first_column並無指定默認值,意味着咱們在使用INSERT插入行時必須顯式的指定這個列的值,而不能省略它,好比這樣就會報錯的:

mysql> INSERT INTO first_table(second_column) VALUES('aaa');
ERROR 1364 (HY000): Field 'first_column' doesn't have a default value mysql> 複製代碼

能夠看到執行結果提示咱們first_column並無設置默認值,因此在插入數據的時候不能省略掉這個列的值。

主鍵

有時候在咱們的表裏能夠經過某個列或者某些列肯定惟一的一條記錄,咱們就能夠把這個列或者這些列稱爲候選鍵。好比在學生信息表student_info中,只要咱們知道某個學生的學號,就能夠肯定一個惟一的學生信息,也就是一條記錄。固然,咱們也能夠經過身份證號來肯定惟一的一條學生信息記錄,因此學號身份證號均可以做爲學生信息表的候選鍵。在學生成績表student_score中,咱們能夠經過學號科目這兩個列的組合來肯定惟一的一條成績記錄,因此學號、科目這兩個列的組合能夠做爲學生成績表的候選鍵

一個表可能有多個候選鍵,咱們能夠選擇一個候選鍵做爲表的主鍵。從定義中就能夠看出,一個表最多隻能有一個主鍵,主鍵的值不能重複,經過主鍵能夠找到惟一的一條記錄。若是咱們的表中有定義主鍵的需求能夠選用下邊這兩種方式之一來指定主鍵:

  1. 若是主鍵只是單個列的話,能夠直接在該列後聲明PRIMARY KEY,好比咱們把學生信息表student_info學號列聲明爲主鍵能夠這麼寫:

    CREATE TABLE student_info (
        number INT PRIMARY KEY,
        name VARCHAR(5),
        sex ENUM('男', '女'),
        id_number CHAR(18),
        department VARCHAR(30),
        major VARCHAR(30),
        enrollment_time DATE
    );
    複製代碼
  2. 咱們也能夠把主鍵的聲明單獨提取出來,用這樣的形式聲明:

    PRIMARY KEY (列名1, 列名2, ...)
    複製代碼

    而後把這個主鍵聲明放到列定義的後邊就行了。好比student_info學號列聲明爲主鍵也能夠這麼寫:

    CREATE TABLE student_info (
        number INT,
        name VARCHAR(5),
        sex ENUM('男', '女'),
        id_number CHAR(18),
        department VARCHAR(30),
        major VARCHAR(30),
        enrollment_time DATE,
        PRIMARY KEY (number)
    );
    複製代碼

    值得注意的是,對於多個列的組合做爲主鍵的狀況,必須使用這種單獨聲明的形式,好比student_score表裏的學號,科目的列組合做爲主鍵,能夠這麼聲明:

    CREATE TABLE student_score (
        number INT,
        subject VARCHAR(30),
        score TINYINT,
        PRIMARY KEY (number, subject)
    );
    複製代碼

在咱們建立表的時候就聲明瞭主鍵的話,MySQL會對咱們插入的記錄作校驗,若是兩條記錄裏有相同的主鍵值的話就會報錯

另外,主鍵列默認是NOT NULL的,也就是必填的,若是填入NULL值會報錯(先刪除原來的student_info表,使用上邊的兩種方式之一從新建立表):

mysql> INSERT INTO student_info(number) VALUES(NULL);
ERROR 1048 (23000): Column 'number' cannot be null
mysql>
複製代碼

因此你們在插入數據的時候至少別忘了給主鍵列賦值哈~

惟一性約束

對於不是主鍵的其餘候選鍵,若是咱們也想讓MySQL替咱們校驗數據的惟一性,那咱們能夠把這個列或列組合聲明爲UNIQUE的,代表該列或者列組合的值是不容許重複的,這種列的屬性叫作惟一性約束。同主鍵的定義同樣,惟一性約束的定義也有兩種方式:

  1. 若是具備惟一性約束的列是單個列的話,能夠直接在該列後聲明UNIQUE或者UNIQUE KEY,好比在學生信息表student_info中,咱們不容許兩條學生記錄中的身份證號是同樣的,那咱們讓id_number這一列具備惟一性約束。

    CREATE TABLE student_info (
        number INT PRIMARY KEY,
        name VARCHAR(5),
        sex ENUM('男', '女'),
        id_number CHAR(18) UNIQUE,
        department VARCHAR(30),
        major VARCHAR(30),
        enrollment_time DATE
    );
    複製代碼
  2. 咱們也能夠把惟一性約束的聲明單獨提取出來,用這樣的形式聲明:

    UNIQUE [約束名稱] (列名1, 列名2, ...)
    複製代碼

    或者:

    UNIQUE KEY [約束名稱] (列名1, 列名2, ...)
    複製代碼

    其中的約束名稱是可選的,其實就是咱們爲這個惟一性約束起的一個名字而已,若是不起名字的話該名稱默認和列名相同,這個不重要哈~ 而後把這個惟一性約束聲明放到列定義的後邊就行了。好比student_info身份證號列聲明惟一性約束的屬性也能夠這麼寫:

    CREATE TABLE student_info (
        number INT PRIMARY KEY,
        name VARCHAR(5),
        sex ENUM('男', '女'),
        id_number CHAR(18),
        department VARCHAR(30),
        major VARCHAR(30),
        enrollment_time DATE,
        UNIQUE KEY (id_number)
    );
    複製代碼

    值得注意的是,對於多個列的組合具備惟一性約束的狀況,必須使用這種單獨聲明的形式。

若是表中定義了惟一性約束的話,MySQL會對咱們插入的記錄作校驗,若是插入的值違反了惟一性約束的話就會報錯

主鍵和惟一性約束的區別

主鍵和惟一性約束都能保證某個列或者列組合的惟一性,可是:

  1. 一張表中只能定義一個主鍵,卻能夠定義多個惟一性約束
  2. 主鍵列不容許存放NULL值,而普通的惟一性約束列能夠存放NULL值

小貼士: 你可能會問爲啥主鍵列不容許存放NULL值,而普通的惟一性約束列卻能夠呢?哈哈,這涉及到底層存儲的事情,如今你只須要記住這個規定就行了,若是你想知道更多的事情,那就繼續日後看唄~

外鍵

插入到學生成績表student_score中的學號(number)列中的值必須能在學生基本信息表student_info中的學號列中找到,不然若是一個學號只在成績表裏出現,而在信息表裏找不到相應的記錄的話,就至關於插入了一個不知道是哪一個學生的成績,這顯然是荒謬的。爲了防止這樣荒謬的狀況出現,MySQL給咱們提供了外鍵約束機制。定義外鍵的語法是這樣的:

CONSTRAINT [外鍵名稱] FOREIGN KEY(列1, 列2, ...) REFERENCES 父表名(父列1, 父列2, ...);
複製代碼

其中的外鍵名稱也是可選的,一個名字而已有沒有都行,不是很重要~ 若是A表中的某個列或者某些列依賴與B表中的某個列或者某些列,那麼就稱A表爲子表,B表爲父表。子表和父表可使用外鍵來關聯起來,上邊例子中student_info就是一個父表,student_score就是子表,咱們能夠這樣來定義student_score列,來使用外鍵關聯起父表和子表:

CREATE TABLE student_score (
    number INT,
    subject VARCHAR(30),
    score TINYINT,
    PRIMARY KEY (number, subject),
    CONSTRAINT FOREIGN KEY(number) REFERENCES student_info(number)
);
複製代碼

這樣,在對student_score表插入數據的時候,MySQL都會爲咱們檢查一下插入的學號是否能在student_info中找到,若是找不到則會報錯。

小貼士: 父表中做爲外鍵的列或者列組合必須創建索引,主鍵和具備惟一性約束的列默認的都創建了索引,置於什麼是索引,咱們以後會詳細嘮叨的。

自增

若是一個表中的某個列是數值類型的,包括整數類型和浮點數類型,那麼這個列能夠設置自增屬性。所謂自增,意思是若是咱們在插入數據的時候不指定該列的值,那麼該列的值就是上一列的值加1後的值,定義語法就是這樣:

列名 列的類型 AUTO_INCREMENT
複製代碼

好比咱們想在first_table裏設置一個自增列id,並把這個列設置爲主鍵,來惟一標記一行記錄,咱們能夠這麼寫:

mysql> DROP TABLE first_table;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE first_table (
    ->     id int UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    ->     first_column INT,
    ->     second_column VARCHAR(100) DEFAULT 'abc'
    -> );
Query OK, 0 rows affected (0.01 sec)

mysql>
複製代碼

先把原來的表刪掉,而後在新表中增長了一個非負int類型的id列,並把它設置爲主鍵並且具備遞增屬性,那咱們插入數據的時候就能夠不用管這個列,可是它的值將會遞增,看:

mysql> INSERT INTO first_table(first_column, second_column) VALUES(1, 'aaa'), (2, 'bbb'), (3, 'ccc');
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM first_table;
+----+--------------+---------------+
| id | first_column | second_column |
+----+--------------+---------------+
|  1 |            1 | aaa           |
|  2 |            2 | bbb           |
|  3 |            3 | ccc           |
+----+--------------+---------------+
3 rows in set (0.00 sec)

mysql>
複製代碼

能夠看到,列id是從1開始遞增的。在使用遞增屬性的時候須要注意這幾點:

  1. 一個表中最多有一個遞增列
  2. 通常只爲整數類型的列定義遞增屬性,浮點數類型基本不用遞增屬性
  3. 具備AUTO_INCREMENT屬性的列必須創建索引。主鍵和具備惟一性約束的列會自動創建索引,至於什麼是索引,咱們後邊會詳細嘮叨。
  4. 通常遞增列都是做爲主鍵的屬性,來自動生成惟一標識一個記錄的主鍵值
  5. 由於具備AUTO_INCREMENT屬性的列是從1開始遞增的,因此最好用UNSIGNED來修飾這個列,能夠提高正數的表示範圍

約束性條件的組合

每一個列能夠有多個約束性條件,聲明的順序無所謂,各個約束性條件之間用空白隔開就行了~

小貼士: 注意,有的約束性條件是衝突的,一個列不能具備兩個衝突的約束性條件,好比一個列不能既聲明爲`PRIMARY KEY,又聲明爲UNIQUE KEY`,不能既聲明爲`DEFAULT NULL`,又聲明爲`NOT NULL`。你們在使用過程當中須要注意這一點。

添加註釋

咱們能夠對每一個列信息以及表做註釋,具體語法以下:

CREATE TABLE 表名 (
    列1 列的類型 [列的屬性] COMMENT '列1的註釋信息',
    列2 列的類型 [列的屬性] COMMENT '列2的註釋信息',
    列3 列的類型 [列的屬性] COMMENT '列3的註釋信息',
) COMMENT '表的註釋信息';
複製代碼

好比咱們能夠這樣建立咱們的first_table表:

CREATE TABLE first_table (
    id int UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '自增主鍵',
    first_column INT COMMENT '第一列',
    second_column VARCHAR(100) DEFAULT 'abc' COMMENT '第二列'
) COMMENT '第一個表';
複製代碼

註釋不必太長,言簡意賅便可,畢竟是給人看的,讓人看明白是個啥意思就OK了。爲了咱們本身的方便,也爲了閱讀你建立的人的方便,請遵照一下職業道德,寫個註釋吧~ 求求你了~ 求求你了~ 求求你了~

標識符的命名

像數據庫名、表名、列名、約束名稱或者咱們以後會遇到的別的名稱,這些咱們起的名字通通被稱爲標識符。雖然MySQL中對標識符的命名沒多少限制,可是卻不歡迎下邊的這幾種命名:

  1. 名稱中全都是數字。

    由於在一些MySQL命令中也會使用到數字,若是你起的名稱中所有都是數字,會讓MySQL服務器分別不清哪一個是名稱,哪一個是數字了。好比名稱1234567就是非法的。

  2. 名稱中有空白字符

    MySQL命令是靠空白字符來分隔各個單詞的,好比下邊這兩行命令是等價的:

    CREATE DATABASE xiaohaizi;
    CREATE   DATABASE   xiaohaizi;
    複製代碼

    可是若是你定義的名稱中有空白字符,這樣會被看成兩個詞去處理,就會形成歧義。好比名稱word1 word2 word3就是非法的。

  3. 名稱使用了MySQL中的保留字

    MySQL中有不少保留的詞是會被看成命令處理的,好比CREATEDATABASEDROPTABLE等等等等,咱們稍後還會介紹大量的命令,這些命令用到的單詞都是做爲MySQL的保留字,若是你的名稱用到了這些詞兒也會致使歧義。好比名稱create就是非法的。

雖然某些名稱可能會致使歧義,可是若是你堅持要使用的話,也不是不行,你可使用反引號``來將你定義的名稱擴起來,這樣MySQL的服務器就能檢測到你提供的是一個名稱而不是別的什麼東西,好比說把上邊幾個非法的名稱加上反引號``就變成合法的名稱了:

`1234567`
`word1 word2    word3`
`create`
複製代碼

咱們上邊對錶first_table的定義能夠把裏邊的標識符全都使用反引號``引發來,這樣語義更清晰一點:

CREATE TABLE `first_table` (
    `id` int UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `first_column` INT,
    `second_column` VARCHAR(100) DEFAULT 'abc'
);
複製代碼

雖然反引號比較強大,可是咱們仍是建議你們不要起各類非主流的名稱,也不要使用全數字、帶有空白字符或者MySQL保留字的名稱。因爲MySQL是C語言實現的,因此在名稱定義上仍是儘可能聽從C語言的規範吧,就是用小寫字母、數字、下劃線、美圓符號等做爲名稱,若是有多個單詞的話,各個單詞之間用下劃線鏈接起來,好比studentstudent_info啥的~

查看錶結構

有時候咱們可能忘記了本身定義的表的結構,可使用下邊這些語句來查看,它們起到的效果都是同樣的:

DESCRIBE 表名;
DESC 表名;
EXPLAIN 表名;
SHOW COLUMNS FROM 表名;
SHOW FIELDS FROM 表名;
複製代碼

好比咱們看一下student_info這個表的結構:

mysql> DESC student_info;
+-----------------+-------------------+------+-----+---------+-------+
| Field           | Type              | Null | Key | Default | Extra |
+-----------------+-------------------+------+-----+---------+-------+
| number          | int(11)           | NO   | PRI | NULL    |       |
| name            | varchar(5)        | YES  |     | NULL    |       |
| sex             | enum('男','女')   | YES  |     | NULL    |       |
| id_number       | char(18)          | YES  | UNI | NULL    |       |
| department      | varchar(30)       | YES  |     | NULL    |       |
| major           | varchar(30)       | YES  |     | NULL    |       |
| enrollment_time | date              | YES  |     | NULL    |       |
+-----------------+-------------------+------+-----+---------+-------+
7 rows in set (0.00 sec)

mysql>
複製代碼

能夠看到,這個student_info表的各個列的類型和屬性就都展現出來了,其中PRIPRIMARY KEY的縮寫,UNIUNIQUE KEY的縮寫。

小貼士: 請注意`number`列的類型是`int(11)`,這個小括號裏的`11`是什麼意思?這個`11`實際上是所謂的顯示寬度,咱們稍後立刻嘮叨。

若是你看不慣這種詳細展現各個字段的的信息,咱們還可使用下邊這個語句來查看錶結構:

SHOW CREATE TABLE 表名;
複製代碼

好比:

mysql> SHOW CREATE TABLE student_info;
+--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table        | Create Table                                                                                                                                                                                                                                                                                                                                                                                        |
+--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| student_info | CREATE TABLE `student_info` (
  `number` int(11) NOT NULL,
  `name` varchar(5) DEFAULT NULL,
  `sex` enum('男','女') DEFAULT NULL,
  `id_number` char(18) DEFAULT NULL,
  `department` varchar(30) DEFAULT NULL,
  `major` varchar(30) DEFAULT NULL,
  `enrollment_time` date DEFAULT NULL,
  PRIMARY KEY (`number`),
  UNIQUE KEY `id_number` (`id_number`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8   |
+--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql>
複製代碼

因爲這行數據太長了,因此輸出效果並非很好,因此把原來用於標記語句結束的分號;改成\G,這樣的效果可能好點:

mysql> SHOW CREATE TABLE student_info\G
*************************** 1. row ***************************
       Table: student_info
Create Table: CREATE TABLE `student_info` (
  `number` int(11) NOT NULL,
  `name` varchar(5) DEFAULT NULL,
  `sex` enum('男','女') DEFAULT NULL,
  `id_number` char(18) DEFAULT NULL,
  `department` varchar(30) DEFAULT NULL,
  `major` varchar(30) DEFAULT NULL,
  `enrollment_time` date DEFAULT NULL,
  PRIMARY KEY (`number`),
  UNIQUE KEY `id_number` (`id_number`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

mysql>
複製代碼

能夠看到,使用SHOW CREATE TABLE這種語句展現出來的表結構就是咱們平時建立表的語句。並且MySQL默認爲主鍵字段加了NOT NULL屬性,爲其餘字段加了DEFAULT NULL屬性,並且還給身份證號的惟一性約束起了和列名同樣的名稱。

小貼士: 你可能疑惑的是在表定義末尾的`ENGINE=InnoDB DEFAULT CHARSET=utf8`是什麼意思,這個是指定表的存儲引擎和默認字符集,這些內容後邊會有專門的專題來詳細嘮叨的,你如今不用關心~

ZEROFILL與顯示寬度

對於無符號整數類型的列,咱們能夠在查詢數據的時候讓數字左邊補0,若是想實現這個效果須要給該列加一個ZEROFILL屬性,就像這樣:

mysql> CREATE TABLE zero_table (
    ->     i1 INT UNSIGNED ZEROFILL,
    ->     i2 INT UNSIGNED
    -> );
Query OK, 0 rows affected (0.03 sec)

mysql>
複製代碼

咱們在zero_table表中建立了兩個整數列,不一樣的是i1列具備ZEROFILL屬性,下邊咱們爲這個表插入一條記錄:

mysql> INSERT INTO zero_table(i1, i2) VALUES(1, 1);
Query OK, 1 row affected (0.00 sec)

mysql>
複製代碼

而後咱們使用查詢語句來顯示一下剛插入的數據:

mysql> SELECT * FROM zero_table;
+------------+------+
| i1         | i2   |
+------------+------+
| 0000000001 |    1 |
+------------+------+
1 row in set (0.00 sec)

mysql>
複製代碼

對於具備ZEROFILL屬性的i1列,在顯示的時候補了一堆0,仔細數數發現是9個0,而沒有ZEROFILL屬性的i2列,在顯示的時候並無補0。爲何i1列會補9個0呢?咱們查看一下zero_table的表結構:

mysql> DESC zero_table;
+-------+---------------------------+------+-----+---------+-------+
| Field | Type                      | Null | Key | Default | Extra |
+-------+---------------------------+------+-----+---------+-------+
| i1    | int(10) unsigned zerofill | YES  |     | NULL    |       |
| i2    | int(10) unsigned          | YES  |     | NULL    |       |
+-------+---------------------------+------+-----+---------+-------+
2 rows in set (0.01 sec)

mysql>
複製代碼

能夠看到,其實i1i2列的類型INT後邊都加了一個(10),這個10就是所謂的顯示寬度顯示寬度是在查詢語句顯示的結果中,若是聲明瞭 ZEROFILL 屬性的整數列的實際值的位數小於顯示寬度時,會在實際值的左側補0,使補0的位數和實際值的位數相加正好等於顯示寬度。咱們也能夠本身指定顯示寬度,比方說這樣:

mysql> DROP TABLE zero_table;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE zero_table (
    ->     i1 INT(5) UNSIGNED ZEROFILL,
    ->     i2 INT UNSIGNED
    -> );
Query OK, 0 rows affected (0.02 sec)

mysql> INSERT INTO zero_table(i1, i2) VALUES(1, 1);
Query OK, 1 row affected (0.01 sec)

mysql> SELECT * FROM zero_table;
+-------+------+
| i1    | i2   |
+-------+------+
| 00001 |    1 |
+-------+------+
1 row in set (0.00 sec)

mysql>
複製代碼

新建立的表中,i1字段的顯示寬度是5,因此最後的顯示結果中補了4個0。

注意事項

  1. 在查詢時,數據自動補0的條件有這幾個

    • 該列必須是整數類型的
    • 該列必須有UNSIGNED ZEROFILL的屬性
    • 該列的實際值的位數必須小於顯示寬度
  2. 在建立表的時候,若是聲明瞭ZEROFILL屬性的列沒有聲明UNSIGNED屬性,那MySQL會爲該列自動生成UNSIGNED屬性

    也就是說若是咱們建立表語句是這樣的:

    CREATE TABLE zero_table (
        i1 INT ZEROFILL,
        i2 INT UNSIGNED
    );
    複製代碼

    MySQL會自動幫咱們爲i1列加上UNSIGNED屬性,也就是這樣:

    CREATE TABLE zero_table (
        i1 INT UNSIGNED ZEROFILL,
        i2 INT UNSIGNED
    );
    複製代碼
  3. 每一個整數類型都會有默認的顯示寬度

    好比TINYINT的默認顯示寬度是4INT的默認顯示寬度是(11)... 若是加了UNSIGNED屬性,則該類型的顯示寬度減1,好比TINYINT UNSIGNED的顯示寬度是3INT UNSIGNED的顯示寬度是11...

  4. 顯示寬度並不會影響實際類型的實際存儲空間

    也就是說INT(1)INT(10)其實並無什麼區別,比方說zero_table表中i1列的顯示寬度是5,而數字12345678的位數是8,它照樣能夠被填入i1列中:

    mysql> INSERT INTO zero_table(i1, i2) VALUES(12345678, 12345678);
    Query OK, 1 row affected (0.01 sec)
    複製代碼
  5. 對於沒有聲明ZEROFILL屬性的列,顯示寬度沒有一毛錢卵用

    記住,只有在查詢聲明瞭ZEROFILL屬性的列時,顯示寬度纔會起做用,不然忽略顯示寬度這個東西的存在。

  6. 只有列的實際值的位數小於顯示寬度時纔會補0,實際值的位數大於顯示寬度時照原樣輸出

    比方說咱們剛剛把12345678存到了i1列裏,在展現這個值時,並不會截短顯示的數據,而是照原樣輸出:

    mysql> SELECT * FROM zero_table;
    +----------+----------+
    | i1       | i2       |
    +----------+----------+
    |    00001 |        1 |
    | 12345678 | 12345678 |
    +----------+----------+
    2 rows in set (0.00 sec)
    
    mysql>
    複製代碼

沒有選擇默認數據庫時對錶的操做

有時候咱們並無使用USE語句來選擇當前的數據庫,或者在一條語句中遇到的表分散在不一樣的數據庫中,咱們就必須顯式的指定這些表所屬的數據庫了。好比無論當前數據庫是否是xiaohaizi,咱們均可以調用這個語句來展現數據庫xiaohaizi裏邊的表:

mysql> SHOW TABLES FROM xiaohaizi;
+---------------------+
| Tables_in_xiaohaizi |
+---------------------+
| first_table         |
| student_info        |
| student_score       |
+---------------------+
3 rows in set (0.00 sec)

mysql>
複製代碼

其餘地方若是使用到表名的話,須要顯式指定這個表所屬的數據庫,指明方式是這樣的:

數據庫名.表名
複製代碼

好比咱們須要查詢first_table表中的數據,能夠這麼寫:

SELECT * FROM xiaohaizi.first_table;
複製代碼

查看錶結構:

SHOW CREATE TABLE xiaohaizi.first_table\G
複製代碼

在其餘不肯定當前數據庫的狀況下,使用到表的地方也都須要加上所屬的數據庫名,就不一一列舉了。

修改表

在表建立好以後若是對錶的結構不滿意,好比想增長或者刪除一列,想修改某一列的數據類型或者約束性條件,想對錶名或者列名進行重命名,這些操做通通都算是修改表結構。MySQL給咱們提供了一系列修改表結構的語句。

修改表名

咱們能夠經過下邊這兩種方式來修改表的名稱:

  1. 方式一:

    ALTER TABLE 舊錶名 RENAME TO 新表名;
    複製代碼

    咱們把first_table表的名稱修改成first_table1

    mysql> ALTER TABLE first_table RENAME TO first_table1;
    Query OK, 0 rows affected (0.01 sec)
    
    mysql> SHOW TABLES;
    +---------------------+
    | Tables_in_xiaohaizi |
    +---------------------+
    | first_table1        |
    | student_info        |
    | student_score       |
    +---------------------+
    3 rows in set (0.00 sec)
    
    mysql>
    複製代碼

    經過SHOW TABLES命令能夠看到已經更名成功了。

  2. 方式二:

    RENAME TABLE 舊錶名1 TO 新表名1, 舊錶名2 TO 新表名2, ... 舊錶名n TO 新表名n;
    複製代碼

    這種更名方式的牛逼之處就是它能夠在一條語句中修改多個表的名稱。這裏就不舉例了,本身測試一下吧。

若是在修改表名的時候指定了數據庫名,還能夠轉移表所屬的數據庫,咱們先再建立一個數據庫dahaizi

mysql> CREATE DATABASE dahaizi;
Query OK, 1 row affected (0.00 sec)

mysql>
複製代碼

而後把first_table1錶轉移到這個數據庫下:

mysql> ALTER TABLE xiaohaizi.first_table1 RENAME TO dahaizi.first_table1;
Query OK, 0 rows affected (0.01 sec)

mysql> SHOW TABLES FROM dahaizi;
+-------------------+
| Tables_in_dahaizi |
+-------------------+
| first_table1      |
+-------------------+
1 row in set (0.00 sec)

mysql> SHOW TABLES FROM xiaohaizi;
+---------------------+
| Tables_in_xiaohaizi |
+---------------------+
| student_info        |
| student_score       |
+---------------------+
2 rows in set (0.00 sec)

mysql>
複製代碼

能夠看到first_table1就從數據庫xiaohaizi轉移到dahaizi裏邊了。咱們再換一種方式把它轉回來,而且改名爲first_table

mysql> RENAME TABLE dahaizi.first_table1 TO xiaohaizi.first_table;
Query OK, 0 rows affected (0.00 sec)

mysql>
複製代碼

增長列

咱們可使用下邊的語句來增長表中的列:

ALTER TABLE 表名 ADD COLUMN 列名 列的類型 [列的屬性];
複製代碼

好比咱們向first_table裏添加一個名叫third_column的列就能夠這麼寫:

mysql> ALTER TABLE first_table ADD COLUMN third_column CHAR(4) DEFAULT '1234' COMMENT '第三列';
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> DESC first_table;
+---------------+------------------+------+-----+---------+----------------+
| Field         | Type             | Null | Key | Default | Extra          |
+---------------+------------------+------+-----+---------+----------------+
| id            | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| first_column  | int(11)          | YES  |     | NULL    |                |
| second_column | varchar(100)     | YES  |     | abc     |                |
| third_column  | char(4)          | YES  |     | 1234    |                |
+---------------+------------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

mysql>
複製代碼

經過查看錶的結構能夠看到該列已經添加成功了。

增長列到特定位置

默認的狀況下列都是加到現有列的最後一列,咱們也能夠在添加列的時候指定它的位置,具體有兩種方式:

  1. 添加到第一列:

    ALTER TABLE 表名 ADD COLUMN 列名 列的類型 [列的屬性] FIRST;
    複製代碼

    讓咱們把fourth_column插入到第一列:

    mysql> ALTER TABLE first_table ADD COLUMN fourth_column CHAR(4) DEFAULT '1234' COMMENT '第四列' FIRST;
    Query OK, 0 rows affected (0.05 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    mysql> DESC first_table;
    +---------------+------------------+------+-----+---------+----------------+
    | Field         | Type             | Null | Key | Default | Extra          |
    +---------------+------------------+------+-----+---------+----------------+
    | fourth_column | char(4)          | YES  |     | 1234    |                |
    | id            | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
    | first_column  | int(11)          | YES  |     | NULL    |                |
    | second_column | varchar(100)     | YES  |     | abc     |                |
    | third_column  | char(4)          | YES  |     | 1234    |                |
    +---------------+------------------+------+-----+---------+----------------+
    5 rows in set (0.00 sec)
    
    mysql>
    複製代碼

    看到插入成功了。

  2. 添加到指定列的後邊:

    ALTER TABLE 表名 ADD COLUMN 列名 列的類型 [列的屬性] AFTER 指定列名;
    複製代碼

    再插入一個fifth_columnfirst_column後邊瞅瞅:

    mysql> ALTER TABLE first_table ADD COLUMN fifth_column CHAR(4) DEFAULT '1234' COMMENT '第五列' AFTER first_column;
    Query OK, 0 rows affected (0.05 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    mysql> DESC first_table;
    +---------------+------------------+------+-----+---------+----------------+
    複製代碼

| Field | Type | Null | Key | Default | Extra | +---------------+------------------+------+-----+---------+----------------+ | fourth_column | char(4) | YES | | 1234 | | | id | int(10) unsigned | NO | PRI | NULL | auto_increment | | first_column | int(11) | YES | | NULL | | | fifth_column | char(4) | YES | | 1234 | | | second_column | varchar(100) | YES | | abc | | | third_column | char(4) | YES | | 1234 | | +---------------+------------------+------+-----+---------+----------------+ 6 rows in set (0.00 sec)

mysql>
```
`fifth_column`列就被插到`first_column`列後邊了。
複製代碼

刪除列

咱們可使用下邊的語句來刪除表中的列:

ALTER TABLE DROP COLUMN 列名;
複製代碼

咱們把剛纔向first_table裏添加幾個列都刪掉試試:

mysql> ALTER TABLE first_table DROP COLUMN third_column;
Query OK, 0 rows affected (0.05 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> ALTER TABLE first_table DROP COLUMN fourth_column;
Query OK, 0 rows affected (0.05 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> ALTER TABLE first_table DROP COLUMN fifth_column;
Query OK, 0 rows affected (0.04 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> DESC first_table;
+---------------+------------------+------+-----+---------+----------------+
| Field         | Type             | Null | Key | Default | Extra          |
+---------------+------------------+------+-----+---------+----------------+
| id            | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| first_column  | int(11)          | YES  |     | NULL    |                |
| second_column | varchar(100)     | YES  |     | abc     |                |
+---------------+------------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)

mysql>
複製代碼

能夠看到刪除成功了。

修改列信息

修改列的信息有下邊這兩種方式:

  1. 方式一:

    ALTER TABLE 表名 MODIFY 列名 新數據類型 [新屬性];
    複製代碼

    咱們來修改一下first_table表的second_column列,把它修改成VARCHAR(2)以及具備NOT NULL約束條件:

    mysql> ALTER TABLE first_table MODIFY second_column VARCHAR(2) NOT NULL COMMENT '第二列';
    ERROR 1406 (22001): Data too long for column 'second_column' at row 1
    mysql>
    複製代碼

    咦,看到報了個錯,意思是second_column列裏存放的數據太大了,咱們看看都存了哪些數據:

    mysql> SELECT * FROM first_table;
    +----+--------------+---------------+
    | id | first_column | second_column |
    +----+--------------+---------------+
    |  1 |            1 | aaa           |
    |  2 |            2 | bbb           |
    |  3 |            3 | ccc           |
    +----+--------------+---------------+
    3 rows in set (0.00 sec)
    
    mysql>
    複製代碼

    原來存放的數據是'aaa''bbb''ccc',它們都是包含3個字符的字符串。如今咱們要把second_column列的數據類型改成VARCHAR(2),而VARCHAR(2)最多隻能存放兩個字符,因此纔會報錯了!知道了錯誤緣由後,咱們把類型改成VARCHAR(3)試試:

    mysql> ALTER TABLE first_table MODIFY second_column VARCHAR(3) NOT NULL COMMENT '第二列';
    Query OK, 3 rows affected (0.03 sec)
    Records: 3  Duplicates: 0  Warnings: 0
    
    mysql> DESC first_table;
    +---------------+------------------+------+-----+---------+----------------+
    複製代碼

| Field | Type | Null | Key | Default | Extra | +---------------+------------------+------+-----+---------+----------------+ | id | int(10) unsigned | NO | PRI | NULL | auto_increment | | first_column | int(11) | YES | | NULL | | | second_column | varchar(3) | NO | | NULL | | +---------------+------------------+------+-----+---------+----------------+ 3 rows in set (0.00 sec)

mysql>
```
好了,這回就對了。這個過程也提醒咱們:<span style="color:red">不能隨便修改列信息,修改後的數據類型和屬性必定要兼容表中現有的數據!</span>。
複製代碼
  1. 方式二:

    ALTER TABLE 表名 CHANGE 舊列名 新列名 新數據類型 [新屬性];
    複製代碼

    能夠看到這種修改方式須要咱們填兩個列名,也就是說在修改數據類型和屬性的同時也能夠修改列名!好比咱們修改second_column的列名爲second_column1

    mysql> ALTER TABLE first_table CHANGE second_column second_column1 VARCHAR(3) NOT NULL COMMENT '第二列';
    Query OK, 0 rows affected (0.01 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    mysql> DESC first_table;
    +----------------+------------------+------+-----+---------+----------------+
    複製代碼

| Field | Type | Null | Key | Default | Extra | +----------------+------------------+------+-----+---------+----------------+ | id | int(10) unsigned | NO | PRI | NULL | auto_increment | | first_column | int(11) | YES | | NULL | | | second_column1 | varchar(3) | NO | | NULL | | +----------------+------------------+------+-----+---------+----------------+ 3 rows in set (0.00 sec)

mysql>
```
咱們只是把`second_column`的列名修改了一下而已,並無改動它的數據類型和屬性,因此直接把舊的數據類型和屬性抄過來就行了,能夠看到結果名稱已經被修改了。
複製代碼
修改列排列位置

若是咱們以爲當前列的順序有問題的話,可使用下邊這幾條語句進行修改:

  1. 將列設爲表的第一列:

    ALTER TABLE 表名 MODIFY 列名 列的類型 列的屬性 FIRST;
    複製代碼

    先看一下如今表first_table的各個列的排列順序:

    mysql> DESC first_table;
    +----------------+------------------+------+-----+---------+----------------+
    複製代碼

| Field | Type | Null | Key | Default | Extra | +----------------+------------------+------+-----+---------+----------------+ | id | int(10) unsigned | NO | PRI | NULL | auto_increment | | first_column | int(11) | YES | | NULL | | | second_column1 | varchar(3) | NO | | NULL | | +----------------+------------------+------+-----+---------+----------------+ 3 rows in set (0.01 sec)

mysql>
```
能夠看到,列的順序依次是: `id`、`first_column`、`second_column1`。如今咱們想把`first_column`放在第一列能夠這麼寫:
```
mysql>  ALTER TABLE first_table MODIFY first_column int(11)  COMMENT '第一列' FIRST;
Query OK, 0 rows affected (0.04 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> DESC first_table;
+----------------+------------------+------+-----+---------+----------------+
複製代碼

| Field | Type | Null | Key | Default | Extra | +----------------+------------------+------+-----+---------+----------------+ | first_column | int(11) | YES | | NULL | | | id | int(10) unsigned | NO | PRI | NULL | auto_increment | | second_column1 | varchar(3) | NO | | NULL | | +----------------+------------------+------+-----+---------+----------------+ 3 rows in set (0.00 sec)

mysql>
```
看到`first_column`已經成爲第一列了!
複製代碼
  1. 將列放到指定列的後邊:

    ALTER TABLE 表名 MODIFY 列名 列的類型 列的屬性 after 指定列名;
    複製代碼

    比方說咱們想把first_column放到second_column1後邊能夠這麼寫:

    mysql> ALTER TABLE first_table MODIFY first_column int(11)  COMMENT '第一列' AFTER second_column1;
    Query OK, 0 rows affected (0.04 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    mysql> DESC first_table;
    +----------------+------------------+------+-----+---------+----------------+
    複製代碼

| Field | Type | Null | Key | Default | Extra | +----------------+------------------+------+-----+---------+----------------+ | id | int(10) unsigned | NO | PRI | NULL | auto_increment | | second_column1 | varchar(3) | NO | | NULL | | | first_column | int(11) | YES | | NULL | | +----------------+------------------+------+-----+---------+----------------+ 3 rows in set (0.00 sec)

mysql>
```
複製代碼

一條語句中包含多個修改操做

若是對同一個表有多個修改操做的話,咱們能夠把它們放到一條語句中執行,就像這樣:

ALTER TABLE 表名 操做1, 操做2, ..., 操做n;
複製代碼

上邊咱們在演示刪除列操做的時候用三條語句連着刪了third_columnfourth_columnfifth_column這三個列,其實這三條語句能夠合併爲一條:

ALTER TABLE first_table DROP COLUMN third_column, DROP COLUMN fourth_column, DROP COLUMN fifth_column;
複製代碼

這樣人敲的命令也少了,服務器也不用分屢次執行效率也高了,何樂而不爲呢?

總結

  1. MySQL服務器能夠包含若干數據庫,每一個數據庫中能夠包含若干個表。

  2. 數據庫相關操做以下:

    • 展現數據庫:SHOW DATABASES;
    • 建立數據庫:CREATE DATABASE 數據庫名;
    • 切換當前數據庫:USE 數據庫名
    • 刪除數據庫:DROP DATABASE 數據庫名
  3. 表結構的相關操做以下:

    • 建立表:

      CREATE TABLE 表名 (
          列名, 列的類型, [列的屬性] COMMENT '列的註釋',
          ... (若干個列的信息)
      ) COMMENT '表的註釋';
      複製代碼
    • 刪除表:DROP TABLE 表名;

    • 修改表:

      • 修改表名:

        • 方式一:

          ALTER TABLE 舊錶名 RENAME TO 新表名;
          複製代碼
        • 方式二:

          RENAME TABLE 舊錶名1 TO 新表名1, 舊錶名2 TO 新表名2, ... 舊錶名n TO 新表名n;
          複製代碼
      • 添加列:

        ALTER TABLE 表名 ADD COLUMN 列名 列的類型 [列的屬性] [FIRST|AFTER 指定列名];
        複製代碼
      • 刪除列:

        ALTER TABLE DROP COLUMN 列名;
        複製代碼
      • 修改列信息:

        • 方式一:

          ALTER TABLE 表名 MODIFY 列名 新數據類型 [新屬性] [FIRST|AFTER 指定列名];
          複製代碼
        • 方式二:

          ALTER TABLE 表名 CHANGE 舊列名 新列名 新數據類型 [新屬性] [FIRST|AFTER 指定列名];
          複製代碼
  4. 各類約束性條件

    • 默認值:在插入語句中沒有指定該列的值的狀況下,使用默認值,聲明語法以下:

      列名 列的類型 DEFAULT 默認值
      複製代碼
    • 非空約束:聲明瞭該屬性的列不容許插入NULL值,聲明語法:

      列名 列的類型 NOT NULL
      複製代碼
    • 主鍵:惟一標識一條記錄,而且一個表中最多字能有一個主鍵,主鍵值不能爲NULL,聲明語法:

      • 方式一:

        列名 列的類型 PRIMARY KEY
        複製代碼
      • 方式二:

        PRIMARY KEY (列名1, 列名2, ...)
        複製代碼
    • 惟一性約束:惟一標識一條記錄,一個表中能夠有多個惟一性約束,而且值能夠爲NULL,聲明語法:

      • 方式一:

        列名 列的類型 UNIQUE [KEY]
        複製代碼
      • 方式二:

        UNIQUE [KEY] [約束名稱] (列名1, 列名2, ...)
        複製代碼
    • 外鍵:表A的某個列或列組合的值依賴表B的某個列或列組合的值,則成表A爲子表,表B爲父表,表A的該列或者列組合稱爲外鍵,聲明外鍵的方式以下:

      CONSTRAINT [外鍵名稱] FOREIGN KEY(列1, 列2, ...) REFERENCES 父表名(父列1, 父列2, ...);
      複製代碼
    • 自增:在插入語句沒有包含自增列的狀況下,該列的值會遞增,聲明方式以下:

      列名 列的類型 AUTO_INCREMENT
      複製代碼

小冊

本系列專欄都是MySQL入門知識,想看進階知識能夠到小冊中查看:《MySQL是怎樣運行的:從根兒上理解MySQL》的連接 。小冊的內容主要是從小白的角度出發,用比較通俗的語言講解關於MySQL進階的一些核心概念,好比記錄、索引、頁面、表空間、查詢優化、事務和鎖等,總共的字數大約是三四十萬字,配有上百幅原創插圖。主要是想下降普通程序員學習MySQL進階的難度,讓學習曲線更平滑一點~

相關文章
相關標籤/搜索