概念
数据库:database(DB),是一种存储数据的仓库
概念
数据库分类:根据数据库的架构和数据组织原理进行分类
1、早期根据数据库的组织数据的存储模型分类
2、现在较多根据实际数据管理模型分类(存储介质)
概念
关系型数据库:是一种建立在关系模型上的数据库
概念
非关系型数据库:NoSQL(Not only SQL),不仅仅是关系型数据库
对比
NoSQL通常是与关系型数据库配合使用的,他们彼此是一种互补关系
小结
1、NoSQL是对非关系型数据库的一类统称
2、NoSQL通常运行在内存
3、NoSQL通常是键值对存储数据,访问也比较简单
概念
SQL:Structured Query Language,结构化查询语言,是一种针对关系型数据库特殊标准化的编程语言
SQL是一种编程语言
能够实现用户数据库查询和程序设计
SQL根据操作不同,分为几类
小结
1、SQL虽然是编程语言,但是目前数据库通常只用来进行数据管理(逻辑部分给其他编程语言)
2、SQL虽然是针对关系型数据库的通用语言,但是不同的产品操作指令不完全通用
概念
MySQL:是瑞典AB公司下的一款关系型数据库
访问原理
小结
1、MySQL是一款流行的关系型数据库
2、MySQL是一款C/S结构的软件,需要客户端访问服务端
3、MySQL是基于SQL指令进行管理操作
概念
MySQL访问:就是客户端连接上服务端,然后实现数据操作的过程
客户端访问服务端
客户端需要连接认证
客户端连接上服务端就表示占用了一个资源,可以进行对应权限的操作
客户端退出服务端(命令窗口输入指令)
注意 ,要配置环境变量
步骤
1、打开客户端(CMD控制台):mysql.exe
2、输入服务器信息(连接)和用户信息(验证)
3、执行SQL操作
4、断开连接
示例
mysql -hlocalhost -P3306 -uroot -proot
我们也可以使用简化版本的访问(省略 -h 和 -P,因为在本机)
mysql -uroot -proot
我们推荐使用控制台密文密码连接认证(安全)
mysql -uroot -p
root
小结
1、MySQL需要通过客户端来进行服务端访问
2、数据库操作需要进行连接认证
3、数据库连接资源有限,用完即关闭
1、数据库的作用要清楚:高效的存储和管理数据,为编程语言提供数据支撑
2、当前市面上数据库的分类主要为两类
3、关系型数据库是几乎所有网站都会使用到的,必须掌握其概念
4、所有关系型数据库都是基于SQL进行数据的操作,MySQL数据库也是(不同的数据库产品对应的SQL指令可能有细微差别)
5、MySQL是一种C/S结构的软件,所以访问者必须通过客户端进行访问
概念
SQL语法规则:SQL是一种结构化编程语言
;
、\g、\G
例如
select * from user;
目标:掌握数据库相关SQL指令
概念
创建数据库:根据项目需求创建一个存储数据的仓库
create database 数据库名字 [数据库选项];
示例
1、创建一个指定名字的数据库
create database db_1;
2、创建一个指定字符集的数据库
create database db_2 charset utf8MB4;
3、创建一个指定校对集的数据库(必须和字符集一起指定)
create database db_3 charset utf8MB4 collate utf8mb4_general_ci;
小结
1、数据库的创建是存储数据的基础,数据库的创建通常是一次性的
2、创建数据库的语法包含几个部分
3、创建好的数据库可以在数据存储指定地点(安装时指定)看到
4 . 我们一般就使用默认的数据库创建语句 create database db_1;
概念
显示数据库:通过客户端指令来查看已有数据库
示例
1、显示所有数据库
show databases;
2、显示数据库创建指令
show create database db_1;
小结
1、查看数据库分为两种方式
2、查看数据库的目的和应用
概念
使用数据库:指在进行具体SQL指令之前,让系统知道操作针对的是哪个数据库
示例
use db_1;
小结
1、使用数据库的指令是:use 数据库名字;
2、使用数据库的目标
概念
修改数据库:修改数据库的相关库选项
alter database 数据库名字 库选项 # 库选项可接多个 ,用空格隔开
示例
1、修改数据库字符集
alter database db_2 charset gbk;
2、修改数据库校对集(如果校对集修改必须同时改变字符集)
alter database db_3 charset gbk collate gbk_chinese_ci;
小结
1、数据库的修改只能修改库选项,不能修改名字
2、字符集的修改指令使用alter,其他跟创建指令一致
3、数据库修改通常有两部分
4、一般我们都不会使用数据库修改(一般要改也是删除后新增)
概念
删除数据库:将当前已有数据库删除
drop database 数据库名字;
示例
drop database db_1;
小结
1、删除数据库使用指令:drop database 数据库名字
2、数据库的删除不可逆
概念
创建数据表:根据业务需求,确定数据表的字段信息,然后创建表结构
表与字段不分家,相辅相成
表的创建需要指定存储的数据库
create table db_1.t_1(
name VARCHAR(32)
)charset=utf8; # db_1 是数据库名 ,t_1 是表名
use 数据库名字
use db_1;
create table t_1(
name VARCHAR(32)
)charset=utf8; # db_1 是数据库名 ,t_1 是表名
字段至少需要指定名字、类型
数据库表不限定字段数量
,
分隔表可以指定表选项(都有默认值)
表创建语法
create table [数据库名.]表名(
字段名 字段类型,
...
字段名 字段类型
)表选项1 表选项2;
注意点 : mysql 中使用UTF-8 字符集只能写成 utf8 ,其他的写法都会报错
示例
1、创建简单数据表(指定数据库创建数据表)
create table db_2.t_1(
name varchar(50)
);
2、创建数据表——多字段
# 使用数据库(进入数据库环境)
use db_2;
create table t_2(
name varchar(50),
age int,
gender varchar(10)
);
3、创建数据表——表选项
create table t_3(
name varchar(50)
)engine Innodb charset utf8;
也可以
CREATE TABLE t_3(
NAME VARCHAR(50)
)ENGINE=INNODB CHARSET=utf8; # default 选择性加在 charset 前面
4, 赋值表
语法
create table 被复制表名 like [数据库名字.]复制表名 # 同一个数据库下就不用加数据库名字
示例 :
CREATE TABLE tt_1 LIKE t_1;
小结
1、创建数据库表是为了存储具体数据
2、数据表的创建与字段是同时存在的
3、数据表的创建需要指定数据库
4、一张数据表用来存一组相关数据
5、扩展:存储引擎是指数据存储和管理的方式,MySQL中提供了多种存储引擎,一般使用默认存储引擎
6、扩展:如果想创建一个与已有表一样的数据表,MySQL提供了一种便捷的复制模式
目的:了解如何查看数据表结构
概念
显示数据表:客户端通过指令显示已有的数据表
示例
1、显示所有数据表——当前数据库下
show tables;
2、显示所有数据表——指定数据库
SHOW TABLES FROM db_2;
3、显示部分关联数据表——匹配
# 搜索当前数据库中是否有 名字 可以匹配 %like 的表
show tables like '%like'; # _表示匹配一个字符(固定位置),%表示匹配N个字符
4、显示数据表的创建指令
show create table t_1; # 看到的结果未必一定是真实创建的指令(系统会加工)
小结
1、显示数据表有两种形式
2、显示数据表通常是为了验证数据表是否存在或者验证数据表的创建指令是否正确
3、在显示数据的时候可以使用不同的语句结束符**(只在命令行中有效)**
目标:了解查看数据表的概念和掌握数据表查看的语法
概念
查看数据表:指查看数据表中的具体结构
desc 表名;
describe 表名;
show columns from 表名;
示例
desc t_1;
小结
1、数据表的查看是为了查看表中具体字段的信息
2、查看数据表的指令有多个,效果都一样
3、查看表结构的原因通常是在开发过程中为了更清晰的了解数据的存储形式和要求
概念
更改数据表:修改表名字和表选项
rename table 表名 to 新表名
alter table 表名 表选项1 表选项2 ;
示例
1、修改表名
rename table t_1 to t1;
注意:如果有时候想要跨库修改的话,需要使用数据库名.表名
RENAME TABLE db_1.t_1 TO t1;
2、修改表选项
alter table t1 charset utf8;
小结
1、更改数据表分为两个部分
2、通常我们较少使用更改数据表,数据表应该在创建时就定义好
删除数据表 : 删除该表
语法 :
drop table 数据表;
示例
1, 删除一个数据表
drop table t_1;
目标:了解字段更改的类型和基本语法的使用
概念
更改字段:指针对表创建好后,里面字段的增删改
概念
新增字段:在表创建好后往里面增加其他字段
字段的新增必须同时存在字段类型
新增语法
# column 可写可不写
alter table 表名 add [column] 字段名 字段类型 [字段属性] [字段位置]
示例
1、给已经存在的t_3表增加一个字段age
alter table t_3 add age int;
2、给已经存在的t_3表增加一个字段nickname
alter table t_3 add column nickname varchar(10);
3, 给已经存在的t_3表增加一个字段id ,放在name后面(字段位置在后面有讲)
ALTER TABLE t_3 ADD id INT AFTER name
小结
1、新增字段就是给已有表追加一个字段(较少)
2、字段新增必须指定字段类型
3、字段新增语法为:alter table 表名 add [column] 字段名 字段类型;
4、字段的追加默认是在所有字段之后
目标:了解字段位置的概念,掌握字段位置的使用
概念
字段位置:指字段放到某个指定字段之后
# 字段操作 如 add change modify drop 等等
alter table 表名 字段操作 字段位置;
示例
1、为t_3表增加一个id字段,放到最前面
alter table t_3 add id int first;
2、在t_3表name字段后增加一个身份证字段card
alter table t_3 add card varchar(18) after name;
小结
1、字段位置是配合字段操作的(新增、修改)
2、字段位置分两种
目标:了解更改字段名的基本语法
概念
更改字段名:指对已经存在的字段名进行修改
alter table 表名 change 原字段名 新字段名 字段类型 [字段属性] [字段位置]
示例
1, 修改字段名card为sfz
ALTER TABLE t_3 CHANGE id sfz VARCHAR(18);
2, 把sfz字段提到第一个(一般不使用这个关键字进行字段名位置修改)
ALTER TABLE t_3 CHANGE sfz sfz VARCHAR(18) FIRST;
小结
1、字段名更改通常只是修改字段名字,但是也必须跟随类型
2、字段名修改语法:alter table 表名 change 原字段名 新字段名 字段类型
3、字段名修改change其实也可以修改字段类型、属性和位置,但是通常不使用,一般使用 modify 操作
目标:了解字段修改的概念和基本语法,掌握字段修改的实现
概念
修改字段:指修改字段的相关信息
alter table 表名 modify 字段名 字段类型 [字段属性] [位置];
示例
1, 修改身份证的类型为char(18)并且位置放到id后面
alter table t_3 modify sfz char(18) after id;
2, 修改身份证的类型为varchar(30)
ALTER TABLE t_3 MODIFY sfz VARCHAR(30);
小结
1、修改字段包含多个操作
2、修改字段语法:alter table 表名 modify 字段名 字段类型 [字段属性] [位置];
目标:了解字段删除语法
概念
删除字段:即将某个不要的字段从表中剔除
alter table 表名 drop 字段名;
示例
1, 删除年龄字段
alter table t_3 drop age;
小结
1、字段删除在删除字段名的同时会删除字段对应的数据,而且不可逆
2、字段删除语法:alter table 表名 drop 字段名
目标:掌握mysql中数据的增删改查的基本操作
目标:了解数据的新增指令和逻辑,实现数据的入库操作
概念
新增数据:将数据插入到数据表永久存储
新增数据是根据表的字段顺序和数据类型要求将数据存放到数据表中
数据表中的数据以行(row)为存储单位,实际存储属于字段(field)存储数据
我们尽量使用单引号来表示填入字段的字符串
数据插入分两种方式
insert into 表名 values(字段列表顺序对应的所有值);
insert into 表名 (字段列表) values(字段列表对应的值顺序列表);
示例
已知 表t_3 的结构如下
1、给t_3表插入一条完整数据
# 填写字段值的时候,我们尽量使用单引号表示字符串 ,因为在别的数据库里面使用双引号非法(双引号用作圈数据库名,数据表名)
INSERT INTO t_3 VALUES('440111200011111101','Jim',18,'Green');
2、根据字段插入数据
insert into t_3(age,sfz,name) values(18,'441000200011111211','Tom');
小结
1、数据插入是利用insert指令将数据永久存储到数据表中
2、数据存储以行为单位,字段为最小实际存储单位
3、数据插入分为两种方式插入数据
概念
查看数据:将表中已经存在的数据按照指定的要求显示出来
*
代替所有字段select *|字段列表 from 表名;
示例
1、查看t_3表中所有数据
select * from t_3;
2、查看t_3表中的name和身份证信息
select name,sfz from t_3;
3、查看t_3表中年龄值为18的信息
select * from t_3 where age = 18;
小结
1、数据查看是数据库中最常用的操作(99%)
2、数据查看分两种情况
3、实际使用时通常会带where条件进行数据筛选
目标:了解更新数据的语法,掌握数据更新操作
概念
更新数据:即更新某个已有字段的值
update 表名 set 字段 = 新值[,字段 = 新值] [where条件筛选];
示例
1、更新所有记录的身份证信息
update t_3 set sfz = '440100200010100001';
2、更新某个记录的多个字段数据
update t_3 set name = 'Lily',sfz = '440100200010100002' where age = 18;
小结
1、更新数据的针对记录的字段数据进行更新
2、更新通常是限定条件更新(一般不会更新全部)
目标:了解删除语法,掌握删除操作实现
概念
删除数据:将数据从已有数据表中清除(针对的是记录record)
delete from 表名 [where条件];
示例
删除t_3表中age为18的数据
delete from t_3 where age = 18;
小结
1、数据删除是不可逆的操作
2、数据删除通常都匹配条件部分删除
目标:了解字符集概念,掌握字符集存储和读取的实现原理
概念
字符集:charset或者character set,是各种文字和符号在计算机中的总称
原理流程图
1、数据存储
2、数据读取
小结
1、字符集是一套符号的总称
2、不同国家地区的符号有区别,所以有自己的字符集
3、常见的字符集目前是三个
4、目前基本都统一使用UTF-8开发和数据存储
5、字符集是指定字符的存储和读取的规范
概念
MySQL字符集:MySQL内部对于数据实际存储的字符集(服务器端)
继承
表 继承
数据库 继承
DBMS示例
查看MySQL支持的所有字符集
show charset;
原理图
1、数据库内部对象字符集原理
1.1、服务端存储的数据最终字符集由字段确定
1.2、字段通常不会设置字符集,继承表的字符集(统一性,真正一般都与数据库一致)
1.3、数据存储的字符集与客户端的字符集没有直接关系,是由表(字段)决定
2、客户端存储数据原理
3、客户端读取数据原理
小结
1、MySQL服务端数据存储的字符集依赖各个对象设置
2、通常字符集的设置都是围绕数据表(现在都在数据库层),不会到具体字段
3、建议使用UTF8字符集存储数据(MySQL8以后建议使用UTF8MB4)
4、MySQL服务端支持各种字符集,并且能够进行各种字符集转换
5、客户端存储数据到服务端原理
客户端告知服务端客户端的字符集
服务端按照客户端指定的字符集接收数据(如果没有指定,使用默认,可能出现乱码)
服务端按照实际存储表对应的字符集进行转换
服务端存储数据
6、客户端读取服务端数据原理
客户端告知服务端客户端的字符集
服务端按照客户指定的指令从数据库读取原始字符集数据
服务端按照客户端的需求将数据进行字符转换
服务端发送目标数据给客户端
客户端按照自己的字符集进行解析
目标:了解乱码发生的原因,实现乱码问题的解决方案
概念
乱码:指数据不能按照正确的字符集进行存储或者解析
set names 客户端字符集;
示例
1、MySQL客户端(CMD打开),命令行客户端字符集是固定的GBK,客户端是什么编码就设置什么编码
set names gbk;
流程图
小结
1、乱码的本质原因就是客户端与服务端的字符集不一致导致
2、解决乱码问题的方案:保证服务端正确理解客户端的字符集
目标:了解set names 字符集的本质原理
概念
字符集设置原理:服务器端正确保障对客户端的数据识别
set names 字符集
就是对变量的修改,总共有三个
示例
1、查看系统内部存储这些记录字符集的信息
show variables like 'character_set%'; #%表示通配符,匹配后续所有不确定的数据
1)character_set_server:mysql server默认字符集。
2)character_set_database:数据库默认字符集。
3)character_set_client:MySQL server假定客户端发送的查询使用的字符集。
4)character_set_connection:MySQL Server接收客户端发布的查询等请求后,将其转换为character_set_connection变量指定的字符集(也就是客户端的编码)。
5)character_set_results:mysql server把结果集和错误信息转换为character_set_results指定的字符集,并发送给客户端。
6)character_set_system:系统元数据(字段名等)字符集
我们可以设置mysql 服务器的默认字符集编码 ,找到mysql安装文件下的 my.ini或my-default.ini文件,打开 ,设置
default-character-set=utf8
character-set-server=utf8
2、修改客户端字符集变量,保证数据正常存进服务端 (客户端是什么编码 ,就设置什么编码)
set character_set_client = uft8;
3、修改客户端解析字符集变量,保证数据正常被客户端查看
set character_set_results = uft8;
4、使用set names 字符集批量修改,保证客户端被服务端正确理解,同时客户端也能正确解析
set names uft8;
注意 : 如果是命令行操作 ,其客户端默认编码为 gbk ,那我们需要默认设置
set names gbk;
小结
1、MySQL字符集控制是在服务端内部通过变量连接(针对每个独立的客户端)
2、set names字符集是一种快捷方式,本质有三个变量被修改
3、通常我们都是使用set names字符集来进行统一设置,而且是在建立连接之后操作数据之前就设置
1、字符集是所有编程语言里都必须面对的首要问题,必须在一开始就选择好字符集(去到企业后先问清楚)
2、乱码是编程中最基础要解决的问题,一旦数据产生了乱码,通常是不可逆操作
3、解决乱码问题其实本质就是统一字符集问题
character_set_client
character_set_connection
character_set_results
set names 客户端字符集
流程总结 :
- mysql 分为客户端和服务器端, 两边分别有不同的编码
- 客户端在向服务器端发送请求的时候, 数据将以客户端的编码解码为二进制数据 ,然后发送给服务器端
- 服务器端接收到数据后 ,首先看一下
character_set_client
,以该变量指定的编码格式把客户端传入的二进制数据转码服务器端默认的编码格式,如果用户没有设置就用character_set_client
的默认值编码(我的是utf8)- 如果用户的请求是存储数据 ,那么服务器端将把传入的数据再转码成 其数据库表的编码存储
- 若用户请求数据 ,首先服务器把数据从表中取出 ,将其数据转换成服务器默认编码 ,再把数据 以
character_set_results
的编码格式解码成二进制数据,传输给客户端- 客户端把服务器端传回来的数据以自身默认编码 编码二进制数据,再把可视化的数据显示,至此结束
概念
校对集:collate/collation,即数据比较时对应的规则
示例
1、_ci,大小写不敏感
A 与 a 是相同的,不存在谁大谁小(系统会转换成一种)
2、_cs,大小写敏感
A 与 a 有大小关系,所以不同(存储数值)
3、_bin,二进制比较
A的二进制是01000001
a的二进制是01100001
二进制按位比较,所以不同
小结
1、校对集是数据比较的规则
校对集依赖字符集存在
每个字符集有多种校对规则
2、校对规则一共有三种
目标:了解MySQL中校对集的设计方式以及规则查看
概念
校对集设置:在创建数据表的时候创建校对规则
collate 校对集规则;
注意 : 校对集依赖于字符集 ,字符集决定校对集 ,两者必须是一个系列才可以 ,决不能说字符集是gbk ,校对集是utf8_bin
示例
1、查看MySQL支持的所有校对集
show collation;
2、在数据库层设计校对集(常见)
create database db_4 charset utf8mb4 collate utf8mb4_bin;
# 或者
create database db_4 charset utf8 collate utf8_bin;
3、在数据表层设计校对集
create table t_4(
id int,
name varchar(10)
)charset utf8mb4 collate utf8mb4_bin;
4、在字段层设计校对集(一般不常用)
create table t_5(
id int,
name varchar(10) collate utf8mb4_bin
)charset utf8mb4;
小结
1、MySQL中四层对象都可以设置校对集
2、校对集从Field到DBMS实现继承
3、校对集依赖字符集,且每个字符集都有默认的校对集(一般情况不需要设置)
目标:了解不同校对集的实际校对原理,掌握校对规则的应用场景
概念
校对集应用:触发校对规则的使用
order by 字段
示例
1、创建校对规则数据表并插入数据
# 创建默认校对规则表(不区分大小写)
create table t_4(
name varchar(1)
)charset utf8mb4;
insert into t_4 values('B');
insert into t_4 values('A');
insert into t_4 values('b');
insert into t_4 values('a');
# 创建二进制校对规则(区分大小写)
create table t_5(
name varchar(1)
)charset utf8mb4 collate utf8mb4_bin;
insert into t_5 values('B');
insert into t_5 values('A');
insert into t_5 values('b');
insert into t_5 values('a');
2、触发校对:排序 order by
select * from t_4 order by name; # 升序
select * from t_5 order by name;
3、数据已经存在的表重新修改校对规则无效
alter table t_5 collate utf8mb4_general_ci; # 无效操作 ,无法修改
小结
1、校对集的应用不是主动触发,而是通过数据比较自动触发
2、校对集对应的数据一旦产生,那么就不可以修改数据表的校对规则
3、校对集通常使用字符集默认校对集,如果需要进行额外的比较应用(通常是区分大小写),那么需要在建表的时候设定好目标校对规则
1、校对集是数据比较的标准
2、校对集的校对规则都是依赖字符集存在的,不外乎三种规则
3、校对集的触发是自动的,只要数据在进行比较的时候就会自动触发设定的校对规则
4、在进行数据表设计之前,要提前了解数据后续可能产生的比较形态,选择好合适的校对规则(一般都默认不区分大小写)
概念
字段类型:MySQL中用来规定实际存储的数据格式
示例
规定类型的字段只能插入相应的数据格式
# 正确数据类型插入
insert into t_6 values(3,'444111222211110101','Lily','Lee');
# 错误数据类型插入
insert into t_6 values('hello','444444222211110102','Lucy','Lu');
小结
1、字段类型的作用就是强制规范录入的数据格式
2、MySQL中有四种数据类型规范
目标:了解MySQL中的整数机制,掌握常用的整数类型解决整数存储问题
概念
整数类型:有效的整数数据
unsigned
来修饰整数类型 ,这样只会表示正数 ,且可表示的值也会翻倍步骤
1、确定数据的格式是存储整数
2、预估整数的范围,选择合适的整数类型
3、确定整数是否需要符号(负数区间)
示例
1、设计一个表记录个人信息:年龄、头发数量
# 年龄:没有负数,正常年龄也不超过200岁,迷你整型无符号即可
# 头发数量:没有负数,大概在几百万根,所以标准整型无符号即可
create table t_7(
age tinyint unsigned, # unsigned修饰整数,表示无符号(从0开始)
haircount int unsigned
)charset utf8 COLLATE utf8_bin;
2、设计一个表记录4S店的汽车销量信息:库存数量、销量、采购量
# 4S店经常是先卖后进货,所以库存可能为负数,一个店铺的库存数通常不会太多,那么小整型即可
# 销量通常全国一个月也就几万台,所以基本上小整型就够了,但是为了保证后续可能存在的爆发,那么中整型也是绝对够了的,而且不会是负数
# 采购通常是正向采购,所以不会出现负数,而采购数量与销量持平就好
create table t_8(
stock smallint,
sales mediumint unsigned,
purchase mediumint unsigned
)charset=utf8 COLLATE=utf8_bin;
小结
1、整型是用来存储整数数据的
2、整数数据也需要根据业务大小来选择合适的存储方式
3、数值型类型在MySQL中默认是有符号的,即有正负
4、一般开发中不会太计较一个或者两个字节(不愿意算),所以tinyint和int居多,其他较少
目标:了解显示宽度的实现,掌握在具体需求下使用显示宽度
概念
显示宽度:int(L),整数在数据库中显示的符号(数字+符号)个数
-
负号会增加一个宽度)id int(11) YES (NULL)
这里的 id 的宽度就是 11位, 即查询出来显示11 位
示例
1、有符号和无符号对应的宽度不一样
create table t_9(
a tinyint, # tinyint(4)
b tinyint unsigned # tinyint(3) unsigned
)charset utf8;
2、可以主动控制显示宽度
增加一个字符设置其显示宽度
alter table t_9 add c tinyint(2) unsigned;
修改一个字符设置其显示宽度
alter table t_9 modify a tinyint(2) unsigned;
3、显示宽度不影响数据的大小
insert into t_9 values(1,1,1); #小于显示宽度
insert into t_9 values(100,100,100); #大于显示宽度
4、可以通过zerofill让小于显示宽度的数值前置补充0到显示宽度
alter table t_9 add d tinyint(2) zerofill; # 0填充只能针对正数
insert into t_9 values(1,1,1,1);
或者
ALTER TABLE t_9 MODIFY a TINYINT(3) UNSIGNED ZEROFILL; # 0填充只能针对正数
INSERT INTO t_9 VALUES(1,2,1,1);
SELECT * FROM t_9;
小结
1、显示宽度是显示整型能表示的最多符号数量
2、显示宽度能主动设置,但是绝对不会改变类型本身能表示的数据大小
3、可以通过zerofill来强制让不够宽度的数据补充前置0来达到显示宽度
概念
浮点数:float/double,存储不是特别精确的数值数据
float/double(总长度,小数部分长度)
步骤
1、确定当前设计的字段的数据为不精确型数据(或者小数)
2、确定数据的大小或者精度的要求范围(精度是整数部分位数加小数部分位数)
3、确定精度的分布:整数部分和小数部分
示例
1、记录宇宙中恒星、行星的数量
# 数量属于不确定量级,所以精确的数据是无意义的,只能是个大概(绝大部分时候float就可以)
create table t_10(
h_star float unsigned,
x_star float(20,0) unsigned
)charset utf8;
insert into t_10 values(1234567890,1.2E10);
select * from t_10; # 1234570000 12000000000
# 说明默认的float精度只有 6位 ,超过6位直接四舍五入
2、记录商品的价格
# 商品名字字符串
# 商品价格一般都允许带小数
create table t_11(
goods_name varchar(20),
goods_price float
)charset utf8;
insert into t_11 values('Nokia3310',199.999); # 成功 ,且没有发生四舍五入
insert into t_11 values('Nokia6100',1999.9999); # 失败 ,四舍五入成2000
小结
1、浮点数是用来记录一些不需要特别精确的数值或者小数数值的
2、浮点数能够表示很大的数值
3、浮点数可以指定整数部分和小数部分的有效数值区间
4、因为浮点数会自动四舍五入,所以不要使用浮点数来存储对精度要求较高的数值
概念
定点型:decimal,能够保证精度的小数
步骤
1、确定小数是否需要保证精度
2、确定有效数位长度
示例
记录个人资产情况:资产和负债
# 资产和负债应该都是精确的,小数部分可以到分
CREATE TABLE t_12(
money DECIMAL(10,2),
beg DECIMAL(10,2) # 八位整数 ,两位小数
)CHARSET=utf8 COLLATE=utf8_bin;
insert into t_12 values(1111111111.12,1111111.99);
insert into t_12 values(1111111111.12,99999999.999); # 错误:进位导致正数部分超过指定范围
小结
1、定点数是用来存储精确的小数的
2、定点数可以指定长度
3、定点数的存储模式不是固定长度,所以数据越大占用的存储空间越长
概念
定长型:char(长度),指定固定长度的存储空间存储字符串
步骤
1、确定数据类型为字符串(或不能用整数存储的超长数字符号)
2、确定数据长度基本一致(定长占用固定空间)
3、确定具体长度
示例
记录个人信息:身份证信息和手机号码
# 身份证为固定长度18位(数字)
# 手机号码是11位固定长度(数字)
create table t_13(
id_number char(18),
phone_number char(11)
)charset utf8;
insert into t_13 values('440111999912120304','13512345678');
小结
1、定长是固定存储空间
2、定长对应的是字符长度,而不是字节长度
3、字符串数据需要使用引号包裹具体数据(推荐使用单引号)
4、定长的访问效率较高,但是空间利用率不高
固定长度的数据使用定长
定长最大数据长度指定不超过255字符
概念
变长型:varchar(最大长度),根据实际存储的数据变化存储空间
步骤
1、确定数据类型为字符串
2、确定数据是不规则的数据
3、确定最大长度
示例
记录个人信息:用户名、密码、姓名、身份证
# 用户名不确定长度,最长不超过50个字符
# 密码不确定长度,最潮超过15个字符
# 姓名不确定长度,最长不超过10个字符
# 身份证固定长度,18个字符
create table t_14(
`username` varchar(50),
`password` varchar(15),
`name` varchar(10),
`id_number` char(18)
)charset utf8;
insert into t_14 values('username','password','name','444111999912121111');
小结
1、变长varchar是根据数据的长度实际计算存储空间
2、变长需要规定数据的最大长度,理论长度为65535个字符
3、变长字符串能够更好的利用存储空间
4、变长字符串需要有额外1-2个字节存储数据长度
5、变长字符串在读取时需要进行长度计算,所以效率没有定长字符串高
目标:了解文本字符串的作用,掌握文本字符串的使用规则
概念
文本字符串:text/blob,专门用来存储较长的文本
2 ^ 8 -1
个字符2 ^ 16 - 1
个字符2 ^ 24 - 1
个字符2 ^ 32 - 1
个字符(4G)步骤
1、确定类型为文本类型
2、确定数据长度可能超过255个字符
3、使用text
示例
记录新闻信息:标题、作者和内容
# 标题一般不会超过50个字符,varchar
# 作者一般不会超过10个字符:varchar
# 内容通常都很长,使用text
CREATE TABLE t_15(
author VARCHAR(32),
title VARCHAR(50),
content TEXT
)CHARSET utf8;
insert into t_15 values('佚名','给联合国的一封信','给联合国的一封信...');
小结
1、文本类型是专门用来存储长文本的
2、一般文本长度超过255的(较长)都使用text
3、text/blob根据数据存储长度有很多种,但是一般使用text/blob,因为文本会根据数据长度自适应选择
概念
枚举:一种映射存储方式,以较小的空间存储较多的数据
步骤
1、确定数据是固定的几种数据之一
2、使用枚举穷举相应的元素
3、数据存储只能选择穷举中的元素之一
示例
1、记录人群类型:小朋友、少年、青年、中年、老年,每个人实际只属于一种类别
# 要保证未来数据只能出现在某种可能中,所以要先列出来,可以使用enum
create table t_16(
type enum('小朋友','少年','青年','中年','老年')
)charset utf8;
insert into t_16 values('少年');
# 等价于
insert into t_16 values(2);
# 错误实例
insert into t_16 values('仙人'); # 不存在的数据不能插入
2、enum是建立映射关系,然后实际存储是数字,数值是按照元素顺序从1开始
# 可以使用字段 + 0来判定数据具体的效果(字符串转数值为0)
select type,type + 0 from t_16;
insert into t_16 values(5); # 等价于 insert into t_16 values('老年');
流程原理
1、枚举定义原理
枚举数据 | 映射值 |
---|---|
数据1 | 1 |
数据2 | 2 |
… | … |
数据N | N(小于65535) |
2、数据存储(读取反过来)
小结
1、枚举是在定义时确定可能出现的元素,而后数据只能出现规定的元素之一的数据类型
2、枚举的存储是一种映射关系,对元素进行顺序编号,实际存储的是编号
3、使用枚举的作用
目标:了解集合概念和存储原理,掌握集合的应用
概念
集合:set,一种映射存储方式,以较小的空间存储较多的数据
步骤
1、确定数据是固定的几种数据组合
2、使用集合穷举相应的元素
3、数据存储只能选择穷举中的元素组合(多个使用逗号分隔)
示例
1、记录个人的球类爱好,有篮球、足球、羽毛球、网球、乒乓球、排球、台球、冰球
# 爱好可以是多种,并非固定的,但是只能从规定的类型中选择
create table t_17(
hobby set('足球','篮球','羽毛球','网球','乒乓球','排球','台球','冰球')
)charset utf8;
insert into t_17 values('足球');
insert into t_17 values('冰球,台球,篮球');
2、集合建立的也是映射关系,映射方式是每个元素对应一个字节的比特位,从左边开始第一个对应字节从右边开始的第一位
# 可以通过字段 + 0的方式查看存储的具体数值
select hobby,hobby + 0 from t_17;
# 可以通过插入数值来组合元素,但是需要确定对应的十进制转换成二进制有对应的元素对应
insert into t_17 values(8); # 二进制表示 00001000 第四位为 1 ,所有是网球
/*
8:00001000
1:00000001
冰球、台球、篮球
11000010 => 1 + 2 ^ 1 + 1 * 2 ^ 6 + 1 * 2 ^ 7 = 2 + 64 + 128 = 194
*/
流程原理
1、集合定义原理
把数据转换为二进制 , 哪一位为 1 则说明集合中有这一位对应的元素
集合数据 | 映射位 |
---|---|
数据1 | 00000001 |
数据2 | 00000010 |
… | … |
数据8 | 10000000 |
2、数据存储(读取反过来)
小结
1、集合是在定义时确定可能出现的元素,而后数据只能出现规定的元素数据类型
2、集合的存储是一种映射关系,每个元素对应字节中的一个位,实际存储的是编号
3、使用集合的作用
概念
年:year,MySQL中用来存储年份的类型
步骤
1、确定存储的数据是年份
2、确定年份的区间在1901-2155之间
3、使用year类型
示例
1、记录个人的出生年份
create table t_18(
y1 year,
y2 year(4)
)charset utf8;
insert into t_18 values(1901,2155);
2、Year类型允许使用2位数来插入,系统会自动匹配对应的年份
insert into t_18 values(69,70); # 查询出来的值 : 2069 1970
3、Year类型的特殊值是0000,可以使用00或者0000插入
insert into t_18 values(00,0000);
小结
1、year类型是MySQL用来存储年份信息的
2、year使用1个字节,所以只能表示256个年号,表示区间为1901-2155年
3、year数据可以用两种方式插入
4、因为year字段表示的范围有限,所以通常会使用字符串来存储(牺牲空间换安全)
概念
时间戳:timestamp,基于格林威治时间的时间记录
步骤
1、确定类型需要使用年月日时分秒格式
2、确定当前字段需要记录数据的最近更新时间
3、使用timestamp时间戳
示例
1、记录商品库存的最后更新时间
create table t_19(
goods_name varchar(10),
goods_inventory int unsigned,
change_time timestamp
)charset utf8;
insert into t_19 values('Nokia3110',100,'1971-01-01 00:00:00');
insert into t_19 values('Nokia7100',100,'19710101000000');
2、timestamp会在自己所在的记录任何位置被修改时自动更新时间
update t_19 set goods_inventory = 90;
更新成功
注意:在MySQL8以后,取消了timestamp的默认自动更新,如果需要使用,需要额外使用属性: on update current_timestamp
alter table t_19 add c_time timestamp on update current_timestamp;
update t_19 set goods_inventory = 80;
小结
1、timestamp是用以时间戳的形式来保存时间的
2、timestamp使用4个字节存储数据
3、timestamp一般用来记录数据变化的,其他时候通常用整型保存真正的时间戳
概念
日期:date,用来记录年月日信息
步骤
1、确定存储的数据格式为日期类格式
2、确定数据格式为YYYY-MM-DD
3、使用date类型
示例
记录个人生日
create table t_20(
name varchar(10),
birth date
)charset utf8;
insert into t_20 values('Jim','2000-12-12');
insert into t_20 values('Tom','10011212');
小结
1、日期date是用来存储YYYY-MM-DD格式的日期的
2、date用3个字节存储,存储区间是1000 - 9999年,跨度很大
3、date可以在需要存储日期的地方放心使用
概念
日期时间:datetime,用来综合存储日期和时间
步骤
1、确定要存储的时间格式包含日期
2、确定存储格式为:YYYY-MM-DD HH:II:SS
3、使用datetime
示例
记录个人具体的出生时间
create table t_21(
name varchar(10),
birth datetime
)charset utf8;
insert into t_21 values('Jim','2000-12-12 12:12:12');
insert into t_21 values('Tom','10011212182323');
小结
1、日期时间是综合存储日期和时间两部分的
2、日期时间datetime使用8个字节存储
3、datetime的存储区间为:1000-01-01 00:00:00 到 9999-12-12 23:59:59
4、实际开发中因为编程语言(PHP)的强大,实际存储的时候通常不会使用这种类型
目标:了解时间的存储格式和实际效果
概念
时间:time,用来记录时间或者时间段
-838:59:59
- 838:59:59
步骤
1、确定要存储的类型是时间格式
2、确定格式类型为time能表示的格式
3、使用time存储
示例
记录用户登录的具体时间
# 具体登录时间可以使用时间戳(包含年月日时分秒信息)
# 也可以时间datetime格式,或者date+time双字段格式(具体后面学习范式时会知道该怎么用)
create table t_22(
login_time1 int unsigned,
login_time2 datetime,
login_date date,
login_time3 time
)charset utf8;
insert into t_22 values(12345678,'2000-12-12 12:12:12','2000-12-12','12:12:12');
insert into t_22 values(1234567,'2000-12-12 12:12:12','2000-12-12','3 12:12:12');
小结
1、时间格式time主要用来记录时间点或者时间段
2、time类型通常被用来做时间段计算:如多少天后的什么时间点(可以理解为过期检查)
1、字段类型是用来规范数据的格式的
2、MySQL中有很多类型用来规范数据格式
3、实际开发的时候,一定要仔细了解需求,根据需求判定好具体选用那种数据类型
4, 开发的时候一般使用整形来代表事件(事件戳)
类型名称 | 显示长度 | 数据库类型 | JAVA类型 | JDBC类型索引(int) |
---|---|---|---|---|
varchar | L+N | VARCHAR | java.lang.String | 12 |
char | N | CHAR | java.lang.String | 1 |
blob | L+N | BLOB | java.lang.byte[] | -4 |
text | 65535 | VARCHAR | java.lang.String | -1 |
interger | 4 | INTEGER UNSIGNED | java.lang.Long | 4 |
tinyint | 3 | TINYINT UNSIGNED | java.lang.Integer | -6 |
smallint | 5 | SMALLINT UNSIGNED | java.lang.Integer | 5 |
mediumint | 8 | MEDIUMINT UNSIGNED | java.lang.Integer | 4 |
big | 1 | BIT | java.lang.Boolean | -7 |
bigint | 20 | BIGINT UNSIGNED | java.math.BigInteger | -5 |
float | 4+8 | FLOAT | java.lang.Float | 7 |
double | 22 | DOUBLE | java.lang.Double | 8 |
decimal | 11 | DECIMAL | java.math.BigDecimal | 3 |
boolean | 1 | 同TINYINT | ||
id | 11 | PK (INTEGER UNSIGNED) | java.lang.Long | 4 |
date | 10 | DATE | java.sql.Date | 91 |
time | 8 | TIME | java.sql.Time | 92 |
datetime | 19 | DATETIME | java.sql.Timestamp | 93 |
timestrap | 19 | TIMESTAMP | java.sql.Timestamp | 93 |
year | 4 | YEAR |
概念
属性:建立在字段类型之后,对字段除类型之外的其他约束
示例
查看表属性:desc 表名
desc t_11;
# Field:字段名字
# Type:数据类型
# Null:是否允许为空(属性)
# Key:索引类型(属性)
# Default:默认值(属性)
# Extra:额外属性
小结
1、属性是用来MySQL用来增加字段规范和约束的
2、数据的写操作必须严格满足字段类型和属性要求
3、用好属性能够提升数据的有效性,方便未来进行数据操作和数据分析(数据真实性和有效性)
概念
NULL:数据是否允许为空
步骤
1、数据类型确定
2、数据是否为空确定
示例
1、用户信息表:用户名、密码、姓名、年龄、注册时间
create table t_23(
username varchar(50) not null,
password char(32) not null,
name varchar(20),
age tinyint unsigned,
reg_time int unsigned not null
)charset utf8;
2、如果字段不能为空(Not Null),那么数据就必须满足条件:插入时不能为空的字段就需要主动提供值
insert into t_23 values('username','password','Jim',20,123456789);
# 错误操作:reg_time不能为空,而默认为空,所以系统报错
insert into t_23 (username,password) values('username','password');
小结
1、Null/Not Null属性是用来限定数据是否为Null值的
2、一般有效的数据都必须设定为Not Null来保证数据的有效性
概念
默认值:default,在设计表字段的时候给定默认数据,在后续字段操作(数据新增)的时候系统没有检测到字段有数据的时候自动使用的值
步骤
1、确定字段的数据类型
2、确定字段可能出现的数据会是某个经常出现的值
3、设定默认值
4、触发默认值
示例
1、用户开户:银行卡账号、身份证号码、姓名、账户余额
create table t_24(
account varchar(19) not null,
id_card char(18) not null,
name varchar(20) not null,
money decimal(16,2) default 0.00 not null
)charset utf8;
2、默认值触发
# 默认触发
insert into t_24 (account,id_card,name) values('6226000000000001','44011120001212000x','Lily');
# 主动触发
insert into t_24 values('6226000000000002','440111200012120011','Tom',default);
3, 修改字段的默认值
alter table t_24 modify money decimal(16,2) default 10.0 first;
小结
1、每个字段都有默认值
2、默认值是在设置表字段的时候添加 ,也可以 修改字段的时候添加
3、默认值触发
4、默认值通常用于一些不重要的字段,但是会出现常用值(或者初始值一样)
概念
主键:primary key,用来保证整张表中对应的字段永远不会出现重复数据
步骤
1、确定字段数据具有唯一性 (unique)
2、确定数据不允许为空 (not null)
3、确定数据会经常用于数据检索(条件查询)
4、使用主键primary key
5、一般每张表都会使用一个逻辑主键(id)
示例
1、银行账户信息:账户、姓名、余额
# 银行账户具有唯一性,不能重复,也不允许为空
create table t_25(
account varchar(17) primary key,
name varchar(20) not null,
money decimal(16,2) not null default 0.00
)charset utf8;
# 复合主键
create table t_26(
account varchar(17),
name varchar(20),
money decimal(16,2) not null default 0.00,
primary key(account,name)
)charset utf8;
# 一般使用逻辑主键
create table t_27(
id int unsigned primary key,
account varchar(17) not null,
name varchar(20) not null,
money decimal(16,2) not null default 0.00
)charset utf8;
2、主键数据不允许重复
insert into t_27 values(1,'6226000000000001','Lily',default);
# 错误:主键1已经存在
insert into t_27 values(1,'6226000000000002','Tom',default);
# 联合主键就是联合字段加起来不重复即可
insert into t_26 values('6226000000000001','Tom',default);
insert into t_26 values('6226000000000002','Tom',default);
3, 删除主键
alter table t_25 drop primary key;
4, 重新设置主键 (只能设置一个字段的主键)
alter table t_25 modify accout varchar(32) primary key;
小结
1、主键的作用就是控制对应字段的数据具有唯一性(不能重复)
2、一张表只能有一个主键
3、虽然主键可以用来保证数据的唯一性,但是一般都是使用逻辑主键作为主键字段(保证唯一性还有其他方式,如唯一键)
4、通常也不怎么使用复合主键
概念
主键管理:在创建表并且已经有数据后的维护
示例
1、删除主键:主键只有一个,所以删除语法也比较特殊
alter table t_26 drop primary key;
2、后期新增主键:如果是针对业务主键需要保证字段数据没有Null数据且没有数据重复(一般主键都会在表创建时维护好)
# 新增的主键有多个字段
alter table t_26 add primary key(account,name);
#新增的主键只有一个字段
alter table t_26 add primary key(id);
小结
1、主键的使用通常是在创建表的时候就会指定好
2、主键的维护实际使用较少,主要涉及的操作是删除和新增
概念
自增长:auto_increment,被修饰的字段在新增时,自动增长数据
auto_increment_offset
,默认是1auto_increment_increment
,默认值也是1show variables like 'auto_increment%';
步骤
1、确定数据类型为整型
2、确定数据需要有规则的变化
3、必须是一个索引字段(逻辑主键)
4、使用auto_increment
示例
1、记录学生信息:学号和姓名
# 学生信息:学号自动增长
create table t_28(
id int primary key auto_increment,
stu_no int(8) zerofill not null,
stu_name varchar(20) not null
)charset utf8;
2、触发自增长
# 使用自增长(可以使用NULL或者default来触发)
insert into t_28 values(null,1,'Jim');
insert into t_28 values(default,2,'Tom');
# 主动控制:自增长的值会从当前最大的值开始自动增长
insert into t_28 values(10,3,'Lily');
insert into t_28 values(null,4,'Lucy');
小结
1、自增长auto_increment一般是配合逻辑主键实现自动增长
2、自增长的触发是通过不给值(默认值)实现自动计算
3、自增长是根据当前表中自增长列最大值运算
4、一张表中只能有一个自增长
概念
自增长管理:在某些特殊使用下,需要自增长按照需求实现
修改表中自增长的值:让下次自增长按照指定值开始
修改自增长控制:调整自增长的变化
示例
1、修改表中自增长的值,跳过一些值,直接从下次开始按照新的目标值出现
alter table t_28 auto_increment = 50;
注意:奇数会保留原值,偶数会自动加1(可能出现的情况)
2、修改自增长控制:步长和起始值(修改针对的是整个数据库,而非单张表)
set auto_increment_increment = 2; # 当前用户当前连接有效(局部)
set @@auto_increment_increment = 2; # 所有用户一直有效(全局)
小结
1、自增长通常不会修改,如果有规则要求必须修改,通常也会在数据库运行前修改好
2、如果碰到要修改操作的,通常会选择全局修改而不是局部修改
概念
唯一键:unique key,用来维护数据的唯一性
步骤
1、确定数据列具有唯一特性
2、确定数据列不用作为主键
3、确定数据会经常用于检索条件
4、唯一键字段是否允许数据为空
5、使用唯一键
示例
1、用户表:用户名唯一,而且经常作为查询条件
create table t_29(
id int primary key auto_increment,
username varchar(50) unique comment '唯一键,可以直接在字段之后增加,使用unique关键字',
password char(32) not null
)charset utf8;
insert into t_29 values(null,'username','password');
insert into t_29 values(null,Null,'password');
insert into t_29 values(null,Null,'password');
# 错误
insert into t_29 values(null,'username','password1');
2、学生成绩表:一个学生只能有一个学科成绩,但是可以有多个学科
# 学号和学科编号共同组成唯一
create table t_30(
id int primary key auto_increment,
stu_name varchar(20) not null,
course varchar(20) not null,
score decimal(5,2),
unique key(stu_name,course)
)charset utf8;
insert into t_30 values(null,'Jim','Math',50);
insert into t_30 values(null,'Jim','English',80);
3, 查看唯一键的名字
show create table t_30;
4, 创建唯一键时指定其名称
# 指定唯一键名称为 hello
create table t_31(
id int primary key auto_increment,
stu_name varchar(20) not null,
course varchar(20) not null,
score decimal(5,2),
unique key hello(stu_name,course)
)charset utf8;
小结
1、唯一键的目标是保证对应字段数据的唯一性
2、唯一键能够弥补主键只有一个的特性(不限定数据量)
3、唯一键使用的位置应该要确保该字段数据会用作数据检索条件
概念
唯一键管理:在表创建后对唯一键的管理
alter table 表名 drop index 唯一键名字;
alter table 表名 add unique key [唯一键名称](字段列表);
示例
1、删除表中已有的唯一键
# stu_name 是 唯一键的名称 (默认为字段名)
alter table t_30 drop index `stu_name`;
2、追加唯一键
# stu_course 是唯一键名称
alter table t_30 add unique key `stu_course` (stu_name,course);
# 也可以
alter table t_30 add unique key(stu_name,course);
也可以
alter table t_30 modify stu_name varchar(20) not null unique;
小结
1、唯一键一般也会在前期架构(创建表)时就会设置好
2、如果在后期数据庞大后进行数据库优化,可能会涉及到后期维护唯一键
3、唯一键的删除不能像主键那样删除,原因就是唯一键在表中不是唯一存在的,必须指定唯一键名字
概念
描述:comment,是用文字描述字段的作用的
步骤
1、字段命名不是特别简单(见名知意)
2、使用comment增加简易描述
示例
1, 创建学生成绩表
# 学生成绩表中通常是存储学生学号
# 学科通常也是学科代码
create table t_32(
id int primary key auto_increment,
stu_no varchar(10) not null comment '学号',
course_no varchar(10) not null comment '课程号',
score decimal(5,2) comment '考试成绩',
unique key `stu_course` (stu_no,course_no) comment '学号和课程号组成唯一键'
)charset utf8;
2, 查看注释信息
show create table t_32;
小结
1、养成描述的良好习惯,为自己也为其他同事提供方便
2、并非所有字段都需要描述,但是对于自定义名字或者关联关系,都应该使用描述说清楚
1、字段属性是基于字段类型对数据控制后,再进行其他控制(辅助加强字段类型对数据的控制)
2、巧妙的利用好字段属性,能够帮助我们更好的保证数据的有效性、安全性
3、字段属性与字段类型通常是搭配使用,常见的属性有
概念
数据库记录长度:MySQL中规定一条记录所占用的存储长度最长不超过65535个字节
步骤
1、字符串字段如果超过长度255字符,使用text/blob替代
2、所有字段是否有允许为Null的,如果有要占用1个字节
3、计算字段所占用的预计总长度不要超过65535个字节
示例
1、GBK表能存储的最大varchar字符串长度
create table t_32(
content varchar(65535)
)charset gbk; # 错误
create table t_32(
content varchar(32767)
)charset gbk; # 错误
create table t_32(
content varchar(32766)
)charset gbk;
2、UTF8表能存储的最大varchar字符串长度
create table t_33(
content varchar(65535)
)charset utf8; # 错误
create table t_33(
content varchar(21844)
)charset utf8;
3、Null也要占用一个字节
create table t_34(
id tinyint,
content varchar(21844)
)charset utf8; # 错误
create table t_34(
id tinyint not null,
content varchar(21844) not null
)charset utf8;
小结
1、MySQL的记录长度是从设定表的时候就会检查所有字段加起来的预占用长度是否超过65535个字节
2、创建表字段的时候要使用text/blob来避免长字符串出现,超过MySQL记录长度
3、Null是个细节,一条记录只要允许出现Null就会占用记录长度里的一个字节
学习目标:了解数据库设计的基础规范,掌握范式在数据库设计上的指导意义,运用范式科学设计好的数据库
概念
范式:Normal Format,符合某一种级别的关系模式的集合,表示一个关系内部各属性之间的联系的合理化程度
范式是离散数学里的概念
范式目标是在满足组织和存储的前提下使数据结构冗余最小化
范式级别越高,表的级别就越标准
目前数据库应用到的范式有以下几层
示例
1、一张员工表
工号 | 姓名 | 部门 | 入职时间 |
---|---|---|---|
0001 | 杨戬 | 武装部 | 0001-01-01 |
0002 | 李白 | 书院部 | 1500-12-12 |
2、每个员工都是与部门挂钩的,但是部门不可能很多,所以上述表中会有很多数据重复,此时应该将部门单独维护出来,减少数据冗余
部门编号 | 部门名称 |
---|---|
1 | 武装部 |
2 | 书院部 |
工号 | 姓名 | 部门编号 | 入职时间 |
---|---|---|---|
0001 | 杨戬 | 1 | 0001-01-01 |
0002 | 李白 | 2 | 1500-12-12 |
N个1和N个武装部占用的磁盘空间肯定是不一样的
小结
1、范式是一种数学理论,在关系型数据库上用来减少数据冗余
2、满足的范式越多,越符合高标准表设计
3、范式一共有6层,但是数据库的设计通常只要求满足3层即可
目标:了解第一范式的原理,掌握第一范式的实际应用
概念
第一范式:1NF,数据字段设计时必须满足原子性
步骤
1、设计的字段是否在使用的时候还需要再拆分?
2、将数据拆分到最小单位(使用),然后设计成字段
3、满足1NF
示例
1、设计一张学生选修课成绩表
学生 | 性别 | 课程 | 教室 | 成绩 | 学习时间 |
---|---|---|---|---|---|
张三 | 男 | PHP | 101 | 100 | 2月1日,2月28日 |
李四 | 女 | Java | 102 | 90 | 3月1日,3月31日 |
张三 | 男 | Java | 102 | 95 | 3月1日,3月31日 |
当前表的学习时间在使用的时候肯定是基于开始时间和结束时间的,而这种设计就会存在使用时的数据拆分,不满足原子性也就是1NF
2、满足1NF的设计:字段颗粒度应用层最小(不需要拆分)
学生 | 性别 | 课程 | 教室 | 成绩 | 开始时间 | 结束时间 |
---|---|---|---|---|---|---|
张三 | 男 | PHP | 101 | 100 | 2月1日 | 2月28日 |
李四 | 女 | Java | 102 | 90 | 3月1日 | 3月31日 |
张三 | 男 | Java | 102 | 95 | 3月1日 | 3月31日 |
小结
1、1NF就是要字段数据颗粒度最小,保证数据取出来使用的时候不用再拆分
2、1NF是满足数据表设计的最基础规范
目标:了解第二范式的原理,掌握第二范式的实际应用
概念:
第二范式:2NF,字段设计不能存在部分依赖
步骤
1、表中是否存在复合主键?
2、其他字段是否存在依赖主键中的一部分?
3、如果存在部分依赖,将部分依赖的关系独立拆分成表
4、满足2NF
示例
1、学生成绩表中学生和课程应该是决定性关系,因此属于主属性(主键)
学生(P) | 性别 | 课程(P) | 教室 | 成绩 | 开始时间 | 结束时间 |
---|---|---|---|---|---|---|
张三 | 男 | PHP | 101 | 100 | 2月1日 | 2月28日 |
李四 | 女 | Java | 102 | 90 | 3月1日 | 3月31日 |
张三 | 男 | Java | 102 | 95 | 3月1日 | 3月31日 |
2、解决方案:将学生信息维护到一张表,课程信息维护到一张表,成绩表取两个表的主属性即可
学生表
Stu_id(P) | 姓名 | 性别 |
---|---|---|
1 | 张三 | 男 |
2 | 李四 | 女 |
课程表
Class_id(P) | 课程 | 教室 | 开始时间 | 结束时间 |
---|---|---|---|---|
1 | PHP | 101 | 2月1日 | 2月28日 |
2 | Java | 102 | 3月1日 | 3月31日 |
成绩表
Stu_id(P) | Class_id(P) | 成绩 |
---|---|---|
1 | 1 | 100 |
2 | 2 | 90 |
1 | 2 | 95 |
小结
1、2NF是在满足1NF的前提之上的
2、2NF的目标是取消表中存在的部分依赖
3、2NF可以实现很大程度的数据冗余减少
概念
第三范式:3NF,字段设计不能存在传递依赖
步骤
1、确定表中的所有字段都是依赖主属性的
2、如果存在不直接依赖主属性,而是通过依赖其他属性产生依赖的,形成独立的表
3、满足3NF
示例
1、学生表:包括所在系信息
学号(P) | 姓名 | 专业编号 | 专业名字 |
---|---|---|---|
1 | 张三 | 0001001 | 软件工程 |
2 | 李四 | 0001002 | 土木工程 |
2、解决方案:将存储传递依赖部分的字段(非主属性)独立成表,然后在需要使用相关信息的时候,引入即可
专业表
专业编号(P) | 专业名字 |
---|---|
0001001 | 软件工程 |
0001002 | 土木工程 |
学生表
学号(P) | 姓名 | 专业编号 |
---|---|---|
1 | 张三 | 0001001 |
2 | 李四 | 0001002 |
小结
1、3NF目的是为了解决非主属性对主属性的传递依赖
2、让有关联关系的表独立成表就可以消除传递依赖,满足3NF
目标:了解逆规范化的概念,掌握逆规范化的应用
概念
逆规范化:为了提升数据查询的效率而刻意违背范式的规则
步骤
1、表中部分数据来源于其他表(通常只需要其他表的某个简单数据)
2、当前表会被高频次查询
3、数据表数据量很大
4、考虑使用逆规范化
示例
1、学生成绩表需要经常查询,而且数据量很大,但是:
学号(P) | 学生姓名 | 课程号(P) | 课程名字 | 成绩 |
---|---|---|---|---|
1 | 张三 | 1 | PHP | 100 |
1 | 张三 | 2 | Java | 90 |
小结
1、逆规范化只有在数据量大,查询效率低下的时候为了提升查询效率而牺牲磁盘空间的一种做法
2、逆规范化后数据表的设计必然是不完全符合范式要求的(2NF/3NF)
1、范式是关系型数据库设计借鉴用来减少数据冗余的
2、在进行数据表设计的时候,需要严格遵循范式规范
学习目标:了解MySQL中表设计关系,理解关系设计给数据库带来的方便,掌握表关系的应用实现复杂数据库设计
概念
表关系:一个表代表一个实体,实体之间都有关联关系的
示例
设计一个简单新闻管理系统的数据库
新闻信息表:id、标题、内容、发布时间、作者id(作者表主属性)、分类id(分类表主属性)、阅读量、推荐数
作者表:id、作者名字、作者来源id(来源表)
来源表:id、来源名字、来源描述
分类表:id、分类名字、分类级别(父分类id)
评论表:id、评论人id(评论表)、评论时间、评论内容(不回复)
小结
1、表关系是体现数据实际联系的方式
2、表关系的设计好坏直接关联数据维护的准确性、有效性
3、良好的数据库设计有助于后期程序开发
目标:了解一对一关系的处理方式,掌握一对一关系的实体设计
概念
一对一关系:一张表中的一条记录与另外一张表中有且仅有一条记录有关系
步骤
1、一张表的数据字段较多且数据量较大
2、表中有部分字段使用频次较高,而另一部分较少使用
3、将常用字段和不常用字段拆分成两张表,使用同样的主键对应
示例
1、学生信息表
学号(P) | 姓名 | 性别 | 年龄 | 身高 | 体重 | 籍贯 | 政治面貌 |
---|---|---|---|---|---|---|---|
1 | 张飞 | 男 | 20 | 178 | 160 | 蜀 | 农民 |
2 | 武则天 | 女 | 21 | 168 | 110 | 唐 | 党员 |
2、一对一关系设计
常用表
学号(P) | 姓名 | 性别 | 年龄 |
---|---|---|---|
1 | 张飞 | 男 | 20 |
2 | 武则天 | 女 | 21 |
不常用表
学号(P) | 身高 | 体重 | 籍贯 | 政治面貌 |
---|---|---|---|---|
1 | 178 | 160 | 蜀 | 农民 |
2 | 168 | 110 | 唐 | 党员 |
小结
1、一对一关系的核心是两张表中记录匹配有且仅有一条匹配
2、一对一关系常用来进行分表,实现优化操作
3、因为一对一关系表通常有相同信息作为匹配条件,所以查询方式也比较方便
目标:了解一对多关系的原理,掌握一对多关系的实体设计
概念
一对多关系:也叫多对一关系,一张表中的一条记录与另外一张表的多条记录对应,反过来另外一张表的多条记录只能对应当前表的一条记录
步骤
1、确定实体间的关系为一对多(多对一)关系
2、在多表中增加一个字段记录一表中对应的主属性
示例
1、老师与学科间的关系:一个老师只能教一个学科,但是一个学科有多个老师教授,学科与老师形成的关系就是一对多(反过来老师与学科的关系就是多对一关系)
老师表(多表)
老师ID(P) | 姓名 | 年龄 | 性别 |
---|---|---|---|
1 | 张老师 | 35 | 男 |
2 | 李老师 | 34 | 女 |
3 | 王老师 | 30 | 男 |
学科表(一表)
学科ID(P) | 名字 | 课时长度 |
---|---|---|
1 | PHP | 600 |
2 | Java | 800 |
2、在多表(讲师)中增加字段维护一表(学科)的关系型,形成多对一关系
老师ID(P) | 姓名 | 年龄 | 性别 | 学科ID |
---|---|---|---|---|
1 | 张三 | 35 | 男 | 1 |
2 | 李四 | 34 | 女 | 1 |
3 | 王五 | 30 | 男 | 2 |
小结
1、一对多关系设计是将实体的关系在表结构层进行强制关联(没有关系程序层也可以控制,但是会非常麻烦)
2、一对多关系的核心在于分析出表与表之间的关系
目标:了解多对多关系的处理方式,掌握多对多关系的实体设计
概念
多对多关系:一张表中的一条记录对应另外一个表中多条记录,反过来一样
步骤
1、确定实体间的关系为多对多关系
2、设计中间表,记录两张表的对应关系
示例
1、老师与学生之间的关系:一个老师会教授多个学生,一个学生也会听多个老师的课,所以实体关系是多对多关系
老师表
老师ID(P) | 姓名 | 年龄 | 性别 |
---|---|---|---|
1 | 张老师 | 35 | 男 |
2 | 李老师 | 34 | 女 |
3 | 王老师 | 30 | 男 |
学生表
学生ID(P) | 姓名 | 年龄 | 性别 |
---|---|---|---|
1 | 小明 | 15 | 男 |
2 | 小红 | 14 | 女 |
3 | 小萌 | 14 | 女 |
2、设计一个中间表:老师与学生关系表,将老师与学生的对应关系对应上(多对一)
中间表
ID(P) | 学生ID | 老师ID |
---|---|---|
1 | 1 | 1 |
2 | 1 | 2 |
3 | 1 | 3 |
4 | 2 | 1 |
5 | 2 | 2 |
6 | 2 | 3 |
7 | 3 | 1 |
8 | 3 | 3 |
小结
1、多对多关系在表上不能直接维护(字段设计违背1NF)
2、多对多关系是将关系抽离形成中间关系表,形成多个多对一的关系
3、多对多关系是否建立主要看业务上是否存在数据要求,如果不存在数据需求,那么就没必要刻意设计
1、表关系的设计是要遵循范式规范作为前提
2、表关系的设计是根据实体关系以及业务需求进行设计
3、在设计数据库的时候,要严格使用表关系来进行实体关联设计