MySQL相关知识
-
数据库:DataBase ,简称DB。按照一定格式存储数据的一些文件的组合。顾名思义:存储数据的仓库,实际上就是一堆文件,这些文件中存储了具有特定格式的数据。
-
数据库管理系统:DataBaseManagement,简称DBMS。数据库管理系统是专门用来管理数据库中的数据的,数据库管理系统可以对数据当中的数据进行增删改查。
常见的数据库管理系统:
MySQL,Oracle,等....
-
结构化查询语句:sql。程序员通过编写sql语句,然后数据库管理系统(DBMS)负责执行SQL语句,最终来完成数据库中数据的增删改查操作。
SQL是一套标准,可以在各种数据库管理系统中使用。
三者之间的关系:
DBMS——执行——>SQL——操作——>DB
mysql常用语句(DQL)
查询语句
1.退出mysql:exit
2.创建数据库:create database 数据库名;
3.展示所有数据库:show databases;
4.选择使用某个数据库:use 数据库名;
5.导入一个外部sql文件:source sql文件路径;
6.查询表结构:desc 表名;
7.查看数据库的版本号:select version();
8.查看当前所使用的数据库:select database();
9.终止sql语句的输入:\c
10.起别名:select 列名 as 要起的别名 from 表名;(as可以省略)(如果要改的别名包含空格,要把别名用单引号或者双引号括起来,不过单引号是标准,双引号在Oracle中不可以被识别)
select A as B from C;
起的别名只能将显示结果列明显示为B,原表列名仍然为A。
select永远不会进行修改操作,他只负责查询。
11.字段可以进行数学运算。
12.删除表:drop table 表名;
13.条件查询语句:select 列名 from 表名 where 属性=值;
注意:在数据库中null不能用等号进行衡量,需要用is null,因为数据库中的null代表什么也没有,它不是一个值,所以不能用等号衡量。只有有值的时候才能用=衡量。
14:and 和or同时出现,and优先级较高,如果想让or先执行,加括号。
15:模糊查询:like ,支持%或者下划线匹配,%代表匹配任意多个字符,下划线代表任意一个字符。
select name from emp where name like ‘%o%‘; (查询名字中带有o的名字)
select name from emp where name like ‘%o‘; (查询名字以o结尾的)
select name from emp where name like ‘o%‘; (查询名字以o开头的)
排序语句
select * from 表名 order by 字段名;(默认是升序排序)
select * from 表名 order by 字段名 desc;(指定降序排列)
select * from 表名 order by 字段名 asc;(指定升序排列)
数据处理函数
数据处理函数又被称为单行处理函数。
单行处理函数特点:一个输入对应一个输出。和单行处理函数对应的是多行处理函数(多行处理函数特点:多个输入对应一个输出)。
常见的单行处理函数:
-
string 大写转换为小写
select lower(要转换的字段名)from 表名;
-
supper 小写转换为大写
select supper(要转换的字段名)from 表名;
-
substr 取子串
select substr(被截取的字符串,起始下标,截取的长度) from 表名;
起始下标从1开始,没有0。
-
concat 字符串拼接
select concat(字段名,字段名) from 列表名;
-
length 取长度
select length(字段名) from 列表名;
-
format(不常用)
fromat(数字,’$999.999‘)以千分位格式显示。
-
str_to_date 把字符串varchar转换为日期date类型(必须严格按照标准标准输出)通常使用在插入insert方面,因为插入的时候需要一个日期类型的数据,需要通过该函数将字符串转换为date。
语法格式:str_to_date(‘字符串日期‘,‘日期格式‘)
str_to_date(‘1999-08-12‘,‘%Y-%m-%d‘)
如果是使用的%D-%m-%d模式的日期模式,即‘1999-08-12‘,可以不用str_to_date函数,系统会自动识别该日期,即直接写‘1999-08-12‘即可。
mysql的日期格式:%Y 年 、%m 月、%d 日、%h 时、%i 分、 %s 秒
-
date_fromat 把日期date类型转换为具有一定格式的字符串varchar类型
date_fomat语法格式:date_fomat(日期类型数据,‘日期格式‘),例如date_format(brith,‘%Y/%m.%d‘),执行完这一句话后,birth字段里面的日期1999-06-22会变成例如1999/06.22这样的模式。
这个函数通常使用在查询日期方面,设置展示日期的格式
并且数据库会自动给日期格式化为%Y-%m-%d模式,所以在往数据库里面插入数据的时候尽量插入年月日标准格式,那样str_to_date和date_format函数就都可以省略不写。
在mysql当中怎么计算两个日期的“年差”,差了多少年? TimeStampDiff(间隔类型, 前一个日期, 后一个日期)
timestampdiff(YEAR, hiredate, now()) 间隔类型: SECOND 秒, MINUTE 分钟, HOUR 小时, DAY 天, WEEK 星期 MONTH 月, QUARTER 季度, YEAR 年
-
round 四舍五入
select round(数值,要保留到小数点的后几位) from 表名;
-
rand() 生成0到1的随机数
select rand() from 表名;
-
ifnull 空处理函数,在所有的数据库当中,只要有null参与的数学运算,最终结果都是null,为了避免这种情况,要使用ifnull。
ifnull用法:ifnull(数据,被当作的值)
如果“数据”为null,把数据当做哪个值。
分组函数(多行处理函数)
多行处理函数特点:输入多行,最终输出一行。
-
count 计数
-
sum 求和
select sum(字段名) from 表名;
-
avg 平均值
-
max 最大值
-
min 最小值
注意:分组函数在使用的时候必须先进行分组,然后才可以使用,如果在使用的时候没有对数据进行分组,那么将默认一整张表为一组。
分组函数自动忽略null,不需要对null进行提前处理。
count(具体字段):表示统计该字段下所有的不为null的元素的总和
count(*):统计表当中的总行数,包括null;
分组函数不能直接使用在where子句中,因为分组函数在使用的的时候必须先分组之后才能使用,where执行的时候,还没有分组,所以where后面不能出现分组函数。
所有分组函数可以组合起来一起用。
分组查询(重点)
分组查询关键字:group by
各个关键字的书写顺序:
select ? ..... from ? ..... where ? ..... group by ? ..... having ? ...... order by ? ..... limit ? ...... 执行顺序:1.from、2.where、3.group by、4.having、5.select、6.order by、7.limit
执行顺序不能颠倒。
在一条select语句中,如果有group by语句的话,select后面只能跟参加分组的字段,以及分组函数,其他的一律不能跟。
使用having可以对分完组之后的数据进行进一步过滤,having不能单独使用,having不能代替where,having必须和group by联合使用。
distinct关键字
distinct:作用:去除重复记录。
结构:select distinct 字段名 from 表名;
distinct只能出现在所有字段的最前方。
如果distinct后面跟有多个字段,则要两个字段同时同时考虑,去除两个字段都相同的记录。
连接查询
多张表联合起来查询数据,被称为连接查询。
连接查询的分类:
根据语法的年代分类:SQL92:1992年出现的语法、SQL99:1999年出现的语法。
根据表连接的方式分类:
-
内连接:等值连接,非等值连接,自连接
-
外连接:左外连接(左连接),右外连接(右连接)
-
全连接:不做重点
笛卡尔积现象:当两张表进行连接查询,没有任何条件限制的时候,最终查询结果条数是两张表条数的乘积。
由笛卡尔积现象可以得知,表的连接次数越多,效率越低,应该尽量减少表的连接次数。
内连接之等值连接
SQL92语法:
select ... ...from a,b where a和b的连接条件;
select 字段名,字段名 from 表名,表名 where 表名.字段名=表名.字段名;
SQL92缺点:结构不清晰,表的连接条件,和后期进一步筛选的条件,都放到了where后面。
SQL99语法:
select .... from a inner join b on a和b的连接条件 where 进一步筛选条件;(inner可以省略,但是加上inner可以一眼就看出来是内连接)
select 字段名,字段名 from 表名 join 表名 on 表名.字段名=表名.字段名;
SQL99优点:表链接的条件是独立的,如果还需要进一步的筛选,再往后加where语句。
内连接之非等值连接
select .... ..... ....from a inner join b on .... between .... and .....;(条件不是一个等量关系)
内连接之自连接
将一张表看成两张表,起两个别名。
外连接
外连接中产生了主次关系。内连接中没有主次关系。
右外连接:select .... .... from 表a right outer join 表b on a和b的连接条件;outer可以省略。
right表示将join关键字右边的表 看成主表,主要是为了将这张表的数据全部查询出来,捎带着关联查询左边的表。
左外连接:select .... .... from a left outer join b on a和b的连接条件;
任何一个左连接都有其左连接的写法。任何一个右连接都有其左连接的写法。
内连接外连接的关联和区别
-
外连接的查询条数一定大于内连接的查询条数
-
内连接的inner和外连接的outer都可以省略不写,但写上可读性更强,区分外连接和内连接主要看join前面是否有right或者left
-
外连接中表的关系有主次之分,内连接表的关系没有主次之分。
多表连接
语法:select .....from a join b on a和b的连接条件
join c on a和c的连接条件
join d on a和d的连接条件;
一条sql中内连接和外连接可以混合存在。
子查询
子查询:select语句中嵌套select语句,被嵌套的select语句称为子查询。
select ? .....(select) from ? .....(select) where ? .....(select)
from字句中的子查询:from后面的子查询,可以将子查询的结果当成一张临时表,给这一张临时表取一个别名。
union
合并查询结果集。可以增加效率。
语法:select * from 表名 where 条件 union select * from 表名 where 条件;
union在使用的时候的注意事项:在进行结果集合并的时候,要求两个结果集的列数相同,并且列和列的数据类型也要一致。
limit
limit是将查询结果集的一部分取出来,通常使用在分页查询当中。
语法:
1:select * from 表名 order by 字段名 排序方式 limit 数据;(limit +数据表示的是取前几名。)
2:select * from 表名 order by 字段名 排序方式 limit startIndex,length;(startIndex是起始下标,length是长度)startIndex从0开始计数
limit 在order by 之后执行。
分页公式:limit (pageNo -1)* pageSize,pageSize(pageNo是页码,pageSize是每页显示的信息条数)
DDL语句
建表:
create table 表名(字段名1 数据类型 default .....,字段名2 数据类型,....);
在建表的时候可以在字段名的数据类型后面指定默认值,语句为default....
如果不指定默认值,则默认值为null;
表名和字段名都属于标识符。
删除表
drop table 表名; //如果表不存在的话会报错
drop table if exists 表名; //如果这张表存在的话,删除,不会报错。
删除数据truncate
和delete 的用法一致。
但truncate删除效率较高,表一次被截断,物理删除,直接把表中全部数据删除,不可以删除单条数据。
优点:删除效率高
缺点:不支持回滚
删除表drop
语法:drop table 表名;
DML语句
插入数据insert
语法格式:insert into 表名(字段名1,字段名2,字段名3....) values(值1,值2,值3....);
表名后的字段名可以省略不写,省略不写代表都写上了,所以values后面都要有对应的值。
字段和值要一一对应。
insert一旦执行成功,必然会多一条记录,如果没有给一些字段指定值的话,那么这些字段就为空。
insert插入多条语句:语法格式:insert into 表名(字段名1,字段名2,字段名3....) values(第一条记录的值1,值2,值3....),(第二条记录的值1,值2,值3.....);
修改数据update
语法格式:update 表名 set 字段名1=值1,字段名 2=值2,..... where 条件;
如果没有条件限制会导致所有的数据全部更新。
删除数据 delete
如果没有条件,整张表的数据会全部删除。
使用delete删除表数据,虽然表中的数据被删除了,但是这个数据在硬盘上的存储空间不会被释放。
delete优点:因为硬盘上的存储空间没有被释放,因此数据被删除后还可以通过回滚来恢复数据。
delete缺点:删除效率比较低。
快速创建(复制)表
语法格式:create table 表名 as select * from 要复制的表名;
原理:将一个查询结果当做一张表新建,表创建完之后,表中的数据也存在新表中。当然也可以选择一部分数据进行建表,只需要修改as后面的内容即可(改成条件查询语句)。
也可以将查询结果插入到一张表中
格式为:insert into 表名 select * from 要插的表;(两张表字段要一致)
约束constraint(重点)
在创建表的时候,给表中的字段加上一些约束,来保证这个表中的数据的完整性,有效性。
约束的作用就是为了保证数据的有效性。
约束包含的种类
列级约束直接在创表的时候在创建字段的后面加上约束语句,表级约束在创表的最后一行加上约束语句。
非空约束:
not null 约束的字段不能为空。
唯一性约束:unique
unique 约束的字段不可以重复,但是可以为null
如果只需要对一个字段约束,则在创建表的时候在字段名后加unique即可 ,如果需要对一个以上的字段进行约束,则需要在创建表的最后一行加上unique(字段名1,字段名2,.....)表示同时对这些字段进行约束,这些字段不可以全部一样,被称为表级约束。
主键约束: primary key(简称pk)
任何一张表都要有主键而且只能有一个,没有主键的话表无效,主键值是每一行记录的唯一标识。
一个字段同时被not null和unique约束的话,该字段自动变成主键字段。(Oracle不是这样的)
主键特征:not null + unique(主键值不能是null,也不能重复)。
复合主键:两个或者两个以上字段做主键,在实际开发中不建议使用复合主键,最好使用单一主键。
主键除了可以按单一主键和复合主键分类外,还可以分为自然主键和业务主键。
自然主键:主键值是一个自然数,和业务没关系
业务主键:主键值和业务紧密关联,例如用银行卡号做主键值,就为业务主键。
在实际开发中自然主键使用的较多,因为自然主键只需要做到不重复就行,不需要有意义,而业务主键不好,因为一旦主键和业务挂钩,当业务发生变动的时候,就可能会影响到主键值,所以不建议使用业务主键。
相关术语:
主键约束
主键字段
主键值
主键值建议使用:int,bigint,char等类型,不建议使用varchar做主键,主键一般都是数字,一般是定长的。
auto_increment 表示自增,从一开始,以一递增。
外键约束: foreign key(简称FK)
格式:foreign key(外键) references 引用的表(相对应的字段);代表着key里面的外键值只能是引用的表中相对应的字段所包含的值。
外键约束涉及的相关术语:
外键约束:一种约束
外键字段:该字段添加了外键约束
外键值:外键字段中的每一个值
外键可以为null,子表中的外键引用的父表中的某个字段,不一定是主键,但至少具有unique约束。
检查约束:check(mysql不支持,Oracle支持)
存储引擎
存储引擎是MySQL中特有的一个术语,其他数据库中没有。(Oracle中有,但是不叫存储引擎)
存储引擎是一个表存储/组织数据的方式,不同的存储引擎,表存储数据的方式不同。
show create table 表名;//查看创建表时候的源代码
在建表的时候可以在最后使用ENGINE来指定存储引擎,CHARSET来指定表的字符编码方式。
结论:mysql默认的存储引擎是:InnoDB,默认的字符编码方式是:utf8.
查看mysql支持的存储引擎:show engines \G
mysql常见的存储引擎:
-
MYISAM存储引擎
他管理的表有以下特征:
-
实用三个文件表示每一个表:
格式文件:存储表结构的定义(mytable.frm)
数据文件:储存表行的内容(mytable.MYD)存储表数据
索引文件:存储表上索引(mytable.MYI)
并且对于一张表来书,主要是主键,或者有unique约束的字段,会自动创建索引。
优势:可被转换为压缩,只读表来节省空间。
缺点:不支持事务,安全性低。
-
-
InnoDB存储引擎
mysql默认的存储引擎,同时也是一个重量级的存储引擎,并且支持事务,支持数据库崩溃后自动恢复机制。
优点:非常安全。(支持事务,以保证数据的安全)
缺点:效率不高,并且也不能压缩,不能转换为只读,不能很好的节省空间。
它管理的表具有下列主要特征: —每个InnoDB表在数据库目录中以. frm格式文件表示 一InnoDB 表空间tablespace 被用于存储表的内容(表空间是一个逻辑名称,表空间存储数据+索引) 一提供--组用来记录事务性活动的日志文件 一用COMMIT (提交)、SAVEPOINT 及ROLLBACK(回滚)支持事务处理 —提供全ACID兼容 一在MySQL服务器崩溃后提供自动恢复 —多版本(MVCC)和行级锁定 一支持外键及引用的完整性,包括级联删除和更新
-
MEMORY存储引擎
使用MEMORY存储引擎的表,其数据存储在内存中,且行的长度固定, 这两个特点使得MEMORY存储引擎非常快。| MEMORY存储引擎管理的表具有下列特征: —在数据库目录内,每个表均以.frm格式的文件表示 一表数据及索引被存储在内存中。(目的就是快,查询快) —表级锁机制。 一不能包含TEXT或BLOB字段。(不可以存储图片视频音频等数据) MEMORY存储引擎以前被称为HEAP引擎。
优点:查询效率是最高的,不需要和硬盘交互。
缺点:不安全,关机之后数据消失,因为数据和索引都是在内存中的。
事务transaction
一个事务其实就是一个完整的业务逻辑,是一个最小的工作单元,不可再分,即批量的DML语句同时成功或者失败。
假设转账,从A账户向B账户中转账10000. 将A账户的钱减去10000 将B账户的钱加上10000 这就是一个完整的业务逻辑。
这是一个最小的工作单元,要么同时失败,同时成功,不可再分。
只有DML语句才会有事务这一说,其他语句与事务无关,
insert,update,delete这三个语句与事务有关,其他的都与事务无关。只要操作涉及到数据的增删改,就一定要考虑安全问题,数据安全是最重要的。
提交事务(commit);清空事务性活动的日志文件,将数据全部彻底持久化到数据库表中。提交事务标着,事务的结束。并且是一种全部成功的结束。
关闭自动提交事务机制用start transaction;语句
回滚事务(rollback):将之前所有的DM操作全部撤销,并且清空事务性活动的日志文件,回滚事务标志着,事务的结束。并且是一种全部失败的结束。回滚只能回滚到上一次的提交点。
mysql默认情况下是自动提交事务(每执行一条DML语句,就提交一次,这种自动提交实际上是不符合我们的开发习惯,因为-一个业务通常是需要多条DM.语句共同执行才能完成的,为了保证数据的安全,必须要求同时成功之后再提交,所以不能执行一条就提交一条。)的。
事物的四个特性:
-
A:原子性(Atomicity),说明事务是最小的工作单元,不可再分
-
C:一致性(consistence),所有事务要求,在同一个事务当中,所有操作必须同时成功,或者同时失败,以保证数据的一致性。
-
I:隔离性(isolation),A事务和B事务之间具有一定的隔离
事务和事务的隔离级别有四个级别:
读未提交:read uncommitted (最低隔离级别)
数据没提交就读到了
事务A可以读到事务B未提交的数据,这种隔离级别存在的问题就是脏读现象(Dirty read)。
这种隔离级别一般都是理论上的,大多数的数据库隔离级别都是二挡起步。
读已提交:read committed
数据提交之后才能读到
事务A只能读取到事务B提交之后的数据,这种隔离级别解决了脏读现象。但是这种隔离级别存在不可重复读数据。不可重复读就是在事务开启之后,第一次读到的数据是3条,当前事务还没有结束,可能第二次再读取的时候,读到的数据是4条,3不等于4称为不可重复读取。这种隔离级别是比较真是的数据,每一次读到的数据是绝对的真实。
Oracle数据库默认的隔了级别是读已提交。
可重复读:repeatable read
数据提交之后也读不到,永远读取得是刚开启事务时的数据
事务A开启之后,不管是多久,每一次在事务A中读取到的数据都是一致的。即使事务B将数据已经修改,并且提交了,事A读取到的数据还是没有发生改变,这就是可重复读,只有当事务A提交后才可以读到事务B对数据的操作。
可重复读解决了不可重复读问题,但是出现了可能会有幻影读的问题。即每一次读到的数据都是幻象,不够真实。
MySQL的默认隔离级别就是可重复读。
序列化/串行化:serializable(最高隔离级别)
这是最高隔离级别,效率最低。解决了所有的问题。 这种隔离级别表示事务排队,不能并发! 有点像java中的synchronized,线程同步(事务同步) 每一次读取到的数据都是最真实的,并且效率是最低的。
查看事务隔离级别:select @@transaction_isolation;
设置事务隔离等级:set global transaction isolation level 隔离等级;隔离等级包括:read uncommitted,repeatable read,read committed,serializable。
-
D:持久性(durability),事务最终结束的一个保障,事务提交,就相当于将没有保存到硬盘上的数据保存到硬盘上。
索引
索引是在数据库表的字段上添加的,是为了提高查询效率存在的一种机制。一张表的一一个字段可以添加一个索引,当然,多个字段联合起来也可以添加索引。索引相当于一本书的目录,是为了缩小扫描范围而存在的一种机制.
MySQL在查询方面主要就是两种方式,一种是全表扫描,一种是根据索引检索。
在MySQL中索引是采用二叉树的形式排序的,采用中序遍历的方式遍历取数据。
在任何数据库中主键都会自动添加索引对象,并且在mysql当中,一个字段上如果有unique约束的话,也会自动创建索引对象。
在任何的数据库当中,任何一张表的任何一条记录在硬盘存储上都有一个硬盘的物理存储编号。
在mysq1当中,索引是一个单独的对象,不同的存储引擎以怀同的形式存在,在MyISAM存 储引擎中,索引存储在一一个. MYI文件中。在InnoDB存储引擎中索引存储在一个 逻辑名称叫做tablespace的当中。在MEMORY存储引擎当中索引被存储在内存当中。不管索引存储在哪里,索引在mysql当中都是以一个自平衡二叉树(B-tree)的形式存在。
在MySQL当中,主键上以及unique字段上都会自动添加索引。
给字段添加索引的条件: 条件1:数据量庞大(到底有多么庞大算庞大,这个需要测试,因为每一个硬件环境不同)
条件2:该字段经常出现在where的后面,以条件的形式存在,也就是说这个字段总是被扫描。
条件3:该字段很少的DML (insert deliete update) 操作。( 因为DML之后,索引需要重新排序。
建议不要随意添加索引,因为索引也是需要维护的,太多的话反而会降低系统的性能,建议通过主键查询,unique约束的字段进行查询效率是比较高的。
索引相关语句:
创建索引:create index A on B(C); 给B表的C字段添加一个名字为A的索引
删除索引:drop index A on B;删除B表上的名字为A的索引。
查看一个sql语句是否使用了索引进行检索:explain 查询语句;(如果使用了索引进行检索,则type为ref类型)
索引失效的情况:
1.查询的时候使用了模糊查询%开头了。
2.使用or的时候会失效,如果使用or那么要求or两边的条件字段都要有索引,才会走索引,如果其中一边有一个字段没有索引,那么另一个字段上的索引也会失效。所以这就是为什么不建议使用or的原因。
3.是用复合索引的时候,没有使用左侧的列查找,索引失效,复合索引就是两个字段或者更多的字段联合起来添加一个索引。
4.在where当中,索引列参加了运算,索引失效。
5.在where当中索引列使用了函数,索引失效。
等等......
索引是各种数据库进行优化的重要手段。有话的时候优先考虑的因素就是索引,索引在数据库中分了很多类,例如单一索引(一个字段上添加索引),复合索引(两个字段或者更多的字段上添加索引),主键索引(主键上添加索引),唯一性索引(具有unique约束的字段上添加索引),不过唯一性比较弱的字段上添加索引用处不大。
试图
view:站在不同的角度去看待同一份数据。
创建视图:create view A as 查询语句;(将查询语句查出来的结果作为试图A)只有DQL语句才能以view的形式创建。
注意:视图对应的语句只能是DQL语句,但是视图对象创建完成之后,可以对视图进行增删改查等操作。
增删改查又叫做CRUD。C:create(增) R:retrieve (查)U:update(改) D:delete(删)
删除视图:drop view A;(删除视图A)
视图特点:通过对视图的操作,会影响到原表数据。
视图作用:方便,简化开发,利于维护。
DBA常用命令
数据导出:在windows的dos命令窗口中执行
导出一个数据库:mysqldump 要导出的数据库的名字 >D:\为导出文件命名.sql -uroot -p123456
例如:mysqldump bjpowernode >D:\bjpowernode.sql -uroot -p123456
导出数据库中的一个表:mysqldump 要导出的数据库的名字 表名>D:\为导出文件命名.sql -uroot -p123456
数据导入:在mysql中执行
先创建相关数据库
然后ues数据库
最后source mysql文件路径
三范式
数据库设计范式是数据库表的设计依据,教你怎么进行数据库表的设计。
数据库的三个范式:
第一范式:要求任何一张表必须有主键,每一个字段的原子性不可再分。最核心最重要的范式,所有的表的设计都要满足。
一对一表设计口诀:一对一,外键唯一
第二范式:建立在第一范式的基础上,要求所有的非主键字段完全依赖主键,不能产生部分依赖。
多对多表设计口诀:多对多,三张表,关系表两个外键。
第三范式:建立在第二范式的基础之上,要求所有非主键字段直接依赖主键,不要产生传递依赖。
一对多表设计口诀:一对多,两张表,多的表加外键
设计数据库表的时候,按照以上范式进行,可以避免表中数据的冗余,空间的浪费。
数据库三范式是理论上的,实践和理论有时候有偏差,最终的目的都是为了满足客户的需求,有的时候回拿冗余换执行速度,因为在sql当中,表和标的连接次数越多,效率越低(笛卡尔积)有的时候可能会存在冗余,但是为了减少表的连接次数,这样做也是合理的,并且对于开发人员来说,sql语句的编写难度也会降低。。
mysql中常见的数据类型
-
varchar(最长255)
可变长度的字符串。会根据实际的数据长度动态分配空间。
优点:节省空间
缺点:需要动态分配空间,速度慢。
-
char(最长255):
定长字符串,不管实际数据长度是多少,都会分配固定长度的空间去存储数据。
优点:不需要动态的分配空间,速度快
缺点:如果使用不当,会导致空间的浪费。
-
int (最长11) 等同于java的int
-
bigint 等同于java的long
-
float 单精度浮点型数据
-
double 双精度浮点型数据
-
date 短日期类型
-
datetime 长日期类型
-
date和 datetime两个类型的区别
date是短日期,只包括年月日信息
mysql短日期默认格式:%Y-%m-%d
datetime是长日期,包括年月日时分秒信息。
mysql长日期默认格式:%Y-%m-%d %h:%i:%s
now()函数可以获取当前系统时间。
-
clob Charactor Large OBject的简称
字符大对象,最多可以存储4G的字符串,超过255个字符的都要使用clob字符大对象来存储。
-
blob Binary Large Object的简称
二进制大对象,专门用来存储图片,视频,声音等流媒体数据。往blob类型的字段上插入数据的时候,需要使用Io流才可以。
sql语句分类
sql语句有很多,可以进行分类,更容易记忆,分为四个种类:
分别为:
DQL:Data Query Language,数据查询语句(凡是带有select关键字的都是查询语句)。
DML:Data Manipulation Language,数据操作语句(凡是对表中的数据进行增删改的都是数据操作语句)insert(增)、delete(删)、update(改)。这些语句主要是操作表中的数据data。
DDL :Data Definition Language,数据定义语言,(凡是带有create、drop、alter、的都是数据定义语言)create(新建,等同于增)、drop(删除)、alter(修改)
这个增删改和DML不同,DDL语言主要是对表结构进行操作。修改表结构的操作是不需要写到java程序当中的。
TCL:Transactional Control Language,事务控制语言,包括commit(事务提交);rollback(事务回滚)。
DCL:Data Control Language,数据控制语言,包括grant(授权),revoke(撤销权限).....等等。
mysql的一些注意事项
-
注意:sql语句所有的符号要使用英文的
-
字符串要用单引号括起来
-