人生倒计时
-
今日已经过去小时
-
这周已经过去天
-
本月已经过去天
-
今年已经过去个月
2021 最热门的 20 个数据库学习总结,你会用哪几个?
数据库有多重要就不用我说了吧,懂得都懂!
今天就来看看2021最热门的数据库有哪些,该怎么学怎么用,文章开始之前先来看看这张图
从图中数据可以看到,稳居前三的Oracle、MySQL和MicrosoftSQLServer分数出现了较大幅度的下跌,分别减少46.82、34.14和7.33分。
其中SQLServer分数已经连续下跌了两个月。若与去年同期的数据相比,三者下跌的分数平均已达到64分。
后起之秀PostgreSQL和MongoDB依旧保持着稳步上升的趋势,分数与上个月相比有小幅度增加,与去年同期相比也平均增加了40分左右。
MySQL、OracleandMicrosoftSQLServer学习笔记
数据库学习相关书籍
2021金三银四数据库面试真题总结
好了,话不多说,坐稳扶好,发车喽!
MySQL概述为什么要学数据库大数据时代,所有最后落地最普遍的便是数据库
数据库是所有软件体系中最核心的存在
什么是数据库数据库——DataBase——DB,数据仓库,用于存储和管理数据。
数据库分类关系型数据库——SQLMySQL,Oracle,SqlServer,DB2,SQLlite
通过表和表、行与列之间的关系进行数据存储
非关系型数据库——NoSQLRedis,MongoDB
存储的是键值对。
DBMS——数据库管理系统——DatabaseManagementSystem数据库管理软件
MySQL是数据库管理系统
MySQL简介稳定版本:5.7,8.0
体积小、速度快,成本底、招人成本底
安装建议:尽量不要使用exe安装,因为删除麻烦,且会进入注册表,尽可能使用压缩包安装。
压缩包安装步骤压缩包版的安装方法
解压
在环境变量path上配置解压后bin所在的目录地址
在mysql解压后目录下新建的文件——配置文件
管理员模式运行cmd,用于注册注册表
初始化MySQL数据库mysqld--initialize-insecure
安装MySQL服务mysqldinstall
启动MySQL服务netstartmysql
跳过登录密码验证注释掉设置mysql客户端默认字符集default-character-set=utf8[mysqld]设置mysql的安装目录basedir=D:\ProgramFiles(x86)\mysql\允许最大连接数max_connections=20创建新表时将使用的默认存储引擎default-storage-engine=INNODBskip-grant-tablesskip-grant-tables
复制代码
修改root密码=PASSWORD('123456')whereUser='root';flushprivileges;
复制代码
alteruser'root'@'localhost'identifiedby'123456';
复制代码
再输入密码
复制代码
SQLyogSQLyog验证码SQLyog/Navicat可以查看历史执行记录,包括创建表,数据库等记录,比如navicat详细。
Mysql定义结构创建数据库默认创建数据库字符集编码和排序规则如下
创建表连接数据库当执行命令行连接数据库报错'mysql'不是内部或外部命令,也不是可运行的程序时,是因为我们没有配置好mysql的环境变量,这时候就需要我们往path上添加mysql的安装地址到bin文件夹路径到path上。
--在客户端查看mysql安装目录的语句showvariableslike"%char%";
复制代码
mysql数据存储位置,安装目录下的data文件夹下C:\ProgramData\MySQL\\Data
复制代码
Mysql存储引擎在物理文件下的区别InnoDB一张表对应两个文件分别是:
*.frm——表结构定义文件
*.ibd——表数据和索引的存储文件
MyISAM一张表对应两个文件分别是:
*.frm——表结构定义文件
*.myd——表数据文件data
*.myi——表索引文件index
设置数据库表的字符集编码在创建表结构时设置如下,建议使用这个:
DEFAULTCHARSET=utf8mb4
复制代码
不设置会是mysql默认的字符集编码,Mysql默认字符集编码是Latin1,不支持中文。
第二种设置字符集编码是在mysql的配置文件中设置默认的字符集编码为utf8mb4。建议使用第一种在表结构文件中设置,这样在其他服务器的mysql中就一定是我们设置的字符集编码,因为别人不一定在配置文件中设置了默认的字符集编码为utf8mb4。
character-set-server=utf8mb4
复制代码
修改删除表--修改表名ALTERTABLE旧表名RENAMEAS新表名;ALTERTABLEt_studentRENAMEASstudent;--增加表字段ALTERTABLE表名ADD字段名列属性ALTERTABLEstudentADDaddressVARCHAR(30)DEFAULTNULLCOMMENT'地址';--修改表字段ALTERTABLE表名MODIFY字段名[列属性];ALTERTABLEstudentMODIFYaddressTIMESTAMP;--CHANGE字段可以重命名和修改约束,MODIFY只能修改约束ALTERTABLEstudentCHANGEupdate_timeupdate_datedate;--删除表字段ALTERTABLE表名DROP字段名;ALTERTABLEstudentDROPaddress;
复制代码
--删除表如果存在则删除DROPTABLEIFEXISTSstudent;
复制代码
MySQL的数据管理外键CREATETABLEIFNOTEXISTS`t_grade`(idBIGINT(10)NOTNULLAUTO_INCREMENTCOMMENT'年级id',grade_nameVARCHAR(30)NOTNULLCOMMENT'年级名',PRIMARYKEY(`id`))ENGINE=INNODBCHARSET=utf8mb4COMMENT'年级表';--创建外键方式1--1、学生表的grade_id字段要添加年级表的外键索引--2、给这个外键添加约束(执行引用)CREATETABLEIFNOTEXISTS`t_student`(`id`BIGINT(10)NOTNULLAUTO_INCREMENTCOMMENT'id',`name`VARCHAR(30)NOTNULLCOMMENT'学生姓名',`age`INT(3)NOTNULLCOMMENT'学生年龄',`grade_id`BIGINT(10)NOTNULLCOMMENT'年级id',`create_user`VARCHAR(30)DEFAULTNULLCOMMENT'创建人',`crreate_time`datetimeDEFAULTNULLCOMMENT'创建时间',`update_user`VARCHAR(30)DEFAULTNULLCOMMENT'修改人',`update_time`datetimeDEFAULTNULLCOMMENT'修改时间',`delete_flag`TINYINT(1)DEFAULTNULLCOMMENT'是否删除0-否1-是',`address`VARCHAR(30)DEFAULTNULLCOMMENT'地址',PRIMARYKEY(`id`),KEY(`fk_grade_id`),CONSTRAINT`fk_grade_id`FOREIGNKEY`grade_id`REFERENCES`t_grade`(`id`))ENGINE=INNODBDEFAULTCHARSET=utf8mb4COMMENT='学生表';--创建外键方式2ALTERTABLEt_studentADDCONSTRAINT`fk_grade_id`FOREIGNKEY(`grade_id`)REFERENCES`t_grade`(`id`);
复制代码
注意:外键是物理外键,属于数据库级别的外键,必须管理关系导致的问题。每次做delete或update时都要考虑外检约束,导致开发和测试都不方便。因此强制不得使用外键和级联,一切外键概念必须在应用层解决。
最佳实践数据库只是单纯的表,只存放数据和字段
通过代码层面实现外键功能
Insert——插入语句示例--插入语句--格式insertinto表名([字段名1,字段名2,字段名3])values(值1,值2,值3),(值1,值2,值3);--插入表的字段如果省略不写则需要在传入值时要所以字段值都填上并且与字段顺序一一对应匹配--Columncountdoesn'tmatchvaluecountatrow1INSERTINTOt_studentVALUES(null,'艾米');INSERTINTOt_studentVALUES(6,'艾米2',18,1,'2002-10-10');--对于自增主键我们在插入时可以使用null代替,这样数据库会自增帮我们插入INSERTINTOt_studentVALUES(null,'艾米2',18,1,'2002-10-10');insertintot_student(`name`,age)values('大青山',19);--插入多条数据用(),()隔开insertintot_student(`name`,age)values('池傲天',20),('霍恩斯',200);
复制代码
注意语法都是英文的,包括英文标的符号
插入字段省略则后面valus值必须一一对应
插入多条语句用括号和英文逗号隔开。
Update——修改语句示例--修改--语法UPDATE表名SETcolumn_name=value,[column_name=value]where[条件]UPDATEt_studentSET`name`='年轻的艾米',`age`=6WHEREid=1;UPDATEt_studentSET`name`='年轻的艾米',`age`=6WHEREid=null;--不加where条件的话则更新全部数据,所以要注意UPDATEt_studentSET`name`='年轻的艾米',`age`=6;--修改id=2到5之间的数据,是闭区间updatet_studentsetgrade_id='7'whereidbetween2and5;--or或updatet_studentsetgrade_id='8'whereid=1orid=6;--and和updatet_studentsetgrade_id='9'whereid=1andage=20;--设置的value值可以是一个具体的值,也可以是变量updatet_studentsetcrreate_time=CURRENT_TIMEwhereid=1andage=20;updatet_studentsetupdate_time=t__timewhereid=1andage=20;
复制代码
注意column表的列名最好都带上``,防止数据库保留的关键字问题
where条件没有加入则会修改表全部的数据
设置的value值可以是一个具体的值,也可以是变量,如now(),current_time
set=value设置值之间用逗号隔开
Delete、TRUNCATE——删除语句示例--语法DELETEFROM表名[WHERE条件]--删除指定条件下的数据DELETEFROMt_studentWHEREid=2;--删除所有数据,避免使用DELETEFROMt_student;--更好的表数据删除使用TRUNCATE语句--TRUNCATE表名--TRUNCATE完全清空数据库表truncatet_student;
复制代码
Delete和TRUNCATE的区别相同点:都可以删除数据,不会影响表结构
不同点:
TRUNCATE会重新设置自增列,自增计数器会归零,而Delete自增计数器不会变
TRUNCATE不受事务影响,而Delete可以在事务中回滚rollback
Delete删除的问题当重启数据库时,InnoDB的自增列会归零,因为计数器存在内存中,断电即失;而MyISAM计数器存放在文件中,不会断电或者重启丢失。
Select——查询(DQL)简单查询示例--查询表全部字段全部数据SELECT*fromstudent;--查询指定字段SELECTstudentno,studentnameFROMstudent;--字段和表都可以起别名,可以用as或者空格SELECTstudentnoas学号,studentname姓名FROMstudents;--拼接函数concat--姓名:张伟前来报到,联系号码:SELECTCONCAT('姓名:',studentname,'前来报到,联系号码:',phone)FROMstudent;--DISTINCT去重;
复制代码
通过SELECT进行函数、表达式、变量使用示例--查看系统版本,(函数)形式--5.7.17-logSELECTVERSION();--用于计算,(表达式)--300SELECT100*5-200AS结果;SELECT100*5-200AStotal;--查看自增的步长,即每次自增多少,(变量)--1SELECT@@auto_increment_increment;--筛选出成绩加1分查看`no`,+1scoreFROMresults;,/10asscoreFROMresults;
复制代码
官网方法与函数操作符地址
where条件子句示例where条件结果问布尔值,由一个或多个表达式组成。
逻辑运算符与或非可以使用下面两种语句都行,尽量使用第一种英文。
andornot
||!
--与或非的其他写法展示--and与SELECT*;--or或SELECT*=70||=68;--not非SELECT*=70;
复制代码
模糊查询示例--模糊查询like%表示0到任意个字符,_表示一个字符--查询姓张,名字为2个字的学生SELECT*'张_';--查询名字中带伟的学生SELECT*'%伟%';--in查询SELECT*(1000,1001);
复制代码
联表查询联表示例--左联、右联等外联是要用on来关联否则报错,on确定主表,无论条件如何主表数据都会返回然后进行筛选。SELECT*=='张伟';--内联时用on或者where进行关联都可以SELECT*=='张伟';SELECT*=='张伟';--联表查询思路/*1、分析需求要的字段来自哪些表2、确定使用哪种连接查询3、确定交叉点,比如订单号id4、判断的条件*/--学生年级联表查询,,,,==`subject`=;--自连接,设计表时把有父子关系的两种层级表合并成一张表--进行查询时自己和自己关联查询父类别,子类别fromcategorya,=;
复制代码
1000张伟大二85高等数学-11000张伟大二70高等数学-21000张伟大二68高等数学-31000张伟大二98高等数学-41000张伟大二58C语言-1
复制代码
七种join理论参考
mysql进行关联Join时where和on的区别Join时where和on的区别关键在于leftjoin,rightjoin,fulljoin(innerjoin)的特殊性,不管on上的条件是否为真都会返回left或right表中的记录,full则具有left和right的特性的并集。而innerjion没这个特殊性,则条件放在on中和where中,返回的结果集是相同的。
在使用mysql数据库时,使用leftjoin或者rightjoin都必须要使用关键字on,否则就sql执行就报错。可以这样理解:on是建立外连的桥,两张表如何连接就靠on后面的条件。因为外连分主次表,数据以主表为基础,次表对应连接,如果没有on来建立连接,那么次表的数据就不知道如何对应上主表。而内连,又称为直连,不存在主次表之分,取得是两者的交集,因此不需要on。
外连接时,on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录。而where条件是在临时表生成好后,再对临时表进行过滤的条件。
参考
参考2
分页和排序分页示例分页的意义缓解数据库压力,体验更好,返回数据更快,瀑布流方式分页
--排序ORDERBY字段名DESC--升序ASC,降序DESCSELECT*;--分页limitoffset,pagesize参数描述:(起始值,从0开始),(页面大小)SELECT*,2;SELECT*,2;
复制代码
Java分页实现/***当前分页总页数*/defaultlonggetPages(){if(getSize()==0){return0L;}longpages=getTotal()/getSize();if(getTotal()%getSize()!=0){pages++;}returnpages;}/***计算当前分页偏移量*/defaultlongoffset(){longcurrent=getCurrent();if(current=1L){return0L;}return(current-1)*getSize();}
复制代码
子查询和嵌套查询示例--子查询关联查询,==80=(SELECTsubjectnofrom`subject`='高等数学-4');--多张表联表查询,=`subject`==80='高等数学-4';--嵌套查询,(=80=(SELECTsubjectnofrom`subject`='高等数学-4'))
复制代码
函数常用函数聚合函数where的条件不能用聚合函数,要改用having过滤。
--通过分组查询各个科目的最高分平均分等聚合统计--通过什么字段来分组,该字段不需要是在展示的列名上,MAX()max,min()min,avg()avgFROMresultrINNERJOIN`subject`==80;
复制代码
执行count(1)、count(*)与count(列名)的区别count(列名)会忽略字段中数据为null的值,这时候不会计入总数,而count(1)、count(*)不会忽略null值,只要这一行有数据就会计数,本质是计算行数。
执行效果上:
count(*)包括了所有的列,相当于行数,统计结果时不会忽略列值为null的记录。
count(1)会忽略所有的列,用1代表一行数据,统计结果时不会忽略列值为null的记录。
count(列名)值包括列名那一列,统计结果时当列值数据为null时会忽略计数,不统计。
执行效率上:
列名为主键,count(列名)会比count(1)快
列名不为主键,count(1)会比count(列名)快
如果表多个列并且没有主键,则count(1的执行效率优于count(*)
如果有主键,则selectcount(主键)的执行效率是最优的
如果表只有一个字段,则selectcount(*)最优。
MD5加密什么是MD5?
MD5信息摘要算法(英语:MD5Message-DigestAlgorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hashvalue),用于确保信息传输完整一致。
MD5不可逆,相同的密码值MD5是一样的,因此MD5破解网站的原理是后台存储了MD5的字典,用于匹配MD5加密后的值和加密前的值。
MD5加盐:盐被称作“Salt值”,这个值是由系统随机生成的,并且只有系统知道。即便两个用户使用了同一个密码,由于系统为它们生成的salt值不同,散列值也是不同的。
--创建用户表,测试md5加密CREATEtable`user`(`id`BIGINT(8)UNSIGNEDauto_incrementNOTnullCOMMENT'id',`name`varchar(20)NOTnullCOMMENT'姓名',`pwd`VARCHAR(50)NOTnullCOMMENT'密码',PRIMARYKEY(`id`))ENGINE=INNODBDEFAULTcharset=utf8mb4;--明文密码insertinto`user`(`name`,`pwd`)VALUES('艾米','123456'),('大青山','123456'),('霍恩斯','123456'),('雷葛','123456');--使用MD5加密--指定用户加密update`user`setpwd=MD5(pwd)where`name`='艾米';--更新所有用户加密--注意加密后的MD5值是一样的,之所以艾米用户的值不一样是因为更新所有导致二次加密了update`user`setpwd=MD5(pwd);--插入时加密insertinto`user`(`name`,`pwd`)VALUES('绿儿',MD5('123456'));--校验加密,相当于用户登录--将用户登录的密码用md5加密后与数据库的值比对SELECT*FROM`user`uwhereu.`name`='绿儿'=MD5('123456');
复制代码
事务ACID原子性(Atomicity)原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
一致性(Consistency)事务前后数据的完整性必须保持一致。
隔离性(Isolation)事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
持久性(Durability)持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响
事务的隔离级别因为隔离性导致的脏读、幻读、不可重复读。
脏读:指一个事务读取了另外一个事务未提交的数据。
虚读(幻读)是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。(一般是行影响,多了一行)
不可重复读:在一个事务内读取表中的某一行数据,多次读取结果不同。(这个不一定是错误,只是某些场合不对)
数据库隔离级别设置settransactionisolationlevel设置事务隔离级别select@@tx_isolation查询当前事务隔离级别
设置描述:Serializable可避免脏读、不可重复读、虚读情况的发生。(串行化)Repeatableread可避免脏读、不可重复读情况的发生。(可重复读)Readcommitted可避免脏读情况发生(读已提交)。Readuncommitted最低级别,以上情况均无法保证。(读未提交)
数据库ACID参考
数据库操作事务示例--关闭事务自动提交SETautocommit=0;--mysql默认开启事务自动提交SETautocommit=1;STARTTRANSACTION;insertinto`user`(`name`,`pwd`)VALUES('艾米','123456'),('大青山','123456'),('霍恩斯','123456'),('雷葛','123456');--成功提交事务持久化COMMIT;--回滚,一般用于失败后回滚数据ROLLBACK;--保存点SAVEPOINTa;--回滚到一个事务的保存点ROLLBACKTOSAVEPOINTa;--释放保存点RELEASESAVEPOINTa;
复制代码
索引索引的分类主键索引——PRIMARYKEY
唯一索引——UNIQUEKEY
普通索引——INDEX、KEY
全文索引——FULLTEXT
MySQL索引背后的数据结构及算法原理
如何用EXPLAIN优化sql查询效率一张图彻底搞懂MySQL的explain
索引示例——测试百万数据的索引效果--测试表CREATETABLE`t_user`(`id`bigint(20)unsignedNOTNULLAUTO_INCREMENTCOMMENT'id',`name`varchar(20)NOTNULLCOMMENT'姓名',`email`varchar(50)DEFAULTNULLCOMMENT'邮箱',`phone`varchar(20)DEFAULTNULLCOMMENT'手机号码',`pwd`varchar(50)DEFAULTNULLCOMMENT'密码',`age`TINYINT(3)DEFAULTNULLCOMMENT'年龄',`create_time`datetimeDEFAULTCURRENT_TIMESTAMPCOMMENT'创建时间',`update_time`datetimeDEFAULTCURRENT_TIMESTAMPCOMMENT'修改时间',PRIMARYKEY(`id`))ENGINE=InnoDBAUTO_INCREMENT=1=utf8mb4COMMENT='测试用户表';--插入100w数据函数--写函数前先更改mysql分隔符为$,写函数标记DELIMITER$CREATEFUNCTION100w_data()RETURNSINTBEGINDECLAREnumINTDEFAULT1000000;DECLAREiINTDEFAULT1;WHILEinumDOINSERTINTOt_user(`name`,`email`,`phone`,`pwd`,`age`)VALUES(CONCAT('VIP客户',i),'884849324@',CONCAT('15',FLOOR(RAND()*1000000000)),UUID(),FLOOR(RAND()*100));SETi=i+1;ENDWHILE;RETURNi;END--执行函数SELECT100w_data();--删除函数DROPFUNCTION100w_data;--才能并行SELECT/*+PARALLEL(8)*/100w_data();--未加索引前耗时1s。加索引后耗时0.01-0.02sSELECT*fromt_useruwhereu.`name`='VIP客户100000';--增加索引ALTERTABLEt_userADDINDEXidx_name(`name`);
复制代码
索引原则索引不是越多越好
不要对经常变动的数据加索引
小数据量的表不需要加索引
索引一般用在经常查询的字段上
索引的数据结构Hash
Btree
权限管理和备份权限添加和删除可视化工具——navicat首选我们可以通过可视化工具进行用户的创建,权限的添加和删除。
SQL但在Linux服务器上我们没有可视化界面因此要使用sql语句执行。
--%是允许所有的主机都可以连接CREATEUSER`roy`@`localhost`IDENTIFIEDBY'123456';GRANTAlter,AlterRoutine,Create,CreateRoutine,CreateTemporaryTables,CreateUser,CreateView,Delete,Drop,Event,Execute,File,GrantOption,Index,Insert,LockTables,Process,References,Reload,ReplicationClient,ReplicationSlave,Select,ShowDatabases,ShowView,Shutdown,Super,Trigger,UpdateON*.*TO`roy`@`localhost`;--创建用户CREATEUSERdevelopIDENTIFIEDby'123456';
复制代码
数据库备份为什么要备份:
保证数据库数据不丢失
用于数据的迁移
MySQL数据库备份的方式
直接copy物理文件/data目录下的物理文件
在可视化工具Navicat等上导出
使用命令行导出
可视化工具备份右击要导出的数据库或表转存数据,可以转存表结构或者表结构及数据。
导入就直接把文件执行即可。
命令行导出——linux中使用导出整个数据库mysqldump-hlocalhost-uroot-p123456schoolD:主机-u用户名-p密码数据库表1表2表3物理磁盘位置/文件名mysqldump-hlocalhost-uroot-p123456schoolstudentD:
复制代码
命令行导入——linux中使用source备份文件sourced:用户名-p密码库名备份文件mysql-uroot-p123456schoolstudentD:
复制代码
项目数据库设计数据库设计对比数据库三大范式——数据库设计规范第一范式(1NF——FirstNormalForm)原子性:保证每一列不可再分。
第二范式(2NF)前提:满足第一范式
单一职责原则:每张表只描述一件事情。
第三范式(3NF)前提:满足第一、第二范式
确保数据表中的每一列数据都和主键直接相关,而不能间接相关。
也就是订单表里只能关联商品id,而不能把商品价格、商品种类、商品名称等商品表信息都加进来。
规范性和性能的问题关联查询最多不得超过三张表
考虑商业化的需求和目标,数据库的性能更重要
考虑查询性能问题故意给某些表增加冗余字段。(从多表查询变为单表查询)
其他保存或更新操作的原理原理如下代码,先判断出传入的保存/更新对象是否包含主键id,包含的话执行根据id查询语句,如果得到数据则走更新操作,否则执行插入操作。
publicbooleansaveOrUpdate(Tentity){if(null==entity){returnfalse;}else{TableInfotableInfo=();(tableInfo,"error:!",newObject[0]);StringkeyProperty=();(keyProperty,"error:!",newObject[0]);ObjectidVal=(entity,());return!(idVal)!(((Serializable)idVal))?(entity):(entity);}}
复制代码
本文先写到这吧,有人看的话写写其他的数据库。
版权声明:本文为作者【北游学Java】的原创文章。
原文链接:【】。