目錄
一、創建表的完整語法
# 語法
[中括號內為可選參數]
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開始記錄