# 數據庫之字段類型和約束條件


一.存儲引擎

​ 存儲引擎是用於根據不同的機制處理不同的數據。

 查看mysql中所有引擎:    
 - show engines;

  • innodb:默認存儲引擎,

      	支持事物,支持行鎖,支持外鍵
    
  • myisam: MySQL老版本在用的存儲引擎

  • blackhole: 黑洞,存任何數據,都會立即消失,相當於經過隊列,數據存入就會被取走

    • memory: 內存引擎(數據存放在內存中,斷電即消失,即關閉服務端)

      舉例說明四種不同的存儲引擎

      • 插入四種不同的存儲引擎
      - 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);
      	 select * from t1;
      - insert into t2 values(1);
      	 select * from t2;
      - insert into t3 values(1);
      	 select * from t3;
      - insert into t4 values(1);
      	 select * from t4;這個需要內存中還有,需要關掉服務端才能銷毀清除。
      

二.創建表完整的語法

create table 表名(字段名1 字段類型(寬度) 約束條件,字段名2 字段類型(寬度) 約束條件);

# 寬度指對存儲數據的限制
create table userinfo(name char);
insert into userinfo values('tank');
'''
1)沒有安全模式的數據庫版本,能夠存放數據但只存存進去一個t。
2)最新數據的版本直接報錯提示無法儲存: Data too long for column 'name'
'''

# 約束條件非必須,可有可無
例如null和not null
create table t1(id int, name char not null)
# 正常存儲
insert into t1 values(1, 'tank');
# 錯誤存儲
insert into t1 values(2, null);
#報錯信息:ERROR 1048 (23000): Column 'name' cannot be null

總結:

  • 創建表的時候字段名不能重復
 create table test(
                id int,
                id int
            );
  • 最后一個字段不能在末尾加逗號
 create table test(
                id int,
                age int,
            );
  • 字段名必須有字段類型與寬度
create table test(
                id int,
                name char
            );
            insert into test values(1, 'tank');

            alter table test modify name char(4);
            insert into test values(2, 'sean');

三.字段類型

  • 確定表結構
  • 字段與字段類型

補充:設置嚴格模式

在一些低版本的mysql里面,即時輸入的數據不符合規格,也會存入進字段里面,所以可以通過設置嚴格模式來解決這個問題

# 查看數據庫配置中變量名包含mode的配置參數:
show variables like "%mode%";

# 修改安全模式:
set session;  # 局部有效,只在你當前操作的窗口有效
set global session;  # 全局有效,永久有效

# 修改嚴格模式,以管理員修改完之后退出當前客戶端重新登錄即可
set global sql_mode = 'STRICT_TRANS_TABLES';

1)整型

  • 分類:tinyint、smallint、mediumint、int、bigint
  • 應用場景: 存儲年齡,等級,id,號碼等
  • 典型存儲范圍

  • 驗證整型字段有無符號及范圍
# TINYINT  tinyint范圍( -128, 127)
1)默認有正負符號限制
create table t2(id TINYINT);
desc t2;

# 超出限制, 插不進去,低版本設置嚴格模式后會報錯,不設置嚴格模式進去會被自動修改數值為-128或127
insert into t2 values(-129), (256);

# 默認范圍是(-128, 127)
insert into t2 values(-128), (127);

select * from t2;

2) 無正負符號限制: unsigne
create table t3(number tinyint unsigned);
# 輸入負號或超出范圍都會報錯
insert into t3 values(-10);  
insert into t3 values(127);



# INT: int默認最大展示的位數是11位
create table t4(id int);
# 默認范圍是(-2147483648, 2147483647)
insert into t4 values(-2147483648), (2147483647);
# 超出默認范圍,報錯
insert into t4 values(-2147483648), (122412451251251);


# 問題: 整型后的寬度能否改變字段存儲的大小?
# create table t5(number int(10));

# int(8)不是限制長度,而是控制展示數據的位數,8位以內以空格補全,超出則正常顯示。
create table t5(id int(8));
insert into t5 values(2147483647);
select * from t5;
+------------+
| id         |
+------------+
| 2147483647 |
|      21474 |
+------------+

# 顯示不夠8位用0補全, 並且只能插入無符號的值
create table t6(id int(8) unsigned zerofill);
+----------+
| id       |
+----------+
| 42949672 |
| 00429496 |
+----------+

'''
總結:
		- 注意1:
			- not null: 字段值不能為空
			- unsigned: 無正負符號
			- zerofill: 不夠以0填充空格
'''

2)浮點型:

  • 分類: float、double、 decimal
  • 應用場景: 身高、體重、薪資
  • 三者最大的區別是存儲精確度不一樣
注意: 字段限制特點(5,3)前一位表示所有的位數,后一位表示小數個數。
    # 存儲限制:
	- float(255, 30)
	- double(255, 30)
	- decimal(65, 30)
    
# 精確度驗證:
create table t7(x float(255, 30));
create table t8(x double(255, 30));
create table t9(x decimal(65, 30));

insert into t7 values(1.1111111111111111111111111111);
''' 
mysql> select *from t7;
+----------------------------------+
| x                                |
+----------------------------------+
| 1.111111164093017600000000000000 |
+----------------------------------+
1 row in set (0.00 sec)
'''

insert into t8 values(1.1111111111111111111111111111);
'''

mysql> select *from t8;
+----------------------------------+
| x                                |
+----------------------------------+
| 1.111111111111111200000000000000 |
+----------------------------------+
1 row in set (0.00 sec)
'''

insert into t9 values(1.1111111111111111111111111111);
'''
mysql> select *from t9;
+----------------------------------+
| x                                |
+----------------------------------+
| 1.111111111111111111111111111100 |
+----------------------------------+
1 row in set (0.00 sec)
'''

總結:三種浮點型的精確度不一樣,最好的是decimal,但是float也夠用了

3)字符類型

  • 分類:varchar 、char

  • 應用場景: 姓名、地址、描述信息

    1)char:定長字符

# 超出四個字符報錯,不夠四個字符空格補全
create table t10(name char(4));

insert into t10 values('tank');
insert into t10 values('lol');

# 報錯
insert into t10 values('hello');


優點:
	存取速度快
缺點:
	浪費空間。
insert into t11 values(1, 't'); # t+三個空格

# 注意: 無法查看字符真實長度
# 針對char類型,mysql在存儲時會將數據用空格補全存放到硬盤中。但是會在讀出結果的時候自動去掉末尾的空格。

2)varchar: 不定長

- 存幾個字符,就是幾個字符的大小,每個字符前都要+1bytes
create table t11(name varchar(4));

- insert into t11 values('tank');
insert into t11 values('lol');

# 報錯
insert into t10 values('hello');


優點:
	節省空間
缺點:
	存取速度慢

4)日期類型

  • 分類:
    • date: 2019-12-10
    • time: 11:11:11
    • datetime: 2019-12-10 11:11:11
    • year: 2019
    • timestamp:時間戳
# 建立表格
create table teacher1(id int, name varchar(16),born_year year,brith date,work_time time,register_time datetime, local_time timestamp);

# 插入記錄:
insert into teacher1 values(1,'tank','2000','2000-12-12','12:11:10','2000-12-12 11:11:11',null);

# 時間戳可以用null代替

# 注意:插入時間需要以字符串格式

表的內容:

mysql> select *from teacher1;
+------+------+-----------+------------+-----------+---------------------+---------------------+

id name born_year brith work_time register_time local_time

+------+------+-----------+------------+-----------+---------------------+---------------------+

1 tank 2000 2000-12-12 12:11:10 2000-12-12 11:11:11 2019-12-11 18:37:00

+------+------+-----------+------------+-----------+---------------------+---------------------+

5)枚舉和集合類型

分類:

  • 枚舉enum 多選一
  • 集合set 多選一 或 多選多
 - enum: 可以 多選一
   create table t13(
       id int,
       name varchar(4),
       gender enum('male', 'female', 'others')
   );
                # insert into 表名(字段名) values(字段名對應的值);
                insert into t13(id, name, gender) values(1, 'tank', 'male');

                # 嚴格模式下,選擇枚舉以外的值會報錯
                insert into t13(id, name, gender) values(2, 'gd', 'animal');
                
 

- set: 可 多選一 或 多選多
                create table t14(
                    id int,
                    name varchar(4),
                    gender enum('male', 'female', 'others'),
                    hobbies set('read', 'sing', '生蚝', 'HSNM', '架子鼓')
                );

                # 多選一
                insert into t14 values(1, '大雞J', 'others', 'HSNM');
                # 多選多
                insert into t14 values(2, 'tank', 'male', 'read,架子鼓,sing,生蚝');

                # 多選多的順序可不一
                insert into t14 values(2, 'tank', 'male', 'read,架子鼓,sing,生蚝');


        

四.約束條件

約束條件就是,對於數據庫表插入數據時加以約束限制。

1)約束條件介紹

- primary key (pk)
    標識該字段為該表的主鍵,主鍵可以是唯一的表示記錄
    
- foreign key (fk)
    標識該字段為該表的外鍵

- not null
    標識該字段不能為空

- unique key (uk)
    標識該字段的值是唯一的

- auto_increment
    標識該字段的值自動增長 (整數類型,並且為主鍵)

- default
    為該字段設置默認值

- unsigned
    無正負符號

- zerofill
    使用0填充空格

2)not null + unique (非空唯一)

create table user1(id int not null,name varchar(4));

#報錯,不能輸入空
insert into user1 values(null,'tank');
# 正確
insert into user1 values(1,'tank');

3)unique 將某個字段設置為唯一的值

create table user3(id int not null unique,name varchar(4));

# 報錯
 insert into user3 values(1,'tank'),(1,'sean');
 
# 正確
insert into user3 values(1,'tank'),(2,'sean');

4)primary key (主鍵)

相等於 :not null + unique

pk就是表中的索引: 可以通過索引快速查找某些數據。 - 提高查詢效率

  create table user4(
                    id int primary key,
                    name varchar(4)
                );
# 唯一
insert into user4 values(1);
insert into user4 values(1);

# 不能為空
insert into user4 values(null);

# 強調:
'''
		1.一張表必須只有一個主鍵,如果沒有設置主鍵,會從上到下搜索,直到遇到 "第一個"非空且唯一的字段自動設置為主鍵。
'''
create table user8(
	id int,
  name varchar(16),
  age int not null unique
)engine=innodb;

desc user8;

'''
		2.如果包里沒有指定任何可以設置主鍵的字段,那innodb會采用自己默認的一個隱藏關鍵字作為主鍵,隱藏意味着查詢你的時候通過這個加速查詢。
		索引: 類似於書的目錄, 沒有主鍵就相當於一頁一頁翻着查詢。

		3.一張表中通常都應該有一個id字段,並且通常將id字段作為主鍵。
'''

# 聯合主鍵: 多個字段聯合起來作為一個主鍵,本質上還是一個主鍵
create table user9(
	id int,
	name varchar(16),
	primary key(id, name)
);
desc user9;

# 主鍵id作為數據的編號,應該設置為自動遞增
create table user10(
	id int primary key auto_increment,
  name varchar(16)
);
desc user10;

insert into user10(name) values('tank');
insert into user10(name) values('sean'),('jason'),('大餅');


 # 若想自增從指定值開始,可插入第一條數據時先指定id的值;
                insert into user4(id, name) values(10, 'tank');
                insert into user4(name) values('sean');  # 11
                insert into user4(name) values('egon');  # 12
                insert into user4(name) values('大雞哥');  # 13
                
                

# 注意: auto_increment通常加在主鍵上,並且只能設置給primary key字段。

# 補充:
delete from user10;
# delete刪除表的記錄或者指定記錄,但id不會重置為0
# 刪除某一條記錄
delete from user10 where id='4';

# 若想要清空id重置為0,可使用truncate user10;

5)unsigned

無符號

create table user5(
    id int unsigned
);
# 報錯
insert into user5 values(-100);
insert into user5 values(0);
insert into user5 values(100);

有符號
create table user6(
 id int
    );

insert into user6 values(-100);

6)zerofill

使用0填充空格

create table user7(
	id int zerofill
	);

insert into user7 values(100);

7)刪除記錄

 create table user8(
                id int primary key auto_increment,
                name varchar(4)
            );

            insert into user8(name) values('tank');
            insert into user8(name) values('大大大'), ('egon');

            - delete:
                # 清空user8表中的所有記錄
                delete from user8;

            - truncate:
                # 清空user8表中的所以記錄,並且id重置為0
                truncate table user8;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM