!= 和<>的 区别?
!=并不是标准的一部分,要描述“不等于”这个操作符时,最好使用<>
mysql可以识别!=
----------------------------
描述表结构?
desc ${table_name}
eg:
desc b_merchant_shop_employee
mer_shop_emp_id int(11) NO PRI auto_increment
user_name varchar(50) YES UNI
merchant_id int(11) YES MUL
is_admin tinyint(1) YES
nick_name varchar(100) YES
emp_name varchar(50) YES
dept varchar(50) YES
email varchar(50) YES
telephone varchar(20) YES
mer_shop_ids varchar(100) YES
mer_user_id int(11) YES MUL
----------------------------------
mysql中You can't specify target table for update in FROM clause错误
mysql中You can't specify target table <tbl> for update in FROM clause错误的意思是说,不能先select出同一表中的某些值,再update这个表(在同一语句中),通过引入中间表可以解决这个问题
eg:
删除商家已经认证但是存在于认证表中的状态!=1的记录
(
SELECT a.id from
( select id from hyip_merchant_company_certified where user_id
in (select user_Id from hyip_merchant_company_certified where state=1) and state!=1 ) a
)
插入 INSERT INTO table_name (列1, 列2,...) VALUES (值1, 值2,....)
更新 UPDATE 表名称 SET 列名称 = 新值,列名称 = 新值 WHERE 列名称 = 某值
删除 DELETE FROM 表名称 WHERE 列名称 = 值
-----------------
DDL
只修改列的数据类型
alter table 表名 modify column 列名 新的列的类型
例如:student表中列sname的类型是char(20),现在要修改为varchar(20),SQL语句如下
alter table student modify column sname varchar(20);
同时修改列名和列的数据类型的方法
alter table 表名 change column 旧列名 新列名 新的列类型
例如:student表中列sname的类型是char(20),现在要修改为stuname varchar(20),SQL语句如下
alter table student change column sname stuname varchar(20);
增加列
alter table 表名 add column 列名 类型
alter table b_merchant_shop_employee add column state tinyint(1) default 0 comment '员工状态,0正常,1冻结';
删除列
删除列:alter table 表名 drop column 列名;
alter table company_certify_guaranty drop column createTime;
alter table company_certify_guaranty add column createTime timestamp default now();
操作索引
删除认证商家上的在userId上的唯一索引,因为一个商家可以认证多次,导致多条记录的增加,所以不应当存在唯一索引
查定义在表上的索引
show index from hyip_merchant_company_certified;
drop 索引
alter table hyip_merchant_company_certified drop index unq_user_id;
drop表
drop table company_certify_guarantyXX
---------------------------------------
like匹配
转载自 http://blog.csdn.net/sollion/article/details/4515179
_ -----------------------与任意单字符匹配
% -----------------------与包含一个或多个字符的字符串匹配
[] ----------------------与特定范围(例如,[a-f])或特定集(例如,[abcdef])中的任意单字符匹配。
[^] -----------------------与特定范围(例如,[^a-f])或特定集(例如,[^abcdef])之外的任意单字符匹配。
eg:
a、LIKE 'Mc%' 将搜索以字母 Mc 开头的所有字符串(如 McBadden)。
b、LIKE '%inger' 将搜索以字母 inger 结尾的所有字符串(如 Ringer、Stringer)。
c、LIKE '%en%' 将搜索在任何位置包含字母 en 的所有字符串(如 Bennet、Green、McBadden)。
d、LIKE '_heryl' 将搜索以字母 heryl 结尾的所有六个字母的名称(如 Cheryl、Sheryl)。
e、LIKE '[CK]ars[eo]n' 将搜索下列字符串:Carsen、Karsen、Carson 和 Karson(如 Carson)。
f、LIKE '[M-Z]inger' 将搜索以字符串 inger 结尾、以从 M 到 Z 的任何单个字母开头的所有名称(如 Ringer)。
g、LIKE 'M[^c]%' 将搜索以字母 M 开头,并且第二个字母不是 c 的所有名称(如MacFeather)。
----------------
TIMESTAMP数据类型的灵活使用
1,TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
在创建新记录和修改现有记录的时候都对这个数据列刷新
2,TIMESTAMP DEFAULT CURRENT_TIMESTAMP
在创建新记录的时候把这个字段设置为当前时间,但以后修改时,不再刷新它
3,TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
在创建新记录的时候把这个字段设置为0,以后修改时刷新它
4,TIMESTAMP DEFAULT ‘yyyy-mm-dd hh:mm:ss’ ON UPDATE CURRENT_TIMESTAMP
在创建新记录的时候把这个字段设置为给定值,以后修改时刷新它
-----------------------------
分页:
方式1: select XX from XX where XX limit m offset n
从偏移量为N开始(说明前面有n条记录,返回的第一条语句是第N+1条),返回m条记录
方式2 select * from table order by id limit m, n;
该语句的意思为,查询m+n条记录,去掉前m条,返回后n条记录
原理和优化
MySQL需要扫描过m+n条记录,然后进行舍弃,当M+N很大时,是很耗费性能的
引入id进行优化? -- 在可以接收的前提下,不做过度优化
limit offset从功能上来讲是非常好的,如果担心offset过大时耗时太长,可以分库分表。或者用搜索引擎
使用limit限制返回的记录数量
select * from hyip_user limit 2
--------------------------
连接
左连接:以左表为主,左表全部显示,如果右表为空,则显示为null
右连接:以右表为主,右表全部显示,如果左表为空,则显示为null
内连接,默认的连接方式:只显示满足条件的记录,左右都不允许空
自然连接: 以等于为条件的内连接
内连接 select * from A join B on A.Aid=B.Bnamid; 等价于select * from A,B where A.Aid=B.Bnamid;
左连接 SELECT ename , dname FROM Emp LEFT JOIN Dept ON Emp.Deptno = Dept.Deptno
右连接 SELECT ename , dname FROM Emp RIGHT JOIN Dept ON Emp.Deptno = Dept.Deptno
-----------------------------
查询优化
1 查询尽量走索引
2 以实际的执行时间,性能作为做权威的判断指标
case 1 ,如果有索引支持,则使用连接操作替换子查询
发版本之前,提交SQL给DBA审核,DBA反馈优化方案:
(具体原因未细分析,既然有索引,那么子查询也是走的索引,不会慢)
select a.role_name from b_merchant_role a where a.role_id in (select role_id from b_merchat_user_role_rel where username=#{username} and merchant_user_id=#{merchantUserId} );
改写为:
select distinct a.role_name from b_merchant_role a, b_merchat_user_role_rel b where a.role_id=b.role_id and b.username=? and b.merchant_user_id=? ;
mysql> select distinct a.role_name from b_merchant_role a, b_merchat_user_role_rel b where a.role_id=b.role_id and b.username='jack' and b.merchant_user_id='9001012' ;
+--------------+
| role_name |
+--------------+
| 商品运营 |
+--------------+
1 row in set (0.05 sec)
mysql> explain select distinct a.role_name from b_merchant_role a, b_merchat_user_role_rel b where a.role_id=b.role_id and b.username='jack' and b.merchant_user_id='9001012' ;
+----+-------------+-------+--------+---------------------------------+---------------------------------+---------+----------------+------+-------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+---------------------------------+---------------------------------+---------+----------------+------+-------------------------------------------+
| 1 | SIMPLE | b | ref | idx_mer_urrl_meruserid_username | idx_mer_urrl_meruserid_username | 606 | const,const | 5 | Using where; Using index; Using temporary |
| 1 | SIMPLE | a | eq_ref | PRIMARY | PRIMARY | 4 | hyip.b.role_id | 1 | |
+----+-------------+-------+--------+---------------------------------+---------------------------------+---------+----------------+------+-------------------------------------------+
2 rows in set (0.00 sec)
----------------------
explain
explain显示了mysql如何使用索引来处理select语句以及连接表。可以帮助选择更好的索引和写出更优化的查询语句。
使用方法,在select语句前加上explain就可以了:
如:
explain select surname,first_name form a,b where a.id=b.id
EXPLAIN列的解释:
table:显示这一行的数据是关于哪张表的
type:这是重要的列,显示连接使用了何种类型。从最好到最差的连接类型为const、eq_ref、ref、range、indexhe和ALL
possible_keys:显示可能应用在这张表中的索引。如果为空,没有可能的索引。可以为相关的域从WHERE语句中选择一个合适的语句
key: 实际使用的索引。如果为NULL,则没有使用索引。很少的情况下,MYSQL会选择优化不足的索引。这种情况下,
可以在SELECT语句中使用USE INDEX(indexname)来强制使用一个索引或者用IGNORE INDEX(indexname)来强制MYSQL忽略索引
key_len:使用的索引的长度。在不损失精确性的情况下,长度越短越好
ref:显示索引的哪一列被使用了,如果可能的话,是一个常数
rows:MYSQL认为必须检查的用来返回请求数据的行数
Extra:关于MYSQL如何解析查询的额外信息。将在表4.3中讨论,但这里可以看到的坏的例子是Using temporary和Using filesort,意思MYSQL根本不能使用索引,结果是检索会很慢
extra列返回的描述的意义:
Distinct:一旦MYSQL找到了与行相联合匹配的行,就不再搜索了
Not exists: MYSQL优化了LEFT JOIN,一旦它找到了匹配LEFT JOIN标准的行,就不再搜索了
Range checked for each Record(index map:#):没有找到理想的索引,因此对于从前面表中来的每一个行组合,MYSQL检查使用哪个索引,并用它来从表中返回行。这是使用索引的最慢的连接之一
Using filesort: 看到这个的时候,查询就需要优化了。MYSQL需要进行额外的步骤来发现如何对返回的行排序。它根据连接类型以及存储排序键值和匹配条件的全部行的行指针来排序全部行
Using index: 列数据是从仅仅使用了索引中的信息而没有读取实际的行动的表返回的,这发生在对表的全部的请求列都是同一个索引的部分的时候
Using temporary 看到这个的时候,查询需要优化了。这里,MYSQL需要创建一个临时表来存储结果,这通常发生在对不同的列集进行ORDER BY上,而不是GROUP BY上
Where used 使用了WHERE从句来限制哪些行将与下一张表匹配或者是返回给用户。如果不想返回表中的全部行,并且连接类型ALL或index,这就会发生,或者是查询有问题不同连接类型的解释(按照效率高低的顺序排序)
system 表只有一行:system表。这是const连接类型的特殊情况
const:表中的一个记录的最大值能够匹配这个查询(索引可以是主键或惟一索引)。因为只有一行,这个值实际就是常数,因为MYSQL先读这个值然后把它当做常数来对待
eq_ref:在连接中,MYSQL在查询时,从前面的表中,对每一个记录的联合都从表中读取一个记录,它在查询使用了索引为主键或惟一键的全部时使用
ref:这个连接类型只有在查询使用了不是惟一或主键的键或者是这些类型的部分(比如,利用最左边前缀)时发生。对于之前的表的每一个行联合,全部记录都将从表中读出。这个类型严重依赖于根据索引匹配的记录多少—越少越好
range:这个连接类型使用索引返回一个范围中的行,比如使用>或<查找东西时发生的情况
index: 这个连接类型对前面的表中的每一个记录联合进行完全扫描(比ALL更好,因为索引一般小于表数据)
ALL:这个连接类型对于前面的每一个记录联合进行完全扫描,这一般比较糟糕,应该尽量避免