通配符
- %:任意类型、任意长度字符
- _:任意单个字符
- escape:配合转义字符/使用,转移字符后面的通配符将丢掉通配符的作用:
select username from gg_user where username like '%xiao/_%' escape '/'
联结查询
mysql联结查询包括内联结(inner join)和外联结(left join和right join),没有full join:
inner join
内联结,查找出两个表都有的满足联结关系的数据行:
SELECT user.id,user.name,question.title
FROM
user inner JOIN question
on
user.Id = question.user_id
如上,找出user和question表中满足条件的所有数据行
left join
左外联结,查找出两个表都有的满足联结关系的数据行,以及左表有、右表没有的数据行:
SELECT user.id,user.name,question.title
FROM
user left JOIN question
on
user.Id = question.user_id
如上,找出user和question表中满足条件的所有数据行,但也可以找到不满足这个联结条件的user表中的数据行
right join
与left join相反,可以找到右表有但左表没有的数据行
SELECT user.id,user.name,question.title
FROM
user right JOIN question
on
user.Id = question.user_id
如上,找出user和question表中满足条件的所有数据行,但也可以找到不满足这个联结条件的question表中的数据行
Mysql为什么不建议使用join(摘自网络)
不建议直接在数据库层面使用表联结,建议在数据库层面仅使用单表查询,在service层再通过dao使用多表关联,将多表的查询在service层进行分解,原因如下:
用分解关联查询的方式重构查询有如下的优势:
让缓存的效率更高。许多应用程序可以方便地缓存单表查询对应的结果对象。如果关联中的某个表发生了变化,那么就无法使用查询缓存了,而拆分后,如果某个表很少改变,那么基于该表的查询就可以重复利用查询缓存结果了。
将查询分解后,执行单个查询可以减少锁的竞争。
在应用层做关联,可以更容易对数据库进行拆分,更容易做到高性能和可扩展。
查询本身效率也可能会有所提升。查询id集的时候,使用IN()代替关联查询,可以让MySQL按照ID顺序进行查询,这可能比随机的关联要更高效。
可以减少冗余记录的查询。在应用层做关联查询,意味着对于某条记录应用只需要查询一次,而在数据库中做关联查询,则可能需要重复地访问一部分数据。从这点看,这样的重构还可能会减少网络和内存的消艳。
更进一步,这样做相当于在应用中实现了哈希关联,而不是使用MySQL的嵌套循环关联。某些场景哈希关联的效率要高很多。
分布式的分库分表,这种时候是不建议跨库join的。目前mysql的分布式中间件,跨库join表现不良
MyISAM 和 InnoDB 对比
数据库引擎都是表级别的
MyISAM引擎
- 该引擎是用B+树建立索引,MYI文件存储索引,MYD文件存储具体数据,通过对索引字段构建B+树,将叶子结点映射到数据的物理地址上,进行高校查询
- MyISAM是非聚集索引,叶子结点存储的不是实际数据,是数据的地址
InnoDB引擎
- 该引擎没有MYI文件,索引和数据都保存在同一个文件
- 该引擎通过主键构成的索引是聚集索引,叶子结点存储的是对应整行的实际数据;非主键的索引为辅助索引,叶子结点保存的是该行的主键
为何建议InnoDB主键用自增主键?
- 插入层面:在新增数据时,如果主键不是自增主键,而是随机主键,重新构建索引树将导致插入数据不连续,造成磁盘存储数据的频繁移动;如果是自增主键,能够保证新插入的数据都在叶子结点的链表尾部,不会引起之前数据的物理地址频繁变动,加入数据的顺序和B+数叶子节点分裂顺序一致
- 有时候不选择自增主键:保证分布式分库分表情况下主键不重复;保证数据安全性