1. 程式人生 > >mysql數據庫 --數據類型、約束條件

mysql數據庫 --數據類型、約束條件

驗證 not 3.1 增長 rds too mysq 位數 由於

今日內容

表的詳細使用

  • 1、創建表的完成語法
  • 2.字段類型

    整型、浮點型、字符類型、日期類型、枚舉與集合類型

  • 3.約束條件

    primary key、unique、not null、default

一、創建表的完成語法

1.語法
create table 表名(
    字段名1 類型[(寬度) 約束條件],
    字段名2 類型[(寬度) 約束條件],
    字段名3 類型[(寬度) 約束條件]
);
PS:註意事項:
    1. 在同一張表中,字段名不能相同
    2. 寬度和約束條件可選,字段名和類型是必須的
    3. 最後一個字段後不能加逗號!
2.補充
(1)寬度指的是對存儲數據的限制
    create table userinfo(name char);
    insert into userinfo values('lisi');

    1.沒有安全模式的數據庫版本,能夠存放數據但是只會存進去一個j
    2.最新數據庫版本直接報錯提示無法存儲(我裝的是5.7 直接出現下面的結果):
    mysql>  insert into userinfo values('lisi');
    ERROR 1406 (22001): Data too long for column 'name' at row 1

(2) 約束條件初識>>> null 與 nut null
    create table t1(id int,name char not null);
    insert into t1 values(1,'j');  # 正常存儲
    insert into t1 values(2,null);  # 報錯
    
# 總結 類型與約束條件區別
# 類型:限制字段必須以什麽樣的數據類型存儲
# 約束條件:約束條件是在類型之外添加一種額外的限制

二、字段類型

2.1 整型
create table t1(x tinyint);
insert into t1 values(128),(-129);

輸出結果:
mysql> insert into t1 values(-1),(-129);
ERROR 1264 (22003): Out of range value for column 'x' at row 2


create table t2(x tinyint unsigned);
insert into t2 values(-1),(256);

輸出結果:
mysql> insert into t2 values(-1),(256);
ERROR 1264 (22003): Out of range value for column 'x' at row 1


create table t3(x int unsigned);
insert into t3 values(4294967296);

輸出結果:
mysql> insert into t3 values (4283942745);
Query OK, 1 row affected (0.07 sec)

說明:由於開啟了嚴格模式,導致t1,t2表插入數據失敗
在不開啟嚴格模式下,可以順利的寫數據,但是:
 (1)tinyint:默認情況下是有符號的
    有符號:-128 ~ 127
    無符號:0 ~ 255
 (2)unsigned:表示無符號
2.1.2 兩點補充

(1)Q:類型後面的寬度能否改變字段存儲的大小限制?
A:對於整型來說,數據類型後的寬度並不是存儲限制,而是顯示限制,所以在創建表時,
如果字段內采用的是整型類型,完全無需指定顯示寬度,默認的是顯示寬度,足夠
完整的顯示當初存放的數據。

    create table t4(x int(8));
    insert into t4 values(1232983640223);
    
    # 顯示時,不夠8位用0填充,如果超出8位則正常顯示
    create table t5(x int(8) unsigned zerofill);
    insert into t5 values(1232983640223);
    
    # create table t6(id int(10) unsigned);
    # create table t7(id int(11));

(2) 嚴格模式補充
在上面設置了char,tinyint,存儲數據時超過它們的最大存儲長度,
發現數據也能正常存儲進去,只是mysql幫我們自動截取了最大長度。
但在實際情況下,我們應該盡量減少數據庫的操作,緩解數據庫的壓力,
讓它僅僅只管理數據即可,這樣的情況下就需要設置安全模式

    how variables like "%mode%";  # 查看數據庫配置中變量名包含mode的配置參數
    # 修改安全模式
    set session # 只在當前操作界面有效
    set global  # 全局有效

    set global sql_mode ='STRICT_TRANS_TABLES'
    # 修改完之後退出當前客戶端重新登陸即可
2.2 浮點型
分類:FLOAT DOUBLE decimal
應用場景:身高、體重、利率

字段限制特點: (5,3)前一位表示所有的位數,後一位表示小數個數

三者最大整數位和小數位對比: ----> 單寫一個測試博客
# 存儲限制
    float(255,30)  # 表示一共位數為255位,小數位為30位
    double(255,30)  # 表示一共位數為255位,小數位為30位
    decimal(255,30)  # 表示一共位數為65位,小數位為30位

# 精確度驗證
    create table t5(x float(255,30));
    create table t6(x double(255,30));
    create table t7(x decimal(65,30));

三者區別:
    精度不同:
        精度由低到高:float --> double --> decimal

代碼輸出結果:
(1) float
    mysql> create table t5 (x float(255, 30));
    Query OK, 0 rows affected (0.54 sec)
    
    mysql> insert into t5 values(1.111111111111111111111111111111);
    Query OK, 1 row affected (0.08 sec)
    
    mysql> select * from t5;
    +----------------------------------+
    | x                                |
    +----------------------------------+
    | 1.111111164093017600000000000000 |
    +----------------------------------+
    1 row in set (0.00 sec)

(2) double
    mysql> create table t6 (x double(255, 30));
    Query OK, 0 rows affected (0.32 sec)
    
    mysql>  insert into t6 values(1.111111111111111111111111111111);
    Query OK, 1 row affected (0.06 sec)
    
    mysql> select * from t6;
    +----------------------------------+
    | x                                |
    +----------------------------------+
    | 1.111111111111111200000000000000 |
    +----------------------------------+
    1 row in set (0.00 sec)

(3) decimal
    mysql> create table t7 (x decimal(65, 30));
    Query OK, 0 rows affected (0.30 sec)
    
    mysql>  insert into t7 values(1.111111111111111111111111111111);
    Query OK, 1 row affected (0.06 sec)
    
    mysql> select * from t7;
    +----------------------------------+
    | x                                |
    +----------------------------------+
    | 1.111111111111111111111111111111 |
    +----------------------------------+
    1 row in set (0.06 sec)
2.3 字符類型
(1)分類:
    char:定長
    varchar:變長
(2)作用:姓名、地址、描述類信息

    create table t8 (name char(4));  # 超過四個字符報錯,不夠四個字符空格補全
    create table t9 (name varchar(4));  # 超過四個字符報錯,不夠四個有幾個就存幾個

    # 驗證存儲限制
    insert into t8 values('hello');
    insert into t9 values('hello');

    # 驗證存儲長度
    insert into t8 values('a'); #'a    '
    insert into t9 values('a'); #'a'

    select * from t8
    select * from t9  # 無法查看真正的結果

    select char_length(name) from t8;
    select char_length(name) from t9;  # 仍然無法查看到真正的結果

    mysql> select char_length(name) from t8;
    +-------------------+
    | char_length(name) |
    +-------------------+
    |                 1 |
    +-------------------+
    1 row in set (0.37 sec)

    mysql> select char_length(name) from t9;
    +-------------------+
    | char_length(name) |
    +-------------------+
    |                 1 |
    +-------------------+
    1 row in set (0.00 sec)

(3) char 和 varchar 的優缺點:
    char:
    缺點:浪費空間
    優點:存取速度都快

    varchar:
    缺點:存儲速度慢
    優點:節省時間
2.4 時間類型
(1) 分類
    date: 2019-05-01
    time: 17:13:32
    datetime: 2019-05-01 17:13:32
    year:2019
(2) 測試
       create table student(
           id int,
           name char(16),
           yy year,
           birth date,
           study_time time,
           reg_time datetime
        );

    insert into student values(1,'lisi','2019','2019-05-13','17:17:32','2019-05-13 17:17:32');

    mysql> select * from student;
    +------+------+------+------------+------------+---------------------+
    | id   | name | yy   | birth      | study_time | reg_time            |
    +------+------+------+------------+------------+---------------------+
    |    1 | lisi | 2019 | 2019-05-13 | 17:17:32   | 2019-05-13 17:17:32 |
    +------+------+------+------------+------------+---------------------+
    1 row in set (0.00 sec)
2.5 枚舉與集合類型
(1)分類:
    枚舉enum多選一
    集合set多選多(可以多選一)

 (2)測試:
 (a)枚舉enum
    create table user(
        id int,
        name char(16),
        gender enum('male','female')
    );

    insert into user values(1, 'lisi','male');  # 正確
    # Query OK, 1 row affected (0.06 sec)

    insert into user values(2, 'zhangsan','xxx');  # 報錯
    # ERROR 1265 (01000): Data truncated for column 'gender' at row 1


  (b)集合set
    create table teacher(
        id int,
        name char(16),
        hobby set('read','music','sleep','run')
    );

    insert into teacher values(1, 'zhangsan','music,sleep');  # 正確
    # Query OK, 1 row affected (0.06 sec)

    insert into teacher values(2, 'lisi','sleep');  # 正確 集合可以只選一個
    # Query OK, 1 row affected (0.06 sec)

    insert into teacher values(3, 'wangwu','heihei');  # 報錯
    # ERROR 1265 (01000): Data truncated for column 'hobby' at row 1

三、約束條件

3.1 約束條件
PRIMARY KEY (PK)    標識該字段為該表的主鍵,可以唯一的標識記錄
FOREIGN KEY (FK)    標識該字段為該表的外鍵
NOT NULL    標識該字段不能為空
UNIQUE KEY (UK)    標識該字段的值是唯一的
AUTO_INCREMENT    標識該字段的值自動增長(整數類型,而且為主鍵)
DEFAULT    為該字段設置默認值

UNSIGNED 無符號
ZEROFILL 使用0填充
3.2 not null + default
(a)not null:
    create table user(
        id int,
        name char(16)
    );
    insert into user values(1,null)  # 可以修改
    # Query OK, 1 row affected (0.10 sec)

    alter table user modify name char(16) not null;
    # 報錯:
        ERROR 1138 (22004): Invalid use of NULL value
        查了一下,應該是由於表裏有數據,所以不可以改
        mysql> delete from user;
        Query OK, 1 row affected (0.10 sec)

    mysql> alter table user modify name char(16) not NULL;
    Query OK, 0 rows affected (0.42 sec)
    Records: 0  Duplicates: 0  Warnings: 0

    insert into user(name,id) values(null,2);  # 報錯 插入數據可以在表名後面指定插入數據對應的字段
    # ERROR 1048 (23000): Column 'name' cannot be null

(b) default:
    create table student(
        id int,
        name char(16) not null,
        gender enum('male','female','others') default 'male'
    );
    
    insert into student(id,name) values(1,'zhangsan')  # 成功
    # Query OK, 1 row affected (0.09 sec)
3.3 unique
(a) 單列唯一:某一項值為獨一無二的
    create table user1(
        id int unique,
        name char(16)
    );

    insert into user1 values(1,'lisi'),(1,'wawu');  # 報錯
    # ERROR 1062 (23000): Duplicate entry '1' for key 'id'

    insert into user1 values(1,'lisi'),(2,'wawu');  # 成功
    # Query OK, 2 rows affected (0.06 sec)
    # Records: 2  Duplicates: 0  Warnings: 0

(b) 聯合唯一:多項值,只要不全相同就ok
    create table server(
        id int,
        ip char(16),
        port int,
        unique (ip,port)
    );

    insert into server values(1,'127.0.0.1',8080);
    # Query OK, 1 row affected (0.06 sec)

    insert into server values(2,'127.0.0.1',8080); # 報錯
    # ERROR 1062 (23000): Duplicate entry '127.0.0.1-8080' for key 'ip'

    insert into server values(1,'127.0.0.1',8081);
    # Query OK, 1 row affected (0.06 sec)
3.4 primary key + auto_increment
(a) 單從約束角度來說 primary key <==> not null unique
    create table t10 (id int primary key);
    desc t10;

    +-------+---------+------+-----+---------+-------+
    | Field | Type    | Null | Key | Default | Extra |
    +-------+---------+------+-----+---------+-------+
    | id    | int(11) | NO   | PRI | NULL    |       |
    +-------+---------+------+-----+---------+-------+
    1 row in set (0.00 sec)

    insert into t10 values(1),(1);  # 報錯
    # ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
    insert into t10 values(1),(2);
    # Query OK, 2 rows affected (0.06 sec)
    # Records: 2  Duplicates: 0  Warnings: 0

# 除了約束之外,它還是innodb引擎組織數據的依據,提升查詢效率
(b) 強調:
    1.一張表中必須有且只有一個主鍵,如果你沒有設置主鍵,
    那麽會從上到下搜索直到遇到一個非空且唯一的字段自動將其設置為主鍵

    create table t11(
        id int,
        name char(16),
        age int not null unique,
        addr char(16) not null unique
    )engine=innodb;
    desc t11;

    mysql> desc t11;
    +-------+----------+------+-----+---------+-------+
    | Field | Type     | Null | Key | Default | Extra |
    +-------+----------+------+-----+---------+-------+
    | id    | int(11)  | YES  |     | NULL    |       |
    | name  | char(16) | YES  |     | NULL    |       |
    | age   | int(11)  | NO   | PRI | NULL    |       |
    | addr  | char(16) | NO   | UNI | NULL    |       |
    +-------+----------+------+-----+---------+-------+
    4 rows in set (0.01 sec)

    2.如果表裏面沒有指定任何的可以設置為主鍵的字段,那麽innodb會采用自己默認的一個隱藏字段作為主鍵,隱藏意味著你在查詢的時候無法根據這個主鍵字段加速查詢了
    索引:類似於書的目錄,沒有主鍵就相當於一頁一頁翻著查
    3.一張表中通常都應該有一個id字段,並且通常將改id字段作成主鍵

(c) 聯合主鍵:多個字段聯合起來作為表的一個主鍵,本質還是一個主鍵
    create table t12(
        ip char(16),
        port int,
        primary key(ip, port)
    );

    desc t12;

    mysql> desc t12;
    +-------+----------+------+-----+---------+-------+
    | Field | Type     | Null | Key | Default | Extra |
    +-------+----------+------+-----+---------+-------+
    | ip    | char(16) | NO   | PRI | NULL    |       |
    | port  | int(11)  | NO   | PRI | NULL    |       |
    +-------+----------+------+-----+---------+-------+
    2 rows in set (0.01 sec)

(d) 主鍵id作為數據的編號,每次最好能自動遞增
    create table t13(
        id int primary key auto_increment,
        name char(16)
    );
    insert into t13 name values ('jason','jason','jason');
    
    Query OK, 3 rows affected (0.36 sec)
    Records: 3  Duplicates: 0  Warnings: 0
    
    # id字段自動從1開始遞增
    # 註意:auto_increment通常都是加在主鍵上,並且只能給設置為key的字段加

mysql數據庫 --數據類型、約束條件