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ù)為空,沒辦法參與運(yùn)算
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數(shù)據(jù)庫命令行分號不能結(jié)束語句的問題
這篇文章主要介紹了解決MYSQL數(shù)據(jù)庫命令行分號不能結(jié)束語句的問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01
MySQL 數(shù)據(jù)庫基礎(chǔ)入門從概念到實戰(zhàn)
本文覆蓋了MySQL的核心基礎(chǔ):從數(shù)據(jù)庫概念、主流數(shù)據(jù)庫對比,到 MySQL的安裝連接、實戰(zhàn)操作和架構(gòu)解析,適合零基礎(chǔ)初學(xué)者快速入門,感興趣的朋友跟隨小編一起看看吧2026-03-03
MySQL單表百萬數(shù)據(jù)記錄分頁性能優(yōu)化技巧
自己的一個網(wǎng)站,由于單表的數(shù)據(jù)記錄高達(dá)了一百萬條,造成數(shù)據(jù)訪問很慢,Google分析的后臺經(jīng)常報告超時,尤其是頁碼大的頁面更是慢的不行2016-08-08
MySQL創(chuàng)建數(shù)據(jù)庫的兩種方法
這篇文章主要為大家詳細(xì)介紹了MySQL創(chuàng)建數(shù)據(jù)庫的兩種方法,感興趣的小伙伴們可以參考一下2016-05-05

