码迷,mamicode.com
首页 > 数据库 > 详细

决胜九月:mysql面试必会基础(三)

时间:2016-04-10 14:57:38      阅读:315      评论:0      收藏:0      [点我收藏+]

标签:

昨天的图片没传上去,更新了一下,太大意了,sorry

之前两篇讲了mysql 检索数据、函数、分组、组合函数、子查询、连接、及组合查询。

复习一下重点: 必会的几个函数avg sum count max min

必会的GROUP BY 、HAVING。

举个2016腾讯笔试题的真实的例子,(lz面试2015腾讯实习生时遇到同样的问题)

有汽车评分表car_score,表中有用户id,汽车名称carname,评分score三个字段,存储着用户对汽车的评分。

默认只有用户对汽车进行两次及以上评分时才有效,求汽车的有效的平均评分并由高到低排序。

表结构如下:

技术分享

技术分享

楼主给出的答案和执行结果:

技术分享

技术分享

Join也是必会的知识点:join、left join、right join、inner join、outer join

无论是哪一种join无非都是选择一个条件将表的列连接,返回对应的数据,上一篇的图解应该很形象。

For Example:题目如:https://leetcode.com/problems/combine-two-tables/  题外话:(LeetCode 上的题很好但自认为如果时间不够不用全刷,java开发面试算法应该不会难过树,数据库操作那10几道题也应该够用了

lz给出的答案: # Write your MySQL query statement below
select t1.FirstName as FirstName , 
t1.LastName as LastName,t2.City as City,
t2.State as State 
from Person as t1 
left join Address as t2 
on t1.PersonId = t2.PersonId

子查询

子查询的效率比较低,但是有时可能会解决一些问题

还是从实际例子出发:LZ给别人开发一个了一个关于“银行贷款申请”的微信公共账号,其中有个需求就是要给申请贷款的用户分配客户经理。

分配策略就是,分配给任务最少的客户经理。相关的表有贷款申请表forms,用户表users。贷款申请表中存储所有的贷款申请信息,主要包括id(主键),uid(申请用户名),workerid(客户经理id),workername(客户经理名)(这里由于客户经理的变化比较少,所以做了一下冗余)。用户表包括,用户id 用户名username 用户类别state 用户组id。

要找到所有用户经理的接单数量,就不能单从贷款申请表查询,因为有的客户经理可能没有接单也就存在在这个表中。

lz想到的方法就是从用户表入手,返回对应用户组中所有用户(客户经理)的接单数量,方法如下。(个人觉得可以不用子查询实现,但目前还没想到,这里留个坑,等我学会了回来填上)

技术分享技术分享

组合查询Union

这个没什么太多说的,就是要注意:每个查询必须包含相同的列,表达式或聚集函数且列的类型必须兼容


---------分割线---------


 插入、删除、更新

INSERT是用来插入(或添加)行到数据库表的。插入数据的几种方式:

 插入完整的行

插入行的一部分

 插入多行

插入某些查询结果

INSERT SELECT语句

INSERT INTO customers(cust_id,cust_name,cust_email) 

SELECT cust_id,cust_name,cust_email FROM custnew;

列省略

    如果表中定义允许,则可以在INSERT操作中省略某些列,省略的列必须满足以下某个条件。

该列定义为允许为NULL

在表定义中给出默认值,

 

提高整体性能

    数据库经常多个客户访问,对处理什么请求以及用什么次序处理进行管理mysql的任务。INSERT操作可能很耗时(特别是由很多索引需要更新时),而且它可能降低等待处理的SELECT语句性能。

    如果数据检索是最重要的(通常是这样的),则你可以通过在INSERT INTO之间添加关键字 LOW_PRIORITY 指示mysql降低INSERT语句的优先集

 

更新和删除数据

 

    为了更新(修该)表中的数据,可使用UPDATE语句,可采用两种方式使用UPDATE

更新表中特定的行

更新表中所有的行

更新行和删除行的时候一定要加上WHERE子句,否则后果自负

UPDATE bname SET zda ‘acontent‘ zdb ‘bcontent‘ WHERE zdid=‘20005‘;

    IGNORE 关键字    如果使用UPDATE更新多行,并且在更新这些行中的一行或多行时出现一个错误,则整个UPDATE操作被取消,(错误发生前更新的所有行被恢复到他们原来的值)为即使发生错误也继续进行更新。可使用IGNORE关键字

UPDATE  IGNORE bname;

 

删除数据

为了从表中删除(去掉)数据,使用DELETE语句,可以使用两种方式:

        1 从表中删除特定的行

从表中删除所有的行

    不要省略WHERE子句

 

    更快的删除  如果想从表中删除所有的行,不要使用DELETE,可以使用TRUNCATE TABLE语句,他完成相同的工作,但速度更快(TRUNCATE实际上是删除原来的表并重新创建一个表,而不是逐行去删除表中的数据)注意TRUNCATE不会写日志数据无法恢复

 

更新和删除的指导原则

下面是许多sql程序员使用的UPDATEDELETE是所遵循的习惯

        除非确实打算更新和删除每一行,否则绝对不要使用不带WHERE子句的UPDATEDELETE语句。

        保证每个表都有主键,尽可能的像WHERE子句那样使用它(可以指定各主键、多个值、和值的范围)

        在对UPDATEDELETE语句操作使用WHERE前,应该先用SELECT进行测试,保证它过滤的数据是正确的记录,以防编写的WHERE子句不正确。

        使用强制实施引用完整的数据库,这样MYSQL将不允许删除具有与其他表相关联的数据的行


创建和改变表

创建表

一般两种创建表的方法

使用具有交互式创建和管理表的工具

表也可以直接用MySQL语句操纵

在使用交互式工具时,工具也是生成MySQL语句操纵数据库

表创建基础

为了利用CREATE TABLE创建表,必须给出下列信息:

新表的名字,在关键字CREATE TABLE之后给出

表列的名字和定义,用逗号分隔

CREATE TABLE table

(

column_id  int       NOT NULL  AUTO_INCRMENT,

columnOne  char(20)  NOT NULL  DEFAULT 1,

columnOne  char(20)  NOT NULL ,

column  char(20)  NOT NULL ,

.....

PRIMARY  KEY column_id)

ENGINE  InnoDB

    如果表已经存在,则必须先删除后在创建他,不可以直接覆盖。如果仅想在表没有存在的情况下创建它,应该在表名后给出 IF NOT EXISTS

使用NULL  如果不指定列为NOT NULL则它默认是NULL

主键再介绍  主键的值必须是唯一的。创建主键时可以用单列做主键PRIMARY KEY(columnOne,columnTwo),也可以使用多列做主键PRIMARY KEY(columnOne,columnTwo).主键值不允许为NULL

索引创建

    CREATE INDEX indexname ON tablename (column [ASC|DESC],....);

使用AUTO_INCREMENT

    每个表只允许使用一个AUTO_INCREMENT列,而且它必须被索引,(如通过使它为主键)

如果两个表关联,添加时一表时需要另一表的主键,该怎么获得呢:

    可以使用last_insert_id()函数获得这个值 此语句返回最后一个AUTO_CREMENT的值。

指定默认值

    如果在插入行时没有给出值,mysql允许指定此时使用默认值。默认值是在CREATE TABLE语句的列定义中的DEFAULT关键字定义的。

        columnOne  char(20)  NOT NULL  DEFAULT 1,

MySQL不允许使用函数作为默认值,它只支持常量

引擎搜索

    你可能已经注意到,迄今为止使用的CREATE  TABLE语句全都以ENGINE InnoDB语句结束

    与其他的DBMS一样,MySQL有一个具体管理和处理数据的内部引擎,在你使用CREATE TABLE语句是,该引擎具体创建表,在其他应用中区修改读取删除表等处理你的请求,多数时候它隐藏在DBMS内,不需要过多的关注它。

    MySQL与其他的DBMS不一样,它具有多种引擎,它打包多个引擎,这些引擎都隐藏在MySQL服务器内,全都能处理用户的请求。

    为什么要发行多种引擎呢,因为他们具有各自不同的功能和特性,为了不同的任务选择正确的引擎能获得良好的功能和灵活性

    当然你也可以省略这些数据库引擎,如果省略ENGINE=语句,则使用默认引擎(很可能为MyISAM),多数sql语句都会默认使用它,但并不是所有的语句都默认使用它,这就是为什么ENGINE=语句很重要的原因。

以下几个需要知道的引擎

InnoDB是一个可靠的事务处理引擎,它不支持全文本搜索。

    MEMORY 在功能上等同于MySAM,但由于数据存储在内存,所以速度更快(特别适用于临时表)

    MySAM是一个性能极高的引擎,它支持全文本搜索,但不支持事务处理

        引擎类型可以混用。混用引擎类型的一个大缺陷。外键不能跨引擎,即使用一个引擎的表不能引用具有使用不同引擎的表的外键

更新表

        为了更新表,可以使用ALTER TABLE语句,但是在理想状态下,当表中存储了数据后就不应该再去更新表了。所以在设计表时需要花费大量的时间去考虑,以便后期不做太大的改动。

    ALERT TABLE更改表结构,必须给出下面的信息:

    ALERT  TABLE之后给出要修改的表名

    所做更改的列表

    添加一列 ALERT TABLE column ADD columnFour CHAR(90);必须指明数据类型

    删除一列 ALERT TABLE column DORP columnFour ;

        定义外键    

            ALERT TABLE tableOne ADD CONSTRAINT columnOne 

            FOREIGN KEY (column_id) PEFERENCES tableTwo (column_id)

        可以单条ALTER TABLE语句对单个表进行多个修改,每个修改用逗号分隔开。

    复杂的表结构一般需要手动删除过程

        用新的列布局创建一个新表

        使用INSERT SELECT 语句从旧表复制数据当道新表。如果有必要,可以使用转换函数和计算字段

        检验包含所需数据的新表

        重名名旧表

        用旧表原来的名字重命名新表

        根据需要,重新创建触发器、存储过程、索引和外键

        小心使用ALTER TABLE 因为它是不可逆的操作,最好操作前完成已备份。

    删除表

        DORP TABLE table;   不可撤销,永久删除表

    重命名表

        RENAME TABLE table TO table2;  多个表重命名 逗号分隔开



决胜九月:mysql面试必会基础(三)

标签:

原文地址:http://blog.csdn.net/liukanglucky/article/details/51107242

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!