千行mysql总结
数据库
启动MySQL客户端程序
mysql -h主机名 -u用户名 -p密码
CREATE DATABASE kk;
DROP DATABASE kk;
use kk;
SHOW ENGINES; #列出mysql支持的所有引擎
表
创建表范式:
CREATE [TEMPORARY] TABLE[ IF NOT EXISTS] [库名.]表名 ( 表的结构定义 ){
字段名 数据类型 [NOT NULL | NULL] [DEFAULT default_value] [AUTO_INCREMENT] [UNIQUE [KEY] | [PRIMARY] KEY] [COMMENT 'string']
}表选项
-- 字符集
CHARSET = charset_name
如果表没有设定,则使用数据库字符集
-- 存储引擎
ENGINE = engine_name
-- 自增起始数
AUTO_INCREMENT = 行数
-- 数据文件目录
DATA DIRECTORY = '目录'
-- 索引文件目录
INDEX DIRECTORY = '目录'
-- 表注释
COMMENT = 'string'
-- 分区
PARTITION BY
举例:
CREATE TABLE if not EXISTS credit_linan.u (
`id` int not null auto_increment ,
`name` varchar(255) default 'kk' comment 'scsc',
primary key (id),
key 自定义索引名 (name)
)ENGINE=innodb charset=utf8 ;
– 查看所有表
SHOW TABLES[ LIKE 'pattern']
SHOW TABLES FROM 库名
– 修改表
ALTER TABLE 表名 表的选项
修改存储引擎: ALTER TABLE 表名 ENGINE=MYISAM;
新增字段 ALTER TABLE 表名 ADD COLUMN 字段名 字段类型;
删除字段 ALTER TABLE [表名] DROP COLUMN [字段名]
修改字段名: ALTER TABLE [表名] ALTER COLUMN 原字段名 新字段名
– 删除表
DROP TABLE IF EXISTS 表名
– 清空表数据
TRUNCATE TABLE 表名
– 查看表结构
SHOW CREATE TABLE 表名
Select
查询的所有关键字的书写顺序:

SELECT [ALL|DISTINCT]查询字段 FROM -> WHERE -> GROUP BY-> HAVING -> ORDER BY -> LIMIT(offset)
执行顺序 :
from--where--group by--having--select--order by--limit
from:需要从哪个数据表检索数据
where:过滤表中数据的条件
group by:如何将上面过滤出的数据分组
having:对上面已经分组的数据进行过滤的条件
select:查看结果集中的哪个列,或列的计算结果
order by :按照什么样的顺序来查看返回的数据
limit:限制返回的数据量
a. 查询表达式
-- 可以使用表达式(计算公式、函数调用、字段也是个表达式)
select stu, 29+25, now() from tb;
-- 可以为每个列使用别名。适用于简化列标识,避免多个列标识符重复。
- 使用 as 关键字,也可省略 as.
select stu+10 as add10 from tb;
b. FROM 子句
用于标识查询来源。
-- 可以为表起别名。使用as关键字。
SELECT * FROM tb1 AS tt, tb2 AS bb;
-- from子句后,可以同时出现多个表。SELECT * FROM tb1, tb2;
-- 多个表会横向叠加到一起,而数据会形成一个笛卡尔积。
-- 向优化符提示如何选择索引
USE INDEX、IGNORE INDEX、FORCE INDEX
SELECT * FROM table1 USE INDEX (key1,key2) WHERE key1=1 AND key2=2 AND key3=3;
SELECT * FROM table1 IGNORE INDEX (key3) WHERE key1=1 AND key2=2 AND key3=3;
c. WHERE 子句
-- 从from获得的数据源中进行筛选。
-- 整型1表示真,0表示假。
-- 表达式由运算符和运算数组成。
-- 运算数:变量(字段)、值、函数返回值
-- 运算符:
=, <=>, <>, !=, <=, <, >=, >, !, &&, ||,
(not) null, (not) like, (not) in, (not) between and, is (not), and, or, not, xor
is/is not 加上ture/false/unknown,检验某个值的真假
<=>与<>功能相同,<=>可用于null比较
d. GROUP BY 子句, 分组子句
GROUP BY 字段/别名
以下[合计函数]需配合 GROUP BY 使用:
count计算行数 count(*)、count(字段)
sum 求和
max 求最大值
min 求最小值
avg 求平均值
e. HAVING 子句,条件子句
f. ORDER BY 子句,排序子句
order by 排序字段/别名 排序方式
升序:ASC,降序:DESC
支持多个字段的排序。
g. LIMIT + offset
1. 当limit后面跟两个参数的时候,第一个数表示要跳过的数量,后一位表示要取的数量,
select* from article LIMIT 1,3 就是跳过1条数据,从第2条数据开始取,取3条数据,也就是取2,3,4三条数据
2. 如果省略第一个值,则默认为0,即表示从0开始要取的数据的数量
例如 select * from article LIMIT 3 表示取前三条数据,
3. 当 limit和offset组合使用的时候,limit后面只能有一个参数,表示要取的的数量,offset表示要跳过的数量 。
例如select * from article LIMIT 3 OFFSET 1 表示跳过1条数据,从第2条数据开始取,取3条数据,也就是取2,3,4三条数据
h. DISTINCT, ALL 选项
distinct 去除重复记录
默认为 all, 全部记录
去除多列的重复结果
SELECT DISTINCT 列名1, 列名2, ... 列名n FROM 表名;
where和having对比
- where和having可以同时使用
where+group by
是先过滤然后分组,group by+having
是先分组然后筛选- having筛选的字段必须是select后面查询出来的,where筛选的字段必须是数据表存在的。所以只要select后查询数据库中存在的字段,where和having就可以同时使用。
- where 不可以使用统计函数。一般需用统计函数才会用 having,比如
having count(*)>1
((sum、count、avg、max和min)) - where可以用于增删改查中, having只能用于select语句中
- where 不可以使用字段的别名,having 可以。因为执行WHERE代码时,可能尚未确定列值。
1、只可以用where,不可以用having的情况
select goods_name from sw_goods where goods_price > 100
//报错!!!因为前面并没有筛选出goods_price 字段
select goods_name,from sw_goods having goods_price > 100
改成下面这样是对的了
select goods_name, goods_price from sw_goods having goods_price > 100
2、只可以用having,不可以用where情况
查询每种goods_category_id商品的价格平均值,获取平均价格大于1000元的商品信息
select goods_category_id , avg(goods_price) as ag from sw_goods group by goods_category having ag>1000
//where则报错
select goods_category_id , avg(goods_price) as ag from sw_goods where ag>1000 group by goods_category
因为from sw_goods 这张数据表里面没有ag这个字段,where 后面要跟的是数据表里的字段,
就算把ag换成avg(goods_price)也是错误的!因为where后面不能使用聚合函数。
而having只是根据前面查询出来的是什么就可以后面接什么。
3、二者一起使用
select jCode,sum(jQty) from jProduct where jCode like '%0123%' group by jCode having sum(jQty)>100
执行流程:WHERE ——GROUP BY——HAVING
offset过大优化
limit分页查询时,如果设置了offset值, mysql是从头将数据都读出来,然后丢弃前面的offset条数据,当offset过大时,前面丢弃的数据过多,导致性能很差。
优化思路:子查询
比如先用limit查出起始的id(只查id走性能开销小),然后再一次用limit从起始id开始查,查出完整的数据。
举例:
经过我的多次验证,下面这条sql语句运行时间保持在0.0187左右
select * from user limit 10000,10;
子查询优化之后,时间保持在0.0061左右,只有前者的1/3。
select * from user where uid >=( select uid from user order by uid limit 10000,1 ) limit 10;
Insert
两种插入写法
1、 INSERT [INTO] 表名 [(字段列表)] VALUES (值列表)[, (值列表), ...]
-- 如果要插入的值列表包含所有字段并且顺序一致,则可以省略字段列表。
--若有字段列表,则值列表要和字段列表一一对应。
-- 可同时插入多条数据记录!
REPLACE 与 INSERT 完全一样,可互换。
2、INSERT [INTO] 表名 SET 字段名=值[, 字段名=值, ...]
实例:
1、insert into person(id,name,age,phone,address) values (1,'yang',22,'123232323','中国上海');
2、INSERT INTO person set id=1,name='kk';# 不要忘了''
我们在插入记录的时候,某些列的值可以被省略,但是这个列必须满足下边列出的某个条件之一
:
- 该列允许存储NULL值
- 该列有DEFAULT属性,给出了默认值
Update
update person set address='浙江杭州', name='kk' where id = 1;
Delete
delete from person where id = 1;
drop、truncate、 delete
用法和区别
1、drop:drop table 表名
删除内容、释放空间、删除表结构
2、truncate :truncate table 表名
删除内容、释放空间、不删除表结构
3、delete:delete from 表名 (where 列名 = 值)
与truncate一样,删除内容、释放空间、不删除表结构
但是truncate只能删除整张表
delete可以删表或删行
并且delete删除的数据可以回滚,drop和truncate不能