MySQL 汤神 02
update 表名 set 列名= 值 where 条件/order by/ limit;
delete from 表名 条件
NOT NULL :表示某列不能存储空值
UNIQUE:这一列数据不能出现重复
DEFAULT:规定默认值
PRIMARY KEY 主键:表示一条记录的身份标识,NOT NULL 和 UNIQUE的结合,确保某列有唯一标识,有助于更容易更快捷地找到表里的一个特定的记录
FOREIGN KEY 外键:描述的是两个表的关联关系
CHECK: 指定一个具体的条件
eg:create table student(id int is not null,name varchar(20));
一个表只能有一个主键,一般是用xxx id 这样的列作为主键
eg:create table student(id int primary key,name varchar(20));
注:除了基础的使用之外,还有联合主键的情况,只有一个主键,但是这个主键是由多个列联合构成的
主键含有 not null 和 unique 属性 非空&唯一
主键不允许重复,怎么样保证主键不重复呢?
mysql提供了自增主键的机制
(自增主键一定是整数类型)
create table student(id int primary key auto_increment,name varchar(20));
当前这个id不需要用户自己指定,让数据库自行进行分配
数据库会按照自增的方式来分配
这里的id 程序员手动写入也是ok 的
每次使用null方式插入自增主键的时候,会更具这一列的最大值继续进行递增,而且这里的递增是不会重复利用之前的值(比如将之前的101删掉,下一个出来的也是102)
上述自增主键,只能在单个数据库下生效
如果数据库是由多个mysql服务器构成的集群时,自增主键就无法生效了
生成的思路:
一个分布式系统中存在唯一的id
- 把主键设置成字符串 类型
- 引入时间戳(ms,us)时间戳确保了不同时刻产生的id是不同的
- 主机编号:同一时间生成的多个数据,只要这几个数据实在不同的主机上,仍然可以通过主机编号确保不重复的
- 同一时刻,同一主机出现多个数据,我们使用随机因子进行区分
- 随机因子(随机数)也不太会出现重复的情况了
--->时间戳+主机编号+随机因子
not null
unique
default
primary key
forign key 外键
加入有一个class表和一个student表
class(classId,name)
student(id ,name,classId)
这时候我希望学生的classId可以和班级对应
将班级的classId设置为主键,学生的classId设置为
foreign key(classId) references class (classId)
相当于引用外表的数据
注:外键约束的写在最后面的
需要指定好三个数据,哪个列引用哪个表的哪一列
此时要求本表的这个列的数据必须在引用表的对应列存在
此时称班级表位父表(约束别人的表),学生表称之为子表(被约束的表)
新增记录就会在父表中先查询,不存在就会报错
使用外键约束的时候,操作子表也会查询父表,操作父表,也要查询子表(伴随很多查询操作)
为了让上述查询更高效,要求子表中的列和父表中被引用的列都得带有索引
当表里有主键之后,就会自动增加索引,才能被子表引用
子表也会因为外键自动增加索引
关于外键,还有一个典型的问题:
比如做一个电商网站
商品表(goodsId,name,price...)
订单表(orderId,goosId,time....)
订单表中的goodsId需要引用自商品表
订单里的商品得是一个有效物品
当引用外界操作,商品为1的商品要下架,这得如何完成操作呢?
历史订单数据时始终存在的,商品可以没了,但是订单不能没
这种场景如何实现?
即:使用外键的前提下,如何在删除商品表的数据不影响订单表???
给一个isOnline 为1就是上线为0就是下线
用户在查询商品列表就可以通过商品列表 isOnline = 0限制确保不会把下线的数据查询出去 (万一还再上线呢)
只是逻辑删除,不就造成硬盘空间的浪费吗???
浪费就浪费,不值钱
删除文件+清空回收站都是没用的 (理论上都是可以恢复数据的)
check后面跟上一个条件,在插入和修改数据的时候,带入条件进行检查
(但是mysql不支持这个操作,因为实际上并没有真正生效)
数据库设计:
1.根据需求找到实体,再梳理清楚实体之间的关系(实体:一些关键性质的对象) 梳理清楚需求,提取出关键的名词
一般来说每个实体都得安排一个表,不同的关系喜爱,有不同的设计表的方式.
2.四种关系 : 一对一 一对多 多对多 两个实体毫不相干
一对一
教务系统,需要表示一个概念,学生,搞一个学生表来描述这个实体 学号,姓名,班级,联系时间,入学时间.........
还有一个概念账户表 账户名,密码,注册时间,上次登录时间
一个时间有一个账户,也只能有一个学生使用
方案1:搞一个大表,把这些信息都放在一起
学生账户表(账户id,账户名,密码.......) 如果这两个表都很简单,就可以考虑合并
如果这两个表都很复杂,不建议合并
方案2:分两个表,使用id引用过来,建立联系
student(studentId,studentName.. accountId)
account(accountId,username,password) 更多用,假如有一个老师,这样更方便
2.一对多
教务系统有一个实体,学生还有一个实体,班级
一个班级可以有多个学生
一个学生,只能从属于一个班级
针对一对多也存在两种方案
方案1:
student(studentId,name)
1 张三
2 李四
class(classId,name,studentList)
1 java100 1,2,3 由于MySQL类型中不支持数组这样的类型,所以这个方案行不通
方案2
class (classId,name)
student(studentId,name,classId)
多对多的情况
核心都是造句
student(studentId,name)
course(courseId,name)
引入一个关联表
student-course(studentId,courseId)
1 100
1 101