一、存儲引擎
存儲引擎即表類型,mysql根據不同的表類型會有不同的處理機制
存儲引擎詳見:https://www.cnblogs.com/zhangchaocoming/p/11789703.html
二、表介紹
表相當於文件,表中的一條記錄就相當於文件的一行內容,不同的是,表中的一條記錄有對應的標題,稱為表的字段
id | name | age | sex |
---|---|---|---|
1 | li | 12 | male |
2 | liu | 13 | female |
3 | hai | 24 | female |
4 | song | 16 | male |
id,name,age,sex稱為字段,其余的,一行內容稱為一條記錄
三、創建表
#語法:
create table 表名(
字段名1 類型[(寬度) 約束條件],
字段名2 類型[(寬度) 約束條件],
字段名3 類型[(寬度) 約束條件]
);
#注意:
1. 在同一張表中,字段名是不能相同
2. 寬度和約束條件可選
3. 字段名和類型是必須的
mysql>create database db1 charset utf8;
mysql>use db1;
mysql>create table t1(
-> id int,
-> name varchar(50),
-> sex enum('male','female'),
-> age int(3)
-> );
mysql>show tables; #查看db1庫下所有表名
mysql>desc t1;
+-------+-----------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(50) | YES | | NULL | |
| sex | enum('male','female') | YES | | NULL | |
| age | int(3) | YES | | NULL | |
+-------+-----------------------+------+-----+---------+-------+
mysql>select id,name,sex,age from t1;
Empty set (0.00 sec)
mysql>select * from t1;
Empty set (0.00 sec)
mysql>select id,name from t1;
Empty set (0.00 sec)
mysql>insert into t1 values
-> (1,'wang',18,'male'),
-> (2,'li',81,'female')
-> ;
mysql> select * from t1;
+------+------+------+--------+
| id | name | age | sex |
+------+------+------+--------+
| 1 | wang | 18 | male |
| 2 | li | 81 | female |
+------+------+------+--------+
mysql>insert into t1(id) values
-> (3),
-> (4);
mysql>select * from t1;
+------+------+------+--------+
| id | name | age | sex |
+------+------+------+--------+
| 1 | wang | 18 | male |
| 2 | li | 81 | female |
| 3 | NULL | NULL | NULL |
| 4 | NULL | NULL | NULL |
+------+------+------+--------+
注意注意注意:表中的最后一個字段不要加逗號
四、查看表結構
mysql>describe t1; #查看表結構,可簡寫為desc 表名
+-------+-----------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(50) | YES | | NULL | |
| sex | enum('male','female') | YES | | NULL | |
| age | int(3) | YES | | NULL | |
+-------+-----------------------+------+-----+---------+-------+
mysql>show create table t1\G; #查看表詳細結構,可加\G
五、數據類型
一、介紹
存儲引擎決定了表的類型,而表內存放的數據也要有不同的類型,每種數據類型都有自己的寬度,但寬度是可選的
mysql常用數據類型概覽
#1. 數字:
整型:tinyinit int bigint
小數:
float :在位數比較短的情況下不精准
double :在位數比較長的情況下不精准
0.000001230123123123
存成:0.000001230000
decimal:(如果用小數,則用推薦使用decimal)
精准
內部原理是以字符串形式去存
#2. 字符串:
char(10):簡單粗暴,浪費空間,存取速度快
root存成root000000
varchar:精准,節省空間,存取速度慢
sql優化:創建表時,定長的類型往前放,變長的往后放
比如性別 比如地址或描述信息
>255個字符,超了就把文件路徑存放到數據庫中。
比如圖片,視頻等找一個文件服務器,數據庫中只存路徑或url。
#3. 時間類型:
最常用:datetime
#4. 枚舉類型與集合類型
enum:多選一(從指定的屬性中選擇一個)比如:性別
set:多選多(從多個屬性中選擇多個,選擇的多個屬性用一對引號,中間用空格間隔開) 比如:愛好;
注意:選擇不再范圍內報錯
二、數值類型
整數類型
tinyint smallint mediumint int bigint
作用:存儲年齡,等級,id,各種號碼等
tinyint[(m)] [unsigned] [zerofill]
小整數,數據類型用於保存一些范圍的整數數值范圍:
有符號:
-128 ~ 127
無符號:
0 ~ 255
int[(m)][unsigned][zerofill]
整數,數據類型用於保存一些范圍的整數數值范圍:
有符號:
-2147483648 ~ 2147483647
無符號:
0 ~ 4294967295
bigint[(m)][unsigned][zerofill]
大整數,數據類型用於保存一些范圍的整數數值范圍:
有符號:
-9223372036854775808 ~ 9223372036854775807
無符號:
0 ~ 18446744073709551615
注意:整型數字int(11),不指定寬度,默認也是11位,數據類型后的寬度並不是存儲限制,而是顯示限制;
如果不指定unsigned(無符號),默認都有signed(有符號),即有‘-’;指定unsigned時,緊跟着int后,不能寫在別的約束條件后面;
zerofill表示位數不足用‘0’補充;
#tinyint默認為有符號
mysql> create table t1(x tinyint); #默認為有符號,即數字前有正負號
mysql> desc t1;
mysql> insert into t1 values
-> (-129),
-> (-128),
-> (127),
-> (128);
mysql> select * from t1;
+------+
| x |
+------+
| -128 | #-129存成了-128
| -128 | #有符號,最小值為-128
| 127 | #有符號,最大值127
| 127 | #128存成了127
+------+
#設置無符號tinyint
mysql> create table t2(x tinyint unsigned);
mysql> insert into t2 values
-> (-1),
-> (0),
-> (255),
-> (256);
mysql> select * from t2;
+------+
| x |
+------+
| 0 | -1存成了0
| 0 | #無符號,最小值為0
| 255 | #無符號,最大值為255
| 255 | #256存成了255
+------+
============有符號和無符號int=============
#int默認為有符號
mysql> create table t3(x int); #默認為有符號整數
mysql> insert into t3 values
-> (-2147483649),
-> (-2147483648),
-> (2147483647),
-> (2147483648);
mysql> select * from t3;
+-------------+
| x |
+-------------+
| -2147483648 | #-2147483649存成了-2147483648
| -2147483648 | #有符號,最小值為-2147483648
| 2147483647 | #有符號,最大值為2147483647
| 2147483647 | #2147483648存成了2147483647
+-------------+
注意:通常int(11)表示有符號
#設置無符號int
mysql> create table t4(x int unsigned);
mysql> insert into t4 values
-> (-1),
-> (0),
-> (4294967295),
-> (4294967296);
mysql> select * from t4;
+------------+
| x |
+------------+
| 0 | #-1存成了0
| 0 | #無符號,最小值為0
| 4294967295 | #無符號,最大值為4294967295
| 4294967295 | #4294967296存成了4294967295
+------------+
==============有符號和無符號bigint=============
mysql> create table t6(x bigint);
mysql> insert into t5 values
-> (-9223372036854775809),
-> (-9223372036854775808),
-> (9223372036854775807),
-> (9223372036854775808);
mysql> select * from t5;
+----------------------+
| x |
+----------------------+
| -9223372036854775808 |
| -9223372036854775808 |
| 9223372036854775807 |
| 9223372036854775807 |
+----------------------+
mysql> create table t6(x bigint unsigned);
mysql> insert into t6 values
-> (-1),
-> (0),
-> (18446744073709551615),
-> (18446744073709551616);
mysql> select * from t6;
+----------------------+
| x |
+----------------------+
| 0 |
| 0 |
| 18446744073709551615 |
| 18446744073709551615 |
+----------------------+
======用zerofill測試整數類型的顯示寬度=============
mysql> create table t7(x int(3) zerofill);
mysql> insert into t7 values
-> (1),
-> (11),
-> (111),
-> (1111);
mysql> select * from t7;
+------+
| x |
+------+
| 001 |
| 011 |
| 111 |
| 1111 | #超過寬度限制仍然可以存
+------+
nt的存儲寬度是4個Bytes,即32個bit,即2**32
無符號最大值為:4294967296-1
有符號最大值:2147483648-1
有符號和無符號的最大數字需要的顯示寬度均為10,而針對有符號的最小值則需要11位才能顯示完全,所以int類型默認的顯示寬度為11是非常合理的
最后:整形類型,其實沒有必要指定顯示寬度,使用默認的就ok
浮點型
#FLOAT[(M,D)] [UNSIGNED] [ZEROFILL]
定義:
單精度浮點數(非准確小數值),m是數字總個數,d是小數點后個數。m最大值為255,d最大值為30
有符號:
-3.402823466E+38 to -1.175494351E-38,
1.175494351E-38 to 3.402823466E+38
無符號:
1.175494351E-38 to 3.402823466E+38
精確度:
**** 隨着小數的增多,精度變得不准確 ****
======================================
#DOUBLE[(M,D)] [UNSIGNED] [ZEROFILL]
定義:
雙精度浮點數(非准確小數值),m是數字總個數,d是小數點后個數。m最大值為255,d最大值為30
有符號:
-1.7976931348623157E+308 to -2.2250738585072014E-308
2.2250738585072014E-308 to 1.7976931348623157E+308
無符號:
2.2250738585072014E-308 to 1.7976931348623157E+308
精確度:
****隨着小數的增多,精度比float要高,但也會變得不准確 ****
======================================
decimal[(m[,d])] [unsigned] [zerofill]
定義:
准確的小數值,m是數字總個數(負號不算),d是小數點后個數。 m最大值為65,d最大值為30。
精確度:
**** 隨着小數的增多,精度始終准確 ****
對於精確數值計算時需要用此類型
decaimal能夠存儲精確值的原因在於其內部按照字符串存儲。
mysql> create table t1(x float(256,31));
ERROR 1425 (42000): Too big scale 31 specified for column 'x'. Maximum is 30.
mysql> create table t1(x float(256,30));
ERROR 1439 (42000): Display width out of range for column 'x' (max = 255)
mysql> create table t1(x float(255,30)); #建表成功
Query OK, 0 rows affected (0.02 sec)
mysql> create table t2(x double(255,30)); #建表成功
Query OK, 0 rows affected (0.02 sec)
mysql> create table t3(x decimal(66,31));
ERROR 1425 (42000): Too big scale 31 specified for column 'x'. Maximum is 30.
mysql> create table t3(x decimal(66,30));
ERROR 1426 (42000): Too-big precision 66 specified for 'x'. Maximum is 65.
mysql> create table t3(x decimal(65,30)); #建表成功
Query OK, 0 rows affected (0.02 sec)
mysql> show tables;
+---------------+
| Tables_in_db1 |
+---------------+
| t1 |
| t2 |
| t3 |
+---------------+
3 rows in set (0.00 sec)
mysql> insert into t1 values(1.1111111111111111111111111111111); #小數點后31個1
Query OK, 1 row affected (0.01 sec)
mysql> insert into t2 values(1.1111111111111111111111111111111);
Query OK, 1 row affected (0.00 sec)
mysql> insert into t3 values(1.1111111111111111111111111111111);
Query OK, 1 row affected, 1 warning (0.01 sec)
mysql> select * from t1; #隨着小數的增多,精度開始不准確
+----------------------------------+
| x |
+----------------------------------+
| 1.111111164093017600000000000000 |
+----------------------------------+
1 row in set (0.00 sec)
mysql> select * from t2; #精度比float要准確點,但隨着小數的增多,同樣變得不准確
+----------------------------------+
| x |
+----------------------------------+
| 1.111111111111111200000000000000 |
+----------------------------------+
1 row in set (0.00 sec)
mysql> select * from t3; #精度始終准確,d為30,於是只留了30位小數
+----------------------------------+
| x |
+----------------------------------+
| 1.111111111111111111111111111111 |
+----------------------------------+
1 row in set (0.00 sec)
三、字符串類型
#char類型:定長,簡單粗暴,浪費空間,存取速度快
字符長度范圍:0-255(一個中文是一個字符,是utf8編碼的3個字節)
存儲:
存儲char類型的值時,會往右填充空格來滿足長度
例如:指定長度為10,存>10個字符則報錯,存<10個字符則用空格填充直到湊夠10個字符存儲
檢索:
在檢索或者說查詢時,查出的結果會自動刪除尾部的空格,除非我們打開pad_char_to_full_length SQL模式(SET sql_mode = 'PAD_CHAR_TO_FULL_LENGTH';)
#varchar類型:變長,精准,節省空間,存取速度慢
字符長度范圍:0-65535(如果大於21845會提示用其他類型 。mysql行最大限制為65535字節,字符編碼為utf-8:https://dev.mysql.com/doc/refman/5.7/en/column-count-limit.html)
存儲:
varchar類型存儲數據的真實內容,不會用空格填充,如果'ab ',尾部的空格也會被存起來
強調:varchar類型會在真實數據前加1-2Bytes的前綴,該前綴用來表示真實數據的bytes字節數(1-2Bytes最大表示65535個數字,正好符合mysql對row的最大字節限制,即已經足夠使用)
如果真實的數據<255bytes則需要1Bytes的前綴(1Bytes=8bit 2**8最大表示的數字為255)
如果真實的數據>255bytes則需要2Bytes的前綴(2Bytes=16bit 2**16最大表示的數字為65535)
檢索:
尾部有空格會保存下來,在檢索或者說查詢時,也會正常顯示包含空格在內的內容
Value | CHAR(4) | Storage Required | VARCHAR(4) | Storage Required |
---|---|---|---|---|
'' | ' ' | 4 bytes | '' | 1bytes |
'ab' | 'ab ' | 4 bytes | 'ab' | 3 bytes |
'abcd' | 'abcd' | 4 bytes | 'abcd' | 5 bytes |
'abcdefgh' | 'abcd' | 4 bytes | 'abcd' | 5 bytes |
測試前了解兩個函數
length:查看字節數
char_length:查看字符數
- char填充空格來滿足固定長度,但是在查詢時卻會很不要臉地刪除尾部的空格(裝作自己好像沒有浪費過空間一樣),然后修改sql_mode讓其現出原形
mysql> create table t1(x char(5),y varchar(5));
Query OK, 0 rows affected (0.26 sec)
#char存5個字符,而varchar存4個字符
mysql> insert into t1 values('你瞅啥 ','你瞅啥 ');
Query OK, 1 row affected (0.05 sec)
mysql> SET sql_mode='';
Query OK, 0 rows affected, 1 warning (0.00 sec)
#在檢索時char很不要臉地將自己浪費的2個字符給刪掉了,裝的好像自己沒浪費過空間一樣,而varchar很老實,存了多少,就顯示多少
mysql> select x,char_length(x),y,char_length(y) from t1;
+-----------+----------------+------------+----------------+
| x | char_length(x) | y | char_length(y) |
+-----------+----------------+------------+----------------+
| 你瞅啥 | 3 | 你瞅啥 | 4 |
+-----------+----------------+------------+----------------+
1 row in set (0.00 sec)
#略施小計,讓char現出原形
mysql> SET sql_mode = 'PAD_CHAR_TO_FULL_LENGTH';
Query OK, 0 rows affected (0.00 sec)
#這下子char原形畢露了......
mysql> select x,char_length(x),y,char_length(y) from t1;
+-------------+----------------+------------+----------------+
| x | char_length(x) | y | char_length(y) |
+-------------+----------------+------------+----------------+
| 你瞅啥 | 5 | 你瞅啥 | 4 |
+-------------+----------------+------------+----------------+
1 row in set (0.00 sec)
#char類型:3個中文字符+2個空格=11Bytes
#varchar類型:3個中文字符+1個空格=10Bytes
mysql> select x,length(x),y,length(y) from t1;
+-------------+-----------+------------+-----------+
| x | length(x) | y | length(y) |
+-------------+-----------+------------+-----------+
| 你瞅啥 | 11 | 你瞅啥 | 10 |
+-------------+-----------+------------+-----------+
1 row in set (0.00 sec)
- 雖然 CHAR 和 VARCHAR 的存儲方式不太相同,但是對於兩個字符串的比較,都只比 較其值,忽略 CHAR 值存在的右填充,即使將 SQL MODE 設置為 PAD_CHAR_TO_FULL LENGTH 也一樣,,但這不適用於like
#InnoDB存儲引擎:建議使用VARCHAR類型
單從數據類型的實現機制去考慮,char數據類型的處理速度更快,有時甚至可以超出varchar處理速度的50%。
但對於InnoDB數據表,內部的行存儲格式沒有區分固定長度和可變長度列(所有數據行都使用指向數據列值的頭指針),因此在本質上,使用固定長度的CHAR列不一定比使用可變長度VARCHAR列性能要好。因而,主要的性能因素是數據行使用的存儲總量。由於CHAR平均占用的空間多於VARCHAR,因此使用VARCHAR來最小化需要處理的數據行的存儲總量和磁盤I/O是比較好的。
#其他字符串系列(效率:char>varchar>text)
TEXT系列 TINYTEXT TEXT MEDIUMTEXT LONGTEXT
BLOB 系列 TINYBLOB BLOB MEDIUMBLOB LONGBLOB
BINARY系列 BINARY VARBINARY
text:text數據類型用於保存變長的大字符串,可以組多到65535 (2**16 − 1)個字符。
mediumtext:A TEXT column with a maximum length of 16,777,215 (2**24 − 1) characters.
longtext:A TEXT column with a maximum length of 4,294,967,295 or 4GB (2**32 − 1) characters.
四、日期類型
DATE TIME DATETIME TIMESTAMP YEAR
作用:存儲用戶注冊時間,文章發布時間,員工入職時間,出生時間,過期時間等
============year===========
MariaDB [db1]> create table t10(born_year year); #無論year指定何種寬度,最后都默認是year(4)
MariaDB [db1]> insert into t10 values
-> (1900),
-> (1901),
-> (2155),
-> (2156);
MariaDB [db1]> select * from t10;
+-----------+
| born_year |
+-----------+
| 0000 |
| 1901 |
| 2155 |
| 0000 |
+-----------+
============date,time,datetime===========
MariaDB [db1]> create table t11(d date,t time,dt datetime);
MariaDB [db1]> desc t11;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| d | date | YES | | NULL | |
| t | time | YES | | NULL | |
| dt | datetime | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
MariaDB [db1]> insert into t11 values(now(),now(),now());
MariaDB [db1]> select * from t11;
+------------+----------+---------------------+
| d | t | dt |
+------------+----------+---------------------+
| 2017-07-25 | 16:26:54 | 2017-07-25 16:26:54 |
+------------+----------+---------------------+
============timestamp===========
MariaDB [db1]> create table t12(time timestamp);
MariaDB [db1]> insert into t12 values();
MariaDB [db1]> insert into t12 values(null);
MariaDB [db1]> select * from t12;
+---------------------+
| time |
+---------------------+
| 2017-07-25 16:29:17 |
| 2017-07-25 16:30:01 |
+---------------------+
============注意啦,注意啦,注意啦===========
1. 單獨插入時間時,需要以字符串的形式,按照對應的格式插入
2. 插入年份時,盡量使用4位值
3. 插入兩位年份時,<=69,以20開頭,比如50, 結果2050
>=70,以19開頭,比如71,結果1971
MariaDB [db1]> create table t12(y year);
MariaDB [db1]> insert into t12 values
-> (50),
-> (71);
MariaDB [db1]> select * from t12;
+------+
| y |
+------+
| 2050 |
| 1971 |
+------+
============綜合練習===========
MariaDB [db1]> create table student(
-> id int,
-> name varchar(20),
-> born_year year,
-> birth date,
-> class_time time,
-> reg_time datetime);
MariaDB [db1]> insert into student values
-> (1,'li',"1995","1995-11-11","11:11:11","2017-11-11 11:11:11"),
-> (2,'wang',"1997","1997-12-12","12:12:12","2017-12-12 12:12:12"),
-> (3,'wsb',"1998","1998-01-01","13:13:13","2017-01-01 13:13:13");
MariaDB [db1]> select * from student;
+------+------+-----------+------------+------------+---------------------+
| id | name | born_year | birth | class_time | reg_time |
+------+------+-----------+------------+------------+---------------------+
| 1 | li | 1995 | 1995-11-11 | 11:11:11 | 2017-11-11 11:11:11 |
| 2 | wang | 1997 | 1997-12-12 | 12:12:12 | 2017-12-12 12:12:12 |
| 3 | wsb | 1998 | 1998-01-01 | 13:13:13 | 2017-01-01 13:13:13 |
+------+------+-----------+------------+------------+---------------------+
# datetime與timesteap的區別
在實際應用的很多場景中,MySQL的這兩種日期類型都能夠滿足我們的需要,存儲精度都為秒,但在某些情況下,會展現出他們各自的優劣。下面就來總結一下兩種日期類型的區別。
1.DATETIME的日期范圍是1001——9999年,TIMESTAMP的時間范圍是1970——2038年。
2.DATETIME存儲時間與時區無關,TIMESTAMP存儲時間與時區有關,顯示的值也依賴於時區。在mysql服務器,操作系統以及客戶端連接都有時區的設置。
3.DATETIME使用8字節的存儲空間,TIMESTAMP的存儲空間為4字節。因此,TIMESTAMP比DATETIME的空間利用率更高。
4.DATETIME的默認值為null;TIMESTAMP的字段默認不為空(not null),默認值為當前時間(CURRENT_TIMESTAMP),如果不做特殊處理,並且update語句中沒有指定該列的更新值,則默認更新為當前時間。
mysql> create table t1(x datetime not null default now()); # 需要指定傳入空值時默認取當前時間
Query OK, 0 rows affected (0.01 sec)
mysql> create table t2(x timestamp); # 無需任何設置,在傳空值的情況下自動傳入當前時間
Query OK, 0 rows affected (0.02 sec)
mysql> insert into t1 values();
Query OK, 1 row affected (0.00 sec)
mysql> insert into t2 values();
Query OK, 1 row affected (0.00 sec)
mysql> select * from t1;
+---------------------+
| x |
+---------------------+
| 2018-07-07 01:26:14 |
+---------------------+
1 row in set (0.00 sec)
mysql> select * from t2;
+---------------------+
| x |
+---------------------+
| 2018-07-07 01:26:17 |
+---------------------+
1 row in set (0.00 sec)
五、枚舉類型與集合類型
字段的值只能在給定范圍中選擇,如單選框,多選框
enum 單選 只能在給定的范圍內選一個值,如性別 sex 男male/女female
set 多選 在給定的范圍內可以選擇一個或一個以上的值(愛好1,愛好2,愛好3...)
枚舉類型(enum)
An ENUM column can have a maximum of 65,535 distinct elements. (The practical limit is less than 3000.)
示例:
CREATE TABLE shirts (
name VARCHAR(40),
size ENUM('x-small', 'small', 'medium', 'large', 'x-large')
);
INSERT INTO shirts (name, size) VALUES ('dress shirt','large'), ('t-shirt','medium'),('polo shirt','small');
集合類型(set)
A SET column can have a maximum of 64 distinct members.
示例:
CREATE TABLE myset (col SET('a', 'b', 'c', 'd'));
INSERT INTO myset (col) VALUES ('a,d'), ('d,a'), ('a,d,a'), ('a,d,d'), ('d,a,d');
mysql> insert into consumer values
create table consumer(
-> name varchar(50),
-> sex enum('male','female'),
-> level enum('vip1','vip2','vip3','vip4','vip5'), #在指定范圍內,多選一
-> hobby set('play','music','read','study') #在指定范圍內,多選多
-> );
mysql> insert into consumer values
-> ('wang','male','vip5','read,study'),
-> ('li','female','vip1','girl');
mysql> insert into consumer values
select * from consumer;
+------+--------+-------+------------+
| name | sex | level | hobby |
+------+--------+-------+------------+
| wang | male | vip5 | read,study |
| li | female | vip1 | |
+------+--------+-------+------------+
六、約束條件
"""
PRIMARY KEY (PK) 標識該字段為該表的主鍵,可以唯一的標識記錄
FOREIGN KEY (FK) 標識該字段為該表的外鍵
NOT NULL 標識該字段不能為空
UNIQUE KEY (UK) 標識該字段的值是唯一的
AUTO_INCREMENT 標識該字段的值自動增長(整數類型,而且為主鍵)
DEFAULT 為該字段設置默認值
UNSIGNED 無符號
ZEROFILL 使用0填充
"""
not null+default
create table user(
id int,
name char(16)
);
insert into user values(1,null) # 可以修改
alter table user modify name char(16) not null;
insert into user(name,id) values(null,2); # 報錯 插入數據可以在表名后面指定插入數據對應的字段
create table student(
id int,
name char(16) not null,
gender enum('male','female','others') default 'male'
)
insert into student(id,name) values(1,'zhang') # 成功
unique
# 單列唯一
create table user1(
id int unique,
name char(16)
);
insert into user1 values(1,'zhang'),(1,'wang') # 報錯
insert into user1 values(1,'zhang'),(2,'wang') # 成功
# 聯合唯一
create table server(
id int,
ip char(16),
port int,
unique(ip,port)
)
insert into server values(1,'127.0.0.1',8080);
insert into server values(2,'127.0.0.1',8080); # 報錯
insert into server values(1,'127.0.0.1',8081);
primary key+auto_increment
# 單從約束角度來說primary key就等價於not null unique
create table t11(id int primary key);
desc t11;
insert into t11 values(1),(1); # 報錯
insert into t11 values(1),(2);
# 除了約束之外,它還是innodb引擎組織數據的依據,提升查詢效率
"""
強調:
1.一張表中必須有且只有一個主鍵,如果你沒有設置主鍵,那么會從上到下搜索直到遇到一個非空且唯一的字段自動將其設置為主鍵
"""
create table t12(
id int,
name char(16),
age int not null unique,
addr char(16) not null unique
)engine=innodb;
desc t12;
"""
2.如果表里面沒有指定任何的可以設置為主鍵的字段,那么innodb會采用自己默認的一個隱藏字段作為主鍵,隱藏意味着你在查詢的時候無法根據這個主鍵字段加速查詢了
索引:類似於書的目錄,沒有主鍵就相當於一頁一頁翻着查
3.一張表中通常都應該有一個id字段,並且通常將改id字段作成主鍵
"""
# 聯合主鍵:多個字段聯合起來作為表的一個主鍵,本質還是一個主鍵
create table t18(
ip char(16),
port int,
primary key(ip,port)
);
desc t18;
# 主鍵id作為數據的編號,每次最好能自動遞增
create table t13(
id int primary key auto_increment,
name char(16)
);
insert into t13('zhang'),('zhang'),('zhang'); # id字段自動從1開始遞增
# 注意:auto_increment通常都是加在主鍵上,並且只能給設置為key的字段加
補充:
delete from tb1;
強調:上面的這條命令確實可以將表里的所有記錄都刪掉,但不會將id重置為0,
所以收該條命令根本不是用來清空表的,delete是用來刪除表中某一些符合條件的記錄
delete from tb1 where id > 10;
如果要清空表,使用truncate tb1;
作用:將整張表重置,id重新從1開始記錄
七、修改表 alter table
語法:
1. 修改表名
ALTER TABLE 表名
RENAME 新表名;
2. 增加字段
ALTER TABLE 表名
ADD 字段名 數據類型 [完整性約束條件…],
ADD 字段名 數據類型 [完整性約束條件…];
ALTER TABLE 表名
ADD 字段名 數據類型 [完整性約束條件…] FIRST;
ALTER TABLE 表名
ADD 字段名 數據類型 [完整性約束條件…] AFTER 字段名;
3. 刪除字段
ALTER TABLE 表名
DROP 字段名;
4. 修改字段
ALTER TABLE 表名
MODIFY 字段名 數據類型 [完整性約束條件…];
ALTER TABLE 表名
CHANGE 舊字段名 新字段名 舊數據類型 [完整性約束條件…];
ALTER TABLE 表名
CHANGE 舊字段名 新字段名 新數據類型 [完整性約束條件…];
示例:
1. 修改存儲引擎
mysql> alter table service
-> engine=innodb;
2. 添加字段
mysql> alter table student10
-> add name varchar(20) not null,
-> add age int(3) not null default 22;
mysql> alter table student10
-> add stu_num varchar(10) not null after name; //添加name字段之后
mysql> alter table student10
-> add sex enum('male','female') default 'male' first; //添加到最前面
3. 刪除字段
mysql> alter table student10
-> drop sex;
mysql> alter table service
-> drop mac;
4. 修改字段類型modify
mysql> alter table student10
-> modify age int(3);
mysql> alter table student10
-> modify id int(11) not null primary key auto_increment; //修改為主鍵
5. 增加約束(針對已有的主鍵增加auto_increment)
mysql> alter table student10 modify id int(11) not null primary key auto_increment;
ERROR 1068 (42000): Multiple primary key defined
mysql> alter table student10 modify id int(11) not null auto_increment;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
6. 對已經存在的表增加復合主鍵
mysql> alter table service2
-> add primary key(host_ip,port);
7. 增加主鍵
mysql> alter table student1
-> modify name varchar(10) not null primary key;
8. 增加主鍵和自動增長
mysql> alter table student1
-> modify id int not null primary key auto_increment;
9. 刪除主鍵
a. 刪除自增約束
mysql> alter table student10 modify id int(11) not null;
b. 刪除主鍵
mysql> alter table student10
-> drop primary key;
復制表
mysql> create table new_service select * from service;
只復制表結構
mysql> select * from service where 1=2; //條件為假,查不到任何記錄
Empty set (0.00 sec)
mysql> create table new1_service select * from service where 1=2;
Query OK, 0 rows affected (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> create table t4 like employees;
九 刪除表
DROP TABLE 表名;