> 数据库 > MySQL >

mysql 简单介绍

mysql 简单介绍

 

mysql 不允许修改数据库名,一些客户端可以变通的方式来修改数据库名称

mysql 1064错误,语法错误

更改表名:
 rename table jian to song;
 
删除表
drop tablde tableName;

DROP TABLE IF EXISTS table_name;

set names gbk; 告诉服务器客户端是什么字符集

建表:
create table song(
id int,
name varchar(100)
) charset [=] gbk;


同时插入多行:
INSERT INTO USER(`name`, `passwd`)
VALUES
    ('a', 'aa'),
    ('b', 'bb'),
    ('c', 'cc');


    范围:补码

//添加字段
alter table table_name add field_name int unsigned

zerofile  默认就是unsigned

null比较,和计算起来都非常不方面, 都无法和他比较大小  只可以用 ISNULL, is not null 比较

select not ISNULL(NULL)
select null is not null;

推荐设置默认值
not null default xxx comment abc;

浮点型 float(M,D) M代表总位数(不包括小数点), D代表小数位数   注意这里的MD会影响小数的范围,这点这整形的不同 

char0255)个字符  利用率<=100%eee
varchar(0-65535)个字节  转换成utf8后大概两万个汉字  记录存了多少个字符需要占用(1-2个字节)所以利用率<100%;
 
 char(M)    M可容纳的字符宽度
 varchar(M) M可容纳的字符宽度
这两个都是记录的字符个数,如果想求占用了多少字节,只能是根据存的东西而定 

char型的如果不够指定长度mysql内部尾部用空格补齐,取出来的时候在踢除
会尾部空格丢失情况

char 比 varchar要快一些

用空间换时间


1.范围
2.利用率
3.空格的处理
4.速度

text不支持全文索引,不支持默认值           10

mysql能够自动识别错误的日期

time还可以表示时间差,所以可以为负值

enum  不符合数据库设计理念(不可分割)  也不节省字节

浮点:直接影响存储范围 float(5,2);  不包括小数点,正负号

银行四舍五入法:
五入不入   1 3 7 9  不入
            2 4 6 8  入
变成无符号的时候范围并不会翻倍

浮点数值
DECIMAL 对DECIMAL(M,D) ,如果M>D,为M+2否则为D+2 依赖于M和D的值 依赖于M和D的值 小数值 m或d中较大的值

create  table 表名(
列名 列类型 [列属性] [默认值]
`author_id`  int(11) UNSIGNED ZEROFILL NOT NULL ,
) engin 引擎名  charset 字符集


create table aa(
 id1  int(11) UNSIGNED ZEROFILL NOT NULL,        //not null必须放在 unsigned 和zerofill后面,而这两个本身是没有顺序的
 id2 int(10)   unsigned  ZEROFILL  not null
);

between  允许等于俩个边界值

select max(id),name,age from user;  //name和age没有什么意义   记录下的是第一个遇到的

where  表达式
列明 当成变量来看

//查询每个栏目下面积压的货款
                sum是针对每个分组的所有的记录
select cat_id, sum(shop_price*goods_nums) from goods group by cat_id;

group by 只有与 sum,max ,min,count聚合函数配合起来才有意义

where 中加的字段必须是表中存在的(既文件中存在的),where发挥作用的时间在结果之前,所以不用用于结果的字段  对原始列起作用

所以:select a,b,a-b as alias where alias <100;  (错误的写法)

正确的写法:
1select a,b,a-b as alias where a-b <100;  计算两次
2select a,b,a-b as alias having alias<100;

查询两门及两门以上不及格的同学的平均分
tip:先求出所有人的平均分,在筛选条件

select name, sum(score<60) as gk,avg(scor) as pj from  stu group by name having gk>=2;

注意这里的sum不可以替换成count,count的统计记录的行数里面的表达式无论是正负还是 0 都会被统计到

查询结果可以看做一个表

having 筛选  对结果起作用  (先where后having)

在没有排序的情况下按硬盘上的物理文件顺序来存取

顺序:where->group->having->order by->limit

好的理解模型:
    1.where 把表达式放到行中看是否为真
    2.列 看做变量,变量可以进行运算
    3.取出的结果可以看做一张临时表

**聚合函数和其他字段共同取出时,其他字段以第一次碰到的数据为准    

子查询查询出来的结果可以当做一张表来看,必须加别名
 create table card2 like card;

where  型子查询:把内层的查询的结果作为外层的查询条件
select * from card where id = (select id from card limit 1);

from    型子查询: 把内层的查询结果当成临时表,供外层sql再次查询
select * from (select * from card) as mycard ;

exists    型子查询    把外层的查询结果拿到内层,看内层的查询结果是否正确

union 联合查询结果
要求:两次查询结果列数一致
如果列类型不一致会转换成  blob类型
推荐:查询的每一列的列类型也一致
列名不一致的时候以第一列为主
如果字句中有order by  ,limit 必须加() 推荐放到字句之后,即对最终合并后的结果进行排序

(select * from classes where id in(2,3) order by id desc limit
ll (select * from classes where id in(4,5) order by id desc limit 2);


如果字句中order by不配合limit,order by 将失效  被语法分析器优化时会被过滤掉(where = 1);


集合:
表-----集合
行---集合的元素

集合相乘:笛卡尔积 其实就是两个集合的完全组合  --->select * from ta, tb;


理论上讲不存在两个相同的行,但是表中可以存在相同的行,因为表内部有一个rowid

a left join b ==== b right join a;

推荐用左连接代替右连接

左连接:以左表为准,去右表匹配数据,找不到用null补齐

内连接是左右连接的交集

mysql能否查出左右连接的并集呢?
目前不能,mysql不支持外连接,可以用 union(左链接 union 右连接) 来实现    

//建表
create table kang(
id int unsigned primary key auto_increment comment '主键',
name varchar(100) not null default '' comment '姓名'
) engine=myisam charset=utf8;

//添加字段
alter table kang add height tinyint unsigned not null default '123' comment '身高'; 

//删除字段
alter table kang drop height after id;  #默认在最后增加一列  [after] [first]

//修改字段
alter table kang change [height 要修改的列名] [height int unsigned default 456 列声明];


tee命令:
命令行中的结果保存到外部文件中
notee/ \t 停止记录

试图:由查询结果形成的一张虚拟表,可以简化查询

//创建视图
create [ALGORITHM= temptable] view view_name as [select 语句];

//删除视图
drop view view_name;

//视图的修改
alter view view_name as [select 语句];

视图可以修改并影响表,但并不是所有的视图都可以增删改
视图中的数据可以和表中的数据一一对应时可以修改
insert 还要注意必须包含所有没有默认值的列


视图的 ALGORITHM  算法
merge:只记录一条sql,当查询时把这个sql和以前的sql合并在在原始表中进行查询
temptable 形成一个临时表,再在这个临时表中进行查询
undefined:

*******************mysql 字符集 **********************
mysql 列,表,数据库,服务器都可以指定字符集,如果哪级没有指定则按他的上级

set names N;

等价于下面三句:

 客户端字符集:character_set_client
 客户端高速中转器转成什么编码:character_set_connection
 查询结果用什么编码:character_set_results
 
set character_set_client=gbk;
set character_set_connection=utf8;
set character_set_results=gbk;
 
latin1 比较特殊 , 当数据库为latin1(iso-8859-1)时,必须 set names latin1
其他的情况 set names的编码应该和文件的编码和想要的编码保持一致


 校对集:utf8_general_ci不区分大小写
 校对集是指对字符集的排序规则
 一个字符集可以有一个或多个排序规则
 
 声明的校对集必须是字符集合法的校对集


触发器的监视范围:增,删,改
触发范围:增,删,改

触发器语法:
delimiter $
create trigger triggerName
after/before insert/update/delete on 表名
for each row(mysql默认,只可以是行触发器)
begin
# sql todo;
end
delimiter ;

#删除触发器
drop trigger triggerName

insert 触发器中用new.列名来引用
 
//示例
delimiter $$ 
create tgrigger tg1
for each row
begin
update g set num = num - new.much where id = new.gid;
end

delete 触发器中用old.列名来引用

对update来说 修改前的数据用old.列明,修改后的数据用new.列明,

before /after区别:

操作之前:相当于饭前检查你有没有足够的钱

before sql语句发过来了,对语句做一个审查,此时语句并没有对硬盘上的数据进行修改
after 是先完成数据的增删改在触发
触发语句晚于增删改,无法影响前面的增删改产生影响

before是先完成触发,在增删改
触发的语句先于监视的增删改,我们有审核,判断,修改即将要发生的操作

下订单前进行判断,强制把所下订单数量<=5(最多只可以下五个订单)

查看触发器:show triggers;

***************************
  Trigger: tg1
    Event: INSERT
    Table: a
Statement: BEGIN
update g set num = num -3 w
END
   Timing: AFTER
  Created: NULL
 sql_mode:
 Definer: root@localhost

事务:
原子性:不可分割
隔离性:中间的过程不可以被看到
一致性:总额一致 
持久性:不可以撤销

#查看mysql的模式
show variables like "%mod%" ;

#切换到严格模式
set sql_mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION";

 
set autocommit = off;#禁止自动提交 查看 show variables like "%commit%";

start transaction;#开启事务

当一个事务 commit/rollback 时这个事务就结束了

注意:有一些语句会隐式的提交事务 参见mysql手册

事务的原理:
    sql 先作用于事务日志 ,然后一起在作用于表

倒大量数据:先去掉索引,统一加索引的速度是非常快的

#执行一条语句然后退出
mysql -uroot -proot dealer  -e"select * from dealer_area where id=54";

备份和回复:
增加备份和整体备份

自带工具:mysqldump
导出表:
mysqldump -u root -p 123456 库名 表一 表二…… >地址 
C:\Users\root>mysqldump -uroot -p ci >ci.sql(ci 库下的所有的表)

不写表名会导出库下的所有的表

导出库:
mysqldump -u root -p 123456 -B 库名 库一 库二…… >地址   [-A] 导出下面所有的库

#导出表结构加参数 -d 即可
mysqldump -uroot -p -B -d ci >ci.sql #库以及库下的所有的表
mysqldump -uroot -p -d ci >ci.sql     #库下的所有的表
mysqldump -uroot -p -d ci kang >ci.sql# ci 库下的 kang 表

#只导出数据 -t 参数
mysqldump -uroot -p -t db_house t_region -w "fid>1">/home/v_jksong/dump.sql
#导出指定的查询结果
mysqldump -uroot -p db_house t_region -w "true  order by fid desc limit 1">/home/v_jksong/dump.sql #没有where条件时记得添加 true 拼凑
mysqldump -uroot -p db_house t_region -w "fid>1">/home/v_jksong/dump.sql

恢复:
source d:\\a.sql;

mysql -uroot -p < d:\\(/)song.sql;(库级)
mysql -uroot -p 库名 < d:\\(/)song.sql;(表级)


二叉树:log2N
哈希:一次:

索引:
哈希索引:(理论上是指差一次)  比较浪费空间
散列算法算出对应的地址
根据散列值在分配空间
弊端:1.算出来的值不连续,申请空间的时候必须连续 ,中间有空缺   2.算出来的值相同

索引:加快查询速度,降低增删改速度,同时占用空间

不要过度索引
索引条件 (where后面最频繁的条件比较适宜)


除主键外的数据一般叫做原数据--主键加在元数据上

主键必唯一,唯一不一定为主键,一张表上只有一个主键

查看一张表上的索引:
show index from 表名

索引名称可以省略,省略后默认是字段名称
增加普通索引:
alter table 表名 add index/unique/fulltext [索引名](列名)
增加主键索引:
alter table 表名 add primary key (列名)  //不要加索引名称,因为主键只有一个

删除非主键索引:
alter table 表名  drop index 索引名

删除主键:
alter table 表名  drop primary key;

全文索引:(对文章的每个词建立索引)
select * from user where  match(name) against ('匹配词');

select match('name') against ('匹配词') from user;  //匹配度

不针对非常频繁的词进行索引 this , is ,you ,my等等

存储过程:
show procedure status;

删除存储过程
drop procedure 名称

查看某个具体的存储过程
show CREATE PROCEDURE song;

 

 

mysql -uroot -proot dealer  -e"select * from dealer_area where id=54";



(责任编辑:IT)