Mysql学习总结
Posted fuckjavacode
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mysql学习总结相关的知识,希望对你有一定的参考价值。
MySQL学习总结
mysql 军规
1、不在数据库做运算,复杂的计算放在业务层处理; 2、平衡范式与冗余, 效率优先,往往牺牲范式;
3、 tinyint(1Byte) 、 smallint(2Byte)、 mediumint(3Byte)
int(4Byte) 、 bigint(8Byte) 、DECIMAL(M,D)
bad case:int(1)/int(11)
bad case:尽量不用TEXT/BLOB数据类型,若必须使用则拆分到单独的表
4、避免使用NULL字段, NULL字段的复合索引无效, NULL字段的索引需要额外空间。
5、字符字段必须建前缀索引 idx_tel ,不在索引做列运算 ( 无法使用索引,导致全表扫描 )
避免 % 前缀模糊查询,B+Tree索引不能使用,导致全表扫描
6、OR改写为IN(),or的效率是n级别; in的效率时log(n)级别;in 个数控制在200内
7、OR改写为UNION (会去重) , mysql的索引合并很弱智
select id from t where phone=’159′
union
select id from t where name=’jonh’
8、性能分析: show profile; mysqlsla; mysqldumpslow; show slow log;
explain; show processlist; show query_response_time(percona);
9、group by XX order by null。 group by 会自动排序,如果不需要排序,这样写。
一、细节规范。
1、表、列名小写,关键字都大写。MySql自动忽略多余的空格。
2、少用子查询,性能不好,多用联结。 3、SELECT 语句后面检索的列用逗号隔开,最后一列不能加逗号(报错) 4、sql语句又叫 结构化查询语句,单条sql语句加不加分号无所谓。 5、少用 * 通配符,不用的字段别查出来,不用的字段查询影响性能。 6、SELECT、FROM、WHERE、GROUP BY、HAVING、ORDER BY、LIMIT 7、笛卡尔积:由没有联结条件的表关系返回的结果。检索的数目为 行数X行数。 8、表别名 AS 只在查询执行中使用。 9、char(定长,不补空格)查询检索更快,varchar(变长,补空格) 利用内存更好 二、常用命令操作 1、开关服务。net start/stop mysql 2、登陆: mysql -uroot -p -P3306 -h127.0.0.1 退出 exit; quit; q; 3、修改密码:set password for [email protected] = password(‘****‘); 4、select database();---->查看当前使用的是什么数据库 show databases; ---> use databases_name ---> show tables [from db_name]--->DDLDML等等语句(与Oracle一样) show columns 查看数据表的结构 创建数据库 create database 修改数据库 alter database 删除数据库 drop database set names GBK -----可以更改字体 5、显示当前版本 SELECT VERSION(); 6、显示当前日期时间 SELECT NOW(); 7、显示当前用户 SELECT USER(); 二、基础语法 1、LIMIT x,y 关键字 --- 限制结果,x 下标从 0开始 例子:… … LIMIT 5; ===>表示返回结果不多于5行 LIMIT 1,2; ===>表示从查询结果第1行开始(不包括),返回第二行、第三行 注意:Mysql5支持一种新语法, LIMIT 5 OFFSET 3 ===>从行3开始取5行,不足5行没关系。 2、is null 如果某个字段的值为null,那么用where xx is null 是查不到这条数据的, 可以where xx =‘null’ 3、or 和 and一起使用,and的优先级比较高,一起使用要加括号(规范) 例子:where id=1000 or id=100 and salary>1000 解析:条件为id等于1000或者,id等于100并且工资大于1000。 4、关于 in 和 or的区别 第一,功能上两者的功能都一样。 第二,in 操作符比 or 操作符更快,建议使用 第三,in 语句里还可以写sql语句,or 不行 5、搜索模式:由字面值和通配符或两者组合在一起的搜索条件。区分大小写。 例子:’abc%’和 ‘ABC1000’是不匹配的。 注意1:尾空格,如果一个词后面有‘abc ’ 那么 ‘%abc’是匹配不到‘abc’的,解决办法是使用函数,去掉首尾空格。!!! 注意2:%通配符不能匹配null值. 比如where name like ‘%’ 是匹配不到name=null值的。 注意3:通配符 % _ 都是很有用的,但是他们效率很差,影响性能,尽量避免少用。 如果要用,通配符最好不要放在第一位,那样性能最差。 where last_name=‘Ngao‘; ------------- 要用单引号,只有取别名和日期转换才用双引号 where salary between 300 and 800; ---------- >=300并且<=800 where last_name in (‘Patel‘,‘Dancs‘); -------在这2个之间的一个 where last_name like ‘N%‘; ------------N开头,任意字符 where last_name like ‘N___‘;------------长度为4以N开头 where last_name like ‘#_%‘ escape ‘#‘; ---------以下划线开头的字符, escape ‘#‘ 表示自定义一个转义字符 # 三、常用函数 (1)常见文本处理函数 1、Concat(xx,xx,xx) 用逗号隔开 2、RTrim(‘xx ’)和LTrim(‘ xx’)可以去掉左右空格。 还有一个函数是TRim(‘ xx ’)去掉两边空格 3、Upper( )、Lower( )、Length( )、SubString( ) 4、Abs( ) 返回一个数的绝对值 5、Rand( )返回一个随机数 6、Sqrt( )返回一个数的平方根 7、Mod( )返回除操作的余数 8、replace(object,search,replace) 9、date_add(now(), interval 1 day) (2)常见的日期、时间处理函数。格式必须为 yyyy-mm-dd 1、CurDate( )返回当前日期 CurTime( )返回当前时间 2、Date( ) 返回日期时间的日期部分 3、Now( )返回当前的日期和时间。 4、DateDiff( ) 计算两个日期之差。 5、Time( ) 返回一个日期的时间部分。类似还有 Year()、Month( )等等 附加:如果要的是日期,使用Date( ‘today’) , 其中today=‘2016 – 11 -11 15:30:05’ (3) 聚集函数 1、AVG()返回某列的平均值,忽略null值。 2、COUNT() *表示返回所有,包括null的值。count(列名)忽略null值 3、MAX()返回某列的最大值,忽略null值。 4、MIN() 返回某列的最小值,忽略null值。 5、SUM()返回某列值之和,忽略null值。 注意:可以在聚集函数中使用 去重DISTINCT参数,比如 AVG(DISTINCT xx_xx) 四、分组数据 1、使用GROUP BY 前提:GROUP BY xx_xx 除了聚集函数语句外,GROUP BY语句中的每个列都必须在SELECT 语句中给出。第二,GROUP BY 子句中每个列都必须是检索列或有效的表达式(不能是聚集函数),而且不能使用别名。 附加:可以在GROUP BY xx-xx后面使用 WITH ROLLUP关键字计算出所有分组的汇总数。 2、使用HAVING 过滤分组,不能使用WHERE 因为WHERE是用来过滤行,而不是分组。 WHERE 在分组前进行过滤,HAVING在分组之后过滤。WHERE过滤的行不会出现在HAVING 分组中。 3、UNION 组合查询(自动去重)。UNION ALL 不自动去重。 就是 SELECT xx ...UNION SELECT xx … 后面的SELECT语句依赖前面的数据返回结果集。每个查询必须包含相同的列、表达式、聚焦函数。 附:其实就是将两个WHERE条件分开写了,比如SELECT … WHERE a And b 那么就可以转为 SELECT … WHERE a UNION SELECT … WHERE b 其中SELECT 语句必须相同,列顺序可以不同。 五、语句划分 1、DML语句 ->增删改 2、DDL语句。create drop alter truncate (1)增加列 alter table table_name add 列的完整定义 比如:alter table student add age number(5) not null; --------------------------------------------------------------- (2)修改列 alter table table_name modify 列的完整定义 比如:alter table student modify age number(10) unique; --------------------------------------------------------------- (3)删除列 alter table table_name drop column col_name 比如:alter table student drop column age; --------------------------------------------------------------- (4)增加约束 alter table table_name add constraint cons_name cons_type(col_name); 比如:alter table student add constraint stu_id_pk primary key(id); --------------------------------------------------------------- (5)删除约束 alter table table_name drop constraint cons_name; 比如:alter table student drop constraint sys_c005489; --------------------------------------------------------------- (6)修改对象的名字 rename old_obj_name to new_obj_name; alter table Xxx rename to Xxx; ----------修改表名称 --------------------------------------------------------------- (7)删除表 drop table table_name [cascade constraint] 当表删除后,是把表放到了回收站中,可以还原。 flashback table Xxx to before drop; 六、连接。两个表为例子。 第一种:内部连接,只展示两张表公共的数据。 INNER JOIN xx ON xx=xx 第二种:左连接,展示左边表数据,以及和右边表公共的数据。LEFT JOIN xx ON xx=xx 第三种:右连接,展示右边表数据,以及和左边表公共的数据。RIGHT JOIN xx ON xx=xx 七、增删改查。 (1)INSERT – INSERT INTO tb_name(xx,xx)VALUES ( xx,xx ); a、场景:大量INSERT INTO 语句很耗时间,会降低MySql的性能,可在INSERT INTO 中间使用 LOW_PRIORITY 指示MySQL降低INSERT 语句的优先级,让Select语句优先执行,从而提高性能。 b、插入多行数据。可以提高性能,所以就有了MyBatis中的批处理foreach INSERT INTO tb_name(xx,xx,xx) VALUES ( xx,xx,xx ),(xx,xx,xx) c、INSERT SELECT 语句,从其他表中导入数据。注意,语句中没有VALUES 例: INSERT INTO xx( xx,xx,xx ) SELECT xx,xx,xx FROM xx_tb WHERE ...; (2)UPDATE(对列进行操作) – UPDATE tb_name SET xx=xx , xx=xx WHERE ... ; update ignore XX →update发生错误,也继续执行,不回滚之前的update 操作。 (3)DELETE(删除的是行不是列) – DELETE FROM tb_name WHERE …; a、如果想删除一列使用ALTER语句,改列的值。 b、如果想删除所有行,不要使用DELETE,可以使用 TRUNCATE TABLE语句, 它完成相同工作,速度更快,性能更好。他是删除表然后重新创建表,而不是一行一行删除 三、使用Mysql正则表达式(RegExp) 1、REGEXP 和 Like 的区别 例子:假设表中有2条数据,一条是abc,一条是abc100 where name like ‘abc’ --->找到一条数据;匹配列值为abc的 where name REGEXP ‘abc’ --->找到两条数据;匹配列值含abc的 注意:1、.这个点是正则表达式的一个字符,表示匹配任意一个字符。 2、LIKE 和 REGEXP 都是不区分大小写的(Mysql不区分大小写), 如果想要区分大小写,可以使用 BINARY,比如 where name like BINARY ‘ABC’ 2、进行OR匹配。正则表达式 where name REGEXP ‘abc|cba|bca’ 表示匹配name 包含 abccbaca。 等同于 where name like ‘abc’ or name like ‘cba’ or name like ‘bca’ !!!所以很明显,发现好方便。 3、[ ]是和运算,类似or。用于匹配几个字符之一。 [ 123 ] 表示匹配1或2或3 [^123]表示匹配除了1、2、3之外的数,^在[ ]表示文本的开始 例子:where name REGEXP ‘[123] Ton’ 表示匹配 值中包含 1 Ton 或2Ton 或3Ton的值,1Ton 45567也会匹配到,REGEXP和like不一样。 4、匹配范围,比如[ 1-9 ]、[ a-z ] 5、匹配特殊字符。 必须使用 ‘\’为前导,’\ .’表示查找 . 点运算符表示匹配任意一个字符 例子:where name REGEXP ‘\ .’ 表示匹配名字中有点的值,而不是任意字符,类似于转义 注意:匹配符 是为了匹配字符本身,两个这种符号是因为mysql转义一次,正则表达式转义一次 6、匹配字符类 Mysql的76页 [ :alnum: ] 任意字母和数字 [ a-zA-Z0-9 ] [ :alpha: ] 任意字符 [ a-zA-Z ] [ :digit: ] 任意数字 [ 0-9 ] [ :upper: ] 任意大写字母 [ A-Z ] 7、匹配多个实例,元字符的使用 * 表示0或者多个匹配 + 表示1个或者多个匹配,等同于 {1,} ? 表示0个或者1个匹配,等同于 {0,1} {n} 指定数目的匹配 {n , } 不少于指定数目的匹配 {n ,m} 匹配数目的范围 (m 不能超过255) 例子:1、where name REGEXP ‘[[ :digit: ]] {4}’ 表示匹配任意4位数的数字。 2、^[ 0-9 \ .]表示匹配以 .或者任意数字为第一个字符的字符串。 八、建表以及其它操作 1、关于AUTO_INCREAMENT,自增默认加1。取得这个值可以用:SELECT last_insert_id 2、DEFAULT 默认值,如果是NULL值,就使用DEFAULT 3、RENAME tb_name TO tb_newName; 改表的名字。 (2)视图 作用:一般和SELECT使用,用SELECT检索的数据结果创建成一个视图。 那么当下次我要使用这个SELECT语句时候,我就可以直接使用这个视图来获取数据,这样提高了SQL的复用,而且提高了性能。 CREATE VIEW创建视图,SHOW CREATE VIEW viewname可以查看创建视图的语句。 DROP VIEW viewname 或者使用CREATE OR REPLACE VIEW 这个是当VIEW不存在时候创建,存在就更新。注意,VIEW是检索出来的数据结果集,不是真的表的数据。 九、面试核心问题之存储过程 (一)你用过存储过程么,觉得它怎么样? 答:我用过存储过程,对于这个存储过程我个人觉得它就是多条SQL的合并,中间加了点逻辑控制,可以加一些条件语句、循环语句,存储过程在处理复杂业务时非常的实用,比如对多张表进行复杂的数据操作,如果在前台处理的话,就要多次的数据库连接,一条一条的编译执行sql语句,数据库的执行速度就很慢了而且容易出现bug,但是使用存储过程就可以一步到位,只需要连接一次数据库,只编译一次,而且可以重复使用。上一家公司做的是电商项目,数据量比较小,sql比较简单,就没使用这个存储过程,我个人的原则是所有数据访问在应用层封装为数据访问层,在那里,如果SQL简单的话,直接用SQL;如果SQL复杂,或者数据交互多且中间数据最后不会用到,就使用存储过程。 性能篇: (1)全文本搜索 两种最常用的引擎,MyISAM 和 InnoDB ,前者支持全文本搜索,InnoDB不支持。 InnoDB支持事务,MyISAM不支持事务 全文本搜索是利用索引来搜索,性能更好。使用FULLTEXT(xx_xx)这样以后就可以使用 Match( 这个函数用来指定搜索列 ) ,Against( 指定要搜索的词 ) 比如 WHERE Match(note_text) Against(‘rabbit’) 功能类似于 WHERE note_text LIKE ‘%rabbit%’
以上是关于Mysql学习总结的主要内容,如果未能解决你的问题,请参考以下文章