mysQl

一范式:列不可分()

二范式:在一范式的基础上(一张表只描述一个内容)

三范式:在二范式的基础上(要有主键)

各种函数的使用
–基本函数:lower(参数变小写)\upper(变大写)\length\substr\concat\replace\ifnull\uuid
–小数的函数:round\ceil \floor

#对小数的处理
#round(四舍五入) & ceil(向上取整) & floor(全舍)
select comm,ceil(comm),floor(comm),round(comm) from emp;

–日期的函数:now\year\ month \ day\hour\minute \second\转义字符

–条件函数distinct/where/like/order by/limit/

修改
update 表1 别名
inner|left|right join 表2 别名
on 连接条件
set 列=值,列=值
wehre 筛选条件删除
DELETE t1,t2 FROM A t1 LEFT JOIN B t2 ON t1.Id = t2.id where t1.Id = 2
delete from product where id
插入
INSERT INTO  [表名]([列名],[列名])  VALUES ([列值],[列值])), ([列值],[列值])), ([列值],[列值]));--40.查询选修“赵”老师所授课程的学生中,成绩最高的学生姓名及其成绩
select b.stuNo,a.stuName,max(score) from student a,score b
where a.stuNo=b.stuNo and b.cNo in
(select a.cNo from course a,teacher b where a.tNo=b.tNo and b.tName='钱市保')
group by b.stuNo,a.stuName,b.cNo
having b.cNo in
(select a.cNo from course a,teacher b where a.tNo=b.tNo and b.tName='钱市保')  substring(字段名,7(从那开始(数据库是从1开始算的)),4(4位))
-
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student`  (//创建表`id` bigint(0) NOT NULL,`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`score` int(0) NOT NULL,`banji` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE //主键
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;列转行
SELECT year,
sum(if(month=1,amount,0)) m1,
sum(if(month=2,amount,0)) m2,
sum(if(month=3,amount,0)) m3,
sum(if(month=4,amount,0)) m4
from table2 GROUP BY yearselect year,
sum(case when month = 1 then amount else NULL end) m1,
sum(case when month = 2 then amount else NULL end) m2,
sum(case when month = 3 then amount else NULL end) m3,
sum(case when month = 4 then amount else NULL end) m4
from table2 GROUP BY year

创建索引

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iOEebJqj-1666622177696)(D:\桌面\bug集\扩展\typora-img\image-20220929165836528.png)]

创建唯一索引:创建唯一索引的列的值不能重复
– create unique index <index_name> on表名(列名)
create unique index index_testl on tb_testindex(tid):

创建普通索引:不要求创建索引的列的值的唯一性

–create index on表名(列名);
create index index-test2 on tb_testindex(name);

创建组合索引

–create index on 表名(列名1,列名2…)
create index index_test3 on tb_testindex(tid,name);

#删除索引
DROP INDEX <索引名> ON <表名>
#添加唯一索引
desc teachers;
alter table teachers add UNIQUE(prof);#检查索引列的值必须唯一
#添加复合索引
alter table teachers add index many_index(tno,tname)

#查看索引
show index <索引名> 表名 from 库名

  • Table 表示创建索引的数据表名,这里是 tb_stu_info2 数据表。
  • Non_unique 表示该索引是否是唯一索引。若不是唯一索引,则该列的值为 1;若是唯一索引,则该列的值为 0。
  • Key_name 表示索引的名称。
  • Seq_in_index 表示该列在索引中的位置,如果索引是单列的,则该列的值为1;如果索引是组合索引,则该列的值为每列在索引定义中的顺序。
  • Column_name 表示定义索引的列字段。
  • Collation 表示列以何种顺序存储在索引中。在 MySQL 中,升序显示值“A”(升序),若显示为 NULL,则表示无分类。
  • Cardinality 索引中唯一值数目的估计值。基数根据被存储为整数的统计数据计数,所以即使对于小型表,该值也没有必要是精确的。基数越大,当进行联合时,MySQL使用该索引的机会就越大。
  • Sub_part 表示列中被编入索引的字符的数量。若列只是部分被编入索引,则该列的值为被编入索引的字符的数目;若整列被编入索引,则该列的值为NULL。
  • Packed 指示关键字如何被压缩。若没有被压缩,值为 NULL。
  • Null 用于显示索引列中是否包含 NULL。若列含有 NULL,该列的值为 YES。若没有,则该列的值为 NO。
  • Index_type 显示索引使用的类型和方法(BTREE、FULLTEXT、HASH、RTREE)。
  • Comment 显示评注。

视图的创建

create view 视图名 as 条件(select * from 表)

触发器

SELECT * FROM information_schema.**triggers**; //触发器存放在**triggers**中
DROP TRIGGER 触发器名称  //删除触发器delimiter //
CREATE TRIGGER [触发器的名字]
[触发器执行时机] [触发器监测的对象]
ON [表名]
FOR EACH ROW [触发器主体代码]//
DELIMITER ;
-----------------------------------------------
###### BEFORE  先看触发条件符不符合符合执行,不符合报错
###### AFTER  先执行语句在触发
----------------------------------------------------
DELIMITER //
CREATE TRIGGER customer_status_records
AFTER INSERT
ON customers
FOR EACH ROW
Insert into customer_status(customer_id, status_notes) VALUES(NEW.customer_id, '账户创建成功')//
DELIMITER ;
-----------------------------------------------------
DELIMITER //
CREATE TRIGGER log_sales_updates
AFTER UPDATE
ON sales
FOR EACH ROW
Insert into audit_log(sales_id, previous_amount, new_amount, updated_by, updated_on) VALUES (NEW.sales_id,OLD.sales_amount, NEW.sales_amount,(SELECT USER()), NOW() )//
DELIMITER ;
-------------------------------------------------------
DELIMITER //
CREATE TRIGGER delete_related_info
AFTER DELETE
ON sales
FOR EACH ROW
Delete from customers where customer_id=OLD.customer_id;//
DELIMITER ;

触发器的结构包括:

  • DELIMITER //:MySQL 默认分隔符是; 但在触发器中,我们使用 // 表示触发器的开始与结束。
  • [触发器的名字]:这里填写触发器的名字
  • [触发器执行时机]:这里设置触发器是在关键动作执行之前触发,还是执行之后触发。
  • [触发器监测的对象]:触发器可以监测 INSERTUPDATEDELETE 的操作,当监测的命令对触发器关联的表进行操作时,触发器就被激活了。
  • [表名]:将这个触发器与数据库中的表进行关联,触发器定义在表上,也附着在表上,如果这个表被删除了,那么这个触发器也随之被删除。
  • FOR EACH ROW:这句表示只要满足触发器触发条件,触发器都会被执行,也就是说带上这个参数后,触发器将监测每一行对关联表操作的代码,一旦符合条件,触发器就会被触发。
  • [触发器主体代码]:这里是当满足触发条件后,被触发执行的代码主体。这里可以是一句 SQL 语句,也可以是多行命令。如果是多行命令,那么这些命令要写在 BEGIN...END 之间。

**注:**在创建触发器主体时,还可以使用OLDNEW 来获取 SQL 执行INSERTUPDATEDELETE 操作前后的写入数据。这里没看明白没关系,我们将会在接下来的实践中,展开讲解。

存储过程

delimiter $$ --自定义结束符
create procedure p2()
beginSELECT id,username from `user`;
end $$
delimiter;
--调用存储过程
call P2();
----------传入参数:in----------------
delimiter $$ --自定义结束符
create procedure p3(in param_id int)
beginSELECT *from `user` where `user`.id = param_id;
end $$
delimiter;call p3(2);
------------存储过程   if-----------------
create procedure p4()
begindeclare count int default 40;--定义变量declare result varchar(10);if count >=50 thenset result :='优秀';else if count >=40 thenset result :='良好';elseset result :='不及格';end if;SELECT result;
end;call p4()
------------存储过程   in输入out输出inout即输入又输出-----------------
create procedure p5(in count int,out result varchar(10))
beginif count >=50 thenset result :='优秀';elseif count >=40 thenset result :='良好';elseset result :='不及格';end if;SELECT @result;
end;call p5(45,@result);

事务

ACID实现原理

A 是原子性 是指多条SQL要么都成功要么都失败
C 是一致性 数据不管怎么操作都是一致的
I 是隔离性 数据库允许高并发,同时增删改查数据
D 是持久性 是指对数据的操作持久有效
  1. 脏读:就是事务A读出了一条不存在的数据
  2. 不可重复读:数据读的不一致(事务 A 多次读取同一数据,但事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。
  3. 幻读:select 某记录是否存在,不存在,准备插入此记录,但执行 insert 时发现此记录已存在,无法插入,此时就发生了幻读。

隔离级别

串行话 效率最低,安全性最高(实现表级锁)
读未提交 效率最高,但是安全性最差(多并发时数据可能出错)
读已提交(RC 效率较低,但是安全性较高(oracle数据库的默认级别)
可重复度(RR mysql默认级别

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yQnJN4py-1666622177697)(D:\桌面\bug集\扩展\typora-img\image-20220930104649063.png)]

悲观锁 在处理数据的时候会认为别的线程也会同步修改数据,所有会上锁,这样别的线程想拿到数据就会阻塞直到它拿到锁
实现:synchronized lock 先加锁的都是悲观锁(适合写操作)
乐观锁 就是多个线程处理数据时认为别的线程不会同时修改数据,所有不会上锁,但是在更新的时候会判断在此之间别的线程有没有更新过这个数据
实现:CAS实现、Version版本号控制(适合读操作)
全局锁 对整个数据库实例加锁,加锁后整个实例就处于只读状态后面的DDL、DML就会被阻塞。 典型的使用场景就是全库的逻辑备份,对所有的表进行锁定从而获取一致性试图,保证数据的完整性flush tables whit read lock;//加全局锁 unlock tables;//释放锁
行锁 锁定单个行记录的锁,防止其他事物对此进行update和delect。在RC、RR隔离级别凑支持
表锁 1.读锁 不会阻塞其他客户端的读会阻塞写
2.写锁 既阻塞其他客户端的读又阻塞写
语法:
1.加锁:lock tables 表名…read/write
2.释放锁:unlock tables 客户端断开连接
意向锁 1.意向共享锁(IS):语句 select …lock in share mode添加。
与表锁共享锁read兼容,于表锁排它锁write互斥。
2.意向排他锁(IX):由insert、update、delete、select…for update添加。
与表锁共享锁read级排它锁write都互斥,意向锁之间不会互斥。
主要解决表锁和行锁冲突的问题行级锁
每次操作锁住对应的行数据.锁定粒度最小,发生锁冲突的概率最低,并发度最高。应用在innoDB存储引擎中.。
元数据锁 为了避免DML于DDL冲突,保证读写的正确性
意向锁 1.意向共享锁(IS):语句 select …lock in share mode添加。
与表锁共享锁read兼容,于表锁排它锁write互斥。
2.意向排他锁(IX):由insert、update、delete、select…for update添加。
与表锁共享锁read级排它锁write都互斥,意向锁之间不会互斥。
主要解决表锁和行锁冲突的问题
间隙锁 锁定索引记录间隙(不含该记录),确保索引记录间隙不变,防止其他事物在这个间隙进行insert,产生幻读。在RR隔离级别下支持。
临键锁 临键锁(Nest-Key Lock):行锁和间隙锁组合,同时锁住数据,并锁住数据前面的间隙Gap。在RR隔离级别下支持。

InnoDB实现了以下俩种类型的行锁:
1.共享锁(s):允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。
2.排他锁(x):允许获取排他锁的事务更新数据,防止其他事务获得相同数据集的共享锁和排他锁。

间隙锁/临键锁
1.索引上的等值查询(唯一索引),给不存在的记录加锁时优化为间隙锁。
2.索引上的等值查询(普通索引),向有遍历时最后一个值不满足查询需求时,nest-key losk退化为间隙锁。

存储过程

InnoDB
是一种兼顾高可靠性和高性能的通用存储引擎,在Mysql5.5后,成为Mysql存储引擎
特点
支持事务
行级锁,提高并发访问性能
支持外键FOREIGN KEY约束,保证数据的完整性和正确性
逻辑存储结构
TablsSpece:表空间
Segment:段
Page:页
Row:行
文件
xxx.ibd:xxx代表的是表名,innoDB引擎的每张表都会对应这样一个表空间文件,存储该表的表jieg(frm、sdi)、数据和索引。
参数:innodb_file_per_table
MylSAM
早期默认存储引擎
特点
不支持事务和外键
支持表锁,不支持行锁
访问速度快
文件
xxx.sdi:存储表结构信息
xxx.MYD:存储数据
xxx.MYI:存储索引
Memory
他的表数据是存储在内存中的,由于受到硬件问题、或者断电问题的影响,只能作为临时表或缓存使用。
特点
内存存放(查询快)
hash索引(默认)
文件
xxx.sdi:存储表结构信息


一,数据库
索引分类 主键 单值 复合 唯一
主键 Primary Key
外键 Foreign Key(子表字段)references(主表字段)
复合 INDEX idx_phone_cardno
唯一 Unique
非空 not null
默认 default
检查 check
自增 AUTO_INCREMENT
l 第一范式(1NF):强调的是列的原子性,即列不能够再分成其他几列。

如电话列可进行拆分—家庭电话、公司电话

l 第二范式(2NF):首先是 1NF,另外包含两部分内容,一是表必须有主键;二是没有包含在主键中的列必须完全依赖于主键,而不能只依赖于主键的一部分。

l 第三范式(3NF):首先是 2NF,另外非主键列必须直接依赖于主键,不能存在传递依赖。

--1,概述存储和管理数据的一个仓库,分为两种数据库:关系型数据库和非关系型数据库关系型数据库:表于表之间有联系非关系型数据库:数据间的关系不紧密-NoSQL关系型数据库产品:MySQL:免费的 / Oracle:收费的英文是database/DB
--2,MySQL数据库--安装mysql服务器端:-设置端口号(默认是3306) + 密码(root) + 编码(默认是latin1->utf-8)--如何检查数据库是否安装成功?--执行DOS命令:-找到开始位置的MySQL-MySQL Command line Client-输入密码-展示Welcome就可以了-win+r-输入cmd-输入命令:C:\Users\Administrator>mysql -uroot -proot-展示Welcome就可以了--用客户端工具连接:点击连接-输入连接名-输入密码(检查端口号)-连接测试-连接成功-确定
--3,数据库的结构--数据库--表--行(一条一条的记录)和列(字段)unsigned    表示不能为负数
CREATE TABLE `pms_album` (`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '记录id',`name` varchar(50) DEFAULT NULL COMMENT '相册名称',`description` varchar(255) DEFAULT NULL COMMENT '相册简介',`sort` tinyint unsigned DEFAULT '0' COMMENT '自定义排序序号',`gmt_create` datetime DEFAULT NULL COMMENT '数据创建时间',`gmt_modified` datetime DEFAULT NULL COMMENT '数据最后修改时间',PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='相册';

二,SQL语言
–1,概述
用来操作数据库的语言。可以对数据库里的数据进行CRUD增删改查
分类: DML-数据操纵语言(CRUD)
DDL-数据库定义语言(创建库、创建表)
DCL-数据库控制语言(分配具体权限)
DQL-数据库的查询语言(各种查的语法)
–2,用法:CRUD
–数据库:查询、创建、删除库(谨慎)
–表:查询、创建、删除、修改
–!!!记录:创建、查询、删除、修改
–3,操作数据库的SQL
–查询所有数据库:show databases;
–新建数据库:create database 数据库名;
–新建数据库:create database 数据库名 default character set utf8;
–删除数据库:drop database 数据库名;
–4,操作数据表的SQL
–使用指定数据库:use 数据库名;
–查询所有数据表:show tables;
–新建数据表:
字段类型:int/long double/float char/varchar
create table 表名(
字段1名字 字段类型(字段长度),
字段2名字 字段类型(字段长度),
字段3名字 字段类型(字段长度)
)

         mysql> create table tb_order_detail(-> id int(11),-> order_id int(11),-> num int(4),-> item varchar(30)-> );--查看数据表结构:desc 表名mysql> desc tb_door;--修改数据表:alter table 表名 add column 字段名 字段类型(字段长度)mysql> alter table tb_door add column addr varchar(100);mysql> desc tb_door;--删除数据表:drop table 表名;mysql> drop table tb_order_detail;
--5,!!!!操作记录的SQL--  插入记录    insert into tb_door values(null,’永和大王1店’,666);insert into tb_door values(null,’ 永和大王2店’,888);--查询记录:select 字段名 / * from 表名mysql> select * from student;--添加记录:insert into 表名 values(字段1的值,字段2的值,字段3的值);mysql> set names gbk; #防止中文乱码mysql> insert into student values(1,'张三',18);--修改记录:update 表名 set 字段名 = 字段值mysql> update student set age=100;mysql> update student set name='tony'; #字段如果是字符串要加'??'--删除记录:delete from 表名mysql> delete from student;

三,字段的约束
–1,主键约束
–是指可以给指定的字段添加一个主键约束,来达到 主键的值是唯一的+不能位空的效果
–mysql> create table a(id int);#id不是主键可以重复可以为空
–mysql> create table b(id int primary key);#id是主键必须唯一不能为空
–mysql> create table c(id int primary key auto_increment);#主键自动递增(从1开始)
–2,非空约束
–是指给特定的字段,添加非空约束,达到 字段值不能为空 的效果
–mysql> create table d(id int primary key auto_increment,
-> name varchar(10) not null #not null就是对name字段的非空约束
-> );
–3,唯一约束
–是指给字段加上唯一约束,达到 字段的值必须唯一 的效果
–mysql> create table e(id int primary key auto_increment,
-> age int not null unique #unique是对age字段的值的唯一约束
-> );
day02
一,基础函数
–1,概述
MySQL提供了很多函数,可以快速操作数据.
–2,各种函数的使用
–基本函数:lower\upper\length\substr\concat\replace\ifnull\uuid
–小数的函数:round\ceil \floor
–日期的函数:now\year\ month \ day\hour\minute \second\转义字符
–练习
#查看表结构
desc dept;
select * from dept;
#MySQL的函数们
select * from dept; #查询所有字段的值-低效
select dname from dept; #只查询dname字段的值-高效
select dname,deptno from dept; #只查询dname,deptno字段的值-高效
select dname,lower(dname) from dept;#lower(参数)-把参数变小写
select dname,upper(dname) from dept;#upper(参数)-把参数变大写
select dname,upper(dname),lower(dname) from dept;#查3列
#length(参数)-获取参数的长度
select dname,length(dname),loc,length(loc) from dept;
#substr(1,2)-1是要截取谁2是从哪儿开始(从1开始)
select dname,substr(dname,3) from dept;
#substr(1,2,3)-1是要截取谁2是从哪儿开始(从1开始)3是截取几个
select dname,substr(dname,2,3) from dept;
#concat()-拼接字符串
select dname,concat(dname,‘hello’) from dept;
select dname,concat(dname,“world”) from dept;
select dname,concat(dname,“world”,“123”) from dept;
#replace(1,2,3)替换-1是要替换的字段是谁2是要被替换的字符是啥3是新字符
#Mysql里整数可以简写,字符必须加’'或者""
select dname,replace(dname,‘c’,6) from dept;
select * from emp;
#ifnull(1,2)-1是字段名2是要被替换成的值
#ifnull如果是null可以替换成新值
select comm,ifnull(comm,1) from emp;

     #对小数的处理#round(四舍五入) & ceil(向上取整) & floor(全舍)select comm,ceil(comm),floor(comm),round(comm) from emp;#对日期数据的操作select now() ; #获取年月日时分秒select CURDATE(); #获取年月日select CURTIME(); #获取时分秒#year() month() day()select now(),year(now()),month(now()),day(now())#hour() minute() second()select now(),hour(now()),minute(now()),second(now())select uuid() #得到32位的字符select 'xian'select 'xi\'an'#'是SQL里的特殊符号,想作为普通字符使用需要转义\

–3,条件查询
–1,distinct/where/like/order by/limit
–2,练习
select ‘xian’
select ‘xi’an’#'是SQL里的特殊符号,想作为普通字符使用需要转义
select distinct loc from dept; #给字段的值去重
select * from emp;#查了所有
#给查询结果 加一个过滤条件
select * from emp where 字段名=字段值;#查id=100的数据
select * from emp where id=100;#查id是100的数据
select * from emp where ename=‘jack’ ;#查ename是jack的数据
select id,job,sal from emp where ename=‘jack’#查ename是jack的id,job,sal数据
select ename,job from emp where job=‘副总’;#副总的名字
#查询id>200的所有数据
select * from emp where id>200
#查询id>200的所有数据的名字和工资总和
select sal,comm,ename,sal+ifnull(comm,0) from emp where id>200
select * from emp where true
#SQL执行的顺序:from > where > select
select * from emp where 1=1
#多个条件间的关系: 并且and 或者or
#查询id是100,ename是jack的记录
select * from emp where id=100 or ename=‘jack’
select * from emp where job=‘副总’ and sal>10000
select * from emp where job=‘副总’ or sal>10000
#查询sal是8000,10000,20000的记录
select * from emp where sal=8000 or sal=10000 or sal=20000
select * from emp where sal in(8000,10000,20000)#等于8000或者等于10000或者等于20000
select * from emp where sal not in(8000,10000,20000)#不等于8000或者等于10000或者等于20000
#like 模糊查询
select * from emp where ename like ‘a’;#条件相当于ename=‘a’
select * from emp where ename like ‘%a%’;#中间包含着a
select * from emp where ename like ‘t%’;#以t开始后面有几个都行
select * from emp where ename like ‘%y’;#以y结束前面有几个都行

 #按照null过滤数据select * from emp where comm is null #过滤出来是null的记录select * from emp where comm is not null#过滤出来不是null的记录#between and select * from emp where sal>8000 and sal<20000#过滤工资在[8000,20000]的select * from emp where sal between 8000 and 20000#[8000,20000]#limit 分页技术select * from emp limit 3 #只取前三条select * from emp limit 1,3 #从第二条开始取,取总共3条select * from emp limit 2,2 #从第三条开始取,取总共2条#order by 排序select * from emp order by sal #默认升序,按数字的从小到大select * from emp order by comm #默认升序,null放最上面select * from emp order by ename #默认升序,按自然顺序select * from emp order by hiredate #默认升序,按自然顺序select * from emp ORDER BY sal desc #默认是升序,desc降序#取工资最高的前3个人select * from emp ORDER BY sal desc limit 3;#desc降序排序#SQL的执行顺序? from > ORDER BY > limitselect * from emp ORDER BY sal desc limit 0,3;#从第一条开始取,取3条#查询岗位是副总的 工资最高的员工信息#SQL的执行顺序? from > where >  order by > limitselect * from emp where job='副总' order by sal desc limit 1#2017年以前入职的员工信息select * from emp where year(hiredate) < 2017select * from emp where hiredate < '2017-1-1'#2017-1-1到2021-5-1入职的员工信息select * from emp where hiredate <= '2021-5-1' and hiredate >= '2017-1-1'#公司福利不错13薪,统计员工的年薪select ename,job,sal,comm,(sal+ifnull(comm,0))*13 from emp

–4,聚合函数
–对一列的结果进行运算
–count \ sum \avg \max \min
–练习
#count \sum \avg \max \min
select * from emp
select count(*) from emp #统计emp的记录总数-低效
select count(1) from emp #高效
select count(id) from emp #高效
select sal from emp
select max(sal) from emp #获取sal的最大值
select min(sal) from emp #获取sal的最小值
select avg(sal) from emp #获取sal的平均值
select sum(sal) from emp #获取sal的求和
#获取每个部门的,最高薪
select deptno,min(sal),max(sal) from emp group by deptno
#分组–聚合函数以外的列都需要分组
扩展:
–1,常见错误:
–表里有3列,赋值时只给两列赋值
mysql> insert into dept2 value(‘研发部’,‘北京’); #错误
ERROR 1136 (21S01): Column count doesn’t match value count at row 1
mysql> insert into dept2 value(null,‘研发部’,‘北京’);#正确

 --中文乱码,本来应该是正确的数据,但是说长度太大mysql> insert into dept2 value(null,'研发部','北京');ERROR 1406 (22001): Data too long for column 'dname' at row 1mysql> set names gbk; #防止中文乱码,后面插入的就不乱码了...--未知的列[SQL]select dname,concat(dname,hello) from dept;[Err] 1054 - Unknown column 'hello' in 'field list'

day03
一,分组
–1,概述
把数据按照一个规则划分成一个一个的组
对分组后的数据进行过滤就用固定搭配having
–2,语法
group by 字段 having 要过滤的字段
–3,练习
#---------------分组-----------
select * from emp;
select * from dept;
#最高薪资和平均薪资
select max(sal),avg(sal) from emp;
select job from emp;
#获取每个岗位的最高薪和平均薪
select max(sal),avg(sal),job from emp GROUP BY job;
#获取每个部门的最高薪和平均薪
select max(sal),avg(sal),deptno from emp GROUP BY deptno;
#给分组后的结果加过滤条件 where
select max(sal),avg(sal),deptno from emp
where deptno=1 #对select的结果过滤
group by deptno
#执行顺序:from > group by > having > select
select max(sal),avg(sal),deptno from emp
group by deptno
having deptno = 1

     #查询岗位是副总的最高薪和平均薪select max(sal),avg(sal) from emp where job='副总' #执行顺序? from > where > group by > selectselect max(sal),avg(sal),job from emp where job='副总'  #from表之后过滤表里的记录group by job#执行顺序? from > group by > having > selectselect max(sal),avg(sal),job from emp  group by jobhaving job='副总'#group by是分组,要过滤固定搭配having#平均工资小于10000的部门select avg(sal),deptno from empgroup by deptno #按照非聚合的列分组having avg(sal) < 15000 ; #ok#having deptno < 15000 ; #ok#having sal < 15000 ; #no ok#having job < 15000 ; #no ok#列名 也可以使用别名代替,语法:列名 别名select avg(sal) avg,deptno from empgroup by deptno #按照非聚合的列分组having avg < 10000 ; #过滤条件#deptno出现的次数select deptno,count(deptno) X from empgroup by deptno #非聚合列需要分组#2号deptno出现的次数#having deptno=2 #okhaving X=2 #ok#having job=2 #no ok#having id=2 #no ok

二,事务
–1,概述
为了保证多条SQL语句要么同时成功,要么就同时失败
MySQL默认就开启了事务,一条SQL一个事务
如果想实现多条SQL在一个事务里执行,只能手动管理事务
开启事务:start transaction/begin
结束事务:commit(成功就提交,失败就自动回滚)/rollback(回滚)
–2,事务的4个特性
ACID
A是原子性–是指多条SQL要么都成功要么都失败
C是一致性–总和守恒
I是隔离性–数据库允许高并发,同时增删改查数据
D是持久性–是指对数据的操作持久有效
–3,事务的隔离级别
读未提交–效率最高,但是安全性最差(多并发时数据可能出错)
读已提交–效率较低,但是安全性较高(oracle数据库的默认级别)
可重复读–效率较低,但是安全性较高(MySQL数据库的默认级别)
串行 – 效率最低,安全性最高(实现表级锁)
–4,测试
#MySQL的事务
#MySQL会自动开启事务管理.一条SQL一条SQL的执行
#非要实现多条SQL在一个事务里,只能手动开启事务和结束事务
insert into dept values(null,‘财务部’,‘北京’)
insert into dept values(null,‘运营部’,‘上海’)
insert into dept values(null,‘人事部’,‘北京’)
select * from dept order by deptno desc
#手动管理事务
BEGIN;
insert into dept values(null,‘财务部X’,‘北京’);
insert into dept val(null,‘运营部2’,‘上海’);
insert into dept values(null,‘人事部2’,‘北京’);
commit;#提交事务–如果都正确就提交数据,如果错误数据回滚
#rollback;#回滚事务–不管SQL正确与否都会回滚–用的少

     SELECT @@tx_isolation;#REPEATABLE-READMySQL的默认值可重复读

day04
一,索引
–1,概述
为了提交数据的查询效率,可以给指定的列加索引
哪些列需要加索引?–常用来做查询条件的就加索引
分为几种:单值索引(一个索引只有一个列)
唯一索引(索引列的值必须唯一)
复合索引(一个索引可以包含多个列)
–2,常用SQL
–创建索引
create index 索引名 on 表名(列名)
–查看索引,主键会自动创建索引
SHOW INDEX FROM 表名
–删除索引
ALTER TABLE 表名 DROP INDEX 索引名
–练习:
#给teachers表的tname加索引,提高按照名字查询时的效率
#创建索引
create index tname_index on teachers(tname);
#查看索引
show index from teachers;
#删除索引
alter table teachers drop index tbirthday;
#添加唯一索引
desc teachers;
alter table teachers add UNIQUE(prof);#检查索引列的值必须唯一
#添加复合索引
alter table teachers add index many_index(tno,tname)

二,关联查询
–1,完成多表的关联查询,要知道查哪些表,表之间有什么关系
–2,练习
select * from dept;
select * from emp;
#笛卡尔积–是指多表联查,但是低效,因为查出来数据太多
select * from emp,dept;
#给笛卡尔积数据加过滤条件–就是指多表的关联关系
select * from emp,dept where emp.deptno = dept.deptno;#两张表的关系
select * from emp a,dept b where a.deptno = b.deptno;#使用别名
#查询students和scores表,其中sno=101的数据
select a.sno,a.sname,b.degree from students a,scores b
where a.sno=b.sno #两张表的关
and a.sno=101 #过滤条件

     #查询students和scores表 --inner join/left join/right joinselect * from scores ainner join scores b on a.sno=b.sno #表间的关联关系where a.sno=101 #过滤结果#查询emp和dept表,过滤dname='research'的数据#笛卡儿积方式select * from dept,emp where dept.deptno=emp.deptno#表间的关联关系and dept.dname='research';#关联查询方式select * from dept inner join emp on dept.deptno=emp.deptno#表间的关联关系where dept.dname='research'#子查询方式--把一次查询结果作为一张表来使用#查询research部门的员工信息#先查部门名称是research的部门编号select deptno from dept where dname='research'#再根据查到的部门编号查emp表#select * from emp where deptno=2select * from emp where deptno=(select deptno from dept where dname='research')select * from students inner join scores on  students.sno=scores.snowhere  degree>90#练习子查询:#查询degree>90的学生信息#笛卡尔积方式select * from scores,students #表名where scores.sno=students.sno #两个表里的关联字段and scores.degree>90 #过滤条件#join方式select * from scores  #表名1inner join students  #表名2on  scores.sno=students.sno #两个表里的关联字段where scores.degree>90 #过滤条件#子查询方式select * from students #表名1where sno in(  #过滤条件select sno from scores where degree>90 #子查询)#练习子查询:#查询能讲高等数学的老师的信息select * from teachers where tno =(#先查courses表里老师的编号,再根据编号查teachers表select tno from courses where cname='高等数学')select * from teachers a,courses bwhere a.tno=b.tno and b.cname='高等数学'#练习子查询:#查询部门地址在二区的员工信息select * from emp where deptno in(select deptno from dept where loc='二区')

三,SQL练习题:
#查询所有记录
select * from teachers #低效
#只查询指定列
select tname,tsex from teachers #高效
#查询tno为804的记录
select * from teachers where tno=804
#模糊查询记录
select * from teachers where prof like ‘%教%’
#查询之间范围之间的所有记录
select * from teachers where tno BETWEEN 800 and 820
select * from teachers where tno>= 800 and tno<= 820
select * from teachers where tno in (804,820) #tno必须是804或者是820
# 查询满足两个条件的记录
select * from teachers where tsex=‘男’ and depart=‘计算机系’
select * from teachers where tsex=‘男’ or depart=‘计算机系’
#查询所有岗位
select distinct prof from teachers #distinct去掉重复值
#查询男老师的信息
select * from teachers where tsex=‘男’
#按tbirthday升序查询记录
select * from teachers order by tbirthday #默认是升序asc
#以tno升序、tbirthday降序查询记录
select * from teachers order by tno asc,tbirthday desc
# 查询总人数
select count(*) from teachers #低效
select count(1) from teachers #高效
# 查询各个系的人数
select depart,count(1) from teachers group by depart#非聚合列必须分组
# 查询至少有2人的岗位是啥
select prof,count(1) from teachers group by prof having count(1)>=2
# 查询记录中最年长和最年轻 #获取到出生日期数字越大年龄越小
select min(tbirthday),max(tbirthday) from teachers
# 查询大于平均年龄的记录
select * from teachers
#where里不能用聚合函数
where tbirthday < (
select avg(tbirthday) from teachers #子查询
)
#查询年龄最大的老师信息
select min(tbirthday) from teachers
#查询每个cno的最高分
select cno,max(degree) from scores group by cno
#查询每个cno的平均分
select * from scores group by cno
#查询cno='3-105’的课程信息
select * from courses where cno=‘3-105’
#查询scores表里出现过的课程信息
select * from courses where cno in (
select DISTINCT cno from scores
)
#查询没划分部门的员工信息
select * from emp where deptno is null
#查询同名的员工记录
#select * from emp where count(ename) > 1
select ename from emp GROUP BY ename having count(ename) > 1
#全部学生按出生日期排序
select * from students ORDER BY sbirthday #默认升序(年龄从大到小)
#每个班上最小年龄的学员
select class,max(sbirthday) from students GROUP BY class

 #查询学生的姓名和年龄select sname,year(now())-year(sbirthday) as age from students#查询男教师及其所上的课程select * from teachers a,courses b where a.tno=b.tno and a.tsex='男'#查询得分前3名的分数信息select * from scores order by degree desc limit 3

day07
一,JDBC
–1,代码
package cn.tedu;

 import java.sql.*;import java.util.Scanner;//测试 JDBC//JDBC用来把java程序和数据库连接起来,目的是通过java代码操作数据库public class TestJdbc {public static void main(String[] args) throws Exception {//        method();//普通方式//        method2();//暴露SQL注入问题method3();//解决SQL注入问题}//需求:按照 用户名 和 密码 查询用户信息private static void method3() throws Exception{//注册驱动Class.forName("com.mysql.jdbc.Driver");//获取连接String url="jdbc:mysql://localhost:3306/jdbctest?characterEncoding=utf8";String name="root";String pwd="root";Connection conn = DriverManager.getConnection(url,name,pwd);//获取传输器Statement,执行SQL//        Statement st = conn.createStatement();//SQL注入攻击问题//        String sql = "select * from user where name='"+a+"' and pwd='"+b+"'";//获取传输器PrepareStatement,执行SQL//?叫做占位符,PreparedStatement只把SQL骨架发送给数据库String sql = "select * from user where name=? and pwd=?";PreparedStatement ps = conn.prepareStatement(sql);//给SQL设置参数ps.setString(1,"jack");//第一个?设置参数ps.setString(2,"123");//第二个?设置参数//执行SQLResultSet rs = ps.executeQuery();//解析结果集while(rs.next()){for (int i = 1; i <= 3 ; i++) {//按照索引查System.out.println(rs.getString(i));}}//释放资源rs.close();ps.close();conn.close();}//暴露SQL注入问题--发生了SQL拼接//需求:按照 用户名 和 密码 查询用户信息private static void method2() throws Exception {//中文查不出来数据://String url="jdbc:mysql://localhost:3306/jdbctest?characterEncoding=utf8";//注册驱动Class.forName("com.mysql.jdbc.Driver");//获取连接String url="jdbc:mysql://localhost:3306/jdbctest";String name="root";String pwd="root";Connection conn = DriverManager.getConnection(url,name,pwd);//获取传输器Statement,执行SQLStatement st = conn.createStatement();//TODO 测试SQL注入攻击问题//是指当用户只输入数据时,恶意包含了特殊的SQL语句,改变了SQL语义//导致只需要名字不需要密码也可以查看所有数据(数据泄露)//名字输入后面两种值,都会产生SQL攻击问题: jack'# 或者 jack' or '1=1String a = new Scanner(System.in).nextLine();String b = new Scanner(System.in).nextLine();String sql = "select * from user where name='"+a+"' and pwd='"+b+"'";//执行SQLResultSet rs = st.executeQuery(sql);//解析结果集while(rs.next()){for (int i = 1; i <= 3 ; i++) {//按照索引查System.out.println(rs.getString(i));}}//释放资源rs.close();st.close();conn.close();}//使用JDBC查询user表的数据private static void method() throws Exception {//1,注册驱动(jar包)Class.forName("com.mysql.jdbc.Driver");//2,连接数据库//getConnection(1,2,3)-1是要连接哪个数据-2是用户名-3是密码Connection con = DriverManager.getConnection(//                "协议//服务器的名字:数据库的端口号/数据库名",//                "jdbc:mysql://localhost:3306/jdbctest","jdbc:mysql:///jdbctest",//url简写(使用本机使用默认的端口号)"root","root");//3,获取传输器StatementStatement st = con.createStatement();//4,执行SQLString sql = "select * from user";ResultSet rs = st.executeQuery(sql);//5,解析结果集while(rs.next()){ //next()判断有数据吗//有数据就一个一个解析id/name/pwdfor (int i = 1; i <= 3; i++) {System.out.println( rs.getString(i) );//按索引查;}String id2 = rs.getString("id");//按索引查String name2 = rs.getString("name");//按索引查String pwd2 = rs.getString("pwd");//按索引查System.out.println(id2+name2+pwd2);}//6,释放资源rs.close();st.close();con.close();}}--2,工具类package cn.tedu;import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.ResultSet;public class JDBCUtils {/*** 获取 数据库的连接* @return Connection* @throws Exception*/public static Connection getConnection() throws Exception{//注册驱动Class.forName("com.mysql.jdbc.Driver");//获取连接String url="jdbc:mysql://localhost:3306/jdbctest?characterEncoding=utf8";String name="root";String pwd="root";Connection conn = DriverManager.getConnection(url,name,pwd);return conn;}/*** 关闭JDBC的资源* @param rs 结果集* @param ps 传输器* @param conn 连接*/public static void close(ResultSet rs, PreparedStatement ps,Connection conn){if(rs != null){//为了防止空指针异常try{rs.close();}catch (Exception e){e.printStackTrace();}finally { //为了close时又异常rs = null;}}if(ps != null){//为了防止空指针异常try{ps.close();}catch (Exception e){e.printStackTrace();}finally { //为了close时又异常ps = null;}}if(conn != null){//为了防止空指针异常try{conn.close();}catch (Exception e){e.printStackTrace();}finally { //为了close时又异常conn = null;}}}}--3,改造代码package cn.tedu;import java.sql.*;import java.util.Scanner;//测试 JDBC//JDBC用来把java程序和数据库连接起来,目的是通过java代码操作数据库public class TestJdbc {public static void main(String[] args) throws Exception {//        method();//普通方式//        method2();//暴露SQL注入问题method3();//解决SQL注入问题}//需求:按照 用户名 和 密码 查询用户信息private static void method3(){Connection conn = null;PreparedStatement ps = null;ResultSet rs = null;try {//TODO  改造 调用工具类,获取和数据库的连接conn = JDBCUtils.getConnection();//获取传输器Statement,执行SQL//        Statement st = conn.createStatement();//SQL注入攻击问题//        String sql = "select * from user where name='"+a+"' and pwd='"+b+"'";//获取传输器PrepareStatement,执行SQL//?叫做占位符,PreparedStatement只把SQL骨架发送给数据库String sql = "select * from user where name=? and pwd=?";ps = conn.prepareStatement(sql);//给SQL设置参数ps.setString(1, "jack");//第一个?设置参数ps.setString(2, "123");//第二个?设置参数//执行SQLrs = ps.executeQuery();//解析结果集while (rs.next()) {for (int i = 1; i <= 3; i++) {//按照索引查System.out.println(rs.getString(i));}}}catch (Exception e){e.printStackTrace();}finally{ //释放资源,一定要被执行 !!!//调用工具,完成关闭资源JDBCUtils.close(rs,ps,conn);}}//暴露SQL注入问题--发生了SQL拼接//需求:按照 用户名 和 密码 查询用户信息private static void method2() throws Exception {//中文查不出来数据://String url="jdbc:mysql://localhost:3306/jdbctest?characterEncoding=utf8";//注册驱动Class.forName("com.mysql.jdbc.Driver");//获取连接String url="jdbc:mysql://localhost:3306/jdbctest";String name="root";String pwd="root";Connection conn = DriverManager.getConnection(url,name,pwd);//获取传输器Statement,执行SQLStatement st = conn.createStatement();//TODO 测试SQL注入攻击问题//是指当用户只输入数据时,恶意包含了特殊的SQL语句,改变了SQL语义//导致只需要名字不需要密码也可以查看所有数据(数据泄露)//名字输入后面两种值,都会产生SQL攻击问题: jack'# 或者 jack' or '1=1String a = new Scanner(System.in).nextLine();String b = new Scanner(System.in).nextLine();String sql = "select * from user where name='"+a+"' and pwd='"+b+"'";//执行SQLResultSet rs = st.executeQuery(sql);//解析结果集while(rs.next()){for (int i = 1; i <= 3 ; i++) {//按照索引查System.out.println(rs.getString(i));}}//释放资源rs.close();st.close();conn.close();}//使用JDBC查询user表的数据private static void method() throws Exception {//1,注册驱动(jar包)Class.forName("com.mysql.jdbc.Driver");//2,连接数据库//getConnection(1,2,3)-1是要连接哪个数据-2是用户名-3是密码Connection con = DriverManager.getConnection(//                "协议//服务器的名字:数据库的端口号/数据库名",//                "jdbc:mysql://localhost:3306/jdbctest","jdbc:mysql:///jdbctest",//url简写(使用本机使用默认的端口号)"root","root");//3,获取传输器StatementStatement st = con.createStatement();//4,执行SQLString sql = "select * from user";ResultSet rs = st.executeQuery(sql);//5,解析结果集while(rs.next()){ //next()判断有数据吗//有数据就一个一个解析id/name/pwdfor (int i = 1; i <= 3; i++) {System.out.println( rs.getString(i) );//按索引查;}String id2 = rs.getString("id");//按索引查String name2 = rs.getString("name");//按索引查String pwd2 = rs.getString("pwd");//按索引查System.out.println(id2+name2+pwd2);}//6,释放资源rs.close();st.close();con.close();}}
三,SQL优化--1,查询语句里,用字段名代替* select id,name,age from user--2,过滤条件尽量不要用or,难以避免select id,name,age from user where id=1 or name='123'--3,表设计时,字段的类型,最好用varchar代替char--char是固定长度,可能浪费空间,varchar长度可变--4,模糊查询,最好先确定前面的数据select id,name,age from user where name like 't%'--5,字段的值,尽量用数字不用字符串--查的快,省空间,1个数字只占一个字符,但是一个汉字要占3个字符(utf8) --6,查询的结果范围尽量小,数据量尽量少select id,name,age from user where name='123' and id=3--7,给字段加索引#如果name有索引,由于123这个值写的不规范,会导致索引失效select id,name,age from user where name=123 --8,每个列都可以加索引,但是不能太多,最好不能超过5个--9,对字段的值可以去重,使用distinct关键字,但是不要对太多列去重select distinct * from user--10,过滤条件里最好不要用!=  <>  --11,尽量给null列设置默认值--12,批量操作--需要一次性删除多条(10000)时,最好分批删除(按照500个的方式删除多次)--增加大量数据时,可以只发起一个insert语句,来减少事务的开启和结束insert into user(id) values(1),(2),(3),(4),(5),(6),(7)--13,group by--尽量把数据的范围控制到最小然后再分组      select id,count(*) from user group by id having id > 100 #低效select id,count(*) from user where id > 100 group by id   #高效--14,伪删除设计真实的开发中,很少真正的删除数据,而是把要删除的数据改变状态1 -> 0


lose();
st.close();
con.close();
}
}
三,SQL优化
–1,查询语句里,用字段名代替*
select id,name,age from user
–2,过滤条件尽量不要用or,难以避免
select id,name,age from user where id=1 or name=‘123’
–3,表设计时,字段的类型,最好用varchar代替char
–char是固定长度,可能浪费空间,varchar长度可变
–4,模糊查询,最好先确定前面的数据
select id,name,age from user where name like ‘t%’
–5,字段的值,尽量用数字不用字符串
–查的快,省空间,1个数字只占一个字符,但是一个汉字要占3个字符(utf8)
–6,查询的结果范围尽量小,数据量尽量少
select id,name,age from user where name=‘123’ and id=3
–7,给字段加索引
#如果name有索引,由于123这个值写的不规范,会导致索引失效
select id,name,age from user where name=123
–8,每个列都可以加索引,但是不能太多,最好不能超过5个
–9,对字段的值可以去重,使用distinct关键字,但是不要对太多列去重
select distinct * from user
–10,过滤条件里最好不要用!= <>
–11,尽量给null列设置默认值
–12,批量操作
–需要一次性删除多条(10000)时,最好分批删除(按照500个的方式删除多次)
–增加大量数据时,可以只发起一个insert语句,来减少事务的开启和结束
insert into user(id) values(1),(2),(3),(4),(5),(6),(7)
–13,group by
–尽量把数据的范围控制到最小然后再分组
select id,count() from user group by id having id > 100 #低效
select id,count(
) from user where id > 100 group by id #高效
–14,伪删除设计
真实的开发中,很少真正的删除数据,而是把要删除的数据改变状态1 -> 0

my mysql text相关推荐

  1. MySQL text类型的最大长度

     MySQL text类型的最大长度             MySQL 3种text类型的最大长度如下: TEXT 65,535 bytes ~64kb MEDIUMTEXT 16,777,21 ...

  2. mysql text index_MySQL 全文索引(fulltext index)

    1.创建全文索引(FullText index) 旧版的MySQL的全文索引只能用在MyISAM表格的char.varchar和text的字段上. 不过新版的MySQL5.6.24上InnoDB引擎也 ...

  3. mysql text 不可指定默认值

    mysql error 1101 text类型不允许有默认值 根据 mysql5.0以上版本 strict mode (STRICT_TRANS_TABLES) 的限制: 不支持对not null字段 ...

  4. mysql text blob_mysql的text/blob和行溢出

    blob存储二进制,text存储文本,前者可当做大个的varbinary,而后者可看成升级版的varchar(与long varchar等价): 两者都有4种子类型:tiny,normal(默认),m ...

  5. MySQL TEXT数据类型的最大长度

    TINYTEXT 256 bytes   TEXT 65,535 bytes ~64kb MEDIUMTEXT  16,777,215 bytes ~16MB LONGTEXT 4,294,967,2 ...

  6. mysql text查找性能_MySQL TEXT字段性能

    I now know that TEXT fields are written to disk rather than in memory when queried 仅当查询需要临时表来存储多个排序或 ...

  7. mysql text类型 使用方法_MySQL使用TEXT/BLOB类型的知识点详解

    一.TEXT和BLOB的区别 TEXT和BLOB家族之间仅有的不同是BLOB类型存储的是二进制数据,没有排序规则或字符集,而TEXT类型有字符集或排序规则.说白了如果要储存中文则选择TEXT. 二.默 ...

  8. mysql text 函数的使用方法_MySQL空间数据操作:GeomFromText()和astext()函数报错解决...

    报错问题: 之前在向MySQL导入经纬度数据的时候,用GeomFromText()方法来将字符串格式的空间点坐标转化为Geometry类型,得到了如下的报错: FUNCTION db.GeomFrom ...

  9. mysql text转varchar_关于企业面试中:“ Mysql重点 ”的28道面试题解析!

    问题1:char.varchar的区别是什么? varchar是变长而char的长度是固定的.如果你的内容是固定大小的,你会得到更好的性能. 问题2: TRUNCATE和DELETE的区别是什么? D ...

  10. mysql text 查询速度_数据库学习之让索引加快查询速度(四)

    数据库学习之让索引加快查询速度 目录 索引简介 mysql的索引分类 创建索引 添加与删除索引 索引简介 索引在MySQL中也叫做"键",是存储引擎用于快速找到记录的一种数据结构. ...

最新文章

  1. X3650M3 客户端联不上加密狗!
  2. C++ 十字链表图转java版
  3. tf.argsort
  4. erp系统方案书_解决方案 |快普M8为系统集成企业定制的ERP系统
  5. java 生成msg文件_java – 如何获取.MSG文件的MIME类型?
  6. Centos8 搭建linux集群
  7. FPGA设计思想与技巧
  8. 计算机操作系统英语,操作系统的英文介绍
  9. EasyUI的增删查改(后台ASP.NET)
  10. java 获取32位纯数字 或字母与数字结合的唯一id
  11. Android多国语言缩写(全)
  12. this和that的几点区别
  13. 泰凌微8258入门教程 环境篇③——Telink BDT烧录下载
  14. itextpdf 怎么下划线_itext生成pdf设置下划线,itextpdf下划线,使用setUnderli
  15. Kaggle泰坦尼克号比赛项目详解
  16. 80211速率控制的研究
  17. 当使用VMware给虚拟机扩展硬盘容量时,显示无法扩展容量并提示:在部分链上无法执行所调用的函数,请打开父虚拟磁盘。
  18. Unreal Engine05:UE4基本概念
  19. 真 · 神经网络发明人福岛邦彦获奖,Schmidhuber、李飞飞点赞
  20. 面试前紧急补货——网络

热门文章

  1. express基本用法
  2. 全球一年电子废料可建4500座埃菲尔铁塔
  3. Scrapy 实例——爬取豆瓣图书排名top250
  4. 【数据结构】无头节点的单链表逆置
  5. Apache的作用是什么?
  6. 大数据分析公司_大数据分析以及处理_提供多种数据服务
  7. Java(5)数组、二维数组
  8. OKC和802.11R的知识小科普
  9. TP5 框架 防止 sql注入 + xss攻击 + session盗窃
  10. 【重要通知】报告厅调价最后一天