时间:2021-07-01 10:21:17 帮助过:2人阅读
关系模型:
?
mysql数据是关系型数据库!
?
何谓关系型(关系模型),利用关系(二维表),去描述实体信息,与实体之间的联系的数据库架构就是关系型数据!
?
所谓关系:二维表!
?
学生信息
学号 | 名字 | 年龄 | 所属班级 |
Itcast_007 | 王翦 | 66 | Java1011 |
Itcast_010 | 李白 | 44 | Php1016 |
Itcast_001 | 杜十娘 | 33 | Ios1021 |
Itcast_123 | 喜羊羊 | 11 | Java1011 |
?
班级信息
班级名称 | 教室号 | ? |
Php1016 | 102 | ? |
Java1011 | 201 | ? |
.net0918 | 108 | ? |
Ios1021 | 218 | ? |
?
?
nosql:not only sql,非关系型数据库
sql:一门语言,结构化查询语言,操作关系型数据的语言!
?
典型的是 key / value型,键值对型
‘abcedefakasdnfakjsdi‘=>{‘itcast_007‘, 王翦, 66, java1011}
‘asdfkndikciuehaalcidk‘=>{‘itcast_001‘, 杜十娘, 33, ios1021, ‘female‘, {‘珠宝‘, ‘百宝箱‘,‘投河‘}}
?
?
关系,二维表
行,记录,一行就是一条记录。
列,字段,一列就是一个字段。
SQL:结构化查询语言,操作关系型数据库的语言!
?
什么数据库系统,mysql 就是数据库系统!
数据库系统最基本应该由:
数据系统 = 数据库(数据主体部分) + 数据管理系统(操作数据的工具)
DBS(DataBase System) = DB(Database) + DBMS(Database Managenemt System)
?
mysql的操作,是基于 C/S 的!
Client / Server,客户端/服务器.
c/s指的是不同的服务器,提供的是不同的终端访问方式!
?
操作mysql,就一定:通过操作mysql客户端,向mysql服务器发出指令,从而完成操作!
?
按照mysql时,自动携带一个命令行的客户端!mysql。
利用该客户端,向服务器发送指令,然后等待执行结果即可!
?
?
任何操作mysql服务器行为的行为,都是mysql客户端发出的!
?
?
?
?
数据库服务器 ->库 ->表 ->字段(数据)
?
完成数据的操作,先建立数据的结构(由库到表再到字段)
?
?
?
SQL:大体分成典型:DML(数据管理语句,数据操作),DDL(数据定义语句,数据结构的控制语句,表操作和库操作)
(create,几乎所有的结构都是用该语法完成)
create database 库名 [库选项]
?
注意的问题:
库选项,只有字符集,校对集的概念!
?
每个库,会对应一个数据目录
存放在当前mysql的总的数据库目录内
参考 mysql的配置文件得到该目录:
看到刚刚的数据库目录:
看看目录内,没有表,没有其他文件,除了一个数据库选项文件:
?
?
?
数据库名的问题
大小写问题,取决于mysql服务器,所在的操作系统!(建议是,认为区分)
特殊名称,关键字,特殊字符等!默认是不可以的!
但是,可以使用反引号将名称包裹起来,告知服务器,此处一个名字,而不是特殊操作!
中文等都可以作为标识符(库名),需要同样反引号!(多字节字符,还需要注意字符集的问题)
?
show databases;
show databases likes;
like 关键字用于过滤多个数据库!
可以使用通配符(通用匹配符,可以匹配多个字符)
% 匹配任意字符的任意次数(包括0次)的组合!
_ 匹配任意字符的一次!
?
like ‘x_y‘;
x1y xby xxy(可以)
xy(不可以)
?
通配符是与 like 关键字一起使用!
?
注意如需要匹配特定的通配符,则需要对通配符转义,使用反斜杠\完成转义!
show create database 库名;
alter database 数据库名
只能修改数据库选项
?
?
drop database 名字
?
?
在 create 与 drop 时,创建和删除时,有两个额外的操作:
?
create database if not exists
如果不存在则创建
?
drop database if exists
如果存在,则删除
?
表本身,与表结构的操作!
?
?
create table 表名 (
字段的定义
) [表选项];
?
其中表名,一定先要确定数据库!因此一个典型的表名是由两部分组成:
所在库.表名
test.itcast ????test库内itcast表
itcast.stu ????itcast库内的stu表
?
但是我们可以设置默认数据库,如果不指定则使用默认数据库(当前数据库)
use 数据库名。选择默认数据库!
在使用表名但是没有指明其所在数据库时,默认数据库才会起作用!
在itcast库内创建:
use itcast ; create table stu;
或者
create table itcast.stu
?
?
其中字段的部分
字段才是最终的数据的载体(与变量的概念是类似的,都是基本保存数据的),mysql的是强类型,字段的类型是固定的,提前定义好的!
因此,在定义字段时,至少要字段名和字段类型!
两种最基本的mysql数据类型(int, varchar,varchar必须指定最大长度字符为单位)
?
表选项部分
典型的常用的表选项有:
字符集(校对集),表引擎。
?
show tables like ‘模式‘
show create table table_name
在mysql的命令行客户端,如果数据过多,不容易展示!
可以使用 \G 作为语句结束符!
?
desc 表名
desc describe的简写
?
alter table table_name [新选项]
?
rename table原表名 to 新表名。
注意,表名可以由库名.表名形式的!
因此,可以跨库修改表名:只要在表名前增加库名即可
?
alter table table_name add column 字段定义 [字段位置]
?
增加一个 age字段:
?
增加一个 height 在 name之后:
使用关键字 after some_column_name;
在最开始增加sn字段
使用关键字,first
?
alter table table_name drop column column_name;
?
?
?
alter table table_name modify column column_name 新的定义!
可以修改位置
alter table table_name change column 原字段名新字段名新字段定义!
注意,不是纯粹的改名,而是需要在修改定义的同时改名!
?
?
drop table if exists
create table if not exists!
?
?
?
?
?
基本的操作
insert into 表名 (字段列表) values (与字段相对的值列表)
不一定要一次性插入所有字段,或者按照原始的字段顺序插入:
但是:
字段与值的数量一定要匹配:
特别的:
如果所有的值都按照字段的出现顺序都插入的话,可以省略字段列表部分!
注意:数值类型,不需要增加引号!而字符串类型都需要出现引号内!(但是数值型,可以出现引号内)
?
select 字段列表 from 表名 [where 条件表达式]
其中字段列表可以使用 * 表示所有字段!
?
关于条件表达式,默认是没有,表示永远为真!
但是,很少出现没有条件的情况!
?
为了突出,应该所有的语句都有查询条件!即使没有条件,我也强制增加一个 where 1;
?
关于字段列表:
也应该够用就可以!
?
?
delete from 表名 where 条件;
关于条件,可以省略。表示永远为真。
注意,删除是不可逆的。要避免没有条件的删除!
?
?
update 表名 set 字段=新值, 字段n=新值n where 条件
关于条件,可以省略。表示永远为真。
?
?
?
create,show,alter,drop ????database/talbe
add,modify,change,drop column
insert , select, update, delete table_name
?
?
?
字符集,描述可见到的图形,在存储和传输时使用的编码称之为字符集!
指的是:
图形与编码之间的对应关系!
?
字 => 11100101 11100001 00010100
?
?
?
数据是存储在服务器端的!究竟是以哪种编码保存的,怎么决定?
数据是最终要映射(保存)到字段的层面上!因此决定数据的编码,也是最终由字段来决定!
?
确定数据的存储编码是由以下的方案完成的:
?
?
?
典型的编码:gbk,utf8!
?
?
?
?
?
在客户端与服务器端交互时,存在两个重要的编码:
?
可以通过 show variables like ‘character_set_%‘展示以character_set开头变量,其中就有上面的两个值:
?
在命令行客户端下:
该客户端,只能是gbk编码!
?
?
?
使用 set 变量名 = 变量值的形式更改变量值!
?
set names gbk,就是一个快捷操作,将上面两个配置同时更改成目标编码!
?
set names gbk|utf8 取决于,客户端所能接受的编码!
?
?
整体流程:
?
?
set names gbk|utf8。
?
?
?
php作为mysql服务器的客户端!
?
连接认证
?
发送sql
????执行sql,生成结果(mysql-server)
处理结果
?
关闭连接
?
?
mysql_connect();
?
?
mysql_connect()
成功返回连接资源,失败 false!
?
?
?
mysql_query(sql, 连接资源);
失败返回false,成功返回资源或者true!
可以使用 mysql _error(连接) mysql_errno(连接)获得错误信息和标识
?
执行成功后:返回数据可以是资源也可以true。执行失败一定是false!
依据所执行的 sql,是否有返回数据!
返回资源:有返回数据:select,show,desc。
返回true:没有返回数据的: use,set,insert,update,delete,DDL
?
?
称之为结果集(result set)类型资源!
?
结果集:结果的集合!
?
将数据,从结果集中取出来!称之为 fetch!
使用函数:
mysql_fetch_assoc|row|array。功能完全一致,只是返回的数据格式不同!
?
在结果集中,取得一条记录。结果集内也存在结果集记录指针的概念!
fetch一次,只能取得当前记录,但是可以向后移动记录指针!配合上循环结构可以将所有的记录从结果集中取出!
?
?
特别注意:
任何有结果的sql操作,返回的都是结果集!
结果集,就是一个二维表的结构!是一行行的记录组成!
即使,结果集中只有一条记录
甚至,我们只需要返回一条数据!
?
?
?
mysql_free_result(结果集)
mysql_close(连接资源);
?
?
?
校对集
列类型(数据类型)
列选项(列属性,列约束)
设计模式(范式,关联)
?
1,模拟查找所有的数据表结构
?
?
2,编码问题!
?
连接的必要四个参数:
?
客户端发送一条sql:
客户端编码(character_set_client)->连接层编码(characger_set_connection)->服务器内部编码(server_internal)
?
服务器端发送结果:
服务器内部编码(server_internal)->连接层编码(characger_set_connection)->客户端接收的结果编码(character_set_results)
?
?
总体的编码问题:
?
?
先获得所有的数据库:
为其增加链接,请求到table.php展示所有的表,应该以 GET方式(在url上传递)形式将库名,传递到table.php
?
table.php
先获得表名列表,再为其增加指向结构和数据的连接!
?
?
注意,在获得表结构与数据时,至少需要库名和表名两个参数!
?
?
column.php获得结构
展示:
?
?
rows.php
展示列表时,先展示字段名,再展示数据!
?
?
?
mysql_num_rows($result)获得结果集中的记录数量
?
指的是字符之间的比较关系!
?
a B c
or?
B????a????c
?
此时,使用 order by对结果排序,看结果:
?
顺序为 a-B-c 忽略了大小写!
?
可以被校对集改变:
利用 show collation; 查看到所有的校对集!
校对集,依赖于字符集!
校对集,指的是,在某个字符集下,字符的排序关系应该是什么,称之为校对集!
?
再创建一个 utt8_bin的校对集表,在排序:
?
?
我们典型的选择:
?
典型的后缀:
_bin 二进制编码层面直接比较:
_ci 忽略大小写(大小写不敏感)比较
_cs 大小写敏感比较
?
三大类:
数值,字符串,日期时间
?
int 4个字节。
还有占用其他空间的整型:
tinyint????????1
smallint ????????2
mediumint????3
int????????????4
bigint????????8
如何选择:
通过业务逻辑判断!常见的是 tinyint,int!
?
mysql的整型,有php整型不具备的概念:
one,无符号
只能表示整数或0。那么最大的整数会很大!
默认是有符号!可通过整型的 unsigned选项,int unsigned 设置整型无符号
?
无符号的:
?
two,显示宽度
显示宽度,不决定整型的范围。而决定在显示出该数之后,如果宽度不够,则采用前导零不齐!此时需要额外的属性 zerofill 来设置!
可见无符号,默认的显示宽度是 10,因此全都使用0来补齐。
可以设置整型的显示宽度!在 int(M)即可!
255个宽度就可以了!
?
注意,如果超出了宽度范围,则直接显示!
?
?
额外的,mysql中,没有布尔型!
但是存在Boolean这个关键字,表示 tinyint(1)
典型的,0表示假,1表示真!
?
单精度,float,4个字节
双精度,double,8个字节
?
?
双精度:
?
在定义浮点数,典型的需要指明其有效位数,和小数位数
float(M,D)
double(M,D)
M:所有的有效位数
D:其中的小数位数
以上两个值,决定一个浮点数的有效范围!
?
典型的浮点数
float(10, 2);
99999999.99
注意,浮点数,近似值,不是精确值!如果一个数,很大,接近最大值,可能出错!
?
一旦出现精确数据(小数)需要保存可以使用,下面的定点数
?
小数点是固定的!
decmal,与定义浮点数一致,也有有效位数与小数位数的概念:
?
decimal(M,D)
不是数的形式存储,类似于字符串的形式!
?
注意,关于小数:
1,支持科学计数法
2,同样支持 unsigned,无符号!
3,同样支持 zerofill,
?
TIP:小数的M,即表示有效范围,也表示显示宽度!(而整数的M只表示显示宽度)
?
?
最基本(定长)的字符串类型!
用于保存,长度固定的内容!
速度快,但是保存变长数据,会浪费空间!
可变长度的字符串!
用于保存长度可变的数据!
保存变长数据时,节省空间,处理起来麻烦些!
?
char(L),varchar(L)
L,表示每个数据的最大长度!单位是字符数(不是字节数)
L 表示最大长度!
?
L的值不是多大都可以!
有最大值:
1,mysql一条记录最大不能超过65535个字节!(字段的长度加起来,不能超过这个值)
2,长度单位是字符数,与编码是相关的!
?
采用单字节编码测试下:
Latin1
测试发现只有一个字段,而且是单字节字符集,还是不能是65535,原因是?
为什么是 65532呢,少了三个字节:
3,由于varchar是变长,需要记录下真实的数据到底有多长!每个varchar类型的数据,还需要额外的1个或2个字节保存真实数据的长度!(取决于真实数据的长度)
4,整条记录,还需要一个字节来保存那些字段为null
?
但是,在使用时,varchar 超过255就选择 text来保存!
?
文本,不限长度的字符串!
该字段,不需要指定长度,而且也不会算入到记录的总长度内!
?
?
选择
定长,char
变长较短(255)个字符之内,varchar
变长,较长,text
?
?
需要在定义枚举类型时,列出哪些是可能的!
?
在处理时,类似字符串型进行操作!
?
意义在于:
原因是枚举型是利用整数进行管理的,能够2个字节进行管理!
?
每个值,都是一个整数标识,从第一个选项开始为1,逐一递增!
管理时整数的形式,速度比字符串快!
?
2 个字节,0-65535,因此可以有 65535个选项可以使用!
类似于 enum枚举,在定义时,也需要指定其已有值!
?
与字符串相比,优势是:
?
?
注意:站在 mysql的角度,尽量多用枚举和集合!
但是站在php操作mysql的角度,尽量少用!(兼容性差)
?
?
,日期时间,用于保存大范围的日期时间!
‘1000-01-01 00:00:00‘到‘9999-12-31 23:59:59‘
在处理时是使用字符串的形式进行管理!
?
时间戳,管理常用的典型时间,从1970-1-1开始。空间少,而且是以整型的形式管理,但是一个字符串的形式展示的!
?
?
日期,如果只记录日期,不记录时间采用 date!
?
在保存年份的时候。
采用一个字节保存!因此只能表示 1901——2155年!
?
时间,时间时刻!
还可以表示时间跨度!时间段的概念!
?
总结:
one:除了time,表示都是时间点的概念!time还表示时间跨度!
?
two:年份的表示
可以采用2位年份:
0-69 表示 20 XX
而 70-99 表示 19XX
1990
2090
?
?
?
放在php程序中:
小范围的日期:使用整型
大范围的日期:字符串!
?
?
mysql的NULL不是数据,也不是类型!只是标识属性!
用于说明某个字段,是否可以为null(是否可以什么都不存)
?
NULL采用关键NULL表示!(不是字符串)
是:NULL,而不是:‘NULL‘
属性:
null 表示可以为空
not null,表示不能为空
?
?
如果,在添加数据时,没有指定值,也可能会是NULL!
?
?
采用 default 关键字,来限定一个字段的默认值,在没有指定字段数据时,采用默认值!
?
default 与 null 的处理关系!
如果此时,该字段被指定了一个null:
不能使用默认值,允许为null则为null,不允许则插入失败!
?
如果一个字段没有指定默认值,那么默认为NULL
此时:如果在定义该字段时,不允许为NULL,则插入时,必须保证该字段有值才可以!
(另外一个选择是增加默认值)
?
?
默认值,存在一些特殊的标记关键字:
default,用在值中的关键字!
?
current_timestamp,用在第一个时间戳类型的字段上,表示当前的时间!
典型在很多表上增加一个 update_time 将其默认值设置成 current_timestamp。就可以记录下当前记录的最后操作时间!
?
站在约束的角度,限制的,该字段,值要唯一!
?
但是主键与唯一不是一个概念:
?
都是索引的一种!
主键:
可以唯一标识记录的字段,称之为主键!
?
唯一:
保证在某个字段上的数据是唯一的,可以设置成唯一约束!
?
但是,一个表,只能有一个主键!
典型的,在创建表时,主动增加一个非实体的自然属性,充当主键,采用整型,运算速度快!
其他的唯一字段,建立唯一约束!
?
建立:
两种方案:
一旦创建了主键:
默认就是不能为空:
唯一,使用 unique key 来创建!
?
一个表可以有多个唯一,但是只能有一个主键!
?
注意:主键或者是唯一,都可以由多个字段组成!
?
因此,主键与字段的概念:字段来充当主键,不是字段就是主键!(称之为复合主键)
尽量采用 id 一个来作为主键!
?
删除主键:
alter table表名 drop primary key;
添加主键
alter table 表名 add primary key(‘字段列表‘);
?
?
删除唯一
alter table 表名 drop index index_name;
索引的名字,可以通过 show create table 看到!
?
?
增加唯一
alter table 表名 add unique key 索引名字 (字段列表)
?
?
用于主键,只有一个字段主键,才能使用auto_increment!
可以,从1开始,逐一递增的数值!
?
目的是保证唯一,计算方面!
?
典型的,从1 开始,没有负数,可以采用无符号 unsigned整型!
?
?
?
注意: unsigned,不是列属性,是类型的一部分!(包括zerofill)因此位置上与类型在一起!
?
?
?
?
外键!
?
?
?
4,语句(查询语句)
1????说说那些地方可以设置编码
2????增加对库的管理(删,增加)
????增加对表的管理(增加,改名,删除)
????增加对字段的管理(增加,删除)
????增加对数据的管理(增加,删除,编辑)
?
?
?
位,bit,比特,计算机可以处理的最小单元
字节,Bytes 存储的最基本单位。KB 千字节, MB,兆字节,GB,1024*MB,TB,1024*GB。一个字节 8 个位。 1Byte = 8 bit.
字符,char,一个显示逻辑上的单位,一个图形就是一个字符。
?
?
?
字,双字节
双字,4字节。
?
参数为 table_name 表名,要求大家返回一个数组,内容是当前表的结构信息!只需要字段名,如果有主键,则在返回其主键(不考虑符合主键)
?
f1(stu)
array(‘id‘, ‘name‘,‘pk‘=>‘id‘)
?
5,建立一个学生信息表!尽可能利用多种类型!
编码:
建表,建库,建字段设置(数据库中的数据的编码)
PHP作为mysql服务器的客户端,设置的客户端编码和连接编码(set names)
设置php返回给浏览器数据的编码,(Content-Type,header(),<meta>)
PHP文件本身保存的编码(文件编码,通过文本编辑器设置)
?
?
[浏览器查看时,可以强制指定编码]
?
?
增加删除的链接,传递所操作的库名!
在数据库列表页:
?
增加一个处理删除的功能页面:
?
在形成sql时,只要出现了标识符(库名,表名,字段名,索引名),都使用反引号!
?
请求跳转:
header(‘Location: url‘);//告知浏览器,对新的url发出请求!
database_drop.php
?
执行 create database
?
?
列表页,增加一个链接,请求到创建页:
?
增加一个create_form表单页面
?
在增加一个脚本处理该数据即可
database_create.php
如果存在多个选项,因该如何处理?
例如字符集!
?
应该,取得所有的字符集。
利用 show character set;可以展示所有的字符集!
?
?
?
在创建库时,需要先对哪个字符集做一次判断!(是否是默认)
database_create.php
?
table.php
利用mysql_num_rows($result)可以获得结果集中的记录数:
?
展示一个增加表名与记录数的小表单:
?
?
table_create_form.php
?
应该为每组数据形成一个唯一的标识!采用数组下标的形式!
?
循环对数据做判断,然后依次拼凑sql语句:
?
?
?
?
范式,NF,normal format,就是指对表的结构的要求!
目的:1,规范结构!2,减少数据冗余!
?
要求字段不能再分,要求字段的原子性
?
增加唯一主键即可!ID
?
范式的要求,是逐渐递增!
在满足了第一范式的前提下,不能出现部分依赖!
部分依赖指的是:普通字段对主键是完全依赖的,而不应该是依赖主键的一部分!
依赖:可以通过那个字段去决定另一个字段
?
因此,出现主键部分依赖的前提是,出现复合主键!
?
其中代课时间,开始和结束时间,没有部分依赖!称之为完全依赖于主键:
?
但是,性别,依赖于讲师字段即可!
讲师字段是主键的一部分!因此称之为性别部分依赖于主键
因此,该表不符合第二范式!
?
怎么做?
消灭复合主键即可!增加一个唯一字段的主键即可。增加一个与业务逻辑毫无关系的,唯一的ID主键,int unsigned primary key auto_increment
?
?
在满足第二范式的前提下,取消传递依赖,就是第三范式!
?
传递依赖:如果字段B对字段A有依赖,而字段C对字段B存在依赖。则出现了传递依赖!
讲师依赖于ID,而性别依赖于讲师。
班级依赖于ID,而教室依赖于班级。
称之为传递依赖!
?
解决,要保证所有的字段都完全依赖于主键,而不依赖于其他字段!
将独立的实体信息,使用独立的关系(二维表)进行保存!
分别增加讲师,班级表,将代课信息内的讲师和班级信息拆分出:
?
?
总结:
每个实体建立一个表,为每个表增加一个主键ID即可!
?
?
?
一个实体表应该如何设计
多个是体表应该如何设计!
?
班级,学生两类实体!
一对多,多对一,1:N, N:1
?
班级,讲师两类实体!
多对多,M:N
?
学生常用信息,学生不常用信息
一对一,1:1
?
在多的那端(那个表内),增加一个字段,用于保存于当前记录相关联的一端记录的主键!
?
?
增加一个专门管理关联的表,使班级与讲师都与关连表存在联系。从而是两个实体间有多对多的关系!
?
因此,一个多对多,会拆分成两个多对一!
?
?
可见,两个表之间存在相同的主键ID即可!
?
?
约束的作用,是用于保证数据的完整性或者合理性的工具!
外键:foreign key,当前表内,指向其他表的主键的字段,称之为外键!
?
外键约束:用于限制相关联的记录在逻辑上保证合理性的约束称之为外键约束!
?
约束,不是字段。
?
建立班级表
?
再创建学生表
?
看看删除班级的情况:
出现了不合理数据:
?
此时,可以通过增加外键约束的方式,来限制以上的操作!
?
alter table 表名 add constraint 约束的名字 foreign key 外键索引名字 (外键字段名) references 关联表名 (关联字段) [操作]
再删除个试试:
?
注意:如果当前的数据,已经不符合所见约束关联,则创建失败!
?
alter table table_name drop foreign_key外键名字!
?
可以通过 show create table 查看约束的名字:
?
?
?
注意,外键约束与索引的关系:
?
如果需要在某个字段上,增加外键约束,那么需要该字段也同样有索引!如果该字段上,没有索引,此时,mysql会自动在该字段上增加一个普通索引!
?
?
可以选择指定外键约束的名字:
注意上面的外键约束自动建立的索引的名字,与外键的名字相同!
?
总结:在创建时:
?
?