1. 程式人生 > 實用技巧 >mysql基礎-02

mysql基礎-02

1.2 資料型別

MySQL中的資料型別是型別,規定是什麼型別,就得輸入什麼樣的值

1.2.1 數值型

1、 整型

整形 佔用位元組數 範圍
tinyint 1 -128~127
smallint 2 -32768~32767
mediumint 3 -8388608~8388607
int 4 -2147483648~2147483647
bigint 8 -9223372036854775808~9223372036854775807

選擇的範圍儘可能小,這樣範圍越小佔用資源越少

mysql> create table stu1(
    -> id tinyint,      # 範圍要儘可能小,範圍越小,佔用空間越少
    -> name varchar(20)
    -> );
Query OK, 0 rows affected (0.02 sec)

-- 超出範圍會報錯
mysql> insert into stu1 values (128,'tom'); -- 128 超出了
ERROR 1264 (22003): Out of range value for column 'id' at row 1

無符號整形(unsigned) 無符號整形就是沒有負數,無符號整數表示範圍是整數的兩倍

mysql> create table stu2(
    -> id tinyint unsigned    # 無符號整數
    -> );
Query OK, 0 rows affected (0.02 sec)

mysql> insert into stu2 values (128);
Query OK, 1 row affected (0.00 sec)

整形支援顯示寬度,顯示寬頻是最小的顯示位數,如int(11)表示整形最少用11位表示,如果不夠位數用0填充。顯示寬度預設不起作用,必須結合zerofill才起作用。

mysql> create table stu4(
    -> id int(5),
    -> num int(5) zerofill   # 新增前導0,int(5)顯示寬頻是5
    -> );
Query OK, 0 rows affected (0.05 sec)

mysql> insert into stu4 values (12,12);-- 如果插入的值的順序和個數與表字段的順序個數一致,插入的欄位名可以省略
Query OK, 1 row affected (0.00 sec)

mysql> select * from stu4;-- 查詢所有欄位的值
+------+-------+
| id   | num   |
+------+-------+
|   12 | 00012 |
+------+-------+
1 row in set (0.00 sec)

小結:

1、範圍要儘可能小,範圍越小,佔用空間越少
2、無符號整數是整數的兩倍
3、整形支援顯示寬度,顯示寬頻是最小的顯示位數,必須結合zerofill才起作用

2、浮點型

浮點型 佔用位元組數 範圍
float(單精度型) 4 -3.4E+38~3.4E+38
double(雙精度型) 8 -1.8E+308~1.8E+308

浮點型的宣告:float(M,D) double(M,D)

 M:總位數   D:小數位數

例題

mysql> create table stu5(
    -> num1 float(5,2),   -- 浮點數
    -> num2 double(6,1)	  -- 雙精度數
    -> );
Query OK, 0 rows affected (0.05 sec)

mysql> insert into stu5 values (3.1415,12.96);
Query OK, 1 row affected (0.00 sec)

mysql> select * from stu5;
+------+------+
| num1 | num2 |
+------+------+
| 3.14 | 13.0 |
+------+------+
1 row in set (0.00 sec)

MySQL浮點數支援科學計數法

mysql> create table stu6(
    -> num float   # 不指定位數,預設是小數點後面6位  double預設是17位
    -> );
Query OK, 0 rows affected (0.03 sec)

mysql> insert into stu6 values (5E2),(6E-2); # 插入科學計數法
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> select * from stu6;
+------+
| num  |
+------+
|  500 |
| 0.06 |
+------+
2 rows in set (0.00 sec)

浮點數精度會丟失

mysql> insert into stu6 values(99.999999999);
Query OK, 1 row affected (0.00 sec)

mysql> select * from stu6;
+------+
| num  |
+------+
|  100 |
+------+

小結:

1、浮點數有單精度和雙精度
2、浮點數支援科學計數法
3、浮點數精度會丟失

3、小數(定點數)

原理:將M整數部分和D小數部分分開儲存

語法:

decimal(M,D) -- M:總位數;D:小數位數

例題:

mysql> create table stu8(
    -> num decimal(20,9)   # 存放定點數
    -> );
Query OK, 0 rows affected (0.00 sec)

mysql> insert into stu8 values(12.999999999);
Query OK, 1 row affected (0.00 sec)

mysql> select * from stu8;
+--------------+
| num          |
+--------------+
| 12.999999999 |
+--------------+
1 row in set (0.00 sec)

小結:

1、decimal是變長的,大致是每9個數字用4個位元組儲存,整數和小數分開計算。M最大是65,D最大是30,預設是(10,2)。
2、定點和浮點都支援無符號、顯示寬度0填充。

1.2.2 字元型

在資料庫中沒有字串概念,只有字元,所以資料庫中只能用單引號

資料型別 描述
char 定長字元,最大可以到255
varchar 可變長度字元,最大可以到65535
tinytext 2^8^–1 =255
text 2^16^–1 =65535
mediumtext 2^24^–1
longtext 2^32^–1

char(4):存放4個字元,中英文一樣。

varchar(L)實現變長機制,需要額外的空間來記錄資料真實的長度。

L的理論長度是65535,但事實上達不到,因為有的字元是多位元組字元,所以L達不到65535。

text系列的型別在表中儲存的是地址,佔用大小大約10個位元組

一個記錄的所有欄位的總長度也不能超過65535個位元組。

小結:

1、char是定長,var是變長
2、char最大值是255,varchar最大值是65535,具體要看字元編碼
3、text系列在表中儲存的是地址
4、一條記錄的總長度不能超過65535

1.2.3 列舉(enum)

從集合中選擇一個值作為資料(單選)

mysql> create table stu12(
    -> name varchar(20),
    -> sex enum('男','女','保密') # 列舉
    -> );
Query OK, 0 rows affected (0.06 sec)

-- 插入的列舉值只能是列舉中提供的選項,如果要給sex欄位賦值,只能是男、女、保密、或者對應數字
mysql> insert into stu12 values ('tom','男');
Query OK, 1 row affected (0.00 sec)
-- 報錯,只能插入男、女、保密
mysql> insert into stu12 values ('tom','不告訴你');
ERROR 1265 (01000): Data truncated for column 'sex' at row 1

列舉值是通過整形數字來管理的,第一個值是1,第二個值是2,以此類推,列舉值在資料庫儲存的是整形數字。

mysql> insert into stu12 values ('berry',2);   -- 插入數字,按照順序,2代表女
Query OK, 1 row affected (0.00 sec)

mysql> select * from stu12;
+-------+------+
| name  | sex  |
+-------+------+
| tom   | 男     |
| berry | 女    |
+-------+------+
-- WHERE字句用於篩選資料,提取滿足條件的記錄。WHERE字句的基本用法:SELECT * from 表名 WHERE 條件語句;
mysql> select * from stu12 where sex=2;   -- 2表示第二個列舉值
+-------+------+
| name  | sex  |
+-------+------+
| berry | 女    |
+-------+------+
1 row in set (0.00 sec)

列舉優點:

(1)、限制值
(2)、節省空間
(3)、執行速度快(整形比字串執行速度快)

思考:已知列舉佔用兩個位元組,所以最多可以有多少個列舉值?

答:2位元組=16位,2^16^=65536,範圍是(0-65535),由於列舉從1開始,所以列舉值最多有65535個

1.2.4 集合(set)

從集合中選擇一些值作為資料(多選)

mysql> create table stu13(
    -> name varchar(20),
    -> hobby set('爬山','讀書','游泳','燙頭')  -- 集合
    -> );
Query OK, 0 rows affected (0.00 sec)

mysql> insert into stu13 values ('tom','爬山');

mysql> insert into stu13 values ('Berry','爬山,游泳');
Query OK, 1 row affected (0.00 sec)

mysql> insert into stu13 values ('Berry','游泳,爬山');   -- 插入的順序不一樣,但顯示的順序一樣
Query OK, 1 row affected (0.00 sec)

mysql> select * from stu13;
+-------+-----------+
| name  | hobby     |
+-------+-----------+
| tom   | 爬山         |
| Berry | 爬山,游泳       |
| Berry | 爬山,游泳       |
+-------+-----------+
3 rows in set (0.00 sec)

集合和列舉一樣,也為每個集合元素分配一個固定值,分配方式是從前往後按2的0、1、2、…次方,轉換成二進位制後只有一位是1,其他都是0。

'爬山','讀書','游泳','燙頭'
  1		2		4	8
  
mysql> select hobby+0 from stu13;
+---------+
| hobby+0 |
+---------+
|       1 |
|       5 |
|       5 |
+---------+

mysql> insert into stu13 values ('rose',15);
Query OK, 1 row affected (0.00 sec)

已知集合型別佔8個位元組,那麼集合中最多有多少選項

答:有64個選項。

1.2.5 日期時間型

資料型別 描述
datetime 日期時間,佔用8個位元組
date 日期 佔用3個位元組
time 時間 佔用3個位元組
year 年份,佔用1個位元組
timestamp 時間戳,佔用4個位元組

1、datetime和date

datetime格式:年-月-日 小時:分鐘:秒。支援的範圍是'1000-01-01 00:00:00'到'9999-12-31
23:59:59'。

mysql> create table stu14(
    -> t1 datetime,    -- 日期時間
    -> t2 date				-- 日期
    -> );
Query OK, 0 rows affected (0.05 sec)
-- 插入測試資料
mysql> insert into stu14 values ('2019-01-15 12:12:12','2019-01-15 12:12:12');
Query OK, 1 row affected, 1 warning (0.00 sec)
-- 查詢
mysql> select * from stu14;
+---------------------+------------+
| t1                  | t2         |
+---------------------+------------+
| 2019-01-15 12:12:12 | 2019-01-15 |
+---------------------+------------+
1 row in set (0.00 sec)

2、timestamp(時間戳)

datetime型別和timestamp型別表現上是一樣的,他們的區別在於:

datetime從1000到9999,而timestamp從1970年~2038年(原因在於timestamp佔用4個位元組,和整形的範圍一樣,2038年01月19日11:14:07以後的秒數就超過了4個位元組的長度)

mysql> create table stu15(
    -> t1 timestamp
    -> );
Query OK, 0 rows affected (0.06 sec)

mysql> insert into stu15 values ('2038-01-19 11:14:07');
Query OK, 1 row affected (0.00 sec)

3、year

只能表示1901~2155之間的年份,因為只佔用1個位元組,只能表示255個數

mysql> create table stu16(
    -> y1 year
    -> );
Query OK, 0 rows affected (0.08 sec)

mysql> insert into stu16 values (2155);
Query OK, 1 row affected (0.00 sec)

4、time

可以表示時間,也可以表示時間間隔。範圍是:-838:59:59~838:59:59

mysql> create table stu17(
    -> t1 time
    -> );
Query OK, 0 rows affected (0.02 sec)

mysql> insert into stu17 values ('12:12:12');
Query OK, 1 row affected (0.00 sec)

mysql> insert into stu17 values ('212:12:12');
Query OK, 1 row affected (0.00 sec)

mysql> insert into stu17 values ('-212:12:12');
Query OK, 1 row affected (0.00 sec)

mysql> insert into stu17 values ('839:00:00');   -- 報錯
ERROR 1292 (22007): Incorrect time value: '839:00:00' for column 't1' at row 1

-- time支援以天的方式來表示時間間隔
mysql> insert into stu17 values ('10 10:25:25');   -- 10天10小時25分25秒
Query OK, 1 row affected (0.00 sec)

mysql> select * from stu17;
+------------+
| t1         |
+------------+
| 12:12:12   |
| 212:12:12  |
| -212:12:12 |
| 250:25:25  |
+------------+
4 rows in set (0.00 sec)

1.2.6 Boolean

MySQL不支援布林型,true和false在資料庫中對應的是1和0

mysql> create table stu18(
    -> flag boolean
    -> );
Query OK, 0 rows affected (0.05 sec)

mysql> desc stu18;
+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| flag  | tinyint(1) | YES  |     | NULL    |       |
+-------+------------+------+-----+---------+-------+
1 row in set (0.00 sec)

mysql> insert into stu18 values (true),(false);
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> select * from stu18;
+------+
| flag |
+------+
|    1 |
|    0 |
+------+
2 rows in set (0.00 sec

小結:

boolean型在MySQL中對應的是tinyint。

1.2.6 練習題

電話號碼一般使用什麼資料型別儲存?			 varchar
手機號碼用什麼資料型別						char
性別一般使用什麼資料型別儲存?				  char  tinyint  enum
年齡資訊一般使用什麼資料型別儲存?			 tinyint
照片資訊一般使用什麼資料型別儲存?		 	 binary
薪水一般使用什麼資料型別儲存?			      decimal

1.3 列屬性

1.3.1 是否為空(null|not null)

null表示欄位值可以為null
not null欄位值不能為空

練習

學員姓名允許為空嗎?					not null
家庭地址允許為空嗎?					not null
電子郵件資訊允許為空嗎?			   null
考試成績允許為空嗎?					null

1.3.2 預設值(default)

如果一個欄位沒有插入值,可以預設插入一個指定的值

mysql> create table stu19(
    -> name varchar(20) not null default '姓名不詳',
    -> addr varchar(50) not null default '地址不詳'
    -> );
Query OK, 0 rows affected (0.05 sec)

mysql> insert into stu19(name) values ('tom');
Query OK, 1 row affected (0.00 sec)

mysql> insert into stu19 values (default,default);
Query OK, 1 row affected (0.00 sec)

mysql> select * from stu19;
+----------+----------+
| name     | addr     |
+----------+----------+
| tom      | 地址不詳        |
| 姓名不詳         | 地址不詳        |
+----------+----------+
2 rows in set (0.00 sec)

小結:

default關鍵字用來插入預設值

1.3.3 自動增長(auto_increment)

欄位值從1開始,每次遞增1,自動增長的值就不會有重複,適合用來生成唯一的id。在MySQL中只要是自動增長列必須是主鍵

1.3.4 主鍵(primary key)

主鍵概念:唯一標識表中的記錄的一個或一組列稱為主鍵。如一張表格的序號標識

特點:

1、不能重複、不能為空
2、一個表只能有一個主鍵。

作用:

1、保證資料完整性
2、加快查詢速度

選擇主鍵的原則

最少性:儘量選擇單個鍵作為主鍵
穩定性:儘量選擇數值更新少的列作為主鍵

比如:學號,姓名、地址  這三個欄位都不重複,選哪個做主鍵
選學號,因為學號最穩定

練習

-- 建立主鍵方法一
mysql> create table stu20(
    -> id int auto_increment primary key,-- primary key 主鍵
    -> name varchar(20)
    -> );
Query OK, 0 rows affected (0.04 sec)

-- 建立主鍵方法二
mysql> create table stu21(
    -> id int auto_increment,
    -> name varchar(20),
    -> primary key(id)
    -> );
Query OK, 0 rows affected (0.02 sec)

組合鍵

mysql> create table stu22(
    -> classname varchar(20),
    -> stuname varchar(20),
    -> primary key(classname,stuname)  -- 建立組合鍵
    -> );
Query OK, 0 rows affected (0.00 sec)

mysql> desc stu22;
+-----------+-------------+------+-----+---------+-------+
| Field     | Type        | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| classname | varchar(20) | NO   | PRI |         |       |
| stuname   | varchar(20) | NO   | PRI |         |       |
+-----------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

通過更改表新增主鍵

mysql> create table stu23(
    -> id int,
    -> name varchar(20)
    -> );
Query OK, 0 rows affected (0.05 sec)

-- 新增主鍵
mysql> alter table stu23 add primary key(id);
Query OK, 0 rows affected (0.09 sec)
Records: 0  Duplicates: 0  Warnings: 0

刪除主鍵

mysql> alter table stu23 drop primary key;
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0

插入資料

mysql> create table stu25(
    -> id tinyint unsigned auto_increment primary key,
    -> name varchar(20)
    -> );
Query OK, 0 rows affected (0.05 sec)

-- 插入資料
mysql> insert into stu25 values (3,'tom');   -- 可以直接插入數字
Query OK, 1 row affected (0.06 sec)

-- 自動增長列可以插入null,讓列的值自動遞增
mysql> insert into stu25 values (null,'berry');
Query OK, 1 row affected (0.00 sec)

小結:

1、只要是auto_increment必須是主鍵,但是主鍵不一定是auto_increment

2、主鍵特點是不能重複不能為空

3、一個表只能有一個主鍵,但是一個主鍵可以有多個欄位組成

4、自動增長列通過插入null值讓其遞增

5、自動增長列的資料被刪除,預設不再重複使用。truncate table刪除資料後,再次插入從1開始

練習

在主鍵列輸入的數值,允許為空嗎?		不可以
一個表可以有多個主鍵嗎?				不可以
在一個學校資料庫中,如果一個學校內允許重名的學員,但是一個班級內不允許學員重名,可以組合班級和姓名兩個欄位一起來作為主鍵嗎?						對
標識列(自動增長列)允許為字元資料型別嗎?	不允許
一個自動增長列中,插入3行,刪除2行,插入3行,刪除2行,插入3行,刪除2行,再次插入是多少?  10

1.3.5 唯一鍵(unique)

區別
主鍵 1、不能重複,不能為空
2、一個表只能有一個主鍵
唯一鍵 1、不能重刻,可以為空
2、一個表可以有多個唯一鍵

例題

-- 建立表的時候建立唯一鍵 
mysql> create table stu26(
    -> id int auto_increment primary key,
    -> name varchar(20) unique    -- 唯一鍵
    -> );
Query OK, 0 rows affected (0.05 sec)

-- 方法二 
mysql> create table stu27(
    -> id int primary key,
    -> name varchar(20),
    -> unique(name)
    -> );
Query OK, 0 rows affected (0.05 sec)

多學一招:
unique 或 unique key 是一樣的

通過修改表新增唯一鍵

-- 將name設為唯一鍵
mysql> alter table stu28 add unique(name);  

-- 將name,addr設為唯一鍵
mysql> alter table stu28 add unique(name),add unique(addr);
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc stu28;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | NO   | PRI | NULL    |       |
| name  | varchar(20) | YES  | UNI | NULL    |       |
| addr  | varchar(20) | YES  | UNI | NULL    |       |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.02 sec)

通過show create table 檢視唯一鍵的名字

通過唯一鍵的名字刪除唯一鍵

mysql> alter table stu28 drop index name;
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

1.3.6 備註(comment)

說明性文字

mysql> create table stu29(
    -> id int primary key comment '學號',
    -> name varchar(20) not null comment '姓名'
    -> );
Query OK, 0 rows affected (0.03 sec)

注意:備註屬於SQL程式碼的一部分

1.4 SQL註釋

單行註釋

-- 單行註釋
# 單行註釋
多行註釋  /*     */

1.5 資料完整性

1.5.1 資料完整性包括

1、實體完整性

1、主鍵約束
2、唯一約束
3、標識列

2、 域完整性

1、資料型別約束
2、非空約束
3、預設值約束

3、 引用完整性

外來鍵約束

4、 自定義完整性

1、儲存過程
2、觸發器

1.5.2 主表和從表

  1. 主表中沒有的記錄,從表不允許插入
  2. 從表中有的記錄,主表中不允許刪除
  3. 刪除主表前,先刪子表

1.5.3 外來鍵(foreign key)

外來鍵:從表中的公共欄位

-- 建立表的時候新增外來鍵
create table stuinfo(
       id tinyint primary key,
       name varchar(20)
)engine=innodb;

create table stuscore(
       sid tinyint primary key,
       score tinyint unsigned,
       foreign key(sid) references stuinfo(id)   -- 建立外來鍵
)engine=innodb;

-- 通過修改表的時候新增外來鍵
語法:alter table 從表 add foreign key(公共欄位) references 主表(公共欄位)

drop table if exists stuinfo;-- 因為上面已經建立了相同的表,所以在這裡刪除了重新建立
create table stuinfo(
       id tinyint primary key,
       name varchar(20)
)engine=innodb;

drop table if exists stuscore;
create table stuscore(
       sid tinyint primary key,
       score tinyint unsigned
)engine=innodb;

alter table stuscore add foreign key (sid) references stuinfo(id)

刪除外來鍵

通過外來鍵的名字刪除外來鍵(首先要顯示出外來鍵的名字,如下:)

-- 刪除外來鍵
mysql> alter table stuscore drop foreign key `stuscore_ibfk_1`;
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

小結:

1、只有innodb才能支援外來鍵
2、公共欄位的名字可以不一樣,但是資料型別要一樣

1.5.4 三種外來鍵操作(這一小節看視訊筆記好)

1、 嚴格限制(參見主表和從表)

2、 置空操作(set null):如果主表記錄刪除,或關聯欄位更新,則從表外來鍵欄位被設定為null。

3、 級聯操作(cascade):如果主表記錄刪除,則從表記錄也被刪除。主表更新,從表外來鍵欄位也更新。

語法:foreign key (外來鍵欄位) references 主表名 (關聯欄位) [主表記錄刪除時的動作] [主表記錄更新時的動作]。

一般說刪除時置空,更新時級聯。

drop table if exists stuinfo;
create table stuinfo(
       id tinyint primary key comment '學號,主鍵',
       name varchar(20) comment '姓名'
)engine=innodb;

drop table if exists stuscore;
create table stuscore(
       id int auto_increment primary key comment '主鍵',
       sid tinyint comment '學號,外來鍵',
       score tinyint unsigned comment '成績',
       foreign key(sid) references stuinfo(id) on delete set null on update cascade
    --  on delete set null:當主表記錄刪除時 (從表外來鍵欄位)置空
    -- on update cascade: 主表記錄更新時 從表級聯(級聯就能實現主表更新,從表也跟著更新)
)engine=innodb;

小結:

置空、級聯操作中外來鍵不能是從表的主鍵

1.6 補充

phpstudy中MySQL預設不是嚴格模式,將MySQL設定成嚴格模式

開啟my.ini,在sql-mode的值中,新增STRICT_TRANS_TABLES

sql-mode="NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES"

測試:然而非嚴格模式下,沒有設定字元編碼,輸入中文,能夠執行,但是顯示不出來或者顯示為亂碼

單詞

medium:中等的
small:小
tiny:微小
big:大