MySQL表約束的實現(xiàn)
前言
hello,各位小伙伴大家好,本章內(nèi)容為大家介紹關(guān)于MySQL約束的相關(guān)內(nèi)容,關(guān)于約束這個概念,如果是第一次接觸可能會有一點難以理解,不過也不用擔(dān)心,相信看完這篇文章對約束這個概念會有一個清晰的認(rèn)識。
1.什么是約束
在談MySQL表的約束之前,先舉一個生活中的例子,我們在學(xué)校中讀書,會受到學(xué)校中各種各樣規(guī)矩的約束,本質(zhì)上在學(xué)校制定許多的規(guī)矩是為了更好的管理學(xué)生,而在MySQL中也有許多的規(guī)矩,這些規(guī)矩是為了規(guī)范程序員在向數(shù)據(jù)庫插入數(shù)據(jù)的時候正確操作,體現(xiàn)為對程序員的一種約束,下面我們就具體來看看,建表的時候都有哪些約束。
2.空屬性
兩個值:null(默認(rèn)的) 和 not null(不為空)
數(shù)據(jù)庫默認(rèn)字段基本都是為空,但是在實際開發(fā)中,盡可能保證字段不為空,因為數(shù)據(jù)為空,沒辦法參與運算
mysql> select null; +------+ | NULL | +------+ | NULL | +------+ 1 row in set (0.00 sec) mysql> select 1+null; +--------+ | 1+null | +--------+ | NULL | +--------+ 1 row in set (0.00 sec)
案例:
創(chuàng)建一個班級表,包含班級名和班級所在的教室。
站在正常的業(yè)務(wù)邏輯中:
- 如果班級沒有名字,你不知道你在哪個班級
- 如果教室名字可以為空,就不知道在哪上課
所以我們在設(shè)計數(shù)據(jù)庫表的時候,一定要在表中進(jìn)行限制,班級名和教室名都不能為空,這就是“約束”。
//創(chuàng)建表 mysql> create table myclass( class_name varchar(20) not null, class_room varchar(20) not null); Query OK, 0 rows affected (0.03 sec) //表結(jié)構(gòu) mysql> desc myclass; +------------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +------------+-------------+------+-----+---------+-------+ | class_name | varchar(20) | NO | | NULL | | | class_room | varchar(20) | NO | | NULL | | +------------+-------------+------+-----+---------+-------+ 2 rows in set (0.00 sec) //正常插入數(shù)據(jù) mysql> insert into myclass values('通信211','4406'); Query OK, 1 row affected (0.00 sec) //給非空屬性字段不插入值報錯 mysql> insert into myclass (class_name) values('通信211'); ERROR 1364 (HY000): Field 'class_room' doesn't have a default value
總結(jié):在創(chuàng)建屬性字段的時候,默認(rèn)情況是null,可以為空,指定為not null,在插入數(shù)據(jù)的時候不能為空,必須有值,而必須有值,則體現(xiàn)為MySQL建表的一種約束
3.默認(rèn)值
默認(rèn)值:某一種數(shù)據(jù)會經(jīng)常性的出現(xiàn)某個具體的值,可以一開始就指定好,在需要真實數(shù)據(jù)的時候,用戶可以選擇性的使用默認(rèn)值。
//創(chuàng)建表 mysql> create table if not exists stu( -> name varchar(12) not null, -> age tinyint unsigned default 18, -> sex char(2) default '男' -> ); Query OK, 0 rows affected (0.03 sec) //表結(jié)構(gòu) mysql> desc stu; +-------+---------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+---------------------+------+-----+---------+-------+ | name | varchar(12) | NO | | NULL | | | age | tinyint(3) unsigned | YES | | 18 | | | sex | char(2) | YES | | 男 | | +-------+---------------------+------+-----+---------+-------+ 3 rows in set (0.00 sec) //全插入 mysql> insert into stu (name,age,sex) values ('張三','20','男'); Query OK, 1 row affected (0.00 sec) //按照默認(rèn)值進(jìn)行插入 mysql> insert into stu (name) values ('李四'); Query OK, 1 row affected (0.01 sec) //插入后的數(shù)據(jù) mysql> select* from stu; +--------+------+------+ | name | age | sex | +--------+------+------+ | 張三 | 20 | 男 | | 李四 | 18 | 男 | +--------+------+------+ 2 rows in set (0.00 sec)
設(shè)置了default的列,在插入數(shù)據(jù)的時候,可以對列進(jìn)行省略。
4.列描述
列描述:comment,沒有實際含義,專門用來描述字段,體現(xiàn)為一種軟性約束
//創(chuàng)建表,通過comment對每個字段進(jìn)行描述 mysql> create table if not exists t7( -> name varchar(20) not null comment "姓名", -> age int default 18 comment '年齡' -> ); Query OK, 0 rows affected (0.03 sec) //查看表結(jié)構(gòu) mysql> show create table t7\G; *************************** 1. row *************************** Table: t7 Create Table: CREATE TABLE `t7` ( `name` varchar(20) NOT NULL COMMENT '姓名', `age` int(11) DEFAULT '18' COMMENT '年齡' ) ENGINE=InnoDB DEFAULT CHARSET=utf8 1 row in set (0.00 sec)
5.zerofill
zerofill對數(shù)據(jù)進(jìn)行格式化顯示,如果寬度小于設(shè)定的寬度,自動填充0
mysql> create table if not exists t8( -> id int zerofill, -> name varchar(20) not null -> ); Query OK, 0 rows affected (0.04 sec) //插入數(shù)據(jù) mysql> insert into t8 values (1,'張三'); Query OK, 1 row affected (0.00 sec) mysql> insert into t8 values (2,'李四'); Query OK, 1 row affected (0.01 sec) //插入數(shù)據(jù)的時候?qū)挾刃∮谠O(shè)定的寬度用0填充。 mysql> select* from t8; +------------+--------+ | id | name | +------------+--------+ | 0000000001 | 張三 | | 0000000002 | 李四 | +------------+--------+ 2 rows in set (0.00 sec) //int類型數(shù)據(jù)寬度為10位 mysql> show create table t8\G; *************************** 1. row *************************** Table: t8 Create Table: CREATE TABLE `t8` ( `id` int(10) unsigned zerofill DEFAULT NULL, `name` varchar(20) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 1 row in set (0.00 sec)
注:自動填充0,這是最后顯示的結(jié)果,在MySQL中實際存儲的還是1和2。
作用:在一些對數(shù)據(jù)格式有要求的地方使用,使得數(shù)據(jù)更加規(guī)范。
6.主鍵
主鍵:primary key用來唯一約束該字段里面的數(shù)據(jù),不能重復(fù),不能為空,一張表最多只能有一個主鍵,主鍵所在的列通常是整數(shù)類型
案例:
給學(xué)生的id添加主鍵,用id唯一標(biāo)識一個學(xué)生
//創(chuàng)建表,指定id為主鍵 mysql> create table if not exists student( -> id int primary key comment '學(xué)號', -> name varchar(20) not null, -> age tinyint default 18 -> ); Query OK, 0 rows affected (0.04 sec) //插入數(shù)據(jù) mysql> insert into student values(1,'張三',20); Query OK, 1 row affected (0.01 sec) mysql> insert into student values(2,'張三',20); Query OK, 1 row affected (0.00 sec) //當(dāng)id值出現(xiàn)重復(fù)或者為空時不能向表中插入數(shù)據(jù) mysql> insert into student values(2,'張三',20); ERROR 1062 (23000): Duplicate entry '2' for key 'PRIMARY' mysql> insert into student values(1,'張三',20); ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY' mysql> insert into student (name,age)values('張三',20); ERROR 1364 (HY000): Field 'id' doesn't have a default value
當(dāng)表創(chuàng)建好以后但是沒有主鍵的時候,可以再次追加主鍵
alter table 表名 add primary key(字段列表);
刪除主鍵
alter table 表名 drop primary key;
復(fù)合主鍵
在創(chuàng)建表的時候,有多個屬性字段作為主鍵,這里的多個屬性字段作為主鍵不是說一張表中有多個主鍵,而是多個主鍵共同約束作為一個主鍵
案例:
創(chuàng)建一張表,該表中有多個屬性字段作為主鍵
mysql> create table if not exists t9( -> id int unsigned, -> course char(10) comment '課程代碼', -> score tinyint default 60 comment '成績', -> primary key(id,score) --id和score共同作為復(fù)合主鍵 -> ); Query OK, 0 rows affected (0.03 sec) mysql> desc t9; +--------+------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------+------------------+------+-----+---------+-------+ | id | int(10) unsigned | NO | PRI | NULL | | | course | char(10) | YES | | NULL | | | score | tinyint(4) | NO | PRI | 60 | | +--------+------------------+------+-----+---------+-------+ 3 rows in set (0.00 sec) mysql> insert into t9 values(1,'數(shù)學(xué)',65); Query OK, 1 row affected (0.00 sec) mysql> insert into t9 values(2,'數(shù)學(xué)',65); Query OK, 1 row affected (0.00 sec) mysql> insert into t9 values(2,'數(shù)學(xué)',65); ERROR 1062 (23000): Duplicate entry '2-65' for key 'PRIMARY' --主鍵沖突
7.自增長
auto_increment:當(dāng)對應(yīng)的字段不給值,會自動的被系統(tǒng)觸發(fā),系統(tǒng)從當(dāng)前字段中已經(jīng)有的最大值+1操作,得到一個新的不同的值。通常和主鍵搭配使用,作為邏輯主鍵
自增長的特點:
任何一個字段要做自增長,前提本身是一個索引;
自增長字段必須是整數(shù);
一張表最多只能有一個自增長
案例:
mysql> system clear; mysql> create table if not exists t10( -> id int unsigned primary key auto_increment, -> name varchar(20) not null -> ); Query OK, 0 rows affected (0.03 sec) mysql> insert into t10 (name) values('張三'); Query OK, 1 row affected (0.01 sec) mysql> insert into t10 (name) values('李四'); Query OK, 1 row affected (0.01 sec) //默認(rèn)從1開始自增長 mysql> select* from t10; +----+--------+ | id | name | +----+--------+ | 1 | 張三 | | 2 | 李四 | +----+--------+ 2 rows in set (0.00 sec)
自增長實現(xiàn)的原理:
獲取上次插入的auto_increment的值
mysql> select last_insert_id(); +------------------+ | last_insert_id() | +------------------+ | 2 | +------------------+ 1 row in set (0.00 sec)
8.唯一鍵
一張表中往往有很多字段需要唯一性,數(shù)據(jù)不能重復(fù),但是一張表中只能有一個主鍵,而唯一鍵的存在可以解決表中有很多字段需要唯一性約束的問題。
唯一鍵和主鍵不同在于,唯一鍵允許為空,而主鍵不允許為空。另外主鍵更多的是標(biāo)識唯一性的,而唯一鍵更多是保證在業(yè)務(wù)上,不要和別的信息產(chǎn)生沖突。
mysql> create table if not exists t11( -> id tinyint primary key, -> name varchar(20) not null, -> class_name varchar(20) unique comment '班級名,不能為空' -> ); Query OK, 0 rows affected (0.03 sec) //唯一鍵約束不能重復(fù) mysql> insert into t11 values (1,'zhangsan','A'); Query OK, 1 row affected (0.00 sec) mysql> insert into t11 values (2,'zhangsan','A'); ERROR 1062 (23000): Duplicate entry 'A' for key 'class_name' //可以為空 mysql> insert into t11 (id,name) values (2,'zhangsan'); Query OK, 1 row affected (0.00 sec) mysql> select* from t11; +----+----------+------------+ | id | name | class_name | +----+----------+------------+ | 1 | zhangsan | A | | 2 | zhangsan | NULL | +----+----------+------------+ 2 rows in set (0.00 sec)
9.外鍵
MySQL是關(guān)系型數(shù)據(jù)庫,一般表跟表之間是有關(guān)聯(lián)關(guān)系的,舉個簡單的例子,有兩張表,一張表是班級表,另一張是學(xué)生表,因為學(xué)生是屬于班級的,所以一般將班級表稱為是主表,而學(xué)生表稱為是從表。
外鍵就是用于定義主表和從表之間的關(guān)系:外鍵約束主要定義在從表上,主表則必須是主鍵約束或者是唯一鍵約束。當(dāng)定義外鍵之后,要求外鍵列數(shù)據(jù)必須在主表的主鍵列存在或為null。
語法:
foreign key 字段名 references 主表(列)
案例:
a.創(chuàng)建主表:
mysql> create table if not exists myclass( -> id int primary key, -> name varchar(20) not null comment '班級名' -> ); Query OK, 0 rows affected (0.03 sec)
b.創(chuàng)建從表:
mysql> create table if not exists stu( -> id int primary key, -> name varchar(20) not null comment '學(xué)生名', -> class_id int, -> foreign key (class_id) references myclass(id) -> ); Query OK, 0 rows affected (0.06 sec)
c.正常插入數(shù)據(jù):
mysql> insert into myclass values (10,'C++大牛班'),(20,'java大神班'); Query OK, 2 rows affected (0.01 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> insert into stu values (100,'張三',10); Query OK, 1 row affected (0.01 sec) mysql> insert into stu values (200,'李四',20); Query OK, 1 row affected (0.01 sec) mysql> insert into stu values (300,'王五',null); Query OK, 1 row affected (0.01 sec)
d.插入一個班級號為30的同學(xué),因為沒有這個班級,所以插入不成功
mysql> insert into stu values (400,'趙六',30);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`test`.`stu`, CONSTRAINT `stu_ibfk_1` FOREIGN KEY (`class_id`) REFERENCES `myclass` (`id`))
e.數(shù)據(jù)顯示
mysql> select* from stu; +-----+--------+----------+ | id | name | class_id | +-----+--------+----------+ | 100 | 張三 | 10 | | 200 | 李四 | 20 | | 300 | 王五 | NULL | +-----+--------+----------+ 3 rows in set (0.00 sec) mysql> select* from myclass; +----+---------------+ | id | name | +----+---------------+ | 10 | C++大牛班 | | 20 | java大神班 | +----+---------------+ 2 rows in set (0.00 sec)
總結(jié)
本篇文章為大家介紹了MySQL中約束相關(guān)的話題,總結(jié)為一句話,約束是在建表的時候進(jìn)行的,目的是為了防止在后續(xù)數(shù)據(jù)插入的時候出現(xiàn)不合法的數(shù)據(jù),實現(xiàn)這個目的方法就是上面介紹的這些規(guī)則,相信掌握了這些規(guī)則之后,對數(shù)據(jù)庫的操作又有了一個不小的提升。
到此這篇關(guān)于MySQL表約束的實現(xiàn)的文章就介紹到這了,更多相關(guān)MySQL表約束內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MySQL生產(chǎn)環(huán)境CPU使用率過高的排查與解決方案
在生產(chǎn)環(huán)境中,MySQL作為一個關(guān)鍵的數(shù)據(jù)庫組件,其性能對整個系統(tǒng)的穩(wěn)定性至關(guān)重要,有時候我們可能會遇到MySQL CPU使用率過高的問題,本文將詳細(xì)介紹如何排查和解決MySQL CPU過高的問題,幫助您迅速恢復(fù)正常的數(shù)據(jù)庫性能,需要的朋友可以參考下2024-03-03windows系統(tǒng)mysql5.7.18安裝圖文教程
這篇文章主要為大家詳細(xì)介紹了windows系統(tǒng)下mysql5.7.18安裝圖文教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-03-03MySQL的時間差函數(shù)(TIMESTAMPDIFF、DATEDIFF)、日期轉(zhuǎn)換計算函數(shù)(date_add、day、da
這篇文章主要介紹了MySQL的時間差函數(shù)(TIMESTAMPDIFF、DATEDIFF)、日期轉(zhuǎn)換計算函數(shù)(date_add、day、date_format、str_to_date),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12MySQL數(shù)據(jù)庫表修復(fù) MyISAM
這篇文章主要介紹了MySQL數(shù)據(jù)庫表修復(fù) MyISAM ,需要的朋友可以參考下2014-06-06mysql優(yōu)化取隨機數(shù)據(jù)慢的方法
mysql取隨機數(shù)據(jù)慢,怎么辦?下面小編與大家一起來看看mysql取隨機數(shù)據(jù)慢優(yōu)化的過程。2013-11-11