SQL金典
ps:补充自己的基础知识,大神请无视..
~~~~~~~~~~~~~~~~~~~~~
DataBase Management System,DBMS。。。。
Catalog 。。。库
Table。。。。表
Column。。。列--Field 字段,每个列描述数据的一个特性。
DataType 。。。数据类型
Record。。。。记录---Row行,
PrimaryKey。。。主键-----多个字段才唯一标识一列时,称为复合主键
Index 。。。索引-不建立索引是全表扫描,速度慢;建立索引只扫描索引,速度快;
缺点:占据一定磁盘空间,减慢了插入和删除速度(更新索引);
表关联:两张表通过字段关联,关联到其他表的主键的字段称为 外键;
SQL的4个功能:创建库并定义表结构,查询数据,更新、删除指定数据,控制数据库安全。
1、入门
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1、数据类型
整型、数值类型、
字符相关类型(固定长度char、可变长度varchar、多语言可变长度nvarchar、可变长度字符串text、ntext可变大字符)、
日期时间类型datetime/smalldatetime/timestamp时间戳、
二进制类型:图片、视频等,非常大的,没有固定结构的数据,设置和读取也需要宿主语言的辅助。如 image(MS sqlServer),其他是blob。 2、通过SQL 管理数据表
创建表 create table name{
字段名1 字段类型,
字段名2 字段类型,
.....
约束定义1,
约束定义2,
.....
}
定义非空约束,在类型定义后增加 NOT NULL ,
定义默认值,------------增加 DEFAULT ,
定义主键,在所有字段定义之后, PRIMARY KEY(字段名),
联合主键:两个字段联合起来作为主键,(复合主键),PRIMARY KEY(字段名1,字段名2),
缺点: 效率低,增删改查都需要处理两个字段,大大降低了数据处理速度,
结构糟糕,联合主键会有业务含义,与“使用逻辑主键不是业务主键”的最佳实践冲突,开发和维护麻烦,
外键麻烦或无法创建,
开发难度很大,工具和框架对单主键支持良好,对多主键复杂特殊处理。
定义外键:所有字段之后,FOREIGN KEY 外键字段名 REFERENCES 目标表名(被关联的字段名)
修改已有数据表: ALTER TABLE 待修改的表名 ADD 字段名 字段类型
ALTER TABLE 待修改的表名 DROP 待删除的字段名
删除数据表 DROP table 表名
2、数据表的创建和管理
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
insert into tableName(A,B,C) values(a,b,c)
insert into tableName(a,b,c) 按照定义表中字段顺序进行插入,不推荐。
非空值必须插入,主键必须唯一不重复,外键值必须在目标表中存在。--所以不推荐在数据库中生成外键,有程序控制更灵活。
update tableName set A=a,B=b,C=c
where X=x
非空值不能更新为NULL,主键不能更新为重复,外键不能不存在。
delete from tableName where X=x 有外键时,必须先删除引用,不然删除失败。
delete只删除数据,drop 删除数据和表结构。
3、数据的增删改
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
select * from tableName where X
select A,B from tableName where X
列名 as 别名 ,as 可省略,但要保留空格。 过滤问题:可程序控制,缺点是 全取出对内存网络消耗都大,程序实现复杂,关联其他表的情况不能处理。所以用数据库提供的最好。 数据汇总
聚合函数 MAX MIN AVG SUM COUNT
count(*)结果集的总条数,count(列名) 列名的值不为NULL的总记录数,不一定相等。
order by A asc/desc, B asc/desc 先A,再B 排序----推荐显式指定排序,防止不同数据库之间差异影响结果。 通配符过滤:
like 二元操作符,左边为列名,右边为表达式,
单字符匹配 下划线 _ ,如 b_d,匹配第一个字符为b,第二个字符任意,第三个字符为d的字符串。
多字符匹配 百分号 % , 如 like ‘%abc%’.
可一起使用,如 like '%n_'
集合匹配 只MS SQL Server 支持,方括号[] ,与字符集中任意一字符想匹配的字符, 如 [bt],有点像..正则表达式啊?
还可以使用否定符取反,[^bt],匹配不是bt的串,
在其他库上可用 or语句实现。
缺点:效率低,不要过多使用。
空值检测 select A,B,C from tableName where X is/is not NULL
反义运算符 ! 作用于运算符的取反,只有MS SQL 和DB2支持,
NOT 作用于表达式的取反, NOT(表达式),推荐使用。
多值检测 or或 in, IN(值1,值2,值3....)
范围值检测 < > 或 between and, 字段名 between leftValue and rightValue ,包括范围边界值。性能好,优先考虑。
低效的where 1=1 :数据库系统无法使用索引等查询优化策略,只能每行数据进行扫描(全表扫描),大大降低了性能。 数据分组:用来将数据分为多个逻辑组,每个组是所有记录的一个子集,从而对每组进行聚合运算。Group by 分组字段。一般放在语句最后。
分组语句必须和聚合函数一起使用?又可以分开使用?
需要分组的所有列,都必须位于group by子句列名列表中,没有出现的列,不能放在select语句后的列名列表中。
select A,B from tableName group by A ,是错误的,A分组了,但B没有,不一样的B但一样的A的无法显示。
select A,sum(B) from tableName group by A,正确,聚合函数得出一样的B值,就能显示。
很多列时是 逐层分组,组中组,结果集是以最末一级分组来进行输出的。
列:select A,B,count(*) as M from tableName group by A,B order by A
Having语句 对部分分组的过滤,
聚合函数不能用于where语句,改为having即可,having 可使用复杂的过滤条件,or、and in 等。
语法和where几乎一样,只是和group by的位置不一样,where在group by 之前,having 在group by 之后,
having语句不能包含未分组的列名,
应该能同时用吧? 限制结果集行数 只检索结果集中的部分行,主流数据库都支持,但差异很大。
MySQL 关键字 limit 放在select语句最后 ,limit 首行行号, 要返回结果集的最大数目 --行号从0开始
例子: select * from tableName order by X desc limit 2,5
SQLServer2000 关键字TOP NUM 结果集中的前N条记录,用子查询实现区间范围功能,
例:select top 3 * froom tableName
where A NOT IN
( select top 5 A from tableName order by X desc)
order by X desc --查询按X排序的第6开始的3条结果。
SQLserver2005 兼容2000,另外还有窗口函数 row_number(),计算每一行数据在结果集中的行号(从1开始),
语法:row_number() over(排序规则) --只出现在select或order by 子句中
例:(select row_number() over(order by A) as rownum,A,B,C,D from tableName ) as M
配合子查询使用
select * from M where rownum >=3 and rownum<=5
Oracle 窗口函数 row_number(),与sqlserver2005一样,但是不用 as定义别名,
另外:Oracle为每个结果集都默认增加行号的列rownum,所以前N条记录可以用 where rownum<=N 实现,
但是 取中间值必须用窗口函数,因为Oracle会把不符合的剔除结果集,后面的rownum会自动减一,一致都不满足。
DB2 窗口函数支持,还有关键字 Fetch,用来提取前N行,放在order by后面,
例:select * from tableName order by X desc fetch first 6 rows only
可用fetch配合子查询实现区间。
数据库分页 核心就是 限制结果集行数
每页数据条数 PageSize,当前页(从0开始计数)CurrentIndex, 一次只查询从P*C开始的P条数据。 抑制数据重复 distinct 关键字是对整个结果集进行数据重复抑制的,不是针对一列。 计算字段:数据默认展现方式不完全符合应用要求时,经计算、转换、格式化等再使用,比用宿主语言处理性能高很多。
常量字段 值确定的一个值作为字段,可用as 。
字段间计算,加减乘除等,可用于where子句,
数据处理函数
字符串长度,length,(在ms sql server中是len)
字符串子串 substring(Oracle和DB2中是substr),
字符串连接
MYSQL会把+ 转化为数值,不能用,应该用函数 concat(),concat_ws()可加入指定分隔符。
MS SQL Server 用+,
Oracle 使用|| 双竖线,也提供concat(),
DB2 双竖线 || ,和concat()。 计算字段的其他用途: 数据过滤、删除、更新中,都可以使用计算字段。 不从实体表中取的数据:
MYSQL和MS SQL Server 允许使用不带FROM子句的select语句来查询 不属于任何实体表的数据,
例: select 1 /select length('abc')
Oracle不允许,但可以使用系统表来作为from子句,常用DUAL。
例: select 1,length('abc') from DUAL
DB2 的系统表是 SYSIBM.SYSDUMMY1 联合结果集: UNION 两个完全不同的查询结果集的组合,显示在一个结果集中。相当于select 语句+起来,一般用于各种报表。
select A,B,C from table1
Union select X,Y,Z from table2
原则:结果集的列数相同,不同时补常量字段;对应列的类型相容,相同或者能转换为同一类型--推荐类型完全相同。
Union 会把完全重复的数据合并为一条,(自带distinct啊...),不需要合并的使用Union all.
4、数据检索
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
数学函数
绝对值 ABS(),指数power(),平方根sqrt(),
随机数 select rand()--Mysql,
select rand(随机数种子) --MS SQL server,
select dbms_random.value from dual --Oracle没有内置随机数函数
还有 dbms_random.value(low,high) ,dbms_random.normal正态分布的一组数,偏差1,期望为0
dbms_random.string(opt,len)随机字符串。
select SYSFUN.rand() from sysibm.sysdummy1 --DB2.
Round()四舍五入
圆周率π, PI(),Oracle等不支持的用 ACOS(-1)代替:-1的反余弦值等于π值。
求符号:SIGN(),大于0,则1,小于0,则-1,等于0,则0.
求整除余数:MOD(),--MS SQLserver中为 操作符%.
自然对数: LOG() --Oracle中为 LN().
LOG10() 计算一个以10为底的对数值 --Oracle中为LOG(m,n),以m为底n的对数。
Power(X,Y)用来计算X的Y次幂。 字符串函数:
长度:length(),----或len(),
小写:lower(),---DB2中为 Lcase().
大写:Upper(),---DB2中为Ucase().
截去左侧空格:LTRIM(),右侧空格:RTRIM(),两侧空格:TRIM()或者组合左右实现。
子串:substring(S,start,length),substr().
计算子串位置:Instr(string,substring),不在返回0,---MS SQL server中为charindex,---DB2中为locate(subs,S).
从左侧取子串:left(s,length),从右侧取子串:right(),
字符串替换:Replace(S,tobeS,toS),toS是空的话就是删除功能。
得到字符的ASCⅡ码:ASCⅡ(), 反过来是 CHAR(),--Oracle中为CHR(),
发音匹配:soundex()计算发音特征值,返回4个字节的字符串,第一个字符总是初始字符串的第一字符,后面是3位数字。
difference()--MS sql server和DB2中额外提供的函数。 日期时间函数:
类型有4种 日期Date、时间Time、日期时间DateTime、时间戳TimeStamp。
一般字符串可自动转化为对应类型,但Oracle需要函数To_Date(),
当前日期时间
MySQL NOW(), ---等同于 SYSDATE()、CURRENT_TIMESTAMP,
CURDATE()日期, CURRENT_DATE.
CURTIME()时间,
MS SQL SERVER
getdate(),配合convert()使用。
select convert(varchar(50),getdate(),101) as 当前日期,
select convert(varchar(50),getdate(),108) as 当前时间,
Oracle 使用系统表 DUAL中查询SYSTIMESTAMP来得到当前时间戳,SYSDATE得到日期时间,
配合TO_CHAR(时间日期值,'YYYY-MM-DD'),TO_CHAR(时间日期值,'HH24:MI:SS')。
DB2 系统表SYSIBM.SYSDUMMY1中的 CURRENT TIMESTAMP/DATE/TIME。
日期增减 MS SQL Server 中 DATEADD(datepart,number,date)
日期差额 MS SQL Server 中 DATEDIFF(datepart,startdate,enddate)返回以datepart为单位的差额
例:select DATEDIFF(S,convert(varchar(50),getdate(),101),getdate())--今天过了多少秒。
计算日期是星期几:
MYSQL dayNAME()
MS SQL server : select datename(dw,getdate()), --dw 工作日,
Oracle: TO_CHAR(DATE,format)--day 会返回周几
取得日期特定部分: MS SQL中 DATENAME() 和DATEPART(), 其他函数:
类型转换,尽量显式转换,避免隐式转换。
MYSQL 中 CAST(expression as type)和Convert(ex,type),
MS SQL server,CAST(expression as type)和Convert(type,ex)。
空值处理:
coalesce(表达式,value1,value2...),返回所有参数中第一个非空表达式,
coalesce()的简化版,两个参数
IFNULL(EX,value)--MYSQL
ISNULL(ex,value)--MS SQL Server
NVL(ex,value)--Oracle
NULLIF(ex1,ex2) 如果表达式不等价,返回ex1的值,如等价,返回ex1类型的空值。
CASE函数:
用法1, case expression
when value1 then returnvalue1
when value2 then returnvalue2
else defaultreturnvalue
end
用法2,case
when condition1 then returnvalue1
when...
else defaultreturnvalue
end --只能对一个表达式进行判断。
各数据库系统独有函数:
MS SQL server ,辅助函数 app_name()返回当前回话的应用程序名称;
current_user 当前登录用户名
host_name()返回工作站名。
newid()生成全局唯一字符串,
函数
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1、索引 针对字段,必须指定字段,可以为多字段创建一个索引,
创建表 create table t_person(
fnumber varchar(20), fname varchar(20), fage int)
创建索引 create index 索引名 on 表名(字段1,字段2,...)
create index idx_person_name on t_person(fname)
删除索引用 drop index 表名.索引名
2、约束 非空 NOT NULL、
唯一 Unique约束 防止一个特定列中两个记录具有同样的值,分为单字段唯一与复合唯一
单字段唯一的 语句是 字段后加 UNIQUE,--该字段不能有重复值
复合唯一是 constraint 约束名 unique(字段1,字段2...)--字段1和字段2,单个可以重复,但是不能同时重复。
在已经创建好的表上添加新约束 alter table 表名 add constraint 约束名 unique(字段1,..)
删除约束 alter table 表名 drop constraint 约束名
CHECK约束 检查输入到记录中的值是否满足一个条件, 任意有效的SQL表达式,
例: age int check(age>0), number varchar(20) check (length(number)>12)
如CHECK子句要使用其他列,则在create table末尾使用 constraint关键字定义。
constraint 约束名 check(条件),
例:create table t1(A INT, B INT,C INT, Cconstraint ck_AB Check(A<B))
主键约束 唯一标识,不空,PRIMARY KEY,
外键: 语法,foreign key 外键字段 references 外键表名(外键表的主键字段)
或 alter table tName add constraint fk_A_B
foreign key (外键字段) references 外键表名(外键表的主键字段)
6、索引与约束
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
join类型: 交叉连接(cross join)、内链接(inner join)、外连接(outter join),部分数据库系统还支持联合连接(union join)。
1、内连接:语法 inner join tableName on condition --进行连接时的条件,
例:select A,B from table1
inner join table2 on table1.M=table2.N where table1.X=x
inner 是可选的,默认就是内连接。
2、不等值连接:连接的条件中可以使用< > <> 等运算符,以及like between and,和函数。
不等值连接是 2个表的笛卡尔运算,一般需配合等值连接匹配条件使用。
3、交叉连接:所有表所有记录包含在结果集中,不存在on子句,分隐式和显式连接。
隐式: select t1.A,t2.B from t1,t2
显示: select t1.A,t2.B from t1 cross join t2。 一般只用隐式连接。
4、自连接:表与自身连接,通常需处理的问题是 一个记录和自己相同,或者A与B相同时B也与A相同的问题。会写成 o1.id<o2.id.
5、外部连接:主要用来解决空值匹配的问题,不需要两个表具有匹配记录,这样可以指定某个表中的记录总是放到结果集中。
分为3种类型:右外 right outer join,左外left outer join,全外full outer join。
左外返回左表中部复合连接条件的数据,右外返回右表中,全外是两个合集。--以关键字join分左右。
7、表连接
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
以结果集供其他SQL语句使用,--嵌套内的查询。
只返回单值的,和返回一个数据集的.
1、单值的又叫标量子查询,可用于列表、表达式、where等场合
2、列值子查询,表子查询,可用于from、insert、连接、IN子句等场合。
select id,name,(select max(X) from B where B.id=A.id) from A
--通过where子句,子查询连接到外部的select,不能单独执行。--相关子查询。
3、集合运算符与子查询
in 匹配某一项,
=any 等价于in, <>any 等价于 NOT IN, any不能与固定的集合想匹配,
All 也需要带比较符,比较的值需要匹配子查询中所有值,不能与固定集合想匹配。
如匹配集合为空,不论什么比较,ALL都返回true。
exists 单目运算符,检查每一行是否匹配子查询,只有和相关子查询一起使用。
select A,B from t1 where exists ( select * from t2 where t2.id=t1.id and t2.X<x)
4、子查询应用
insert into t1(A,B) select A,B from t2 --列序对应。
A或者B换成 case 子句,可实现 数据处理,
8、子查询
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1、SQL注入漏洞攻防 :用户在输入中拼接字符串,偶后转入数据库去执行这字符串,造成不可预测影响。
过滤敏感字符和使用参数化SQL;
过滤 or/and/select/delete等关键字,--麻烦且不严谨。
2、SQL调优 :
二八原则:找出消耗性能的语句,优化。
索引:最根本的优化方法,内功!
聚簇索引:数据表的物理顺序与索引顺序相同; 字典里拼音和偏旁部首都是索引,前一是聚簇的,
存储碎片-重建索引,reindex/rebuild ,
尽量减少全表扫描,创建必要索引,使用预编译查询(参数化SQL)、
调整where子句连接顺序-DBMS一般采用自下而上的顺序解析WHERE子句,表连接最好写在其他where条件之前,以过滤掉最大数量记录后再连接,
select中不使用*,尽量压缩SQL到一条语句且一次执行。
用where 替换 having--后者只会在检索出所有记录后才对结果集过滤,
使用表别名,前缀每个列,减少解析时间和错误。
用exists替代IN--in子句执行一个子查询内部的排序和合并,
用表连接替换exists
避免在索引列上使用计算--
使用UNION all 替换union--在确保结果不重时,不实用检索的自动去重功能。
避免隐式类型转换造成全表扫描--查询条件中使用匹配的类型值,
防止检索范围过宽--使用is not null 或 不等于判断,可能造成优化器假设匹配记录数太多,或使用like的带 %c 形式,不能有效评估匹配数量。
3、事务:原子操作,transaction,原子性Atomicity、一致性Consistency、隔离性Isolation、持久性Durability,简称 ACID特性。
启动、提交、回滚..制定锁粒度、隔离级别..
例: set transaction isolation level read uncommited
begin transaction
....
commit
4、自动增长字段: MS SQLserver 中 关键字为 identity(startvalue,step)起始数字,步长。
业务主键后期维护不方便,逻辑主角不能合并表。
6、NULL的学问:NULL表示未知,而不是没有值,和任何运算都是NULL,出现在where子句是False, 在聚合函数中会被忽略。
7、开窗函数: 函数名(列) over(选项) --
select A,B,COUNT(*) OVER() from t1 where X<x
partition by 子句 ,定义行的分区,从而进行聚合计算,创建的分区独立于结果集,位于over的选项内。
可多次使用,结果互不影响。
select A,B,COUNT(*) OVER(partition by A),COUNT(*) OVER(partition by B) from t1.
8、with子句和子查询:降低使用子查询的次数可以优化性能,
SQL提供了with子句用于为子查询定义一个别名,一次定义多次使用。
DRY don't repeat yourself.
格式: with 别名 as (子查询) --是SQL语句,不是存储过程,可远程调用。
还可以定义列别名: with 别名(f1,f2) as (子查询)
9、表复制: create table t2 as select * from t1 where 1<>1
select * into t2 from t1 where 1<>1
10、高级话题
SQL金典的更多相关文章
- 读《程序员的SQL金典》[1]--基础数据检索
前言 <程序员的SQL金典>这本书是杨中科老师的,拜读了一下,简单做了读书笔记供以后翻阅.仅供学习分享,要想细读的话推荐购买原版呀! 这次读书的时候用了新的办法把看书计划进行了量化,虽然简 ...
- 读《程序员的SQL金典》[4]--SQL调优
一.SQL注入 如果程序中采用sql拼接的方式书写代码,那么很可能存在SQL注入漏洞.避免的方式有两种: 1. 对于用户输入过滤敏感字母: 2. 参数化SQL(推荐). 二.索引 ①索引分类 聚簇索引 ...
- 读《程序员的SQL金典》[3]--表连接、子查询
一.表连接-JOIN 1. 自连接实例 查询类型相同的订单信息. SELECT O1 .*,O2.* FROM T_Order O1 JOIN T_Order O2 ON O1 .FTypeId= O ...
- 读《程序员的SQL金典》[2]--函数
一.数学函数 1.RAND SELECT RAND () ---0.302870228294199 取0-1之间的随机小数. 2.小数取整 CEILINT(data)舍掉小数部分并向上取整. FLOO ...
- 程序员的sql金典
1.数据库基础概念 2.数据类型 3.通过SQL语句管理数据表 4.数据的增删改 5.Select的基本用法 6.高级数据过滤 7.数据分组 8.限制结果集行数和抑制重复数据 9.计算字段 10.不从 ...
- 【程序员的SQL金典】笔记(第6章~第11章)
第六章 索引与约束 1.索引用来提高数据的检索速度,而约束则用来保证数据的完整性. 2.创建索引 创建索引的SQL 语句是CREATE INDEX,其语法如下: CREATE INDE ...
- 【程序员的SQL金典】笔记(第1章~第5章)
第一章数据库入门 1.概念: 数据库 表 列 记录(行) 主键 索引 第二章 数据表的创建和管理 1.数据库系统中的数据类型大致可以分为五类:整数.数值.字符相关.日期时间以及二进 ...
- SQL Server数据库性能优化(一)之 优化SQL 语句
最近工作上基本没什么需求(好吧 不是最近是好久了,所以随便看看基础的东西来填补自己的空白) 原文出自:http://www.blogjava.net/allen-zhe/archive/2010/07 ...
- SQL SERVER开窗函数
作为一名开发人员来讲,我感觉在职场白混了好多年,可能是自己真的没有进取的精神吧,看了<程序员的SQL金典>这本电子书,真的让我学到了不少知识,真心喜欢这本电子书,书中讲解的内容比较好懂,也 ...
随机推荐
- elasticsearch term 查询之一
1.前言 term级别查询将按照存储在倒排索引中的确切字词进行操作,这些查询通常用于数字,日期和枚举等结构化数据,而不是全文本字段. 或者,它们允许您制作低级查询,并在分析过程之前进行. term级别 ...
- 修改git的author 和 commiter
点击:Add Entry
- TestNG+ReportNG+Maven优化测试报告
转载:https://www.cnblogs.com/hardy-test/p/5354733.html 首先在eclipse里面创建一个maven项目,具体要配置maven环境,请自行百度搭配环境. ...
- Linux学习笔记 (八)Shell概述
一.什么是Shell? Shell是一个命令行解释器,它为用户提供了一个向Linux内核发送请求以便运行程序的界面系统级程序,用户可以用Shell来启动,挂起,停止甚至是编写一些程序.Shell还是一 ...
- 在github上建立jekyll blog
1.git常用命令(简易介绍见http://rogerdudler.github.io/git-guide/index.zh.html) git init #创建新的git仓库 git clo ...
- datagridview 日期列排序
1.datagridview 日期列排序 private void Form1_Load(object sender, EventArgs e) { //方法1 dataGridView1.Colum ...
- C语言学习笔记(五) 数组
数组 数组的出现就是为了解决大量同类型数据的存储和使用的问题: 数组的分类:一维数组.二维数组. 一维数组:为多个变量连续分配存储控件:所有的变量的数据类型必须相同:所有变量所占的字节大小必须相等: ...
- Android模拟器Genymotion安装apk
一.下载apk 选择你需要安装的apk进行下载,下载完以后放在与adb.exe同一目录下: 看我的 二.安装apk遇到的问题 开启Genymotion模拟器,然后cmd到你的platform-tool ...
- CentOS6.5配置PHP CI程序
步骤: 1.安装CentOS6.5系统: 1.选择PHP+Mysql环境 2.关闭防火墙和SeLinux 1.chkconfig --level 35 iptables off ...
- android-gradle-深入浅出-五:build type
默认情况下,Android插件自动为项目构建一个debug和一个release版本的应用.这两个版本的不同主要体现在在非开发机上的调试功能以及APK的签名方式.debug版本使用一个用公开的name/ ...