目录
约束
- not null
- default
- unique
- 单例唯一约束
- 多列唯一约束
- not null + unique :主键
- auto_increment
- auto_increment_increment : 步长 and 起始偏移量:auto_increment_offset
- primary key
-单列做主键
- 多列做主键(复合主键)
- foreign key
- 多表关系
除了数据类型外额外添加的约束,以保证数据的合法性和完整性。
分类:
- not null :非空约束,即数据不能为空
- default:默认值约束,即可指定字段的默认值
- unique:唯一性约束,即该字段的值不可重复。例:身份证号
- zerfill :使用0进行填充
- unsigned :无符号
- auto_increment :自动增长,通常搭配主键字段使用。
- primary key:主键约束,用于唯一标识表中一条数据。
- foreign key:外键约束,用于多表之间建立联系。
定义:非空约束,即数据不能为空
create table student (id ind,name char(10) not null);
定义:默认值约束,即可指定字段的默认值
create table user (id ind,name char(10) not null,sex char(1) default "woman");
定义:唯一性约束,即该字段的值不可重复。例:身份证号
- 1.unique本质是一种索引,是一种数据结构,用于提高查询效率。
- 2.可以为空。
- 3.一张表中可以存有多个唯一约束。
- 单例唯一约束
'''方法一''' create table department1( id int, name varchar(20) unique, comment varchar(100) ); '''方法二''' create table department2( id int, name varchar(20), comment varchar(100), constraint uk_name unique(name) );
- 多列唯一约束
create table t6 ( idcard char(18), phonenumber char(11), unique(idcard,phonenumber) ); # 联合唯一 ''' 即:身份证相同 并且 手机号相同(与运算) 则判断重复'''
- not null + unique :主键
mysql> create table t1(id int not null unique); Query OK, 0 rows affected (0.02 sec) mysql> desc t1; +-------+---------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+---------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | +-------+---------+------+-----+---------+-------+ 1 row in set (0.00 sec)
定义:自动增长,通常搭配主键字段使用,只能用于整形。
'''不指定id,则自动增长''' create table student( id int primary key auto_increment, name varchar(20), sex enum('male','female') default 'male' ); mysql> desc student; +-------+-----------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+-----------------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(20) | YES | | NULL | | | sex | enum('male','female') | YES | | male | | +-------+-----------------------+------+-----+---------+----------------+ mysql> insert into student(name) values -> ('name1'), -> ('name2') -> ; mysql> select * from student; +----+-------+------+ | id | name | sex | +----+-------+------+ | 1 | name1 | male | | 2 | name2 | male | +----+-------+------+ '''手动指定相应id''' mysql> insert into student values(4,'111','female'); Query OK, 1 row affected (0.00 sec) mysql> insert into student values(7,'222','female'); Query OK, 1 row affected (0.00 sec) mysql> select * from student; +----+-------+--------+ | id | name | sex | +----+-------+--------+ | 1 | name1 | male | | 2 | name2 | male | | 4 | 111 | female | | 7 | 222 | female | +----+-------+--------+ '''对于自增的字段,在用delete删除后,再插入值,该字段仍按照删除前的位置继续增长''' mysql> delete from student; Query OK, 4 rows affected (0.00 sec) mysql> select * from student; Empty set (0.00 sec) mysql> insert into student(name) values('111'); mysql> select * from student; +----+------+------+ | id | name | sex | +----+------+------+ | 8 | 111 | male | +----+------+------+ ''' 应该用truncate清空表,比起delete一条一条地删除记录 truncate是直接清空表,在删除大表时用它 ''' mysql> truncate student; Query OK, 0 rows affected (0.01 sec) mysql> insert into student(name) values('name'); Query OK, 1 row affected (0.01 sec) mysql> select * from student; +----+------+------+ | id | name | sex | +----+------+------+ | 1 | name | male | +----+------+------+ 1 row in set (0.00 sec)
- auto_increment_increment : 步长 and 起始偏移量:auto_increment_offset
#在创建完表后,修改自增字段的起始值 mysql> create table student( -> id int primary key auto_increment, -> name varchar(20), -> sex enum('male','female') default 'male' -> ); mysql> alter table student auto_increment=3; mysql> show create table student; ....... ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 mysql> insert into student(name) values('name'); Query OK, 1 row affected (0.01 sec) mysql> select * from student; +----+------+------+ | id | name | sex | +----+------+------+ | 3 | name | male | +----+------+------+ row in set (0.00 sec) mysql> show create table student; ....... ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 #也可以创建表时指定auto_increment的初始值,注意初始值的设置为表选项,应该放到括号外 create table student( id int primary key auto_increment, name varchar(20), sex enum('male','female') default 'male' )auto_increment=3; #设置步长 sqlserver:自增步长 基于表级别 create table t1( id int。。。 )engine=innodb,auto_increment=2 步长=2 default charset=utf8 mysql自增的步长: show session variables like 'auto_inc%'; #基于会话级别 set session auth_increment_increment=2 #修改会话级别的步长 #基于全局级别的 set global auth_increment_increment=2 #修改全局级别的步长(所有会话都生效) #!!!注意了注意了注意了!!! If the value of auto_increment_offset is greater than that of auto_increment_increment, the value of auto_increment_offset is ignored. 翻译:如果auto_increment_offset的值大于auto_increment_increment的值,则auto_increment_offset的值会被忽略 ,这相当于第一步步子就迈大了,扯着了蛋 比如:设置auto_increment_offset=3,auto_increment_increment=2 mysql> set global auto_increment_increment=5; Query OK, 0 rows affected (0.00 sec) mysql> set global auto_increment_offset=3; Query OK, 0 rows affected (0.00 sec) mysql> show variables like 'auto_incre%'; #需要退出重新登录 +--------------------------+-------+ | Variable_name | Value | +--------------------------+-------+ | auto_increment_increment | 1 | | auto_increment_offset | 1 | +--------------------------+-------+ create table student( id int primary key auto_increment, name varchar(20), sex enum('male','female') default 'male' ); mysql> insert into student(name) values('name1'),('name2'),('name3'); mysql> select * from student; +----+-------+------+ | id | name | sex | +----+-------+------+ | 3 | name1 | male | | 8 | name2 | male | | 13 | name3 | male | +----+-------+------+
约束角度看,主键字段的值不为空且唯一。但主键主要是innodb存储引擎组织数据的依据。
一张表中必须有且只有一个主键。
-单列做主键
============单列做主键=============== '''方法一:not null+unique''' create table department1( id int not null unique, #主键 name varchar(20) not null unique, comment varchar(100) ); mysql> desc department1; +---------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+--------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | name | varchar(20) | NO | UNI | NULL | | | comment | varchar(100) | YES | | NULL | | +---------+--------------+------+-----+---------+-------+ rows in set (0.01 sec) '''方法二:在某一个字段后用primary key''' create table department2( id int primary key, #主键 name varchar(20), comment varchar(100) ); mysql> desc department2; +---------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+--------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | name | varchar(20) | YES | | NULL | | | comment | varchar(100) | YES | | NULL | | +---------+--------------+------+-----+---------+-------+ rows in set (0.00 sec) '''方法三:在所有字段后单独定义primary key''' create table department3( id int, name varchar(20), comment varchar(100), constraint pk_name primary key(id); #创建主键并为其命名pk_name mysql> desc department3; +---------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+--------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | name | varchar(20) | YES | | NULL | | | comment | varchar(100) | YES | | NULL | | +---------+--------------+------+-----+---------+-------+ rows in set (0.01 sec)
- 多列做主键(复合主键)
复合主键 :表的主键含有一个以上的字段组成
比如
create table test
(
name varchar(19),
id number,
value varchar(10),
primary key (name,id)
)
上面的name和id字段组合起来,就是表的复合主键
因为name字段可能会出现重名,所以要加上ID字段这样就可以保证记录的唯一性
一般情况下,主键的字段长度和字段数目要越少越好==================多列做主键================ create table service( ip varchar(15), port char(5), service_name varchar(10) not null, primary key(ip,port) ); mysql> desc service; +--------------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------------+-------------+------+-----+---------+-------+ | ip | varchar(15) | NO | PRI | NULL | | | port | char(5) | NO | PRI | NULL | | | service_name | varchar(10) | NO | | NULL | | +--------------+-------------+------+-----+---------+-------+ 3 rows in set (0.00 sec) mysql> insert into service values -> ('172.16.45.10','3306','mysqld'), -> ('172.16.45.11','3306','mariadb') -> ; Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> insert into service values ('172.16.45.10','3306','nginx'); ERROR 1062 (23000): Duplicate entry '172.16.45.10-3306' for key 'PRIMARY'
定义:外键约束,用于多表之间建立联系。
- 多表关系
- 一对一:表A的一条记录唯一对应表B的一条记录,反之亦然。
例:一个人对应一个身份证,一个身份证代表一个人。
foreign key(A字段) references B(id) # A字段和外键的字段一定要保证unique#一定是student来foreign key表customer,这样就保证了: #1 学生一定是一个客户, #2 客户不一定是学生,但有可能成为一个学生 create table customer( id int primary key auto_increment, name varchar(20) not null, qq varchar(10) not null, phone char(16) not null ); create table student( id int primary key auto_increment, class_name varchar(20) not null, customer_id int unique, #该字段一定要是唯一的 foreign key(customer_id) references customer(id) #外键的字段一定要保证unique on delete cascade on update cascade ); '''增加客户''' insert into customer(name,qq,phone) values ('李飞机','31811231',13811341220), ('王大炮','123123123',15213146809), ('守榴弹','283818181',1867141331), ('吴坦克','283818181',1851143312), ('赢火箭','888818181',1861243314), ('战地雷','112312312',18811431230) ; '''增加学生''' insert into student(class_name,customer_id) values ('3班',3), ('1期',4), ('2期',5) ;
2.一对多(多对一):表A中的多条数据对应表B中的一条数据,则A的外键是B字段。
例:一个出版社出版多本不同的书。=====================多对一===================== create table press( id int primary key auto_increment, name varchar(20) ); create table book( id int primary key auto_increment, name varchar(20), press_id int not null, foreign key(press_id) references press(id) on delete cascade on update cascade ); insert into press(name) values ('北京工业地雷出版社'), ('人民音乐不好听出版社'), ('知识产权没有用出版社') ; insert into book(name,press_id) values ('九阳神功',1), ('九阴真经',2), ('九阴白骨爪',2), ('独孤九剑',3), ('降龙十巴掌',2), ('葵花宝典',3) ;
3.多对多:表A的多条信息对应表B的一条信息,且,表B的多条信息对应表A的一条信息。
例如:一个作者可以写多本书,一本书可以有多个作者。
注:解决多对多需求方法:建立一个中间表,分别外键联系AB表,将两边主键序号一一对应。=====================多对多===================== create table author( id int primary key auto_increment, name varchar(20) ); #这张表就存放作者表与书表的关系,即查询二者的关系查这表就可以了 create table author2book( id int not null unique auto_increment, author_id int not null, book_id int not null, constraint fk_author foreign key(author_id) references author(id) on delete cascade on update cascade, constraint fk_book foreign key(book_id) references book(id) on delete cascade on update cascade, primary key(author_id,book_id) ); #插入四个作者,id依次排开 insert into author(name) values('author1'),('author2'),('author3'),('author4'); #每个作者与自己的代表作如下 1 author1: 1 九阳神功 2 九阴真经 3 九阴白骨爪 4 独孤九剑 5 降龙十巴掌 6 葵花宝典 2 author2: 1 九阳神功 6 葵花宝典 3 author3: 4 独孤九剑 5 降龙十巴掌 6 葵花宝典 4 author4: 1 九阳神功 insert into author2book(author_id,book_id) values (1,1), (1,2), (1,3), (1,4), (1,5), (1,6), (2,1), (2,6), (3,4), (3,5), (3,6), (4,1) ;