1. 程式人生 > >表相關操作

表相關操作

重復 lob 客戶端 mod 決定 open 浮點 表示 isp

一.存儲引擎

1.什麽是存儲引擎?

存儲引擎就是如何存儲數據、如何為存儲的數據建立索引和如何更新、查詢數據等技術的實現方法。因為在關系數據庫中數據的存儲是以表的形式存儲的,所以存儲引擎也可以稱為表類型。

數據庫提供了多種存儲引擎,用戶可以根據不同的需求為數據表選擇不同的存儲引擎,用戶也可以根據自己的需要編寫自己的存儲引擎。

引擎是建表時規定的,提供給表使用的,不是數據庫。

技術分享圖片

# 展示所有引擎
show engines;
# 查看正在使用的存儲引擎
show variables like storage_engine&;
# innodb是mysql數據庫的默認存儲引擎:支持事務,行級鎖,外鍵。
# myisam:查詢效率優於innodb,當不需要支持事務, 行級鎖, 外鍵, 可以通過設置myisam來優化數據庫。 +--------------------+---------+----------------------------------------------------------------+--------------+------+------------+ | Engine | Support | Comment | Transactions | XA | Savepoints | +--------------------+---------+----------------------------------------------------------------+--------------+------+------------+ | FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL | | MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO | | MyISAM | YES | MyISAM storage engine | NO | NO | NO | | BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO | | CSV | YES | CSV storage engine | NO | NO | NO | | MEMORY | YES | Hash based, stored in
memory, useful for temporary tables | NO | NO | NO | | ARCHIVE | YES | Archive storage engine | NO | NO | NO | | InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES | | PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO | +--------------------+---------+----------------------------------------------------------------+--------------+------+------------+

2.使用存儲引擎

在創建表時,其後加上engine=引擎名。

create table t1(id int)engine=innodb;

create table t2(id int)engine=myisam;

create table t3(id int)engine=blackhole; # 黑洞引擎,把不要的數據放入,不會進行存儲

create table t4(id int)engine=memory; # 數據存放到內存中,重啟服務數據會丟失

二.創建表的完整語法

create table 表名(
字段名1 類型[(寬度)約束條件],
字段名1 類型[(寬度)約束條件],
字段名1 類型[(寬度)約束條件]
)engine=innodb charset=utf8;

# []可選參數
# create table db1.t1(name char(3) not null);
# 數據插入時,name不能為空(null), 且最長只能存放三個字符
# 總結: 寬度和約束條件為可選參數, 用來限制存放數據的規則

三.數據庫的模式

# sql_mode:反映數據庫的全局變量
# 數據庫模式限制的是客戶端對服務器操作數據的方式

# 兩種模式:
no_engine_substitution:非安全性,默認
strict_trans_tables:安全模式

# 查看當前數據庫模式:
show variables like "%sql_mode%"; # %匹配0~n個任意字符 =》模糊查詢

# 設置為安全模式
set global sql_mode="strict_trans_tables";

# 重啟連接(客戶端)

# 在安全模式下:修改一個表的數據類型也會報錯
create table t1(name char(2));
insert into t1 values ("ab") # 正常
insert into t1 values ("zero") # 錯誤 Data too long for column ‘name‘ at row 1

四.數據類型

mysql數據類型:

# 整型 浮點型 字符型 時間類型 枚舉類型 集合類型

1.整型

# tinyint: 1個字節,smallnit: 2個字節,mediumint:3個字節,int:4個字節,bigint:8個字節

# tinyint  1個字節
# 小整數,數值範圍:
# 有符號:-128 ~ 127
# 無符號:0 ~ 255
# mysql中無布爾值,使用tinyint(1)構造

# int  4個字節
# 整數,數值範圍:
# 有符號:-2147483648 ~ 2147483647
# 無符號:0 ~ 4294967295

寬度:
寬度不是規定存儲寬度,用於表示顯示寬度,且不能限制存儲寬度,不用關心長度,默認長度就是最大寬度。

約束:
unsigned:無符號
zerofill:0填充
技術分享圖片
# eg:1
create table t9(x int(5));
insert into t9 values(123456); 
select (x) from t9; # 結果: 123456
insert into t9 values(2147483648); 
select (x) from t9; # 結果: 2147483647
insert into t9 values(10); 
select (x) from t9; # 結果: 10
# eg:2
create table t10(x int(5) unsigned zerofill); # 區域0~4294967295
insert into t10 values(10); 
select x from t10; # 結果: 00010
insert into t10 values(12345678900); 
select x from t10; # 結果: 4294967295
驗證

技術分享圖片

2.浮點型

類型:
float:4字節,3.4E–38~3.4E+38
double:8字節,1.7E–308~1.7E+308
decimal:M,D大值基礎上+2

寬度:
限制存儲寬度
(M, D) => M為數字總個數,D為小數位的個數
float(255, 30):精度最低,最常用
double(255, 30):精度高,占位多
decimal(65, 30):字符串存,全精度
技術分享圖片
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)
驗證

3.字符型

# 類型:
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)
    
    檢索:
        尾部有空格會保存下來,在檢索或者說查詢時,也會正常顯示包含空格在內的內容
技術分享圖片
‘‘‘寬度
限制存儲寬度
char(4):以4個字符存儲定長存儲數據
varchar(4):數據長度決定字符長度,為可變長度存儲數據
‘‘‘
# eg:
create table t15 (x char(4), y varchar(4));
insert into t15 values("zero", owen); # ‘‘ | "" 均可以表示字符
select x,y from t15; # 正常
insert into t15 values("yanghuhu", lxxVSegon); # 非安全模式數據丟失,可以存放, 安全模式報錯
select x,y from t15; # 可以正常顯示丟失後(不完整)的數據
insert into t15 values(a, b);

# 驗證數據所在字符長度
# 前提: 安全模式下以空白填充字符
set global sql_mode="strict_trans_tables,PAD_CHAR_TO_FULL_LENGTH";
# 重啟連接
select char_length(x), char_length(y) from t15; # a占4 b占1

‘‘‘重點: 存儲數據的方式 **  => 數據庫優化
char: 一定按規定的寬度存放數據, 以規定寬度讀取數據, 通常更占空間
varchar: 首先根據數據長度計算所需寬度, 並在數據開始以數據頭方式將寬度信息保存起來, 是一個計算耗時過程, 取先讀取寬度信息,以寬度信息為依準讀取數據, 通常節省空間
‘‘‘
8: zero    egon    lxx     yanghuhu
8: 4zero4egon3lxx8yanghuhu
註: varchar的數據頭占1~2字節
    規定char|varchar寬度均為4,用來存放4個字符的數據, char存取更高效,char占4字符,varchar占5字符,char更省空間

總結: 數據長度相近的數據提倡用char來存放數據, 數據需要高速存取,以空間換時間, 采用char
驗證

4.時間類型

作用:存儲用戶註冊時間,文章發布時間,員工入職時間,出生日期,過期時間等。

‘‘‘類型
year:yyyy(1901/2155)
date:yyyy-MM-dd(1000-01-01/9999-12-31)
time:HH:mm:ss
datetime:yyyy-MM-dd HH:mm:ss(1000-01-01 00:00:00/9999-12-31 23:59:59)
timestamp:yyyy-MM-dd HH:mm:ss(1970-01-01 00:00:00/2038-01-19 ??)
‘‘‘
# datetime vs timestamp
# datetime:時間範圍,不依賴當前時區,8個字節,可以為null
# timestamp:時間範圍,依賴當前時區,4個字節,有默認值current_timestamp
技術分享圖片
# eg: 1
create table t16(my_year year, my_date date, my_time time);
insert into t16 values(); # 三個時間類型的默認值均是null
insert into t16 values(2156, null, null); # 在時間範圍外,不允許插入該數據
insert into t16 values(1, 2000-01-01 12:00:00, null); # 2001 2000-01-01 null
insert into t16 values(2019, 2019-01-08, "15-19-30"); # time報格式錯誤 => 按照時間規定格式存放數據

alter table t16 change my_year myYear year(2); # 時間的寬度修改後還是采用默認寬度 => 不需要關系寬度


# eg:2
create table t17(my_datetime datetime, my_timestamp timestamp);
insert into t17 values(null, null); # 可以為空, 不能為null,賦值null采用默認值current_timestamp
insert into t17 values(4000-01-01 12:00:00, 2000-01-01 12:00:00); # 在各自範圍內可以插入對應格式的時間數據
驗證

5.枚舉與集合

字段的值只能在給定範圍中選擇,如單選框,多選框

enum :單選,只能在給定的範圍內選一個值,如性別sex 男/女

set:多選,在給定的範圍內可以選擇一個或者一個以上的值(如:愛好1,愛好2,愛好3...)

create table t19(
    sex enum(male,female,wasai) not null default wasai, # 枚舉
    hobbies set(play,read,music) # 集合
);

insert into t19 values (null, null); # sex不能設置null
insert into t19 values (); # wasai null
insert into t19 (hobbies) values (play,read), (music,play); # sex采用默認值, 對hobbies字段添加兩條記錄
insert into t19 (sex,hobbies) values (male,female, play); # sex字段只能單選

五.約束條件

"""
primary key:主鍵,唯一標識,表都會擁有,不設置為默認找第一個 不空,唯一 字段,未標識則創建隱藏字段
foreing key:外鍵
unique key:唯一性數據, 該條字段的值需要保證唯一,不能重復

auto_increment:自增,只能加給key字段輔助修飾

not null:不為空
default:默認值

unsigned:無符號
zerofill:0填充
"""
技術分享圖片
註:
1.鍵是用來講的io提供存取效率
2.聯合唯一
create table web (
    ip char(16),
    port int,
    unique(ip,port)
);
3.聯合主鍵
create table web (
    ip char(16),
    port int,
    primary key(ip,port)
);

# eg:1
# 單列唯一
create table t20 (
    id int unique
);
# 聯合唯一
create table web (
    ip char(16),
    port int,
    unique(ip,port)
);
# 如果聯合兩個字段,兩個字段全相同才相同,否則為不同
insert into web values (10.10.10.10, 3306), (10.10.10.10, 3306);

# 註: 
# 1.表默認都有主鍵, 且只能擁有一個主鍵字段(單列主鍵 | 聯合主鍵)
# 2.沒有設置主鍵的表, 數據庫系統會自上而下將第一個規定為unique not null字段自動提升為primary key主鍵
# 3.如果整個表都沒有unique not null字段且沒有primary key字段, 系統會默認創建一個隱藏字段作為主鍵
# 4.通常必須手動指定表的主鍵, 一般用id字段, 且id字段一般類型為int, 因為int類型可以auto_increment

# eg:2
create table t21(id int auto_increment); # 自增約束必須添加給key的字段
# eg:3
create table t21(id int primary key auto_increment); # 自增要結合key,不賦值插入,數據會自動自增, 且自增的結果一直被記錄保留
# eg:4
# 聯合主鍵
create table t22(
    ip char(16),
    port int,
    primary key(ip,port)
);
# 如果聯合兩個字段,兩個字段全相同才相同,否則為不同
insert into web values (10.10.10.10, 3306), (10.10.10.10, 3306);
驗證

表相關操作