mysql中創建表的語法、基本數據類型,約束條件


一、創建表的完整語法

# 語法
    [中括號內為可選參數]
    create table 表名(
    字段名1 類型[(寬度)] [約束條件],  # 這里的類型既:限制 字段1 必須以 XX類型 來存儲記錄
    字段名2 類型[(寬度)] [約束條件],
    字段名3 類型[(寬度)] [約束條件]
    )

代碼示例:
    create table file(
    id int unsigned,  # 未設置寬度,設置了約束條件
    sex char(6),  # 設置了寬度,未設置約束條件
    age int(3) unsigned,  # 寬度 和 約束條件都設置了
    hobby char  # 寬度 和 約束條件 都未設置
    )

# 注意!
1、在同一張表中,字段名不能相同
2、寬度 和 約束條件為可選參數,字段名 和 字段名下記錄的類型 是必須的
3、最后一個字段后不能加逗號

# 補充
1)寬度指的是對存儲數據的限制(除整型外)
mysql> create table userinfo (name char);
Query OK, 0 rows affected (0.04 sec)

mysql> desc userinfo;  # 從表中可以看出 char類型默認存儲長度為 1
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| name  | char(1) | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)

mysql> insert userinfo values ('egon');  # 超過 1 位存儲長度則報錯
ERROR 1406 (22001): Data too long for column 'name' at row 1
mysql> insert userinfo values ('e');  # 可以存儲1位長度的記錄
Query OK, 1 row affected (0.00 sec)

mysql> select * from userinfo;  # 查看記錄
+------+
| name |
+------+
| e    |
+------+
1 row in set (0.00 sec)

# MySQL 3.7及以上版本都為嚴格模式,故超過可存儲數據長度則會報錯

2)約束條件
create table t1(id int,name char not null);  # not null 既 對字段name的約束(不能為null)
insert into t1 values(1,'j');  # 正常存儲
insert into t1 values(2,null);  # 報錯


# 總結:
	類型是用來限制 字段 必須以何種數據類型來存儲記錄
	類型其實也是對字段的約束(約束字段下的記錄必須為XX類型)
	類型后寫的 約束條件 是在類型之外的 額外添加的約束
  • 設置嚴格模式

我們剛剛在上面設置了char,tinyint,存儲數據時超過它們的最大存儲長度,發現數據也能正常存儲進去,只是mysql幫我們自動截取了最大長度。但在實際情況下,我們應該盡量減少數據庫的操作,緩解數據庫的壓力,讓它僅僅只管理數據即可,這樣的情況下就需要設置安全模式


show variables like "%mode%";  # 查看數據庫配置中變量名包含mode的配置參數
# 修改安全模式
set session # 只在當前操作界面有效
set global  # 全局有效

set global sql_mode ='STRICT_TRANS_TABLES'
# 修改完之后退出當前客戶端重新登陸即可

二、基本數據類型

  • 整型

    分類: TINYINT SMALLINT MEDIUMINT INT BIGINT
    	  tinyint smallint mediumint int bigint
    作用: 存儲各種年齡,等級,id,號碼等數據
    
    類型存儲范圍:參考圖片https://images2017.cnblogs.com/blog/1036857/201708/1036857-20170801181433755-146301178.png
    

    類型存儲范圍 參考圖片連接 ←點我

    驗證整型字段有無符號及范圍

    測試環境皆為嚴格模式

    mysql> create table t1 (x tinyint);
    Query OK, 0 rows affected (0.05 sec)
    
    mysql> insert into t1 values (128);  # 不在范圍內,報錯
    ERROR 1264 (22003): Out of range value for column 'x' at row 1
    mysql> insert into t1 values (127);  # 在范圍內,成功
    Query OK, 1 row affected (0.03 sec)
    
    mysql> insert into t1 values (-129);  # 不在范圍內,報錯
    ERROR 1264 (22003): Out of range value for column 'x' at row 1
    mysql> insert into t1 values (-128);  # 在范圍內,成功
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select * from t1;  # 查看表內記錄
    +------+
    | x    |
    +------+
    |  127 |
    | -128 |
    +------+
    2 rows in set (0.00 sec)
    
    # tinyint的范圍:(-128,127)
    
    mysql> create table t2 (x tinyint unsigned);  # 約束條件unsigned限制字段不可存儲帶符號的記錄,既原來的(-128,0)區間的數就沒了,這樣范圍總數就變成了(0,255)
    Query OK, 0 rows affected (0.04 sec)
    
    mysql> insert into t2 values (-1);  # 不在范圍內,報錯
    ERROR 1264 (22003): Out of range value for column 'x' at row 1
    mysql> insert into t2 values (0);  # 在范圍內,成功
    Query OK, 1 row affected (0.00 sec)
    
    mysql> insert into t2 values (256);  # 不在范圍內,報錯
    ERROR 1264 (22003): Out of range value for column 'x' at row 1
    mysql> insert into t2 values (255);  # 在范圍內,成功
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select * from t2;  # 查看表內記錄
    +------+
    | x    |
    +------+
    |  255 |
    |    0 |
    +------+
    2 rows in set (0.00 sec)
    
    # tinyint unsigned 的范圍:(0,255)  包括0的
    
    mysql> create table t3(x int unsigned);  # 
    Query OK, 0 rows affected (0.05 sec)
    
    mysql> insert into t3 values(4294967296);  # 不在范圍內,報錯
    ERROR 1264 (22003): Out of range value for column 'x' at row 1
    mysql> insert into t3 values(4294967295);  # 在范圍內,成功
    Query OK, 1 row affected (0.00 sec)
    
    mysql> insert into t3 values(-1);  # 不在范圍內,報錯
    ERROR 1264 (22003): Out of range value for column 'x' at row 1
    mysql> insert into t3 values(0);  # 在范圍內,成功
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select * from t3;
    +------------+
    | x          |
    +------------+
    | 4294967295 |
    |          0 |
    +------------+
    2 rows in set (0.00 sec)
    
    # int類型有符號范圍為(-1247483648,1247483647) | 無符號范圍為(0,4294967295)
    
    # 結論:整型默認都是有符號的
    

    疑問:類型后面的寬度能否改變字段存儲的大小限制

    mysql> create table t4(x int(8));  # 寬度為8
    Query OK, 0 rows affected (0.04 sec)
    
    mysql> insert into t4 values(1000000000);  # 10位數 可以存儲
    Query OK, 1 row affected (0.00 sec)
    
    # 顯示時,不夠8位用0填充,如果超出8位則正常顯示
    mysql> create table t5(x int(8) unsigned zerofill);  # 約束條件zerofill 既 用 0 填充
    Query OK, 0 rows affected (0.04 sec)
    
    mysql> insert into t5 values(10000);  # 5位數
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select * from t4,t5;
    +------------+----------+
    | x          | x        |
    +------------+----------+
    | 1000000000 | 00010000 |   # 超過8位正常顯示,不超過則用 0 填充
    +------------+----------+
    1 row in set (0.00 sec)
    
    強調:對於整型來說,數據類型后的寬度並不是存儲限制,而是顯示限制,所以在創建表時,如果字段采用的是整型類型,完全無需指定顯示寬度, 默認的顯示寬度,足夠顯示完整當初存放的數據
    
  • 浮點型

    分類: FLOAT DOUBLE decimal
    	  float double decimal
    	  
    作用:記錄身高,體重,薪資等數據
    
    字段限制特點:(5,3)前一位表示所有的位數,后一位表示小數個數
    
    # 存儲限制
    float(255,30)
    double(255,30)
    decimal(65,30)
    
    # 精確度驗證
    mysql> create table t6(x float(255,30));
    Query OK, 0 rows affected (0.04 sec)
    
    mysql> create table t7(x double(255,30));
    Query OK, 0 rows affected (0.05 sec)
    
    mysql> create table t8(x decimal(65,30));
    Query OK, 0 rows affected (0.06 sec)
    
    mysql> 
    mysql> insert into t6 values(1.111111111111111111111111111111);
    Query OK, 1 row affected (0.00 sec)
    
    mysql> insert into t7 values(1.111111111111111111111111111111);
    Query OK, 1 row affected (0.00 sec)
    
    mysql> insert into t8 values(1.111111111111111111111111111111);
    Query OK, 1 row affected (0.00 sec)
    
    mysql> mysql> select * from t6;
    +----------------------------------+
    | x                                |
    +----------------------------------+
    | 1.111111164093017600000000000000 |  # float 精度最低
    +----------------------------------+
    1 row in set (0.00 sec)
    
    mysql> select * from t7;
    +----------------------------------+
    | x                                |
    +----------------------------------+
    | 1.111111111111111200000000000000 |  # double 精度第二
    +----------------------------------+
    1 row in set (0.00 sec)
    
    mysql> select * from t8;
    +----------------------------------+
    | x                                |
    +----------------------------------+
    | 1.111111111111111111111111111111 |  # decimal 精度最高
    +----------------------------------+
    1 row in set (0.00 sec)
    
    # 由低至高 精度排名:float < double < decimal
    
  • 字符類型

    分類:
        char(定長)
        varchar(變長)
        
    作用:姓名,地址,描述類信息
    
    

    測試代碼:測試char | varchar 區別

    mysql> create table t9(name char(4));  # 超出四個字符報錯,不夠四個 就用字符空格補全
    Query OK, 0 rows affected (0.04 sec)
    
    mysql> create table t10(name varchar(4));  # 超出四個字符報錯,不夠四個有幾個就存幾個
    Query OK, 0 rows affected (0.04 sec)
    
    mysql> insert into t9 values('hello');  # 驗證存儲限制
    ERROR 1406 (22001): Data too long for column 'name' at row 1
    mysql> insert into t10 values('hello');  # 驗證存儲限制
    ERROR 1406 (22001): Data too long for column 'name' at row 1
    mysql> insert into t9 values('a');  # 'a   '  # 補了3個空格
    Query OK, 1 row affected (0.00 sec)  # 'a'
    
    mysql> insert into t10 values('a');
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select * from t9,t10;  # 無法查看真正的結果
    +------+------+
    | name | name |
    +------+------+
    | a    | a    |
    +------+------+
    1 row in set (0.00 sec)
    
    mysql> select char_length(name) from t9;  # 仍然無法查看到真正的結果
    +-------------------+
    | char_length(name) |
    +-------------------+
    |                 1 |
    +-------------------+
    1 row in set (0.00 sec)
    
    mysql> select char_length(name) from t10;  # 仍然無法查看到真正的結果
    +-------------------+
    | char_length(name) |
    +-------------------+
    |                 1 |
    +-------------------+
    1 row in set (0.00 sec)
    # -----------------以下不是測試代碼-----------------
    """首先應該肯定的是在硬盤上存的絕對是真正的數據,但顯示的時候mysql會自動將末尾的空格取掉"""
    # 如果不想讓mysql幫你做自動去除末尾空格的操作,需要再添加一個模式
    set global sql_mode="strict_trans_tables,PAD_CHAR_TO_FULL_LENGTH";
    # 退出客戶端重新登陸
    select char_length(x) from t12;  # 4
    select char_length(y) from t13;  # 1
    
    # 針對char類型,mysql在存儲時會將數據用空格補全存放到硬盤中。但是會在讀出結果的時候自動取掉末尾的空格
    
    

    char與varchar的使用區別

    name char(5)
    # 缺點:浪費空間
    # 優點:存取速度都快
    egon alex lxx  jxx  txx  
    ==> egon_alex_lxx__jxx__txx__  # 以空格補全成5個字符,然后讀取時一次性讀5個,並去除多去的空格
    
    name varchar(5)
    # 缺點:存取速度慢
    # 優點:節省空間
    1bytes+egon 1bytes+alex 1bytes+lxx  1bytes+jxx  1bytes+txx
    # 存儲時真實數據前會帶有一個標識真實數據長度的表頭,讀取數據時,先讀取報頭,再讀取根據報頭得到的長度去讀取真實數據
    
    
  • 時間類型

    分類:
    date:2019-05-01
    time:11:11:11
    Datetime:2019-01-02 11:11:11
    Year:2019
    
    

    測試代碼

    mysql> create table student(
        ->     id int,
        ->     name char(16),
        ->     born_year year,
        ->     birth date,
        ->     study_time time,
        ->     reg_time datetime
        -> );
    Query OK, 0 rows affected (0.05 sec)
    
    mysql> insert into student values(1,'egon','2019','2019-05-09','11:11:00','2019-11-11 11:11:11');
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select * from student;
    +------+------+-----------+------------+------------+---------------------+
    | id   | name | born_year | birth      | study_time | reg_time            |
    +------+------+-----------+------------+------------+---------------------+
    |    1 | egon |      2019 | 2019-05-09 | 11:11:00   | 2019-11-11 11:11:11 |
    +------+------+-----------+------------+------------+---------------------+
    1 row in set (0.00 sec)
    
    
    
  • 枚舉與集合類型

    分類:
    	枚舉 enum   # 多選一
    	集合 set    # 多選多
    

    測試代碼

    # 枚舉
    mysql> create table user(
        ->   id int,
        ->   name char(16),
        ->   gender enum('male','female','others')  # 枚舉,一次只能在枚舉范圍中選一個
        -> );
    Query OK, 0 rows affected (0.04 sec)
    
    mysql> insert into user values(1,'jason','xxx');  # 不可以選枚舉范圍外的
    ERROR 1265 (01000): Data truncated for column 'gender' at row 1
    mysql> insert into user values(2,'egon','female,others');  # 不可以選多個
    ERROR 1265 (01000): Data truncated for column 'gender' at row 1
    mysql> insert into user values(2,'egon','female');
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select * from user;
    +------+------+--------+
    | id   | name | gender |
    +------+------+--------+
    |    2 | egon | female |
    +------+------+--------+
    1 row in set (0.00 sec)
    
    
    # 集合
    mysql> create table teacher(
        ->   id int,
        ->   name char(16),
        ->   gender enum('male','female','others'),
        ->   hobby set('read','sleep','sanna','dbj')  # 集合,一次可以從集合范圍中選多個
        -> );
    Query OK, 0 rows affected (0.04 sec)
    
    mysql> insert into teacher values(1,'egon','male','read,sleep,dbj');  # 可以選多個
    Query OK, 1 row affected (0.00 sec)
    
    mysql> insert into teacher values(1,'egon','male','read');  # 也可以只選一個
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select * from teacher;
    +------+------+--------+----------------+
    | id   | name | gender | hobby          |
    +------+------+--------+----------------+
    |    1 | egon | male   | read,sleep,dbj |
    |    1 | egon | male   | read           |
    +------+------+--------+----------------+
    2 rows in set (0.00 sec)
    

三、約束條件

NOT NULL    		標識該字段不能為空
DEFAULT    			為該字段設置默認值
PRIMARY KEY (PK)    標識該字段為該表的主鍵,可以唯一的標識記錄
FOREIGN KEY (FK)    標識該字段為該表的外鍵
UNIQUE KEY (UK)    	標識該字段的值是唯一的
AUTO_INCREMENT    	標識該字段的值自動增長(整數類型,而且為主鍵)

UNSIGNED 無符號
ZEROFILL 使用0填充

  • not null+default(字段不能為空+為字段設置默認值)

    mysql> create table user(
        -> id int,
        -> name char(16)  # 沒有其他約束條件
        -> );
    Query OK, 0 rows affected (0.05 sec)
    
    mysql> insert into user values(1,null);
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select * from user;
    +------+------+
    | id   | name |
    +------+------+
    |    1 | NULL |  # 可以寫入NULL記錄
    +------+------+
    1 row in set (0.00 sec)
    
    mysql> delete from user where id=1;  # 嚴格模式下修改字段需要字段下的記錄都合法,所以要刪除原違法記錄
    Query OK, 1 row affected (0.00 sec)
    
    mysql> alter table user modify name char(16) not null;  # 修改字段,加上不可為空的約束
    Query OK, 0 rows affected (0.06 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    mysql> insert into user (name,id) values (null,2);  # 指定傳入字段,如是先傳name,再傳id,name加了約束條件,不能為NULL,故報錯
    ERROR 1048 (23000): Column 'name' cannot be null
    mysql> insert into user (name,id) values ('egon',2);  # 合法值傳入,成功
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select * from user;
    +------+------+
    | id   | name |
    +------+------+
    |    2 | egon |
    +------+------+
    1 row in set (0.00 sec)
    
    
    # not null 與 defult 與 枚舉/集合  聯用
    mysql> create table student(
        ->   id int,
        ->   name char(16) not null,  # 約束了name not null
        ->   gender enum('male','female','others') default 'male'  # 指定了枚舉范圍,以及默認值
        -> );
    Query OK, 0 rows affected (0.11 sec)
    
    mysql> insert into student(id,name) values(1,'jason');
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select * from student;
    +------+-------+--------+
    | id   | name  | gender |
    +------+-------+--------+
    |    1 | jason | male   |
    +------+-------+--------+
    1 row in set (0.00 sec)
    
  • unique

    # 單列唯一
    mysql> create table user1(
        -> id int unique,   # 約束 該字段不可以有重復記錄
        -> name char(16)
        -> );
    Query OK, 0 rows affected (0.04 sec)
    
    mysql> insert into user1 values(1,'jason'),(1,'egon');
    ERROR 1062 (23000): Duplicate entry '1' for key 'id'
    mysql> insert into user1 values(1,'jason'),(2,'jason');
    Query OK, 2 rows affected (0.00 sec)
    Records: 2  Duplicates: 0  Warnings: 0
    
    mysql> select * from user1;
    +------+-------+
    | id   | name  |
    +------+-------+
    |    1 | jason |
    |    2 | jason |
    +------+-------+
    2 rows in set (0.00 sec)
    
    
    # 聯合唯一
    mysql> create table server(
        ->   id int,
        ->   ip char(16),
        ->   port int,
        ->   unique(ip,port)
        -> );
    Query OK, 0 rows affected (0.04 sec)
    
    mysql> insert into server values(1,'127.0.0.1',8080);
    Query OK, 1 row affected (0.00 sec)
    
    mysql> insert into server values(2,'127.0.0.1',8080);  # 報錯,因為ip與port同時與上已存在的記錄相同了
    ERROR 1062 (23000): Duplicate entry '127.0.0.1-8080' for key 'ip'
    mysql> insert into server values(1,'127.0.0.0',8080);  # ip不同,port相同是合法的
    Query OK, 1 row affected (0.00 sec)
    
    mysql> insert into server values(1,'127.0.0.1',8081);  #  ip相同,port不同是合法的
    Query OK, 1 row affected (0.00 sec)
    
    總結:
    單列唯一 既 單個字段下的記錄不能重復
    聯合唯一 既 多個字段下的記錄不能同時重復
    

    primary key + auto_increment

    primary key: 標識該字段為該表的主鍵,可以唯一的標識記錄
    auto_increment: 標識該字段的值自動增長(整數類型,而且為主鍵)
    
    # 單從約束角度來說primary key就等價於not null unique
    
    # ============單列做主鍵===============
    # 方法一:not null+unique
    create table department1(
    id int not null unique,  # 主鍵
    name varchar(20) not null unique,
    comment varchar(100)
    );
    
    mysql> desc department1;
    +---------+--------------+------+-----+---------+-------+
    | Field   | Type         | Null | Key | Default | Extra |
    +---------+--------------+------+-----+---------+-------+
    | id      | int(11)      | NO   | PRI | NULL    |       |
    | name    | varchar(20)  | NO   | UNI | NULL    |       |
    | comment | varchar(100) | YES  |     | NULL    |       |
    +---------+--------------+------+-----+---------+-------+
    rows in set (0.01 sec)
    
    # 方法二:在某一個字段后用primary key
    create table department2(
    id int primary key,  # 主鍵
    name varchar(20),
    comment varchar(100)
    );
    
    mysql> desc department2;
    +---------+--------------+------+-----+---------+-------+
    | Field   | Type         | Null | Key | Default | Extra |
    +---------+--------------+------+-----+---------+-------+
    | id      | int(11)      | NO   | PRI | NULL    |       |
    | name    | varchar(20)  | YES  |     | NULL    |       |
    | comment | varchar(100) | YES  |     | NULL    |       |
    +---------+--------------+------+-----+---------+-------+
    rows in set (0.00 sec)
    
    # 方法三:在所有字段后單獨定義primary key
    create table department3(
    id int,
    name varchar(20),
    comment varchar(100),
    constraint pk_name primary key(id);  # 創建主鍵並為其命名pk_name
    
    mysql> desc department3;
    +---------+--------------+------+-----+---------+-------+
    | Field   | Type         | Null | Key | Default | Extra |
    +---------+--------------+------+-----+---------+-------+
    | id      | int(11)      | NO   | PRI | NULL    |       |
    | name    | varchar(20)  | YES  |     | NULL    |       |
    | comment | varchar(100) | YES  |     | NULL    |       |
    +---------+--------------+------+-----+---------+-------+
    rows in set (0.01 sec)
    
    # ==================多列做主鍵================
    create table service(
    ip varchar(15),
    port char(5),
    service_name varchar(10) not null,
    primary key(ip,port)  # ip和port作為主鍵==>ip和port,不可以為空,不可重復
    );
    
    mysql> desc service;
    +--------------+-------------+------+-----+---------+-------+
    | Field        | Type        | Null | Key | Default | Extra |
    +--------------+-------------+------+-----+---------+-------+
    | ip           | varchar(15) | NO   | PRI | NULL    |       |
    | port         | char(5)     | NO   | PRI | NULL    |       |
    | service_name | varchar(10) | NO   |     | NULL    |       |
    +--------------+-------------+------+-----+---------+-------+
    3 rows in set (0.00 sec)
    
    mysql> insert into service values
        -> ('172.16.45.10','3306','mysqld'),
        -> ('172.16.45.11','3306','mariadb')
        -> ;
    Query OK, 2 rows affected (0.00 sec)
    Records: 2  Duplicates: 0  Warnings: 0
    
    mysql> insert into service values ('172.16.45.10','3306','nginx');  # ip和port與第一條記錄重復了,故報錯
    ERROR 1062 (23000): Duplicate entry '172.16.45.10-3306' for key 'PRIMARY'
    

    補充

    delete from tb1;
    強調:上面的這條命令確實可以將表里的所有記錄都刪掉,但不會將id重置為0,
    所以收該條命令根本不是用來清空表的,delete是用來刪除表中某一些符合條件的記錄
    delete from tb1 where id > 10;
    
    如果要清空表,使用truncate table 表名;
    作用:將整張表重置,id重新從0開始記錄
    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM