1. 程式人生 > >Python學習之旅—Mysql數據庫之數據類型和約束

Python學習之旅—Mysql數據庫之數據類型和約束

都是 warnings there 結構 clas 體重 set集合 scale 自增

前言

   本篇博客我們主要專註於解決Mysql數據庫中的數據類型和約束,將重點聚焦於字符類型,日期類型,集合類型和主鍵和unique等知識點,希望各位可以好好掌握今天的知識點。

一.整數類型

#整數類型:TINYINT SMALLINT MEDIUMINT INT BIGINT
#作用:存儲年齡,等級,id,各種號碼等
#ps:默認都是有符號的
關於整數類型,我們需要關註一點,即整形的寬度指的是顯示寬度,而不是存儲寬度
我們來看看如下的例子:

create table t1(id int(1));
insert into t1 values(256111);
select * from t1;

create table t2(id int(20));


insert into t2 values(256111);
select * from t2;

create table t3(id int(20) zerofill);
insert into t3 values(256111);
select * from t3;

mysql> create table t4(id int);
Query OK, 0 rows affected (0.46 sec)

mysql> desc t4;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |


+-------+---------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
1 row in set (0.02 sec)

mysql> insert into t4 values(1111111111111111111111111111111111111111111);
Query OK, 1 row affected, 2 warnings (0.17 sec)

mysql> select * from t4;


+------------+
| id |
+------------+
| 2147483647 |
+------------+
1 row in set (0.00 sec)


mysql> create table t5(id int unsigned);
Query OK, 0 rows affected (0.45 sec)

mysql> desc t5;
+-------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+-------+
| id | int(10) unsigned | YES | | NULL | |
+-------+------------------+------+-----+---------+-------+
1 row in set (0.01 sec)

mysql> insert into t5 values(11111111111111111111111111111111111111111);
Query OK, 1 row affected, 2 warnings (0.05 sec)

mysql> select * from t5;
+------------+
| id |
+------------+
| 4294967295 |
+------------+
1 row in set (0.00 sec)

二.浮點數類型

浮點類型主要分為三種:FLOAT,DOUBLE,DECIMAL;其主要用來標識體重,薪資,價格等屬性

mysql> create table t6(weight float(256,56) unsigned);
ERROR 1425 (42000): Too big scale 56 specified for column ‘weight‘. Maximum is 30.

mysql> create table t6(weight float(256,30) unsigned);
ERROR 1439 (42000): Display width out of range for column ‘weight‘ (max = 255)

mysql> create table t6(weight float(255,30) unsigned);
Query OK, 0 rows affected (0.37 sec)

mysql> desc t6;
+--------+------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+------------------------+------+-----+---------+-------+
| weight | float(255,30) unsigned | YES | | NULL | |
+--------+------------------------+------+-----+---------+-------+
1 row in set (0.01 sec)

mysql> create table t7(weight double(256,33) unsigned);
ERROR 1425 (42000): Too big scale 33 specified for column ‘weight‘. Maximum is 30
mysql> create table t7(weight double(256,30) unsigned);
ERROR 1439 (42000): Display width out of range for column ‘weight‘ (max = 255)
mysql> create table t7(weight double(255,30) unsigned);
Query OK, 0 rows affected (0.36 sec)


mysql> create table t8(weight decimal(66,33) unsigned);
ERROR 1425 (42000): Too big scale 33 specified for column ‘weight‘. Maximum is 30.
mysql> create table t8(weight decimal(66,30) unsigned);
ERROR 1426 (42000): Too big precision 66 specified for column ‘weight‘. Maximum is 65.
mysql> create table t8(weight decimal(65,30) unsigned);
Query OK, 0 rows affected (0.39 sec)

三.日期類型

日期類型主要分為如下五種:
DATE:2017-11-11  出生年月日
TIME:10:14:11  上課時間
DATETIME:2017-11-11 10:14:11 註冊時間,文章發布時間,員工入職時間
TIMESTAMP:2017-11-11 10:14:11
YEAR :1970 出生年

我們來驗證下:
CREATE DATABASE day47;
use day47;

create table t10(
    born_date DATE,
    class_time  TIME,
    reg_time DATETIME,
    born_year YEAR
);

INSERT INTO t10 VALUES
  (1999-11-11, 08:30:00, 2017-03-01 11:11:11, 1992);==============================================
下面我們來看看datetime與timestamp的區別:

create table t11(
    x datetime,
    y timestamp
);

desc t11;

mysql> desc t11;
+-------+-----------+------+-----+-------------------+-----------------------------+
| Field | Type      | Null | Key | Default           | Extra                       |
+-------+-----------+------+-----+-------------------+-----------------------------+
| x     | datetime  | YES  |     | NULL              |                             |
| y     | timestamp | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-------+-----------+------+-----+-------------------+-----------------------------+
2 rows in set (0.01 sec)

從上面的信息可知,timestamp默認是不能傳空,其默認值是當前的時間戳;而datetime是可以傳空的。
我們來驗證下:
mysql> insert into t11 values(null,null);
Query OK, 1 row affected (0.04 sec)

mysql> select * from t11;
+------+---------------------+
| x    | y                   |
+------+---------------------+
| NULL | 2017-10-23 10:25:07 |
+------+---------------------+
1 row in set (0.00 sec)
從上面的信息可知,當我們為timestamp傳遞空值時,其默認值是當前的時間。

實際使用我們使用的還是datetime.

四.字符類型

char類型:
    範圍:0-255
    特點:
        定長,簡單粗暴,浪費空間(待存儲的數據長度<寬度限制),存取速度快

varchar類型:
    範圍:0-21844
    特點:
        變長,精準,節省空間(待存儲的數據長度<寬度限制),存取速度慢
註意:如果我們需要存儲的是定長的字段,推薦使用char,例如IP地址;而且當我們使用where條件進行過濾時,由於它的存取速度比較
快,所以更加適合使用where條件來過濾。如果是一些不定常的字段,而且不會使用到where條件進行過濾時,推薦使用varchar(),例如
關於某件商品的評價等等。

五.枚舉與集合類型

枚舉與集合類型往往對應這樣的需求,例如某些字段的值是固定的幾個,例如性別,男或者女,此時我們就可以將性別這個字段設定
為枚舉類型;使用enum關鍵字修飾;再例如,用戶的字段屬性可能有多個值,其他用戶屬性可以從這幾個值中選取幾個作為自己的值。
例如以用戶權限表為例子,管理員具有查看學生,修改學生表,創建學生記錄的功能,而班主任只能查看學生記錄,此時如果需要定義具體的
權限,我們就可以將權限描述字段定義為一個集合即可。
create table t18( id
int, name char(10), sex enum(male,female,None) # 表示只能從集合中取一個值 ); # 修改表的結構,表示不能傳遞空,默認是male alter table t18 modify sex enum(male,female,None) not null default male; insert into t18 values(1,egon,xxxxx); insert into t18(id,name) values(1,egon); 下面我們來關註下set集合:表示多選,例如下面的例子中我為hobbies設置值時,可以從裏面選擇多個值進行組合。 create table t19( id int, name char(10), hobbies set(music,read,basketball,football,eat,sleep) ); insert into t19 values(1,egon,music,read,eat);

六.字段的約束

KEY:
    primay key 主鍵,一個表中只能有一個主鍵,主鍵的意思就是非空且唯一
    unique 定義該字段的值唯一

【001】我們設置一個整形字段直接自增,會報錯:提示只能有一個自增長的字段,要麽是unique key,要麽是primary key
mysql
> create table t20(id int auto_increment,name char(10)); ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key create table t20(id int primary key auto_increment,name char(10)); create table t21(id int not null unique auto_increment,name char(10)); 比較t20和t21這兩張表,我們發現primary key和not null unique是等同的 【002】下面我們來驗證下,一張表中是否可以建立多個主鍵 create table t22( id int primary key, name char(10) ); create table t23( id int, name char(10), constraint pri_id primary key(id) # 在字段定義完畢後,再來限制它為主鍵,這裏pri_id給約束起一個名字 ); 上面的方式也可以像如下的方式這樣寫(實際中我們還是直接在定義字段的時候就指定主鍵) create table t24( id int, name char(10), primary key(id) ); 下面我們演示直接加入unique key,下面兩種方式均可以 create table t25( id int, name char(10), constraint uni_id unique(id) ); create table t26( id int, name char(10), unique(id) ); #只能有一個主建,但是可以有多個not null unique # 創建如下這張表時會報錯,因為一張表中只能存在一個主鍵 create table t27( id int, name char(10), primary key(id), primary key(name) ); 一張表中可以有多個not null unique create table t28( id int not null unique, name char(10) not null unique ); DESC t28; 雖然可以存在多個not null unique,但是最終只有一個成為了主鍵,只有ID成為了主鍵 即如果你在定義一個表時,沒有使用primary key定義主鍵,那麽默認就用第一個not null unique修飾的字段作為主鍵 表中不一定需要存在主鍵 我們最後來看一個聯合唯一的主鍵 需求:現在我使用t29來存儲一個服務信息, 為了保證每個服務是獨立的,我需要保證該服務所對應的IP地址和端口的組合不一樣 IP地址可以一樣,只要端口不一樣即可,這就設計到聯合唯一的概念。我們可以將 ip和端口設置為一個聯合主鍵 #聯合唯一 create table t29( id int, ip char(15), # 由於IP地址是固定的長度,所以我們推薦使用char類型 port int, primary key(ip,port) ); insert into t29 values (1,1.1.1.1,3306), (2,1.1.1.2,3306), (3,1.1.1.1,8080) ; 現在問題來了,這樣設置不合理,因為ID這個字段應該是自增的,用來標識此時到了多少條記錄 既然是自增的,那麽就要將它設置為一個key,要麽是primary key,要麽是unique key; 通常ID字段設置為primary key,我們通常查詢表時,都是通過ID字段來作為查詢依據,這涉及到 MySQL的優化機制。像上面的那樣,如果設置將IP和port設置為primary key,以後查詢就很不方便。 而同時我們又要保證ip和port的組合不為空且唯一,所以只能將其設置為unique。 這樣設置完畢後,就可以保證ip和port是聯合唯一的,但主鍵不是它們兩個 create table t30( id int primary key auto_increment, ip char(15) not null, port int not null, unique(ip,port) ); desc t30; 此時我們可以得知ip和port就是聯合唯一的,下面我們插入值就可以使用如下的方式啦,非常方便: insert into t30(ip,port) values (1.1.1.1,3306), (1.1.1.1,3307), (1.1.1.2,3307) ;

結語:

   本篇博客主要梳理了數據類型相關聯的知識點,大家需要重點掌握不同數據類型的約束,下一篇我們將重點梳理使用外鍵來定義不同表之間的關系。

Python學習之旅—Mysql數據庫之數據類型和約束