1. 程式人生 > >數據庫中的數據類型

數據庫中的數據類型

har subst 基礎上 規則 sel 時間 指定 not 可選

一:引擎

  引擎決定數據庫存取數據的方式==>不同的特點==>不同的用戶體驗

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

show engines;    #展示所有引擎

重點:innodb(默認):支持事務,行級鎖,外鍵
        myisam:查詢效率要優於innodb,當不需要支持事務,行級鎖,外鍵,可以通過設置myisam來優化數據庫

具體實現:
    use db1;
    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; insert into t1 values(1); insert into t2 values(1); insert into t3 values(1); insert into t4 values(1); select * from t1; ...

二:創建表完整語法

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

[]:表示可選參數
create table db1(name char(3) not null);
數據插入時,name不能為空(null),且最長只能存放三個字符

總結:
    寬度和約束條件為可選參數,用來限制存放數據的規則

三:數據庫模式

  sql_mode:反映數據庫的全局變量

  數據庫模式限制的是客戶端對服務器操作數據的方式(是否嚴格)

  兩種模式:

  no_engine_substitution;非安全性,默認

  strict_trans_table;安全模式

具體操作:  

  查看當前數據庫模式:

  show variables like "%sql_mode%";  #
匹配0~n個任意字符 ==> 模糊查詢   設置為安全模式:   set global sql_mode="strict_trans_table";   重啟連接(客戶端):   quit 應用:   create table t1(name char(2));   insert into t1 values("ab"); #正常格式   insert into t1 values("abcd"); #錯誤,過長:Data too long for column ‘name‘ at row 1

四:數據類型

  Mysql數據庫支持:整形,浮點型,字符型,時間類型,枚舉類型,集合類型

  4.1:整形

類型:
tinyint:1字節   -128~127
smallint:2字節
mediumint:3字節
int:4字節    -2147483648~2147483647
bigint:8字節

約束:
unsigned:無符號
zerofill:0填充

不同類型所占字節數不一樣,決定所占空間及存放數據的大小限制

例子:

create table t8(x tinyint);
insert into t8 values(200);    #非安全模式存入,值只能到最大值127
select (x) from t8;  
寬度:
1.不能決定整形存放數據的寬度,超過寬度可以存放,最終由數據類型所占字節決定
2.如果沒有超過寬度,且有zerofill限制,會用0填充前置位的不足位
3.沒有必要規定整形的寬度,默認設置的寬度就為該整形能存放數據的最大寬度

例如:
create table t2(x int(5) unsigned zerofill);
insert into t2 values(10);
select * from t2;

技術分享圖片

例子1:
create table t3(x int(5));
insert into t3 values(123456);
select (x) from t3;    #結果:123456

insert into t3 values(2147483648);
select (x) from t3;    #結果: 2147483647
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

技術分享圖片

  4.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):字符串存,全精度

例子:

一:
create table t5(age float(256,30));
#ERROR 1439 (42000): Display width out of range for column ‘age‘ (max = 255)
create table t5 (age float(255, 31));
#ERROR 1425 (42000): Too big scale 31 specified for column ‘age‘. Maximum is 30.
二:
create table t6(age float(256,30));
create table t7(x double(255,30));
create table t8(x decimal(65,30));

insert into t6 values(1.1111111111111111111111111);
insert into t7 values(1.1111111111111111111111111);
insert into t8 values(1.1111111111111111111111111);

select * from t6;    #小數據,精度要求不高,均采用float來存儲
select * from t7;
select * from t8;

alter table t8 modify x decimal(10,5);# 1.11111 => 限制了數據的存儲寬度

結果:見附圖

技術分享圖片

  4.3字符型

類型:
char:定長
varchar:不定長

寬度:
限制存儲寬度
char(4):以4個字符存儲以char屬性存儲的數據
varchar(4):數據長度決定字符長度,為可變長度存儲數據

例子:

create table t9(x char(4),y varchar(4));
insert into t9 values("Haru","Lani");
select x,y from t9;
+------+------+
| x    | y    |
+------+------+
| Haru | Lani |
+------+------+
1 row in set (0.00 sec)

但是這樣:
insert into t9 values("Grace","Shelly"); #非安全模式數據丟失,可以存放,安全模式報錯
select x,y from t9; #Query OK, 1 row affected, 2 warnings (0.06 sec)可以正常顯示丟失後(不完整)的數據

+------+------+
| x | y |
+------+------+
| Haru | Lani |
| Grac | Shel |
+------+------+
2 rows in set (0.00 sec)

insert into t9 values("a","b");

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

+----------------+----------------+
| char_length(x) | char_length(y) |
+----------------+----------------+
|              4 |              4 |
|              4 |              4 |
|              1 |              1 |
+----------------+----------------+
3 rows in set (0.05 sec)

重點:存儲數據的方式 ==>數據庫優化

char:一定按規定的寬度存放數據,以規定寬度讀取數據,通常更占空間

varchar:首先根據數據長度計算所需寬度,並在數據開始以數據頭方式將寬度信息保存起來,是一個計算耗時過程,首先讀取寬度信息,以寬度信息為依準讀取數據,通常節省空間。

8: zero egon Grace yanghuhu

8:4zero 4egon 5Grace 8yanghuhu

註:varchar的數據頭占1~2個字節

  規定char | varchar寬度均為4,用來存放4個字符的數據,char存取更高效,char占4個字符,varchar占5個字符,char更節省空間

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

  4.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(1970-01-01 00:00:00/2308-01-19 (具體幾點不知道))
一:
create table t10(my_year year,my_date date,my_time time);
insert into t10 values();    #三個時間類型的默認值均是null
insert into t10 values(2156,null,null);    #在時間範圍外,不允許插入該條數據
insert into t10 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); # 時間的寬度修改後還是采用默認寬度 => 不需要關系寬度

二:
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); # 在各自範圍內可以插入對應格式的時間數據

# datetime VS timestamp
datetime:時間範圍,不依賴當前時區,8字節,可以為null
timestamp:時間範圍,依賴當前時區,4字節,有默認值CURRENT_TIMESTAMP

  4.5枚舉與集合

類型:
enum:單選
set:多選
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字段只能單選

  4.6約束條件

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);

數據庫中的數據類型