-- 回顾
数据库基础知识:
1.关系型数据库(磁盘),建立在关系模型上的数据库,数据结构(二维表),浪费空间。
操作数据的指令集合:SQL(DDL,DML[DQL]和DCL)
完整性约束:表内和表之间(实体)
mysql 关系型数据库:c/s结构软件(连接认证,发送SQL指令,服务器处理指令返回结果,客户端接收结果解析结果)
mysql服务端对象:DBMS->Datebase->Table->fields
sql 基本操作:库操作,表操作(字段)和数据操作
字符集问题:中文数据问题
改变服务器接收数据的字符集:chatacter_set_client
改变服务器返回数据的字符集:character_set_results
快捷方式:set names 字符集(三件事)
web乱码问题:浏览器解析,php处理(本地文件),数据库处理
校队集问题:比较规则:_bin , _cs和_ci
-- 数据类型(列类型)
所谓的数据类型:对数据进行统一的分类,从系统的角度出发为了能够使用统一的方式进行管理更好的利用有限的空间。
SQL 中将数据类型分成三大类:数值类型,字符串类型和时间类型。
一.数值型
数值型数据:都是数值,系统将数值型分为整数和小数型
1.整数型
存放整型数据:再SQL中因为更多考虑如何节省磁盘空间,所以系统将整型分为5类
Tinyint :迷你整型,使用一个字节存储,表示的状态最多位256个(常用)
smallint:小整形,使用2个字节存储,表示的状态最多位65536种
mediumint:中整型,使用3个字节存储,表示
int:标准整型,使用4个字节存储(常用)
bigint:大整型,使用8个字节存储
例:创建一张整型表
mysql> create table my_int(int_1 tinyint, int_2smallint, init_3int) charset utf8;
例:输入数据:只能插入整型,范围内的整型
mysql> insert into my_int values (100,100,100,100); #有效数据
mysql> insert into my_int values (‘a‘,‘b‘,‘199‘,‘f‘); #无效数据,类型限定
mysql> insert into my_int values (255,1000,10000,100000); #超出范围
SQL中的数值类型全部都是默认有符号:分正负,但有时候需要使用无符号数据:需要给数据限定:int unsigned; #无符号,从0开始
例:给表增加一个无符号类型
mysql> alter table my_int add int_5 tinyint unsigned;
例:插入数据
mysql> insert into my_int values(127,1000,10000,100000,255);
查看表结构的时候,发现每个字段的数据类型之后都自带一个括号里面有数值,这个是显示宽度,但它没有任何含义只是告诉用户可以显示的形式而已;实际上用户是可以控制的,这种控制不会改变数据本身大小;
例:mysql> alter table my_int add int_6 tinyint(1) unsigned; #指定显示宽度为1
说明:显示宽度的意义是在当数据不够显示宽度的时候,会自动让数据变成对应的显示宽度;通常需要搭配一个前导0来增加宽度,但是值大小不变。zerofill(零填充):零填充会导致数据自动变成无符号
例:mysql> alter table my_int add int_7 tinyint (2) zerofill; #表示显示宽度为2,0填充
例:mysql> insert into my_int values(1,1,1,1,1,1,1); #零填充+显示宽度的效果
mysql> insert into my_int values(100,100,100,100,100,100,100);
零填充的意义(显示宽度):保证数据格式
2.小数型
小数型:带有小数点或者范围超出整型,SQL中将小数型分成两种:浮点型和定点型
浮点型:小数点浮动,精度有限,而且会丢失精度
定点型:小树点固定,精度是固定的,不会丢失精度
2.1浮点型
浮点型数据是一种精度型数据:超出指定范围之后,会丢失精度(自动四舍五入)
Float : 单精度,占用4个字节存储数据,精度范围大概为7位左右
Double: 双精度,占用8个字节存储数据,精度方位大概为15位左右
例:创建浮点数表
浮点数的使用方式:直接float 表示没有小数部分;float(M,D):M代表总长度,D代表小数部分长度,整数部分长度为 M-D
mysql> create table my_float (f1 float,f2 float(10,2),f3 float(6,2)) charset utf8;
例:插入符合条件数据,可以是直接小数也可以是科学计数法
mysql> inster into my_float values(1000.10,1000.10,1000.10); #符合条件
mysql> inster into my_float values(1234567890,12345678.90,1234.56); #符合条件
mysql> inster into my_float values(9999999999,99999999.99,9999.99); #最大值
mysql> inster into my_float values(3e38,3.01e7,1234.56); #符合条件
浮点型数据的插入:整数部分是不能超出长度的,但是小数部分可以超出长度(系统会自动四舍五入)
例:超出长度插入数据
mysql> inster into my_float values(123456,1234.12345678,123.9876543);#小数部分是可以的
mysql> inster into my_float values(123456,1234.12,123456.56); #整数部分超出
结果:浮点数一定会进行四舍五入(超出精度范围):浮点数如果是因为系统进位导致整数超出指定的长度那么系统也允许成立
2.2 定点型
定点型:绝对保证整数部分不会被四舍五入(不会丢失精度),小数部分有可能(理论小数部分也不会丢失)
创建定点数表
mysql> create table my_decimal(f1 float(10,2),d1 decimal(10,2)) charset utf8;
插入数据:定点数的整数部分一定不能超出长度(进位不可以),小数部分的长度可以随意超出(系统自动四舍五入)
mysql> inster into my_decimal values(12345678.90,12345678.90); #有效数据
mysql> inster into my_decimal values(1234.123456,1234.123456); #小数部分超出
发现有一条警告,查看警告的命令位: mysql> show warnings;
浮点数如果进位导致长度溢出是可以的,但定点数不行
mysql> insert into my_decimal values(99999999.99,99999999.99);
mysql> insert into my_decimal values(99999999.99,99999999.999); #进位超出范围
查看数据
二 . 时间日期类型
Datetime:时间日期,格式是 YYYY-mm-dd HH:ii:ss 表示的范围是从1000年开始到9999年,有0值:0000-00-00 00:00:00
Date:日期,就是datetime 中的date部分
Time:时间(段),指定的某个区间之间,-时间到+时间
Timestamp:时间戳,并不是时间戳,只是从1970年开始的YYYY-mm-dd HH:ii:ss 格式和datetime 完全一致
Year:年份,两种表示形式,year(2)和year(4):1901-2156
创建时间日期表
mysql> create table my_date(d1 datetime,d2 date,d3 time,d4 timestamp,d5 year) charset utf8;
插入数据:时间time可以是负数,而且可以是很大的负数,year 可以使用2位数插入,也可以使用4位
mysql> insert into my_date values(‘2015-9-28 11:50:36‘,‘2015-9-28‘,‘11:50:54‘,‘2015-9-28 11:51:08‘,2015);
mysql> insert into my_date values(‘2015-9-28 11:50:36‘,‘2015-9-28‘,‘-11:50:54‘,‘2015-9-28 11:51:08‘,2015);
mysql> insert into my_date values(‘2015-9-28 11:50:36‘,‘2015-9-28‘,‘-211:50:54‘,‘2015-9-28 11:51:08‘,2015);
year 可以使用两位或者四位
mysql> insert into my_date values(‘2015-9-28 11:50:36‘,‘2015-9-28‘,‘-11:50:54‘,‘2015-9-28 11:51:08‘,69);
mysql> insert into my_date values(‘2015-9-28 11:50:36‘,‘2015-9-28‘,‘-11:50:54‘,‘2015-9-28 11:51:08‘,70);
Timestramp 字段:只要当前所在的记录被更新,该字段一定会自动更新成当前时间
修改记录
mysql> update my_date set d1 = ‘2015-9-28 11:55:45‘ where d5 = 2069;
三.字符串类型
在SQL中,将字符串类型分成了6类:char,varchar,text,blob,enum和set
1.1 定长字符串
定长字符串:char,磁盘(二维表)在定义结构的时候,就已经确定了最终的存储长度,以后不能改变
char(L):L 代表length,可以存储的长度,单位为字符,最大长度为255.
char(4):在 utf8 环境下,需要4 * 3 = 12 字节
1.2 变长字符串
变长字符串:varchar,在分配空间的时候,按照最大的空间分配,但是实际上最终用了多少,是根据具体的数据来确定。
1.2 变长字符串
varchart(L):L 表示字符长度
理论长度是65536 个字符,但是会多出1到2个字节来确定存储的实际长度:但是实际上如果长度超过255,就既不用定长也不用变长,使用文本字符串text
varchar(10):的确存了10个汉字,utf8环境,10*3+1=31
存储了3个汉字 3*3+1=10(bytes)
定长与边长的存储实际空间(utf8)
如何选择定长或者是变长字符串呢?
定长的磁盘空间比较浪费,但效率高;如果数据基本上确定长度都一样,那么就使用定长,如:身份证,电话号,手机号等;
变长的磁盘空间比较节省,但是效率低;如果数据不能确定长度(不同数据有变化),如
姓名,地址等
1.2 文本字符串
如果数据量非常大,通常超过255个字节就会使用文本字符串
文本字符串根据存储的数据的格式进行分类:text和blob
Text :存储文字(二进制数据实际上都是存储路径)
Blob :存储二进制数据(通常不用)
四:枚举字符串
枚举:enum,事先将所有可能出现的结果都设计好,实际上存储的数据必须是规定号中的一个
枚举的使用方式
定义:enum(可能出现的元素列表);
使用:存储数据,只能存储上面定义好的数据
创建枚举表:
mysql> create table my_enum(gender enum(‘男‘,‘女‘,‘保密‘)) charset utf8;
插入数据:作用之一:规范数据,数据只能是其中的一个
mysql> insert into my_enum values(‘男‘),(‘保密‘); #有效数据
mysql> insert into my_enum values(‘male‘); #错误数据,没有该元素
作用二:节省存储空间(枚举别名:单选框):枚举实际存储的是数据而不是字符串
在mysql中,系统也是自动转换数据格式的:而且基本和php一样(尤其是字符串数字)
证明字段存储的数据是数值:将数据取出来+0就可以判断出原来的数据存的到底是字符串还是数值:如果是字符串最终结果永远为0
mysql> select gender + 0, gender from my_enum; #将字段取出来进行+0运算
找出了枚举元素的实际规律:按照元素出现的顺序;从1开始开始编号
枚举原理:枚举在进行数据规范的时候系统会自动建立数字与枚举元素的对应关系(关系放到日志中):然后在进行数据插入的时候,系统自动将字符转换成对应的数字存储,然后在进行数据抓取的时候,系统自动将数值转换成对应的字符串显示。
因为枚举实际存储的是数值所以可以直接插入数值
mysql> insert into my_enum values (1),(2);
五:集合字符串
集合跟枚举很类似:实际存储的是数值,而不是字符串(集合是多选)
集合使用方式
定义:set(元素列表)
使用:可以使用元素列表中的元素(多个),使用,分隔
mysql> create table my_set(hobby set(‘篮球‘,‘足球‘,‘乒乓球‘,‘羽毛球‘,‘排球‘,‘台球‘,‘网球‘,‘棒球‘)) charset utf8; #集合中:每个元素都是对应一个二进制位,被选中为1,没有则为0,组后反过来。
创建集合表:
插入数据:可以使用多个元素字符串组合,有可以直接插入数值
mysql> insert into my_set values(‘足球‘,‘台球‘,‘网球‘);
mysql> insert into my_set values(3);
查看集合数据
mysql> select hobby + 0, hobby from my_set;
集合中每个元素都是对应二进制位;
mysql> inster into my_set values(255);
集合中元素的顺序没有关系,最终系统都会去匹配顺序。
颠倒元素出现的顺序
mysql> inster into my_set values(‘网球‘,‘台球‘,‘足球‘);
集合的强大在于能够规范数据和空间,在实际应用中效率优先,所以很少使用。
六:Mysql记录长度
Mysql 中规定:任何一条记录最长不能超过65535个字节,(varchar 永远达不到理论值) varchar 的实际存储长度能达到多少需看字符集
UTF8 下 varchar 的实际顶配:21844 字符
GBK 下 varchar 的实际顶配;32766 字符
如果想用完65535个字节长度需增加个tinyint 字段
mysql记录着如果有任何一个字段允许为空,那么系统会自动从整个记录中保留一个字节来存储null(若想释放null所占用的字节,必须保证所以的字段都
允许空)
Mysql 中 text 文本字符串,不占用记录长度;额外存储,但是text文本字符串也是属于记录的一部分,一定需要占用记录中的部分长度10个字节。(保存数据的地址和长度)
text 占用十个字节长度
mysql> create table my_utf82(age tinyint not null,name varchar(21843) not null,content text) charset utf8;
七:列属性
列属性:真正约束字段的是数据类型,但是数据类型的约束很单一,因此需要一些额外的约束来增加保证数据的合法性
列属性有很多:NULL/NOT NULL,defaul,prinary key,uniquee key,auto_increment,comment
空属性:NULL(默认的)和NOT NULL(不为空)
虽然默认的,数据库基本都是字段为空,但是实际上我们尽可能保证所有数据都不应该为空:空数据没有意义;空数据没有办法参与运算。
创建实际案例表:班级表(名字,教室)
mysql> creare table my_class(name varchar(20) not null,room varchar(20) null) charset utf8; #代表允许为空,null不写默认就是为空
八:列描述
列描述:comment,描述没有实际意义:是专门用来描述字段,会根据表创建语句保存:用来给数据库管理员来进行了解的。
创建表
mysql> create table my_teacher(name varchar(20) not null comment ‘姓名‘,money decimal(10,2) not null comment ‘工资‘) charset utf8;
八:默认值
默认值:某一种数据会经常性的出现某个具体的值,可以再一开始就指定好,再需要真实的数据时,用户可以选择性的使用默认值。
默认值关键字:default
mysql> create table my_default(name varchar(20) not null ,age tinyint unsigned default 0,gender enum(‘男‘,‘女‘,‘保密‘) default ‘男‘) charset utf8;
默认值的生效:使用,在数据进行插入时,不给改字段赋值
插入数据
mysql> insert into my_default (name) values(‘高强‘);
想要使用默认值,可以不一定区指定列表;可以使用default关键字代替值
mysql> insert into my_default values(‘范立峰‘,‘18,default);
字段的属性
主键,唯一键和自增长。
主键:primary key,主要的键,一张表中只能有一个字段可以使用对应的键,用来唯一的约束该字段里面的数据,不能重复,这种称之为主键,一张表只能有最多一个主键
增加主键:
sql操作中有多种方式可以给表增加主键:分为三种方法
方案1:在创建表的时候,直接在字段之后,跟primary key 关键字(主键默认不允许
为空)
mysql> create table my_pri1(name varchar(20) not null comment ‘姓名‘,number char(10) primary key comment ‘学号:itcast + 0000,不能重复‘) charset utf8;
优点非常直接,缺点是只能使用一个字段作为主键
方案2:在创建表的时,在所有的字段之后,使用primary key(主键字段列表)来创建主键(如果有多个字段作为主键,可以是复合主键)
mysql> create table my_pri2(number char(10) comment ‘学号:itcast + 0000‘,course char(10) comment ‘课程代码:3901 + 0000‘,score tinyint unsigned default 60 comment ‘成绩‘,primary key(number,course)) charset utf8;
方案3:当表已经创建好之后
,额外追加属性:可以通过修改表字段属性,也可直接追加
mysql> altar table [表名] add primary key(字段列表);
mysql> create table my_pri3(course char(10) not null comment ‘课程编号:3901 + 000‘,name varchar(10) not null comment ‘课程名字‘); #创建无主键新表
mysql> alter table my_pri3 modify course char(10) primary key comment ‘课程编号:3901 + 000‘; #方法1:追加主键
mysql> alter table my_pri3 add primary key(course); 方法2:添加主键
方法2前提:表中字段对应的数据本身是独立的(不重复)