mysql学习总结

1、一个汉字占多少长度与编码有关:
UTF-8:一个汉字=3个字节
GBK:一个汉字=2个字节
一秒等于1000毫秒,mysql中int默认长度为11


如果想知道mysql 数据库中的每个表占用的空间、表记录的行数的话,可以打开mysql的information_schema数据库。在该库中有一个tables表,这个表主要字段分别是:
table_schema:数据库名
table_name:表名
engine:所使用的存储引擎
table_rows:记录数
data_length:数据大小(单位字节)
index_length:索引大小
row_format: 可以查看数据表是否压缩过
1.查看执行时间和cpu占用时间
set statistics time on
select * from dbo.Product
set statistics time off

2.查看查询对I/0的操作情况
set statistics io on
select * from dbo.Product
set statistics io off

--比较实用的sql优化
http://www.cnblogs.com/knowledgesea/p/3686105.html

https://www.cnblogs.com/Little-Li/p/8031295.html

一、 基本操作(建、增删改查、关键字(约束、函数等))

AUTO_INCREMENT定义列为自增的属性,一般用于主键,数值会自动加1(只是MySQL特有的)
PRIMARY KEY关键字用于定义列为主键。 您可以使用多列来定义主键,列间以逗号分隔
UNIQUE 唯一约束


-- 用于查询mysql中的时间(显示当前时间)
-- 获取当前时间,格式为(YYYY-MM-DD HH:MM:SS)
SELECT NOW();
-- 获取当前时间,格式为(YYYY-MM-DD)
SELECT CURDATE();
-- 获取当前时间,格式为(HH:MM:SS)
SELECT CURTIME();

时间日期数据类型:
date:你直接就可以理解为2017-3-21 不带时分秒的
datetime,则是带时分秒的 
time (HH-MM-SS)
timestamp:时间戳 很好理解
-- date (YYYY-MM-DD) datetime(YYYY-MM-DD HH-MM-SS)
-- time  (HH-MM-SS)  TIMESTAMP(YYYY-MM-DD HH-MM-SS)

mysql解决datetime与timestamp精确到毫秒的问题
DATETIME(3)       TIMESTAMP(3)  


distinct  查询出某个字段不重复的记录,返回不重复字段的条数count(distinct id)

数据的类型和长度说明:https://www.runoob.com/mysql/mysql-data-types.html

1 、-------------------------------------建:-------------------------------------

索引的类型:
    UNIQUE(唯一索引):不可以出现相同的值,可以有NULL值
    INDEX(普通索引):允许出现相同的索引内容
    PROMARY KEY(主键索引):不允许出现相同的值
    fulltext index(全文索引):可以针对值中的某个单词,但效率确实不敢恭维
    组合索引:实质上是将多个字段建到一个索引里,列值的组合必须唯一

-- 创建用户表(先判断是否存在该用户)

DROP TABLE IF EXISTS users;
CREATE TABLE users(
userId INT AUTO_INCREMENT,
userPhone VARCHAR(20) NOT NULL,
userName VARCHAR(100) NOT NULL,
userPwd VARCHAR(40) NOT NULL,
userOther VARCHAR(100),
userNo VARCHAR(100) UNIQUE NOT NULL,
login_Error INT,
login_Old_Time DATETIME,
PRIMARY KEY (userId)
);

INSERT INTO users(userPhone,userName,userPwd,userNo) VALUES('13122100063','朕1','123456','zhen');
SELECT * FROM users;

DROP TABLE IF EXISTS userInfo;
CREATE TABLE userInfo(
sex VARCHAR(2),
userAddress VARCHAR(100),
userCity VARCHAR(50),
user_No VARCHAR(100) NOT NULL,
user_IDS INT
);
--  创建外键
 ALTER TABLE userInfo ADD FOREIGN KEY (user_IDS)
      REFERENCES user (userId);

或者是:
CREATE TABLE userInfo(
sex VARCHAR(2),
userAddress VARCHAR(100),
userCity VARCHAR(50),
user_No VARCHAR(100) NOT NULL,
user_IDS INT,
FOREIGN KEY fk_emp(user_IDS) REFERENCES USERs(userId)
);

//mysql 中创建视图
    create view V_ESB_SERV_LIST(id,name) as select id,name from esb_serv_list ORDER BY id;
    
//mysql ------    eg:  创建索引  
  alert table 表名 add index 索引名(被创建索引的列名)
    普通索引
    alter table table_name add index index_name (column_list) ;
    唯一索引
    alter table table_name add unique (column_list) ;
    主键索引
    alter table table_name add primary key (column_list) ;
    
    CREATE INDEX index_name ON table_name(username(length)); -- 直接创建索引
  删除索引:
    drop index index_name on table_name ;
    alter table table_name drop index index_name ;
    alter table table_name drop primary key ;-- 只在删除PRIMARY KEY索引中使用,因为一个表只可能有一个PRIMARY KEY索引

    
    
-- 创建存储过程,把一个表中的数据转移到另一个表中。存储过程中先查询最大行数值,通过into赋值给变量,在以变量为查询条件进行数据转移。
-- 1 
DELIMITER$$
DROP PROCEDURE IF EXISTS `cunChu`$$
CREATE PROCEDURE cunChu(IN days INT)
BEGIN
DECLARE maxS INT;
SELECT MIN(userId) INTO maxS FROM users WHERE userId<days;
INSERT INTO myuser SELECT * FROM users WHERE userId>maxS;
END$$
DELIMITER;
-- 调用存储过程
CALL cunChu(5);

2、------------------------------------增-------------------------------------

INSERT INTO users(userPhone,userName,userPwd,userNo) VALUES('13122100063','朕1','123456','zhen');

-- 新增  (给表中新增加一列)
alert table +表名 add(列名 类型);
eg:alert table user add(name varchar2(20));

3、-------------------------------------改-------------------------------------
UPDATE userInfo SET sex='' WHERE user_No=''

-- 删除主键约束
alter table 表名 drop primary key;
-- 添加主键约束
alter table 表名 add primary key(id,name);
-- 修改主键约束
alter  table 表名 modify id int primary key;
-- 添加外键约束
 ALTER TABLE 表名1 ADD FOREIGN KEY (表名1.列名)  REFERENCES 表名2 (表名2.列名);
 
 --修改 (修改表中一列的类型长度)alter--数据库中修改的关键词  MODIFY--指修改(修改已存在的列)
ALTER TABLE Timed_Task_Master MODIFY COLUMN last_Execution_Time DATETIME(3);-- 把日期的精确度改为毫秒


4、-------------------------------------删-------------------------------------

delete from +表名 where +条件;-- 删除数据库中对应的数据
-- 删除 表 已存在的数据
DROP TABLE IF EXISTS userInfo;
-- 删除存储过程-
DROP PROCEDURE IF EXISTS 存储名称


  删除--程度从强到弱
drop  table tb 
 drop将表格直接删除,没有办法找回
truncate (table) tb
 删除表中的所有数据,不能与where一起使用
delete from table (where)
删除表中的数据(可制定某一行)

在mysql中模糊查询写法:
SELECT *FROM ESB_APPS_SYS_LIST WHERE queue_id LIKE '%SAP%';

5、-------------------------------------查------------------------------------- 


limit ?,? 第一个参数显示分页从哪一条开始的,第二个参数为取出多少条数据(limit 5,7从第6条开始然后取出7条数据)

//mysql中的分页:
pageNo显示当前页数
pageSize显示每页显示的条数
(int startIndex=page.getPageSize() * (page.getPageNO()-1);//从哪一条开始的
int endIndex=page.getPageSize();//显示多少条        )

mysql中 round(x,y);x指要处理的数,y是指保留几位小数
        eg:查询: select round(1123.26723,2);
        结果:1123.27        
        查询: select round(1123.26723,-2);
        结果:1100
        
CONCAT()函数用于将多个字符串连接成一个字符串
        eg:SELECT CONCAT(’My’, ‘S’, ‘QL’);
        结果为:MySQL

-- ORDER BY的用法,对一个表的数据列分为A段、B段,分别按照两列进行排序 ,先按照A段中pub_created_time列进行倒叙,再按照B段中的sub_created_time列进行排序
ORDER BY pub_created_time DESC,sub_created_time DESC

desc 降序 、asc 升序


1:join、inner join、cross join;语法select * from A inner join B on A.id = B.A_ID,返回匹配的行

2:left join;语法 select * from A left join B on A.id = B.A_ID,即使右表中没有匹配,也返回左表的所有的行,右表没匹配的都为null;

3:right join ;语法select * from A right join B on A.id = B.A_ID,即使左表中没有匹配,也返回右表所有的行,左表没匹配的都为null。


二、优化操作(查询、插入等)


1)应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。
2)应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描
3)很多时候用 exists 代替 in 是一个好的选择
4)用Where子句替换HAVING 子句 因为HAVING 只会在检索出所有记录之后才对结果集进行过滤

当只需要一行数据的时候使用limit 1
(union all链接两表时,两表的字段要保持一致。)
两表链接查询统计一共有多少条数据:(注:必需给子查询的表加一个伪名eg:allTable)
select count(1),allTable.id
from 
(
select id
from a 
where id>5
union all
select id 
from b 
where id>5
) AS allTable

                   -------            数据转移                 -------            
-- 创建存储过程,把一个表中的数据转移到另一个表中。存储过程中先查询最大行数值,通过into赋值给变量,在以变量为查询条件进行数据转移。
-- 1 
DELIMITER 
USE `esb`
DROP PROCEDURE IF EXISTS `procBackupEsbServHealthLog`
CREATE PROCEDURE `procBackupEsbServHealthLog`(IN days INTEGER)
BEGIN 
    DECLARE maxSeq INT;
    SELECT MAX(seq) INTO maxSeq FROM esb_log.esb_serv_health_log  WHERE DATEDIFF(DATE_FORMAT(NOW(),'%Y-%m-%d'), DATE_FORMAT(created_time,'%Y-%m-%d'))>days;
    INSERT INTO esb_log.esb_serv_health_log_history SELECT * FROM esb_log.esb_serv_health_log WHERE seq <= maxSeq;
  DELETE FROM esb_log.esb_serv_health_log WHERE seq <= maxSeq;
    END
DELIMITER ;

-- 2
DELIMITER 
USE `esb`
DROP PROCEDURE IF EXISTS `procBackupEsbServLog`
CREATE PROCEDURE `procBackupEsbServLog`(IN days INTEGER)
BEGIN 
    DECLARE maxSeq INT;
    SELECT MAX(seq) INTO maxSeq FROM esb_log.esb_serv_log  WHERE DATEDIFF(DATE_FORMAT(NOW(),'%Y-%m-%d'), DATE_FORMAT(created_time,'%Y-%m-%d'))>days;
    INSERT INTO esb_log.esb_serv_log_history SELECT * FROM esb_log.esb_serv_log WHERE seq <= maxSeq;
  DELETE FROM esb_log.esb_serv_log WHERE seq <= maxSeq;
    END
DELIMITER ;

unique一般表示唯一,多与主键primary key
constraint是用来添加完整性约束条件,并且指定该约束条件的名字(这样就方便以后删除这个约束条件)。


三、问题解决


//----- 往MySQL数据库中保存较大的文件时,遇到:
com.mysql.jdbc.PacketTooBigException: Packet for query is too large (8332986 > 4194304).异常
造成这个错误的原因是因为MySQL对数据写入操作进行了限制,限定了单次写入操作的数据大小上限。 
要解决这个问题很简单,只要修改MySQL的该配置即可。

找到MySQL的安装路径下的  my.ini 并打开
查找max_allowed_packet,有没有,没有的话增加
#上传文件的最大值
max_allowed_packet = 20M   

然后重启MySQL


//-----    mysql中添加外键约束遇到一下情况: 
cannot add foreign key constraint 
出现这个问题一般是开发工作者对外键的使用出现了疏忽,我们先清晰一下外键的使用: 
1. 外键字段不能为该表的主键; 
2. 外键字段参考字段必须为参考表的主键。
(外键的建立条件:主表需要有主键,从表关联字段是主表主键。因为主键只有一个,两个表之间只能有一个外键。)

//----- mysql中的查询:(倒叙,OR,模糊查询)
-- 查询内容
SELECT SEQ,SERV_ID,SERV_SN,SERV_DIR,DIRACTORY_NAME,SERV_NAME,REQ_APPS_SYS_ID,REQ_APPS_SYS_NAME,
PROVIDER_APPS_SYS_ID,PROVIDER_APPS_SYS_NAME,BUSINESS_STATUS,MESSAGE_STATUS,REQ_IN_TIME,REQ_OUT_TIME,
RES_IN_TIME,RES_OUT_TIME,ESB_TIME,REQ_TIME,RES_TIME,SERV_TIME,SERV_IP 
FROM V_ESB_SERV_LOG_ALL2 WHERE 1 = 1  AND SERV_ID  LIKE'%10060000000004%'
AND SERV_TYPE  ='2' AND ( MESSAGE_STATUS  ='F' OR BUSINESS_STATUS ='F' ) 
AND CREATED_DATE >='2018-01-01' AND CREATED_DATE <='2018-04-24' ORDER BY SEQ DESC

. 为什么需要预编译
JDBC 中使用对象 PreparedStatement 来抽象预编译语句,使用预编译。预编译阶段可以优化 sql 的执行。
预编译之后的 sql 多数情况下可以直接执行,DBMS 不需要再次编译,越复杂的sql,编译的复杂度将越大,预编译阶段可以合并多次操作为一个操作。
预编译语句对象可以重复利用。把一个 sql 预编译后产生的 PreparedStatement 对象缓存下来,下次对于同一个sql,可以直接使用这个缓存的 PreparedState 对象。
mybatis 默认情况下,将对所有的 sql 进行预编译

#{}与${}的区别: 
1. 能使用#{}的地方尽量使用#{}。${}在预编译之前已经被变量替换了,这会存在sql注入问题。
    #方式能够很大程度防止sql注入,预编译时会编译为?代替参数,能预防SQL注入。
(预编译:sql 预编译指的是数据库驱动在发送 sql 语句和参数给 DBMS 之前对 sql 语句进行编译,这样 DBMS 执行 sql 时,就不需要重新编译。)
2. 表名作为变量时,必须使用 ${ },这是因为,表名是字符串,使用 sql 占位符替换字符串时会带上单引号 '',这会导致 sql 语法错误


在mysql中创建函数时:报This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its de
(mysql 报错This function has none of DETERMINISTIC解决方案(网页地址:https://www.jb51.net/article/97037.htm))
原因:
这是我们开启了bin-log, 我们就必须指定我们的函数是否是
1 deterministic 不确定的
2 no sql 没有sql语句,当然也不会修改数据
3 reads sql data 只是读取数据,当然也不会修改数据
4 modifies sql data 要修改数据
5 contains sql 包含了sql语句
其中在function里面,只有 deterministic, no sql 和 reads sql data 被支持。如果我们开启了 bin-log, 我们就必须为我们的function指定一个参数。
解决方法:
-- 执行
show variables like 'log_bin_trust_function_creators';
-- 显示结果为
 Variable_name          | Value |
+---------------------------------+-------+
| log_bin_trust_function_creators | OFF  |

-- 执行(解决方法(可设置的参数:log_bin_trust_function_creators=off
或者设置为log_bin_trust_function_creators=on))
set global log_bin_trust_function_creators=1;
-- 执行
show variables like 'log_bin_trust_function_creators';
-- 显示结果为
| Variable_name          | Value |
+---------------------------------+-------+
| log_bin_trust_function_creators | ON  |

四、面试常见问题:

1、数据库事务的四个特性及含义(ACID属性)
原子性,一致性,隔离性,持久性
原子性:整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
一致性:在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。
隔离性:隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行 相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操作间的混淆,必须串行化或序列化请 求,使得在同一时间仅有一个请求用于同一数据。
持久性:在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。

并发事务处理带来的问题:

2、视图的作用,可以更改吗?
视图是虚拟的表,不包含任何列和数据,是为了简化复杂的sql查询,隐藏具体细节,保护数据;视图创建后,可以使用与表相同的方式利用它们。
视图不能被索引,也不能有关联的触发器或默认值

3.drop,delete与truncate的区别
drop直接删掉表 truncate删除表中数据,再插入时自增长id又从1开始 delete删除表中数据,可以加where字句。
TRUNCATE 和DELETE只删除数据,而DROP则删除整个表(结构和数据)


4、数据库三大范式
第一范式就是无重复的域,确保每列保持原子性。

第二范式确保每列都和主键相关。

第三范式确保每列都和主键直接相关,而不是间接相关。

5、简述触发器、函数、视图、存储过程?
触发器:trigger触发器是一个特殊的存储过程,它是MySQL在insert、update、delete的时候自动执行的代码块。
eg:create trigger trigger_name
after/before insert /update/delete on 表名
for each row
begin
sql语句:(触发的语句一句或多句)
end

函数: 可以定义,也有内置函数如:sum、concat、round、COUNT(col)返回指定列中非NULL值的个数
视图:view 用于简化复杂的sql操作,
存储过程:procedure


6、索引
1.普通索引
2.唯一索引
3.主键索引
4.组合索引
5.全文索引

    索引的弊端:
1占用磁盘空间
2对dml(插入、修改、删除)操作有影响,变慢
使用场景:
1在经常用where条件,查询数据的地方
2该字段的内容不是唯一的几个值
3字段的内容不需要经常变化,(如修改)
索引优点:
索引大大提高了查询速度,

. 列举 创建索引但是无法命中索引的8种情况

1.如果条件中有or,即使其中有条件带索引也不会使用(这也是为什么尽量少用or的原因)
2.对于多列索引,不是使用的第一部分,则不会使用索引
3.like查询是以%开头
4.如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引
5.如果mysql估计使用全表扫描要比使用索引快,则不使用索引


开启慢查询日志,可以让MySQL记录下查询超过指定时间的语句,通过定位分析性能的瓶颈,才能更好的优化数据库系统的性能。
MySQL中InnoDB引擎的行锁是通过加在什么上完成(或称实现)的?为什么是这样子的?
InnoDB是基于索引来完成行锁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值