第一部分:DML--数据库操作语言

	
常用表管理语句:
		
		set names gbk;--设置字符编码
		查看所有数据库:show databases;
		查看所有表:show tables
		查看表结构:desc 表名/视图名
		use 表名;--选择表
		查看建表过程:show  create table  表名
		查看建视图过程:show create view 视图
		查看所有详细表信息:show table status\G(让结果显示好看一些)
		查看某张表详细信息:show table status where name='goods(表名)'\G
		删除表:drop table 表名
		删除视图:drop view 视图名;
		删除列:alter table drop column 指定列
		改表名:rename table oldName to newName
		更新表:update 表名 set 字段
		插入数据:insert into 表名 value()
		清空数据:truncate 表名;(相当于删除表在重建)
		写错语句退出:\c
		让结果显示好看一些:\G
		
insert:

	insert into 表名 插入列与值要严格对应

	数字不必加单引号 字符串必须加单引号
	
	例子:insert into test(age,name)values(10,'小明');
	


update操作:

	 例子:update user set age=8 where name=lianying;(注意where条件不加会影响所有行,需要小心)
	 

delete操作:

	不可能针对某一列删除 要删必须一行
	delete from 表名 where 添加
	
	delete from user where uid=1;(必须加上添加,否则全部数据删除)
	
	
select查找:

	select * from 表名(全部查出)
	select uid,name from user where uid>10;
	select * from user where uid=11;
	
	
select查询模型(重要):

	select * from 表名 where 1(where是一个表达式 为真则取出来 为假不取)
	
	把列看成变量,既然是变量就能参与运,。这个过程称为广义投影(比如:取出两列参与运算) 也可以带到函数里面计算
	
查询练习:

	子查询可以查出一个栏目下所有字栏目的商品
	模糊查询:where 字段 like '%A%'  --%代表任意字符 _代表单一字符
	

注意:NULL:查询方法: select * from test where name is (not)null

	
group分组与统计函数:

	统计函数:
			max()
			count()
			avg()
			min()
			sum()
			

在sql中重复要用的语句:用as名字新变量,以便调用

select goods_id,goods_name,(market_price-shop_price) as save from goods


having -- 对查询出来的结果集进行筛选
where 不能写在having后面

order by :(默认升序asc) 降序asc(排序很浪费资源)
	select goods_id,goods_name,shop_price from goods order by  shop_price desc;
	

limit用法:(做分页类能用到)

			限制取出条目(limit有两个参数 :偏移量 取出的条目)

			select goods_id,goods_name,shop_price
			-> from goods
			-> order by shop_price desc
			-> limit  0,3;



子句的查询陷阱:

		5种语句有严格的顺序,where ,group by,having,order by,limit
		不能颠倒顺序
		
		例子: #语句有严格的顺序
		
				mysql> select id,sum(num) 
					-> from
					-> (select * from a union select * from b) as temp
					-> group by id
					-> having sum(num)>10
					-> order by sum(num) desc
					-> limit 0,1;
		
	
子查询:
	
	where字查询:(内层的查询结果作为外层的比较条件)
	
		静态的:select goods_id,goods_name from goods where goods_id=32;
		动态的:select goods_id,goods_name from goods where goods_id=(select max(goods_id) from goods);
		
		#取出每个栏目下最新的商品:
		select goods_id,cat_id,goods_name from goods where goods_id in (select max(goods_id) from goods group by cat_id);
	
	from子查询:
		#每个栏目下最新的商品:
		mysql> select goods_id,goods_name from (select * from goods where 1 order by cat_id desc) as tmp
			-> group by cat_id;
			
	exists子查询:
	
		#查询栏目下是否有商品
		mysql> select * from category
			-> where exists(select * from goods where goods.cat_id=category.cat_id)
	
	
内连接查询(重要):

			内连接是左右连接结果的交集

			select xxx from
			table1 inner jion table2 on table1.xx=table2.xx
	
		
		mysql> select boy.hid,boy.bname,girl.hid,girl.gname
			-> from
			-> boy inner join girl on boy.hid=girl.hid;
		
	
左连接特点:

		以左表的数据为标准,去找右表的数据,查不到的为NULL
		
		#左连接
		mysql> select boy.hid,boy.bname,girl.hid,girl.gname
			-> from
			-> boy left join girl on boy.hid=girl.hid;
		
		#右连接
		mysql> select boy.hid,boy.bname,girl.hid,girl.gname
		-> from
		-> boy right join girl on boy.hid=girl.hid;

		
		mysql> select goods_id,cat_name,goods_name,shop_price
			-> from
			-> goods left join category on goods.cat_id= category.cat_id
			-> where goods.cat_id=4;
			

union查询:
			把2条或多条的额查询结果,合并成1个结果集
			
			sql1 N行
			sql2 M行
			sql1 union sql2,N+M行
			
			union语句必须满足一个条件:各语句取出的列数要相同
			
			union语句中不用写order by 因为sql合并后得到总的结果集可以order by 字句order by失去意义
			
			场景:2条语句,各自的where非常复杂,可以简化成简单的条件在union
			
			注意:使用union时,完全相等的行将会被合并
				  合并是比较耗时的操作,一般不让union合并,使用union all 可以避免合并 对速度有提升
				  
			mysql> select * from a
				-> union all #union all 可以避免重复语句合并
				-> select * from b;
					

			
			mysql> select goods_id,cat_id,goods_name,shop_price from goods where cat_id=2
				-> union
				-> select goods_id,cat_id,goods_name,shop_price from goods where cat_id=4;
				

				

第二部分:DDL数据库定义语言(建表)

	create table 表名 (
	列1 列类型 [列属性 默认值]
	列2 列类型 [列属性 默认值]
	...
	);
	engine = 存储引擎
	chartset = 字符集
		

	建表过程:声明表头的过程,也就是声明列的过程
	
	
		选择合理的列类型 合理的列宽度(即放下内容 又不浪费磁盘空间)
		
		列选什么类型的列 列给什么样的属性
		
	

	
		数值型--整形,浮点型,定点型
		
		字符串型--char varchar text
		
		日期时间类型--2012-12-13 14.25.36
		
		
		
	整形列:
		 
		类型:        字节:      最小值:                  最大值:

		bigint     -- 8字节        -9223372036854775808		18446744073709551615
		int        -- 4字节		   --2147483648             4294967295
		mediunint  -- 3字节		   -8388608                 8388607
		smallint   -- 2字节        -32768                   32767
		tinyint    -- 1字节        -128                     127
		
		整行列的可选参数:
		
			unsigned 无符号,列的值从0开始不为负
			zerofill M(宽度)适合用于 学号 编码等固定宽度的数字,可以用0填充至固定宽度
			
			学号:1--0001
			
			注意:zerofill属性默认决定是unsigned
		
			
	浮点列与定点列:
		
			float(M,D)M是精度总位数 D代表小数点后面的位数
			double
			
			float/double 范围区别和decimal相比:浮点数存储有精度的损失
	
			decimal 定点型更精确
			
			
	字符型列:

			char(M)--char(10)只能存10个字符
			
			char型:如果不够M个字符,内部会用空格补齐,取出时在把右侧空格删掉
					注意:这意味着 右侧本身有空格将会丢失
				
				
			varchar(M)--用多少占多少--自动扩展		
			varchar不会丢失空格
			
			
			速度上:定长char快一些  在一定范围内用char定长寻址快 速度快
			M比较短20个以内用char
			
			text:存大段文本
			blob:是二进制类型 用来存图像信息 音频等二进制信息
				 blob意义在于防止因为字符集的问题导致信息丢失
				 
		
			enum枚举类型:是定义好 值就在某几个枚举范围内
						  gender emum('男','女') insert 只能选其中之一
						  
						  
						  
	日期时间类型:
				year:存年份
				date:存年份日期2016-18
				time:存时分秒
				datetime:年月日时分秒
				
			mysql> create table t8(
				-> ya year,
				-> dt date,
				-> tm time,
				-> dttm datetime);
				-> insert into t8 (ya,dt,tm) values(2015,'2015-12-18','18:28:36');
		

	列的默认值:
			
			1、NULL查询不方便
			2、NULL索引效率不高
			3、实际中避免列的值为NULL
			
			如何避免:声明列NOT NULL default默认值
			
			mysql> create table t10(
				-> id int not null default 0,
				-> name char(10) not null default ''
				-> );
						
	主键与自增:
			
			主键primary key 此列不重复,能区分每一行
			
			
			primary key,auto_increment(一般那两个一起出现)
			
			注意:一张表列只能有一列为auto_increment 且此列必须加索引(index key)
	
	 优化:
			定长(char)与变长(varchar)分离
			常用与不常用列分离
			
			能提高表的查询效率
			
	
	列的删除与增加:(列的增删改)
	
			alter  table 表名 add 列名 列类型 列属性 默认在表的最后
			alter  table  表名 drop column 指定列--删除列
			alter  table  表名 add列名  列类型 列属性 [after 指定列的后面]
			
			alter table  表名 change height(要修改的) shengao(被修改后的) smallint
			alter table  表名 modify 列名  要改成的新的属性
			
			#alter table t12 modify shengao bigint;
			
			
	视图:(存储的都是语句)
		 view被称为虚拟表,view是sql语句的查询结果(物理表的一个映射结果,物理表一改变,视图表也改变)
		 
		 view好处:
				1、权限控制可用:
								 比如某几个列允许用户查询,其他不允许
								 可通过视图开放其中一列或几列,起到权限控制作用
				
				2、简化复杂的查询
				
				3、视图能更新?
					如果视图的每一行是与物理表一一对应的可以
					view的行是由物理表多行经过计算得到的结果,view不可以更新
				
					
		视图的algorithm:
			
				对于检查查询形成的view,在对view查询时,如order by where
				可以把建视图语句+查视图的语句===合并成==>查物理的语句
				这种视图的算法叫merger(合并)
				
					
		
	引擎的概念:
	
		mysql 5.0以上默认的引擎是innoDB  一般建表时指定引擎
		
		myisam引擎存储的数据可以直接考出来拿去用
		innDB要把数据导出来
		
		myisam和innDB引擎区别:
							
							mysiam     innDB 
		
			批量插入的速度:  高          低
			存储限制:			没有     64TB
		
		
	字符集与乱码问题:
	
		字符集、校对集(排序规则)、乱码
		
		文字本来的字符集与展示的字符集不一致导致
		
		客户端编码设置:set names gbk/utf8;
		表设置编码:create table ()charset utf8;
		服务器端utf8/gbk 都可
		网页的话:mate:charset=utf8;
		
	索引:
	
		索引是数据的目录,能快速定位行数据的位置
		索引提高了查询的速度,降低了增删改的速度,并非越多越好
		一般在查询频率的列上加,而且在重复低列上加效果好
		
		key 普通索引
		unique key 唯一键
		primary key 主键索引
		fulltext 全文索引(在中文环境下几乎无效,一般用第三方解决方案:如sphinx)
		
		索引长度:建索引时,可以只索引列的前一部分的内容比如:前十个字符 key email(email(10));
		
		多列索引:就是把2列或者多列的值,看成一个整体,然后键索引
		
		冗余索引:在某个列上可能存在多个索引
		
		
		
		索引操作:
			
				查看索引:show index from goods\G
				删除索引:alter table 表名 drop index 索引名
						或者:drop index 索引名 on 表名
				
				添加:alter table 表名 add [index \unqiue]索引名(列名)
				
				添加主键索引:alter table 表名 add primary key 列名
				删除主键索引:alter table 表名 drop primary key
				
		
	常用函数:
	

	一、数学函数

		abs(x)   返回x的绝对值
		bin(x)   返回x的二进制(oct返回八进制,hex返回十六进制)
		ceiling(x)   返回大于x的最小整数值
		exp(x)   返回值e(自然对数的底)的x次方
		floor(x)   返回小于x的最大整数值
		greatest(x1,x2,...,xn)返回集合中最大的值
		least(x1,x2,...,xn)      返回集合中最小的值
		ln(x)                    返回x的自然对数
		log(x,y)返回x的以y为底的对数
		mod(x,y)                 返回x/y的模(余数)
		pi()返回pi的值(圆周率)
		rand()返回0到1内的随机值,可以通过提供一个参数(种子)使rand()随机数生成器生成一个指定的值。
		round(x,y)返回参数x的四舍五入的有y位小数的值
		sign(x) 返回代表数字x的符号的值
		sqrt(x) 返回一个数的平方根
		truncate(x,y)            返回数字x截短为y位小数的结果

	二、聚合函数(常用于group by从句的select查询中)

		avg(col)返回指定列的平均值
		count(col)返回指定列中非null值的个数
		min(col)返回指定列的最小值
		max(col)返回指定列的最大值
		sum(col)返回指定列的所有值之和
		group_concat(col) 返回由属于一组的列值连接组合而成的结果

	三、字符串函数

		ascii(char)返回字符的ascii码值
		bit_length(str)返回字符串的比特长度
		concat(s1,s2...,sn)将s1,s2...,sn连接成字符串
		concat_ws(sep,s1,s2...,sn)将s1,s2...,sn连接成字符串,并用sep字符间隔
		insert(str,x,y,instr) 将字符串str从第x位置开始,y个字符长的子串替换为字符串instr,返回结果
		find_in_set(str,list)分析逗号分隔的list列表,如果发现str,返回str在list中的位置
		lcase(str)或lower(str) 返回将字符串str中所有字符改变为小写后的结果
		left(str,x)返回字符串str中最左边的x个字符
		length(s)返回字符串str中的字符数
		ltrim(str) 从字符串str中切掉开头的空格
		position(substr,str) 返回子串substr在字符串str中第一次出现的位置
		quote(str) 用反斜杠转义str中的单引号
		repeat(str,srchstr,rplcstr)返回字符串str重复x次的结果
		reverse(str) 返回颠倒字符串str的结果
		right(str,x) 返回字符串str中最右边的x个字符
		rtrim(str) 返回字符串str尾部的空格
		strcmp(s1,s2)比较字符串s1和s2
		trim(str)去除字符串首部和尾部的所有空格
		ucase(str)或upper(str) 返回将字符串str中所有字符转变为大写后的结果

	四、日期和时间函数

		curdate()或current_date() 返回当前的日期
		curtime()或current_time() 返回当前的时间
		date_add(date,interval int keyword)返回日期date加上间隔时间int的结果(int必须按照关键字进行格式化),如:selectdate_add(current_date,interval 6 month);
		date_format(date,fmt)  依照指定的fmt格式格式化日期date值
		date_sub(date,interval int keyword)返回日期date加上间隔时间int的结果(int必须按照关键字进行格式化),如:selectdate_sub(current_date,interval 6 month);
		dayofweek(date)   返回date所代表的一星期中的第几天(1~7)
		dayofmonth(date)  返回date是一个月的第几天(1~31)
		dayofyear(date)   返回date是一年的第几天(1~366)
		dayname(date)   返回date的星期名,如:select dayname(current_date);
		from_unixtime(ts,fmt)  根据指定的fmt格式,格式化unix时间戳ts
		hour(time)   返回time的小时值(0~23)
		minute(time)   返回time的分钟值(0~59)
		month(date)   返回date的月份值(1~12)
		monthname(date)   返回date的月份名,如:select monthname(current_date);
		now()    返回当前的日期和时间
		quarter(date)   返回date在一年中的季度(1~4),如select quarter(current_date);
		week(date)   返回日期date为一年中第几周(0~53)
		year(date)   返回日期date的年份(1000~9999)

	一些示例:

		获取当前系统时间:select from_unixtime(unix_timestamp());
		select extract(year_month from current_date);
		select extract(day_second from current_date);
		select extract(hour_minute from current_date);
		返回两个日期值之间的差值(月数):select period_diff(200302,199802);
		在mysql中计算年龄:
		select date_format(from_days(to_days(now())-to_days(birthday)),'%y')+0 as age from employee;
		这样,如果brithday是未来的年月日的话,计算结果为0。
		下面的sql语句计算员工的绝对年龄,即当birthday是未来的日期时,将得到负值。
		select date_format(now(), '%y') - date_format(birthday, '%y') -(date_format(now(), '00-%m-%d') 100,'true','false');
		if()函数在只有两种可能结果时才适合使用。然而,在现实世界中,我们可能发现在条件测试中会需要多个分支。在这种情况下,mysql提供了case函数,它和php及perl语言的switch-case条件例程一样。
		case函数的格式有些复杂,通常如下所示:
		case [expression to be evaluated]
		when [val 1] then [result 1]
		when [val 2] then [result 2]
		when [val 3] then [result 3]
		......
		when [val n] then [result n]
		else [default result]
		end
		
		这里,第一个参数是要被判断的值或表达式,接下来的是一系列的when-then块,每一块的第一个参数指定要比较的值,如果为真,就返回结果。所有的when-then块将以else块结束,当end结束了所有外部的case块时,如果前面的每一个块都不匹配就会返回else块指定的默认结果。如果没有指定else块,而且所有的when-then比较都不是真,mysql将会返回null。
		case函数还有另外一种句法,有时使用起来非常方便,如下:
		case
		when [conditional test 1] then [result 1]
		when [conditional test 2] then [result 2]
		else [default result]
		end
		
		这种条件下,返回的结果取决于相应的条件测试是否为真。
		
		示例:
		
		mysql>select case 'green'
			 when 'red' then 'stop'
			 when 'green' then 'go' end;
		select case 9 when 1 then 'a' when 2 then 'b' else 'n/a' end;
		select case when (2+2)=4 then 'ok' when(2+2)<>4 then 'not ok' end asstatus;
		select name,if((isactive = 1),'已激活','未激活') as result fromuserlogininfo;
		select fname,lname,(math+sci+lit) as total,
		case when (math+sci+lit) < 50 then 'd'
		when (math+sci+lit) between 50 and 150 then 'c'
		when (math+sci+lit) between 151 and 250 then 'b'
		else 'a' end
		as grade from marks;
		select if(encrypt('sue','ts')=upass,'allow','deny') as loginresultfrom users where uname = 'sue';#一个登陆验证

	七、格式化函数

		date_format(date,fmt)  依照字符串fmt格式化日期date值
		format(x,y)   把x格式化为以逗号隔开的数字序列,y是结果的小数位数
		inet_aton(ip)   返回ip地址的数字表示
		inet_ntoa(num)   返回数字所代表的ip地址
		time_format(time,fmt)  依照字符串fmt格式化时间time值
		其中最简单的是format()函数,它可以把大的数值格式化为以逗号间隔的易读的序列。
		
		示例:
		
		select format(34234.34323432,3);
		select date_format(now(),'%w,%d %m %y %r');
		select date_format(now(),'%y-%m-%d');
		select date_format(19990330,'%y-%m-%d');
		select date_format(now(),'%h:%i %p');
		select inet_aton('10.122.89.47');
		select inet_ntoa(175790383);

	八、类型转化函数

		为了进行数据类型转化,mysql提供了cast()函数,它可以把一个值转化为指定的数据类型。类型有:binary,char,date,time,datetime,signed,unsigned
		示例:
		
		select cast(now() as signed integer),curdate()+0;
		select 'f'=binary 'f','f'=cast('f' as binary);

	九、系统信息函数

		database()   返回当前数据库名
		benchmark(count,expr)  将表达式expr重复运行count次
		connection_id()   返回当前客户的连接id
		found_rows()   返回最后一个select查询进行检索的总行数
		user()或system_user()  返回当前登陆用户名
		version()   返回mysql服务器的版本
		
		示例:
		
		select database(),version(),user();
		selectbenchmark(9999999,log(rand()*pi()));#该例中,mysql计算log(rand()*pi())表达式9999999次。