对表中的数据进行限制,保证数据的正确性、有效性和完整性。一个表如果添加了约束,不正确的数据将无法插入到表中。约束在创建表的时候添加比较合适。
约束名 | 约束关键字 |
---|---|
主键 | primarily key |
外键 | foreign key |
非空 | not null |
唯一 | unique |
检查 | check(MySQL不支持) |
用来唯一标识数据库中的每一条记录。
通常不用业务字段作为主键,单独给每张表设计一个 id 的字段,把 id 作为主键。主键是给数据库和程序使用的,不是给最终的客户使用的。所以主键有没有含义没有关系,只要不重复,非空就行。
如:身份证,学号不建议做成主键。自动生成的无意义的ID号码则可以用来作为主键。
字段名 字段类型 PRIMARY KEY
ALTER TABLE 表名 ADD PRIMARY KEY(字段名);
-- 创建表学生表 st5, 包含字段(id, name, age)将 id 做为主键 create table st5 ( id int primary key, -- id 为主键 name varchar(20), age int ); desc st5;
-- 删除 st5 表的主键 alter table st5 drop primary key; -- 添加主键 alter table st5 add primary key(id);
主键如果让我们自己添加很有可能重复,我们通常希望在每次插入新记录时,数据库自动生成主键字段的值。
AUTO_INCREMENT 表示自动增长(字段类型必须是整数类型)
-- 插入数据 insert into st6 (name, age) values ('⼩乔', 18); insert into st6 (name, age) values ('大乔', 20); -- 另一种写法 insert into st6 values(null, '周瑜', 35); select * from st6;
DELETE 和 TRUNCATE 对自增长的影响:
唯一约束:表中某一列不能出现重复的值。
字段名 字段类型 UNIQUE
实现唯一约束:
-- 创建学生表 st7, 包含字段(id, name),name 这一列设置唯一约束, 不能出现同名的学 生 create table st7 ( id int, name varchar(20) unique ); -- 添加一个同名的学生 insert into st7 values (1, '张三'); select * from st7; -- Duplicate entry '张三' for key 'name' insert into st7 values (2, '张三'); -- 重复插入多个 null 会怎样? insert into st7 values (2, null); insert into st7 values (3, null); # null 没有数据,不存在重复的问题
非空约束:某一列不能为null。
字段名 字段类型 NOT NULL
-- 创建表学生表 st8, 包含字段(id, name, gender)其中 name 不能为 NULL create table st8 ( id int, name varchar(20) not null, gender char(1) ); -- 添加一条记录其中姓名不赋值 insert into st8 values (1, '张三', '男'); select * from st8; -- Column 'name' cannot be null insert into st8 values (2, null, '男');
字段名 字段类型 DEFAULT 默认值
-- 创建一个学生表 st9, 包含字段(id, name, address), 地址默认值是⼴州 create table st9 ( id int, name varchar(20), address varchar(20) default '⼴州' ); -- 添加一条记录, 使用默认地址 insert into st9 values (1, '李四', default); select * from st9; insert into st9 (id, name) values (2, '李⽩'); -- 添加一条记录,不使用默认地址 insert into st9 values (3, '李四光', '深圳');
新建表时增加外键:
FOREIGN KEY(外键字段名) REFERENCES 主表名(主键 字段名)
已有表增加外键:
ALTER TABLE 从表 ADD FOREIGN KEY (外键字段名) REFERENCES 主表(主键字段名);
-- 创建从表employee并添加外键约束 -- 多方,从表 create table employee( id int primary key auto_increment, name varchar(20), age int, dep_id int, -- 外键对应主表的主键 -- 创建外键约束 foreign key (dep_id) references department(id) );
ALTER TABLE 从表 drop foreign key 外键名称;
具体操作:
-- 删除 employee 表的 emp_depid_fk 外键 alter table employee drop foreign key emp_depid_fk; -- 在 employee 表情存在的情况下添加外键 alter table employee add constraint emp_depid_fk foreign key (dep_id) references department(id);
在实际的开发过程中,一个业务操作,如:转账,往往是要多次访问数据库才能完成的。转账是一个用户扣钱,另一个用户加钱。如果其中有一条 SQL 语句出现异常,这条 SQL 就可能执行失败。
事务执行是一个整体,所有的 SQL 语句都必须执行成功。如果其中有 1 条SQL 语句出现异常,则所有的 SQL 语句都要回滚,整个业务执行失败。
MySQL 中可以有两种方式进行事务的操作:
手动提交事务的 SQL 语句
功能 | SQL语句 |
---|---|
开启事务 | start transaction; |
提交事务 | commit; |
回滚事务 | rollback; |
手动提交事务使用过程
事务特性 | 含义 |
---|---|
原⼦性 (Atomicity) | 每个事务都是一个整体,不可再拆分,事务中所有的 SQL 语句要么都执行成功, 要么都失败。 |
一致性 (Consistency) | 事务在执行前数据库的状态与执行后数据库的状态保持一致。如:转账前 2 个人的总金额是 2000,转账后 2 个人总金额也是 2000 |
隔离性 (Isolation) | 事务与事务之间不应该相互影响,执行时保持隔离的状态。 |
持久性 (Durability) | 一旦事务执行成功,对数据库的修改是持久的。就算关机,也是保存下来的。 |
事务在操作时的理想状态:所有的事务之间保持隔离,互不影响。因为并发操作,多个用户同时访问同一个数据。可能引发并发访问的问题:
并发访问的问题 | 含义 |
---|---|
脏读 | 一个事务读取到了另一个事务中尚未提交的数据 |
不可重复读 | 一个事务中两次读取的数据内容不一致,要求的是一个事务中多次读取时数据是一致的,这是事务 update 时引发的问题 |
幻读 | 一个事务中两次读取的数据的数量不一致,要求在一个事务多次读取的数据的数量是一致的,这是 insert 或 delete 时引发的问题 |
数据库有四种隔离级别,上面的级别最低,下面的级别最高。“是”表示会出现这种问题,“否”表示不会出现这种问题。
级别 | 名字 | 隔离等级 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|---|---|
1 | 读未提交 | read uncommitted | 是 | 是 | 是 |
2 | 读未提交 | read committed | 否 | 是 | 是 |
3 | 可重复读 | repeatable read | 否 | 否 | 是 |
4 | 串行化 | serializable | 否 | 否 | 否 |
隔离级别越高,性能越差,安全性越高。