mysql你问我答
1.尊敬的先生,请您谈谈mysql数据库的引擎
数据库中的表设定了什么存储引擎,那么该表在数据存储方式、数据更新方式、数据查询性能以及是否支持索引等方面就会有不同的“效果”。
mysql引擎大致分两类:
InnoDB:支持事务:
可以实现表锁:select * from tb for update;
还可以实现行锁:select id,name from tb where id=2 for update ;
Myisam:支持全文索引:
特点是查询速度快:
也支持表锁;select * from tb for update;
2.请您写出创建外键的语句
例子援引自 https://my.oschina.net/sallency/blog/465079
//学生表 cid作为外键关联班级表 pid作为 档案表外键的关联 所以这俩货都得有索引
create table my_student(
`id` int unsigned not null auto_increment primary key,
`name` varchar(25) not null comment 'student name',
`pid` int unsigned not null comment 'student profile id',
`cid` int unsigned not null comment 'student class id',
key `cid`(`cid`),
key `pid`(`pid`)
)engine=InnoDB default charset=utf8 auto_increment=1;
//班级表 id作为 学生表外键的关联 已为主键索引
create table my_class(
`id` int unsigned not null auto_increment primary key,
`cname` varchar(25) not null comment 'class name',
`info` tinytext not null default ''
)engine=InnoDB default charset=utf8 auto_increment=1;
添加外键 alter table my_profile add constraint profile_student foreign key (`id`) references my_student(`pid`) on delete cascade on update no action;
3.请您写出语句阐明多对多的关系:援引自 https://www.cnblogs.com/ugfly/p/7739182.html
create table course (
id int primary key auto_increment,
name varchar(20),
teacher_id int unique,
foreign key(teacher_id) references teacher(id)
);
create table student (
id int primary key into_increment,
name varchar(20),
sex enum('male','famale') default 'male',
class_id int,
foreign key(class_id) references class(id)
);
create table student2course (
id int primary key auto_increment,
student_id int,
course_id int,
foreign key(student_id) references student(id)
on delete cascade
on update cascade,
foreign key(course_id) references course(id)
on delete cascade
on update cascade,
score int
);
4.可能的笔试题----mysql数据查询疯狂41例
http://www.cnblogs.com/saintdingspage/p/9017370.html
5.mysql其他重要知识点:援引自https://www.cnblogs.com/OldJack/p/6973579.html#t2
下列数据结构都保存在数据库中
- 触发器
对某个表进行【增/删/改】操作的前后如果希望触发某个特定的行为时,可以使用触发器,触发器用于定制用户对表的行进行【增/删/改】前后的行为。
不过触发器性能不高!
-- 插入前
CREATE TRIGGER tri_before_insert_tb1 BEFORE INSERT ON tb1 FOR EACH ROW
BEGIN
...
END -- 插入后
CREATE TRIGGER tri_after_insert_tb1 AFTER INSERT ON tb1 FOR EACH ROW
BEGIN
...
END -- 删除前
CREATE TRIGGER tri_before_delete_tb1 BEFORE DELETE ON tb1 FOR EACH ROW
BEGIN
...
END -- 删除后
CREATE TRIGGER tri_after_delete_tb1 AFTER DELETE ON tb1 FOR EACH ROW
BEGIN
...
END -- 更新前
CREATE TRIGGER tri_before_update_tb1 BEFORE UPDATE ON tb1 FOR EACH ROW
BEGIN
...
END -- 更新后
CREATE TRIGGER tri_after_update_tb1 AFTER UPDATE ON tb1 FOR EACH ROW
BEGIN
...
END
插入前触发器
delimiter //
CREATE TRIGGER tri_before_insert_tb1 BEFORE INSERT ON tb1 FOR EACH ROW
BEGIN IF NEW. NAME = 'alex' THEN
INSERT INTO tb2 (NAME)
VALUES
('aa');
END IF;
END //
delimiter ;
插入后触发器
CREATE TRIGGER tri_after_insert_tb1 AFTER INSERT ON tb1 FOR EACH ROW
BEGIN
IF NEW. num = THEN
INSERT INTO tb2 (NAME)
VALUES
(''),
('') ;
ELSEIF NEW. num = THEN
INSERT INTO tb2 (NAME)
VALUES
(''),
('') ;
END IF;
END//
delimiter ;
特别的:NEW表示即将插入的数据行,OLD表示即将删除的数据行。
2. 删除触发器
DROP TRIGGER tri_after_insert_tb1;
3. 使用触发器
触发器无法由用户直接调用,而只由对表的【增/删/改】操作被动引发。
insert into tb1(num) values();
存储过程是一个SQL语句集合,当主动去调用存储过程时,其中内部的SQL语句会按照逻辑执行。
1. 创建存储过程
-- 创建存储过程 无参数存储过程 delimiter //
create procedure p1()
BEGIN
select * from t1;
END//
delimiter; -- 执行存储过程 call p1();
对于存储过程,可以接收参数,其参数有三类:
- in 仅用于传入参数用
- out 仅用于返回值用
- inout 既可以传入又可以当作返回值
-- 创建存储过程 有参数的存储过程
delimiter \\
create procedure p1(
in i1 int,
in i2 int,
inout i3 int,
out r1 int
)
BEGIN
DECLARE temp1 int;
DECLARE temp2 int default 0; set temp1 = 1; set r1 = i1 + i2 + temp1 + temp2; set i3 = i3 + 100; end\\
delimiter ; -- 执行存储过程
set @t1 =4;
set @t2 = 0;
CALL p1 (1, 2 ,@t1, @t2);
SELECT @t1,@t2;
应用:
a. 获得结果集
delimiter //
create procedure p1()
begin
select * from v1;
end //
delimiter ;
b. 获得结果集+out值
delimiter //
create procedure p2(
in n1 int,
inout n3 int,
out n2 int,
)
begin
declare temp1 int ;
declare temp2 int default 0; select * from v1;
set n2 = n1 + 100;
set n3 = n3 + n1 + 100;
end //
delimiter ;
c. 事务
delimiter \\
CREATE PROCEDURE p1 (OUT p_return_code TINYINT)
BEGIN
DECLARE
EXIT HANDLER FOR SQLEXCEPTION
BEGIN
-- ERROR
SET p_return_code = 1 ; ROLLBACK ;
END ; DECLARE
EXIT HANDLER FOR SQLWARNING
BEGIN
-- WARNING
SET p_return_code = 2 ; ROLLBACK ;
END ; START TRANSACTION ; DELETE
FROM
tb1 ; INSERT INTO tb2 (NAME)
VALUES
('seven') ; COMMIT ; -- SUCCESS
SET p_return_code = 0 ;
END\\ delimiter ;
d. 游标 cursor
delimiter //
CREATE PROCEDURE p3 ()
BEGIN
DECLARE
ssid INT ; -- 自定义变量1
DECLARE
ssname VARCHAR (50) ; -- 自定义变量2
DECLARE
done INT DEFAULT FALSE ; DECLARE
my_cursor CURSOR FOR SELECT
sid,
sname
FROM
student ; DECLARE
CONTINUE HANDLER FOR NOT FOUND
SET done = TRUE ; OPEN my_cursor ; xxoo :
LOOP
FETCH my_cursor INTO ssid,
ssname ;
IF done THEN
LEAVE xxoo ;
END
IF ; INSERT INTO teacher (tname)
VALUES
(ssname) ;
END
LOOP
xxoo ; CLOSE my_cursor ;
END// delimter ;
e. 动态执行SQL
delimiter \\
CREATE PROCEDURE p4 (IN nid INT)
BEGIN
PREPARE prod
FROM
'select * from student where sid > ?' ;
EXECUTE prod USING @nid ;
DEALLOCATE PREPARE prod ;
END\\ delimiter ;
2. 删除存储过程
drop procedure proc_name;
3. 执行存储过程
若执行存储过程前,该存储过程已被修改,则不会应用最新修改,需要重新建立存储过程,或将原存储过程删除后重新运行定义部分
-- 无参数
call proc_name(); -- 有参数,全in
call proc_name(1,2); -- 有参数,有in,out,inout
set @t1=0;
set @t2=3;
call proc_name(1,2,@t1,@t2);
6.mysql常用内置函数
7.索引相关 援引自http://www.cnblogs.com/wupeiqi/articles/5716963.html
7.1、索引
索引是表的目录,在查找内容之前可以先在目录中查找索引位置,以此快速定位查询数据。对于索引,会保存在额外的文件中。
7.2、索引种类
普通索引:仅加速查询
唯一索引:加速查询 + 列值唯一(可以有null)
主键索引:加速查询 + 列值唯一 + 表中只有一个(不可以有null)
组合索引:多列值组成一个索引,
专门用于组合搜索,其效率大于索引合并
全文索引:对文本的内容进行分词,进行搜索
索引合并,使用多个单列索引组合搜索
覆盖索引,select的数据列只用从索引中就能够取得,不必读取数据行,换句话说查询列要被所建的索引覆盖
7.3、相关命令
- 查看表结构
desc 表名
- 查看生成表的SQL
show create table 表名
- 查看索引
show index from 表名
- 查看执行时间
set profiling = 1;
SQL...
show profiles;
7.4、使用索引和不使用索引
由于索引是专门用于加速搜索而生,所以加上索引之后,查询效率会快到飞起来。
# 有索引
mysql> select * from tb1 where name = 'wupeiqi-888';
+-----+-------------+---------------------+----------------------------------+---------------------+
| nid | name | email | radom | ctime |
+-----+-------------+---------------------+----------------------------------+---------------------+
| 889 | wupeiqi-888 | wupeiqi888@live.com | 5312269e76a16a90b8a8301d5314204b | 2016-08-03 09:33:35 |
+-----+-------------+---------------------+----------------------------------+---------------------+
1 row in set (0.00 sec)
# 无索引
mysql> select * from tb1 where email = 'wupeiqi888@live.com';
+-----+-------------+---------------------+----------------------------------+---------------------+
| nid | name | email | radom | ctime |
+-----+-------------+---------------------+----------------------------------+---------------------+
| 889 | wupeiqi-888 | wupeiqi888@live.com | 5312269e76a16a90b8a8301d5314204b | 2016-08-03 09:33:35 |
+-----+-------------+---------------------+----------------------------------+---------------------+
1 row in set (1.23 sec)
7-5、正确使用索引
数据库表中添加索引后确实会让查询速度起飞,但前提必须是正确的使用索引来查询,如果以错误的方式使用,则即使建立索引也会不奏效。
即使建立索引,索引也不会生效:
- like '%xx'
select * from tb1 where name like '%cn';
- 使用函数
select * from tb1 where reverse(name) = 'wupeiqi';
- or
select * from tb1 where nid = 1 or email = 'seven@live.com';
特别的:当or条件中有未建立索引的列才失效,以下会走索引
select * from tb1 where nid = 1 or name = 'seven';
select * from tb1 where nid = 1 or email = 'seven@live.com' and name = 'alex'
- 类型不一致
如果列是字符串类型,传入条件是必须用引号引起来,不然...
select * from tb1 where name = 999;
- !=
select * from tb1 where name != 'alex'
特别的:如果是主键,则还是会走索引
select * from tb1 where nid != 123
- >
select * from tb1 where name > 'alex'
特别的:如果是主键或索引是整数类型,则还是会走索引
select * from tb1 where nid > 123
select * from tb1 where num > 123
- order by
select email from tb1 order by name desc;
当根据索引排序时候,选择的映射如果不是索引,则不走索引
特别的:如果对主键排序,则还是走索引:
select * from tb1 order by nid desc;
- 组合索引最左前缀
如果组合索引为:(name,email)
name and email -- 使用索引
name -- 使用索引
email -- 不使用索引
7.6、其他注意事项
- 避免使用select *
- count(1)或count(列) 代替 count(*)
- 创建表时尽量时 char 代替 varchar
- 表的字段顺序固定长度的字段优先
- 组合索引代替多个单列索引(经常使用多个条件查询时)
- 尽量使用短索引
- 使用连接(JOIN)来代替子查询(Sub-Queries)
- 连表时注意条件类型需一致
- 索引散列值(重复少)不适合建索引,例:性别不适合
-创建表,把固定长度的往前放,char是定长,varchar长度是自增长
-如果字段的值相对固定,则待选值可以融入数据库列的设置,---相当于把数据放入内存,也能提高查询速度!否则你将不得不用到连接查询!
-尽量避免全表搜索
8.开启慢日志查询的办法
slow_query_log = ON 是否开启慢日志记录
long_query_time = 2 时间限制,超过此时间,则记录
slow_query_log_file = /usr/slow.log 日志文件
log_queries_not_using_indexes = ON 为使用索引的搜索是否记录
9.执行计划
explain + 查询SQL - 用于显示SQL执行信息参数,根据参考信息可以进行SQL优化
mysql> explain
select
*
from
tb2;
+
----+-------------+-------+------+---------------+------+---------+------+------+-------+
| id | select_type |
table
| type | possible_keys |
key
| key_len | ref |
rows
| Extra |
+
----+-------------+-------+------+---------------+------+---------+------+------+-------+
| 1 | SIMPLE | tb2 |
ALL
|
NULL
|
NULL
|
NULL
|
NULL
| 2 |
NULL
|
+
----+-------------+-------+------+---------------+------+---------+------+------+-------+
1 row
in
set
(0.00 sec)
10.导入和导出的mysql命令
不管是Oracle数据库还是SQL Server数据库,每个数据库都有自己的一套数据备份和恢复的方法,MySQL数据库也不例外。MySQL数据库备份和恢复用到了两个命令,分别是“mysqldump”和“mysql”,我们使用“mysqldump”命令进行数据库备份,使用“mysql”命令对数据库进行数据恢复。
语法一、导出数据库中所有表结构;只导出表结构, 不导出表中的数据
mysqldump --opt -d 数据库名称 -u用户名 -p密码 > 保存文件路径
语法二、导出数据库中所有表中的数据;只导出表中的数据,不导出表结构
mysqldump -t 数据库名称 -u用户名 -p密码 > 保存文件路径
语法三、导出数据库中所有的表结构和数据;导出表结构和数据
mysqldump 数据库名称 -u用户名 -p密码 > 保存文件路径
语法四、导出指定表的结构和数据
mysqldump -u用户名 -p密码 -B 数据库名称 --table 表名 > 保存文件路径
语法五、导出指定表数据,只导出数据,不导出表结构
mysqldump -t 数据库名称 -u用户名 -p密码 --table 表名 > 保存文件路径
语法六、将备份文件导入到数据库
mysql -u用户名 -p密码 数据库名称 < 用于恢复数据库的数据文件路径
11.请您谈谈对海量数据的分页意见
问题:往后翻页的时候,会对数据表进行扫描,从而把所有的分页扫描一遍
- 先查主键,在分页。
- select * from tb where id in (
- select id from tb where limit 10 offset 30
- )
- 按照业务需求是否可以设置只让用户看200页(假如客户不看历史数据)
- 记录当前页 数据ID最大值和最小值(上一页下一页)
在翻页时,根据条件先进行筛选;筛选完毕之后,再根据limit offset 查询。
select * from (select * from tb where id > 22222222) as B limit 10 offset 0
如果用户自己修改页码,也可能导致慢;此时对url种的页码进行加密(可以参考rest framework 的分页,对url进行加密,开发时对这种url进行解密开发)。
如果在海量数据中只想获得一条数据,则可以如下操作 select * from coachinfo where name = 'xuxiaodong' limit 1
mysql你问我答的更多相关文章
- MySQL一问一答
一.问:如果有一张表,里面有个字段为id的自增主键,当已经向表里面插入了10条数据之后,删除了id为8,9,10的数据,再把mysql重启,之后再插入一条数据,那么这条数据的id值应该是多少,是8,还 ...
- mysql快问快答
1.查看mysql版本 select version(); show variables like 'version'; 2.mysql 可以按timestamp排序吗? 可以 3.怎么查询商户下是否 ...
- OpenGL快问快答
OpenGL快问快答 本文内容主要来自对(http://www.opengl.org/wiki/FAQ)的翻译,随机加入了本人的观点.与原文相比,章节未必完整,含义未必雷同,顺序未必一致.仅供参考. ...
- Oracle百问百答(四)
Oracle百问百答(四) 31.怎样查看某用户下的表? select table_name from all_tables where owner=upper('jhemr'); 32.怎样查看某用 ...
- Oracle百问百答(二)
Oracle百问百答(二) 11. nvl函数有什么用? NVL( string1, replace_with) 功能:如果string1为NULL,则NVL函数返回replace_with的值,否则 ...
- Oracle百问百答(一)
Oracle百问百答(一) 01.如何查看oracle的版本信息? 02.如何查看系统被锁的事务信息? 03.怎么获取有哪些用户在使用数据库? 04. 数据表中的字段最大数是多少? 表或视图中的最大列 ...
- 微信小程序参数二维码6问6答
微信小程序参数二维码[基础知识篇],从6个常见问题了解小程序参数二维码的入门知识. 1.什么是小程序参数码? 微信小程序参数二维码:针对小程序特定页面,设定相应参数值,用户扫描后进入相应的页面. 2. ...
- k3 Bos开发百问百答
K/3 BOS开发百问百答 (版本:V1.1) K3产品市场部 目录 一.基础资料篇__ 1 [摘要]bos基础资料的显示问题_ 1 [摘要]单 ...
- Java 面试题问与答:编译时与运行时
Java 面试题问与答:编译时与运行时 2012/12/17 | 分类: 基础技术, 职业生涯 | 5 条评论 | 标签: RUNTIME, 面试 分享到:58 本文作者: ImportNew - 朱 ...
随机推荐
- PTA(Advanced Level)1033.To Fill or Not to Fill
With highways available, driving a car from Hangzhou to any other city is easy. But since the tank c ...
- icell更改用户管理员
管理员页面是http://127.0.0.1:8080/PORTAL/tsysLoginController/admin超级管理员是http://127.0.0.1:8080/PORTAL/tsysL ...
- python 之 Urllib库的基本使用
目录 python 之 Urllib库的基本使用 官方文档 什么是Urllib urlopen url参数的使用 data参数的使用 timeout参数的使用 响应 响应类型.状态码.响应头 requ ...
- analysis_tools
- S03_CH04_AXI_DMA_OV5640摄像头采集系统
S03_CH04_AXI_DMA_OV5640摄像头采集系统 4.1概述 本课程讲解如何搭建基于DMA的图形系统,方案原理和搭建7725的一样,只是OV5640显示的分辨率是1280X720如下,只是 ...
- 【第一季】CH06_FPGA设计Verilog基础(三)
[第一季]CH06_FPGA设计Verilog基础(三) 一个完整的设计,除了好的功能描述代码,对于程序的仿真验证是必不可少的.学会如何去验证自己所写的程序,即如何调试自己的程序是一件非常重要的事情. ...
- JAVA生成验证码代码
生成base64格式图片验证码 /** * 验证码的候选内容 */ private char codeSequence[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', ...
- 怎样理解第三方Cookie
1. Cookie往往是用来存储用户信息的, 但有些恶意站点设法伪造了带有正确Cookie的HTTP请求, 这时就会产生安全问题( CSRF 攻击 ). 这里恶意网站获取cookie的行为就是第三方c ...
- [转载]Grid Search
[转载]Grid Search 初学机器学习,之前的模型都是手动调参的,效果一般.同学和我说他用了一个叫grid search的方法.可以实现自动调参,顿时感觉非常高级.吃饭的时候想调参的话最差不过也 ...
- Python的global指令的作用
Python的global指令的作用 学过其他常用编程语言的同学一定清楚,Python是一个语法非常宽容的语言.它是个变量的定义可以省略.直接赋值.根据赋值结果自动确定变量类型的弱类型语言. 但是这样 ...