zoukankan      html  css  js  c++  java
  • MySQL

    一。基本SQL语句

    SQL:(Structured Query Language) 结构化查询语言 专门用来和关系型数据库进行通信的语言

    SQL语句中的大小写问题:
    1)关键字、函数名、列名和索引名不区分大小写
    2)数据库名、表名、别名及视图名区分大小写的(因为linux区分大小写的)
    3)存储过程、事件不区分大小写,但是触发器区分大小写

    SQL语句功能:
    增删改查

    SQL语句的分类:
    DML:Data Manipulation Language 数据操纵语言
    insert
    update
    delete
    DCL:Data Control Language 数据控制语言
    grant
    revoke
    DDL:Data Definition Language 数据定义语言
    create
    alter
    drop
    truncate
    DQL:Data Query Language 数据查询语言
    select

    基本SQL语句:
    1、查看当前用户
    mysql> select user();
    +----------------+
    | user() |
    +----------------+
    | root@localhost |
    +----------------+
    2、对数据库的操作
    1)查看当前操作的数据库
    mysql> select database();
    +------------+
    | database() |
    +------------+
    | NULL |
    +------------+
    1 row in set (0.00 sec)
    2)选择操作哪个数据库
    mysql> use test;
    3)查看系统中有哪些数据库
    mysql> show databases;
    +--------------------+
    | Database |
    +--------------------+
    | information_schema | 信息模式数据库,保存服务器的信息
    | mysql 核心管理数据库,保存用户和权限信息,记录了和系统安全相关的信息
    | performance_schema 性能模式数据库,搜索服务器的性能参数
    | test | 测试数据库
    +--------------------+
    4)查看当前数据库下有哪些表
    mysql> show tables;
    5)创建数据库
    mysql> create database updb1;
    注意:数据库名不能重复
    6)删除数据库(轻易不要这么做,风险大)
    mysql> drop database updb1;
    3、对表的操作 (表一定是存在数据库中的)
    1)创建表结构
    语法:create table 表名 (字段1名 字段类型,字段2名 字段类型,... ...,字段n名 字段类型);
    mysql> create table t1 (id int,name char(10));
    2)查看表结构
    mysql> desc t1;
    +-------+----------+------+-----+---------+-------+
    | Field | Type | Null | Key | Default | Extra |
    +-------+----------+------+-----+---------+-------+
    | id | int(11) | YES | | NULL | |
    | name | char(10) | YES | | NULL | |
    +-------+----------+------+-----+---------+-------+
    字段名 类型 是否允许为空 键值 默认值 其他
    3)查看建表时使用的语句
    mysql> show create table t1;
    4)向表中插入数据
    (1)插入时不指定字段,在写值的时候的顺序就需要与表中的字段顺序一一对应
    语法:insert into 表名 values (值1,值2,...);
    mysql> insert into t1 values(1,"Tom");
    (2)插入时指定字段
    语法:insert into 表名(字段名,......) values (值1,... ...);
    mysql> insert into t1(id) values(2);
    mysql> insert into t1(name) values("Mary");
    mysql> select * from t1; //查询表中数据
    +------+------+
    | id | name |
    +------+------+
    | 1 | Tom |
    | 2 | NULL |
    | NULL | Mary |
    +------+------+
    3 rows in set (0.02 sec)
    (3)向表中插入多条数据
    mysql> insert into t1 values (4,"Jack"),(6,"Kite"),(8,"LiLei");
    5)查询表中数据
    mysql> select * from t1; //全表查询
    mysql> select id from t1; //指定字段查询
    mysql> select name,id from t1; //同时查询多个字段
    6)修改表结构 alter
    a、增加字段
    (1)向表中增加字段(默认添加到最后一个字段)
    语法:alter table 表名 add 字段名 字段类型 [first|after 字段名];
    mysql> alter table t1 add sex char(10);
    (2)将字段添加为表中的第一个字段
    mysql> alter table t1 add qq int first;
    (3)在某个字段后面插入字段
    mysql> alter table t1 add tel int(15) after id;
    b、修改字段属性
    change:既能修改字段类型,又能修改字段名字
    modify:只能修改字段类型
    修改字段类型
    语法:alter table 表名 modify 字段名 字段类型;
    mysql> alter table t1 modify name char(15);
    修改字段名字
    语法:alter table 表名 change 原字段名 新字段名 字段类型;
    mysql> alter table t1 change qq msn char(15);
    注意:如果只修改字段类型,那么原字段名和新字段名一样
    如果只修改字段名字,那么字段类型与原来的字段的类型保持一致。
    c、删除字段
    语法:alter table 表名 drop 字段名;
    mysql> alter table t1 drop msn;
    7)修改表名
    语法:alter table 表名 rename 新表名;
    mysql> alter table t1 rename test1;
    8)更新表中的数据
    语法:update 表名 set 字段名=值[,字段名2=值2] where 条件;
    mysql> update test1 set id=3 where name="Mary";
    mysql> update test1 set tel=45629009,sex="male" where name="Tom";
    9)删除表中记录
    (1)删除表中指定行
    mysql> delete from test1 where id>=4;
    (2)删除表中全部记录
    mysql> delete from test1;
    10)截断表 truncate
    truncate table 表名;
    delete:可以回滚的
    truncate:不可以回滚的,删除数据同时会释放空间。大表数据清除一定要用truncate,速度快。
    11)删除表
    drop table 表名;

    二。MySQL的函数

    一、时间函数
    1、查看当前时间
    mysql> select curtime();
    mysql> select current_time();
    2、查看当前日期
    mysql> select curdate();
    mysql> select current_date();
    3、查看当前系统时间
    mysql> select now();
    mysql> select sysdate();

    二、聚合函数
    求和 sum(字段名)
    求平均数 avg(字段名)
    求最大值 max(字段名)
    求最小值 min(字段名)
    统计匹配行数 count(字段名) count(*):一般用于统计表中有多少条非空记录。

    准备环境
    mysql> select database();
    +------------+
    | database() |
    +------------+
    | up1 |
    +------------+
    mysql> create table score (sno int,sname char(10),ule int,ula int,uoa int);
    mysql> insert into score values (1,"tom",70,80,90),(2,"mary",55,75,65),(3,"jack",75,45,95),(4,"mike",90,100,86);

    mysql> select max(ule),min(uoa) from score;
    +----------+----------+
    | max(ule) | min(uoa) |
    +----------+----------+
    | 90 | 65 |
    +----------+----------+
    1 row in set (0.02 sec)

    mysql> select max(ule) mae,min(uoa) mio from score; //给列起别名
    +------+------+
    | mae | mio |
    +------+------+
    | 90 | 65 |
    +------+------+
    1 row in set (0.00 sec)

    列的别名:
    列名 [as] 别名
    统计表中的记录数
    mysql> select count(*) from score;
    计算ula的平均成绩
    mysql> select avg(ula) from score;
    查询各科的总成绩
    mysql> select sum(ula),sum(ule),sum(uoa) from score;
    查询每个学生的姓名及总成绩
    mysql> select sname,ule+ula+uoa from score;
    mysql> select sname,ule+ula+uoa total from score;

    -----------------------------------------------------------------------------------------------------------------
    插曲:参考手册853页case语句
    求一行中的最大值
    mysql> select sname,case when (ule>ula) and (ule>uoa) then ule when (ula>ule) and (ula>uoa) then ula else uoa end max_score from score;
    +-------+-----------+
    | sname | max_score |
    +-------+-----------+
    | tom | 90 |
    | mary | 75 |
    | jack | 95 |
    | mike | 100 |
    +-------+-----------+
    4 rows in set (0.00 sec)
    ----------------------------------------------------------------------------------------------------------------
    三、其它函数
    1、连接函数 concat() concatenate
    mysql> select concat(sno,sname) from score;
    mysql> select concat(sno,' ',sname) from score;
    2、转换成大写 upper()
    转换成小写lower()
    mysql> select upper(sname) from score;
    mysql> update score set sname="Tom" where sname="tom";
    mysql> select lower(sname) from score;
    3、求长度 length()
    mysql> select sname,length(sname) from score;

    三。MySQL查询语句

    一、指定条件查询
    select 用来过滤字段
    from 从哪些表中查询数据
    where 用来过滤记录(行)
    查询ula及格的人的姓名和ula成绩
    mysql> select sname,ula from score where ula>=60;
    查询每一科都及格的人的姓名
    mysql> select sname from score where ule>=60 and ula>=60 and uoa>=60;
    查询有任何一科不及格的学生的全部信息
    mysql> select * from score where ule<60 or ula<60 or uoa<60;
    二、模糊查询
    like
    使用通配符:
    _:匹配单个字符
    %:匹配0个或多个字符
    mysql> select sname from score where sname like "___";
    mysql> select * from score where sname like 'm%'; //以m开头的人
    mysql> select * from score where sname like '%m'; //以m结尾的人
    mysql> select * from score where sname like '%m%'; //名字含有m的人
    mysql> show variables like 'da%'; //查看变量值
    +-----------------+-------------------+
    | Variable_name | Value |
    +-----------------+-------------------+
    | datadir | /data/mysql/ |
    | date_format | %Y-%m-%d |
    | datetime_format | %Y-%m-%d %H:%i:%s |
    +-----------------+-------------------+
    三、分组 group by 字段名
    mysql> alter table score add class int;
    mysql> insert into score values (5,"rose",75,65,95,2);
    mysql> update score set class="1" where sno=1;
    mysql> update score set class="2" where sno=2;
    mysql> update score set class="1" where sno=3;
    mysql> update score set class="2" where sno=4;
    mysql> select class,sum(ula),avg(ula) from score group by class;
    //求每个班的总成绩和平均成绩

    注意:group by里面条件不能使用where,可以与having连用
    显示班级人数超过2人的班级的总成绩及平均成绩
    mysql> select class,sum(ula),avg(ula) from score group by class having count(*)>2;

    四、排序
    order by 字段名 [asc|desc]
    asc:按照升序排序,是默认的
    desc:按照降序排序
    mysql> select sname,ula from score order by ula desc;
    +-------+------+
    | sname | ula |
    +-------+------+
    | mike | 100 |
    | Tom | 80 |
    | mary | 75 |
    | rose | 65 |
    | jack | 45 |
    +-------+------+
    mysql> select * from score order by uoa,ula;

    mysql> select sname,ula from score order by 2 desc; //按照字段的序号排序

    五、限制输出 limit
    limit n:只显示前n条记录
    limit m,n:从第m+1行开始显示n行
    mysql> select sname,ula from score order by ula desc limit 3;
    mysql> select sname,ula from score order by ula desc limit 2,2; //显示第3和第4行

    mysql> select sname,ula from score order by ula desc limit 1;
    mysql> select sname,ula from score order by ula desc limit 0,1;

    六、子查询
    也叫嵌套查询,将一个查询的查询结果作为外层查询的条件。
    查询ula成绩最高的人的学号和姓名
    mysql> select sno,sname from score where ula=(select max(ula) from score);

    小结:
    1、select关键字的顺序
    -----------------------------------------------------------------------------------------------
    关键字 功能 是否必须
    -----------------------------------------------------------------------------------------------
    select 过滤要返回的列或表达式 是
    -----------------------------------------------------------------------------------------------
    from 要检索的表 仅当需要从表中检索数据时使用
    -----------------------------------------------------------------------------------------------
    where 过滤行 否
    -----------------------------------------------------------------------------------------------
    group by 分组 仅在按组计算聚集时使用
    -----------------------------------------------------------------------------------------------
    having 组级过滤(与group by连用) 否
    -----------------------------------------------------------------------------------------------
    order by 对输出排序,默认是升序 否
    -----------------------------------------------------------------------------------------------
    limit 限制输出的行 否
    -----------------------------------------------------------------------------------------------
    2、SQL 语句的执行顺序如下:
    from where group by having select order by limit

    查:select
    慢查询。
    查询的方式:
    1、单表查询
    基本查询
    使用 函数 查询
    2、多表查询
    子查询
    联结查询
    语法:select 列 from 表 [查询条件];
    (1)基本查询
    mysql> select * from q1; 全表查询
    mysql> select name,sex from q1; 查询几列

    mysql> select * from q1 where id=1; 带条件的查询
    mysql> select name,sex from q1 where id=1;

    带字符串的要用 "" 包起来:
    mysql> select id,name from q1 where sex="W";
    mysql> select id,name from q1 where sex=W;
    ERROR 1054 (42S22): Unknown column 'W' in 'where clause'

    创建一个表,练习用的:一个商店,记录的供货商的信息。
    id name price city street riqi
    int varchar float varchar varchar date
    mysql> create table shop (id int,name varchar(20),price float(5,2),city varchar(20),street varchar(20),riqi date);

    mysql> insert into shop values(1001,".1 niu1",5.99,"shenyang","sanhaojie","2015-08-02");
    mysql> insert into shop values(1002,".2 niu2",6.99,"shenyang","sanhaojie","2015-07-02");
    mysql> insert into shop values(1003,".3 niu3",9.99,"shenyang","sanhaojie","2015-07-15");
    mysql> insert into shop values(1004,"4 ma4",5.39,"beijing","zhongguancun","2015-06-15");
    mysql> insert into shop values(1005,"5 ma5",10.90,"beijing","zhongguancun","2015-06-16");
    mysql> insert into shop values(1006,"6 ma6",20.00,"beijing","zhongguancun","2015-06-20");
    mysql> insert into shop values(1007,"wangqi",10.50,"dalian","xianlu","2015-05-20");
    mysql> insert into shop values(1008,"houba",100.00,"dalian","xianlu","2015-05-30");
    mysql> insert into shop values(1009,"zhaojiu",999.00,"dalian","xianlu","2015-05-01");

    (2)去掉重复项 distinct
    mysql> select distinct city from shop;
    +----------+
    | city |
    +----------+
    | shenyang |
    | beijing |
    | dalian |

    (3)限制查询结果的输出 limit
    mysql> select * from shop limit 0,2;
    +------+---------+-------+----------+-----------+------------+
    | id | name | price | city | street | riqi |
    +------+---------+-------+----------+-----------+------------+
    | 1001 | .1 niu1 | 5.99 | shenyang | sanhaojie | 2015-08-02 |
    | 1002 | .2 niu2 | 6.99 | shenyang | sanhaojie | 2015-07-02 |
    第1个数,从哪行开始
    第2个数,向下查询几行
    (4)对输出结果进行排序 order by
    mysql> select * from shop order by price; 升序
    mysql> select * from shop order by price desc; 降序

    mysql> select * from shop order by street;

    mysql> select * from shop order by street,price;
    mysql> select * from shop order by street,price desc;

    mysql> select * from shop order by price,id;
    说明:指定两列排序的时候,只有第一列出现重复值的时候,第2列才起作用。

    练习:查询出 商品价格最贵的人的信息?
    mysql> select * from shop order by price desc limit 0,1;
    +------+---------+--------+--------+--------+------------+
    | id | name | price | city | street | riqi |
    +------+---------+--------+--------+--------+------------+
    | 1009 | zhaojiu | 999.00 | dalian | xianlu | 2015-05-01 |

    (5)where 组合其他的条件
    1)比较运算符 > < = != <> >= <= between ... and ...
    mysql> select * from shop where price > 10.00;

    mysql> select * from shop where city="beijing";

    mysql> select * from shop where city>"beijing"; 尽量别用

    上货的日期 限定是 5月份:
    riqi >= 2015-05-01 and riqi <= 2015-05-31

    mysql> select * from shop where riqi >= "2015-05-01" and riqi <= "2015-05-31";
    mysql> select * from shop where riqi between "2015-05-01" and "2015-05-31";

    2)逻辑运算符 and or !
    mysql> select * from shop where price > 10.00 or price < 6.00;

    mysql> select * from shop where !(price > 10.00 or price < 6.00);

    说明:and的优先级 高于 or ;先or 后and,需要用 and ( or )

    3)in ;not in 匹配多个值

    mysql> select * from shop where id in (1003,1005,1007);
    mysql> select * from shop where id not in (1003,1005,1007);
    mysql> select * from shop where id in (1003,1005,1007,1010);

    4)is NULL ; is not NULL 匹配空值
    mysql> select * from shop where name is NULL;
    mysql> select * from shop where name is not NULL;

    5)白板 ""

    6)like 模糊查询
    通配符:
    _ 任意的单个字符
    % 字符出现 任意次
    mysql> select * from shop where name like "_____";
    mysql> select * from shop where price like "_____";

    mysql> select * from shop where price like "_%";
    mysql> select * from shop where price like "10%";
    mysql> select * from shop where price like "10.%";
    mysql> select * from shop where price like "%9";
    注意:
    1、模糊查询比较消耗时间,不要过度使用;
    2、用的时候,尽量不要让 通配符 出现在开始的位置,避免全表扫描。
    7)regexp 正则表达式
    元字符:. * + ? {} ^ $
    [[:<:]] 词首符 [[:>:]] 词尾符
    转义符号 \
    mysql> select * from shop where name regexp "^\.";
    mysql> select * from shop where name regexp "[[:<:]]w";
    mysql> select * from shop where name regexp "[0-9][[:>:]]";

    select * from shop where id like "100";
    没有返回值
    select * from shop where id regexp "100";
    所有的数据
    说明:like匹配的是整个列的数据,当没有加 通配符的时候,条件要求的值是什么,列的值就得是什么;正则表达式是 使用的基本字符的匹配方式;
    ----------------------------------------------------------------------
    简单的算数运算:
    mysql> select 2+1; 支持 + - * / % 运算
    +-----+
    | 2+1 |
    +-----+
    | 3 |
    -------------------------------------------
    新的需求:
    (1)把 城市和街道 连接到一起:
    输出: shenyang shi sanhaojie
    (2)如果有其他的支出,如何显示成本:

    (3)输出结果是小写的,转变成大写:

    解决:
    1、字符串函数
    (1)连接函数 concat()
    mysql> select concat(city," shi ",street) as address from shop where city is not null;

    mysql> select concat(city," shi ",street) as address from shop where city="shenyang";

    关键字:as 指定别名;现在使用的是 输出列的别名。

    (2)
    mysql> select name,price+1 as price from shop where price is not null;

    (3)
    upper() 小写转大写
    lower() 大写转小写
    mysql> select upper(name) from shop;

    其他的字符串函数,自己看书<<MySQL入门很简单>>。

    2、数据汇总函数:
    说明:
    这些函数都忽略空值 NULL
    sum 和 avg 需要数值型数据
    (1)count() 统计
    mysql> select count(*) from shop;
    +----------+
    | count(*) |
    +----------+
    | 10 |
    mysql> select count(name) from shop;
    +-------------+
    | count(name) |
    +-------------+
    | 9 |

    (2)max() 求最大值
    (3)min() 求最小值
    mysql> select max(price) from shop;
    mysql> select min(price) from shop;
    mysql> select min(name) from shop;

    (4)sum() 求和

    (5)avg() 求平均数
    mysql> select sum(price) from shop;
    +------------+
    | sum(price) |
    +------------+
    | 1168.76 |

    mysql> select avg(price) from shop;
    +------------+
    | avg(price) |
    +------------+
    | 129.862222 |

    3、时间和日期函数
    date() 返回时间和日期数据的 日期 部分
    time() 返回时间和日期数据的 时间 部分
    year() 返回时间和日期数据的 年 部分;
    month() 返回时间和日期数据的 月 部分;
    应用:
    统计 哪一年的数据
    mysql> select sum(price) from shop where year(riqi)=2015;
    +------------+
    | sum(price) |
    +------------+
    | 1168.76 |
    统计 某个月的数据
    mysql> select sum(price) from shop where month(riqi)=6;
    +------------+
    | sum(price) |
    +------------+
    | 36.29 |

    day()
    hour()
    minute()
    second()

    4、其他的函数
    查看当前所在的数据库
    mysql> select database();
    +------------+
    | database() |
    +------------+
    | db1 |

    查看当前的连接用户
    mysql> select user();
    +----------------+
    | user() |
    +----------------+
    | root@localhost |

    mysql> select now();
    +---------------------+
    | now() |
    +---------------------+
    | 2015-07-31 10:53:44 |

    mysql> select version();
    +------------+
    | version() |
    +------------+
    | 5.5.11-log |
    -------------------------------------------
    分组查询:
    需求:每个城市 价格最贵的 商品信息?
    使用分组查询解决。
    group by
    不忽略空值,所有的空值都是1组。

    mysql> select city,max(price) from shop where city is not null group by city;
    +----------+------------+
    | city | max(price) |
    +----------+------------+
    | beijing | 20.00 |
    | dalian | 999.00 |
    | shenyang | 9.99 |

    还想进行下一步判断,找出分组之后,超过20块钱的?
    having 用法和where一样。
    mysql> select city,max(price) as city_max_price from shop where city is not null group by city having city_max_price>=20;
    +---------+----------------+
    | city | city_max_price |
    +---------+----------------+
    | beijing | 20.00 |
    | dalian | 999.00 |

    -------------------------------------
    mysql> select * from t1;
    +------+------+------+
    | id | name | sex |
    +------+------+------+
    | 101 | niu1 | M |
    | 102 | niu2 | W |
    | 103 | niu3 | W |
    | 104 | niu4 | M |
    | 105 | niu5 | W |

    group by 的连接函数 group_concat():

    mysql> select sex,group_concat(name) from t1 group by sex;
    +------+--------------------+
    | sex | group_concat(name) |
    +------+--------------------+
    | W | niu2,niu3,niu5 |
    | M | niu1,niu4 |
    按照性别分组,把每种性别的名字列表显示。
    算 男的几个人,女的几个人?
    mysql> select sex,count(sex) from t1 group by sex;
    +------+------------+
    | sex | count(sex) |
    +------+------------+
    | W | 3 |
    | M | 2 |

    ----------------------------
    mysql> select city,max(price) as city_max_price from shop where city is not null group by city having city_max_price>=20 order by city_max_price desc limit 0,1;
    单表查询的关键字就用上了。

    关键字的书写顺序:
    select --> from --> where --> group by --> having --> order by --> limit

    关键字的执行顺序:
    from --> where --> group by --> having --> select --> order by --> limit

    关键字 功能 是不是必须的
    select 查询 是
    from 从表中检索数据 只有从表中取数据时是必须的
    where 行级过滤 否;需要过滤输出行的条件指定
    group by 分组 否
    having 分组过滤 否
    order by 排序 否
    limit 限制输出行 否

    子查询:
    嵌套查询。把内层查询结果作为外层查询的判断条件。
    select xx from table where (select )
    连接用的字符:
    比较运算符:= > < >= <= !=
    关键字:IN NOT IN ANY ALL
    找出 价格最贵的 人名:
    mysql> select name from shop where price=(select max(price) from shop);
    +---------+
    | name |
    +---------+
    | zhaojiu |

    mysql> select price from shop where price >=100;
    +--------+
    | price |
    +--------+
    | 100.00 |
    | 999.00 |

    mysql> select name from shop where price=(select price from shop where price >=100);
    ERROR 1242 (21000): Subquery returns more than 1 row
    如果内层的查询结果是 >= 2个的时候,不能使用 = 连接。
    mysql> select name from shop where price IN (select price from shop where price >=100);
    +---------+
    | name |
    +---------+
    | houba |
    | zhaojiu |
    mysql> select name from shop where price NOT IN (select price from shop where price >=100);
    使用IN或NOT IN

    find -perm
    ANY +;只要满足查询结果的任意一个,就可以使用。
    ALL -;只有满足所有的查询结果,才可以使用。

    mysql> select price from shop where price >= 20;
    +--------+
    | price |
    +--------+
    | 20.00 |
    | 100.00 |
    | 999.00 |

    mysql> select name from shop where price >= ANY (select price from shop where price >= 20);
    +---------+
    | name |
    +---------+
    | 6 ma6 |
    | houba |
    | zhaojiu |

    mysql> select name from shop where price >= ALL (select price from shop where price >= 20);
    +---------+
    | name |
    +---------+
    | zhaojiu |
    --------------------------
    用到一个关键字:distinct 去重
    --------------------------
    建立子查询的思路:
    逐渐进行;先建立内层查询,再建立外层查询,如果都没有问题,在把内层查询嵌套进外层查询。

     四。索引与表的联结

    索引:
    1、什么是索引?
    索引是一个创建在表上的特殊文件,对表中的 一列 或 几列 值进行排序的一种结构,记录表中的数据指针。

    2、索引的功能?
    加快数据的查询速度。
    索引在MySQL中,也叫做“键”,是存储引擎用于快速找到 行记录的一种数据结构。
    索引的类型:
    B树索引:MyISAM InnoDB 存储引擎使用。
    hash索引:Memory 存储引擎使用。

    3、什么时候使用索引?
    在查询大表的数据时候使用。

    4、什么时候不用索引?
    (1)索引使数据的 增删改 操作变慢,每修改一次数据,索引也要更新一次;
    (2)查询索引也要花费时间,因此小表没有必要创建索引;
    (3)保存索引也要耗费存储空间,空间不足的时候就别建了。

    5、如何使用索引?
    (1)在哪些情况下无法使用索引:
    where 里面出现 不等于
    where 里面出现 函数
    使用模糊查询 like 把 通配符放在 开始的位置 %a
    如果表中 列上出现很多重复的数据,索引的效果也不好
    (2)创建索引的注意事项:
    如果表的数据频繁的发生变化,就不要创建索引了;
    尽量在经常被查询的列上创建索引;
    尽量在数据比较整齐的列上创建索引;比如说 int

    开始实验:
    1、创建索引:
    (1)创建普通索引

    创建表的同时创建索引(基本没用):
    mysql> create table t2 (id int,name varchar(21),index(id));
    在表的 id 列上创建索引;关键字是 index=key
    mysql> show create table t2;
    KEY `id` (`id`)

    mysql> create table t3 (id int,name char(11),key id_key (id));
    mysql> show create table t3;
    KEY `id_key` (`id`)

    是表已经创建好了,并且有数据,这时候创建索引:
    mysql> create index id_key on shop(id); 给表shop的id列创建索引 id_key
    mysql> show create table shop;
    KEY `id_key` (`id`)

    mysql> desc shop;
    +--------+-------------+------+-----+---------+-------+
    | Field | Type | Null | Key | Default | Extra |
    +--------+-------------+------+-----+---------+-------+
    | id | int(11) | YES | MUL | NULL | |


    mysql> alter table t1 add index id_index(id);给t1表的id列创建索引id_index
    mysql> show create table t1;
    KEY `id_index` (`id`)

    删除:
    mysql> drop index id on t2;
    mysql> alter table t3 drop index id_key;

    测试:普通索引是不是会加快查询的速度?
    mysql> set profiling=1; 开启统计sql语句的执行时间
    mysql> select * from shop;
    mysql> select id from shop;
    mysql> select * from shop where id=1001;
    mysql> select id from shop where id=1003;
    mysql> select id from shop where price > 10.00;

    mysql> show profiles;
    +----------+------------+------------------------------------------+
    | Query_ID | Duration | Query |
    +----------+------------+------------------------------------------+
    | 1 | 0.02058500 | select * from shop |
    | 2 | 0.00027675 | select id from shop |
    | 3 | 0.00195025 | select * from shop where id=1001 |
    | 4 | 0.00030750 | select id from shop where id=1003 |
    | 5 | 0.00033350 | select id from shop where price > 10.00 |

    mysql> set profiling=0;

    (2)创建唯一性索引
    保证列中不可以出现重复的值,也叫唯一性约束。
    关键字:unique
    mysql> create table t4 (id int unique,name char(11));
    mysql> show create table t4;
    UNIQUE KEY `id` (`id`)

    mysql> desc t4;
    +-------+----------+------+-----+---------+-------+
    | Field | Type | Null | Key | Default | Extra |
    +-------+----------+------+-----+---------+-------+
    | id | int(11) | YES | UNI | NULL | |

    mysql> insert into t4 values(1,"a1");

    mysql> insert into t4 values(1,"a2");
    ERROR 1062 (23000): Duplicate entry '1' for key 'id'

    mysql> insert into t4(name) values("a2");
    mysql> insert into t4(name) values("a3");
    mysql> select * from t4;
    +------+------+
    | id | name |
    +------+------+
    | 1 | a1 |
    | NULL | a2 |
    | NULL | a3 |
    缺欠:唯一性约束对空值无效。

    解决缺欠:加 非空约束
    关键字:NOT NULL
    mysql> create table t5 (id int not null,name char(11) not null);

    mysql> desc t5;
    +-------+----------+------+-----+---------+-------+
    | Field | Type | Null | Key | Default | Extra |
    +-------+----------+------+-----+---------+-------+
    | id | int(11) | NO | | NULL | |
    | name | char(11) | NO | | NULL | |

    mysql> insert into t5 (id) values(1),(2);
    mysql> insert into t5 (name) values("a1"),("a2");

    mysql> select * from t5;
    +----+------+
    | id | name |
    +----+------+
    | 1 | |
    | 2 | |
    | 0 | a1 |
    | 0 | a2 |
    在非空约束里面,字符型数据变成 白板,数值型数据变成0。
    mysql> select * from t5 where name="";
    +----+------+
    | id | name |
    +----+------+
    | 1 | |
    | 2 | |

    把非空约束和唯一性约束组合到一起:
    唯一 + 非空 = 主键 primary key
    mysql> create table t6 (id int unique not null,name char(11) unique not null);

    mysql> desc t6;
    +-------+----------+------+-----+---------+-------+
    | Field | Type | Null | Key | Default | Extra |
    +-------+----------+------+-----+---------+-------+
    | id | int(11) | NO | PRI | NULL | |
    | name | char(11) | NO | UNI | NULL | |
    一个表只能有一个主键。
    mysql> show create table t6;
    UNIQUE KEY `id` (`id`),
    UNIQUE KEY `name` (`name`)

    mysql> insert into t6(id) values(1),(2);
    ERROR 1062 (23000): Duplicate entry '' for key 'name'

    mysql> insert into t6(name) values("1");
    mysql> select * from t6;
    +----+------+
    | id | name |
    +----+------+
    | 0 | 1 |
    mysql> insert into t6(name) values("2");
    ERROR 1062 (23000): Duplicate entry '0' for key 'id'

    给主键创建的索引叫做 主索引。

    主键:唯一标识表中的记录的。
    外键:需要依赖另一张表的 主键的数据。
    主键和外键是 关系表的粘合剂。
    创建主键的时候,没有要求。

    当需要同时创建主键和外键的时候,要求:
    (1)存储引擎是 innodb的;
    (2)创建主键的列和创建外键的列的数据类型必须是一致的;int >>> int

    mysql> show engines; 查看默认的存储引擎。
    | InnoDB | DEFAULT

    创建主键表:
    表1 学员的个人信息表:
    mysql> create table stu1 (id int primary key,name varchar(20) not null,tel char(11)not null);

    mysql> desc stu1;
    +-------+-------------+------+-----+---------+-------+
    | Field | Type | Null | Key | Default | Extra |
    +-------+-------------+------+-----+---------+-------+
    | id | int(11) | NO | PRI | NULL | |
    | name | varchar(20) | NO | | NULL | |
    | tel | char(11) | NO | | NULL | |

    创建外键表:
    表2:学员成绩表
    mysql> create table stu2 (id int primary key,ule tinyint,ula tinyint,oracle tinyint,foreign key (id) references stu1(id));
    foreign key (id) 给id列创建外键
    references stu1(id) 外键依赖 stu1 表的id列
    mysql> show create table stu2;
    KEY `id` (`id`),
    CONSTRAINT `stu2_ibfk_1` FOREIGN KEY (`id`) REFERENCES `stu1` (`id`)

    向表插入数据:
    mysql> insert into stu2 values(2015060801,60,65,75);
    ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`db1`.`stu2`, CONSTRAINT `stu2_ibfk_1` FOREIGN KEY (`id`) REFERENCES `stu1` (`id`))
    主键还没有数据,外键是不允许插入数据的。
    mysql> insert into stu1 values(2015060801,"yangchao","13112345678");
    mysql> insert into stu1 values(2015060802,"cuidongyang","13212345678");
    mysql> insert into stu1 values(2015060803,"wangxu","13312345678");

    mysql> insert into stu2 values(2015060801,65,75,85);
    mysql> insert into stu2 values(2015060802,66,76,86);

    在建表之后补充创建主键:
    mysql> alter table stu2 add primary key (id);

    删除外键:
    mysql> alter table stu2 drop foreign key stu2_ibfk_1;
    stu2 表名
    stu2_ibfk_1 外键名
    再添加外键:建表之后再创建外键。
    mysql> alter table stu2 add foreign key(id) references stu1(id);
    foreign key(id) 给 stu2 的id 列创建外键

    mysql> delete from stu1 where id=2015060801;
    ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`db1`.`stu2`, CONSTRAINT `stu2_ibfk_1` FOREIGN KEY (`id`) REFERENCES `stu1` (`id`))
    mysql> delete from stu1 where id=2015060803;
    说明:id=2015060801行数据有外键表依赖,不可以删除;
    mysql> update stu1 set id=2015060810 where id=2015060801;
    ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`db1`.`stu2`, CONSTRAINT `stu2_ibfk_1` FOREIGN KEY (`id`) REFERENCES `stu1` (`id`))
    说明:id=2015060801行数据有外键表依赖,不可以修改;

    在外键表上创建:
    级联删除 on delete cascade
    级联修改 on update cascade
    mysql> alter table stu2 add foreign key (id) references stu1(id) on update cascade on delete cascade;
    show create table stu2G;设置级联修改时先把子表原来的外键删除以免产生影响
    mysql> delete from stu1 where id=2015060801;
    mysql> select * from stu1;
    +------------+-------------+-------------+
    | id | name | tel |
    +------------+-------------+-------------+
    | 2015060802 | cuidongyang | 13212345678 |
    mysql> select * from stu2;
    +------------+------+------+--------+
    | id | ule | ula | oracle |
    +------------+------+------+--------+
    | 2015060802 | 66 | 76 | 86 |

    mysql> update stu1 set id=2015060810 where id=2015060802;
    mysql> select * from stu1;
    +------------+-------------+-------------+
    | id | name | tel |
    +------------+-------------+-------------+
    | 2015060810 | cuidongyang | 13212345678 |
    mysql> select * from stu2;
    +------------+------+------+--------+
    | id | ule | ula | oracle |
    +------------+------+------+--------+
    | 2015060810 | 66 | 76 | 86 |

    =================================================
    关系表查询:
    stu1 stu2 使用 主键和外键关联起来了。

    mysql> create table stu3 (id int,work enum("Y","N"),sal int);
    mysql> insert into stu3 values(2015060801,"Y",5000);
    mysql> insert into stu3 values(2015060802,"Y",7000);
    mysql> insert into stu3 values(2015060803,"Y",6500);
    mysql> insert into stu3 values(2015060810,"N",0);

    mysql> select * from stu1;
    +------------+-------------+-------------+
    | id | name | tel |
    +------------+-------------+-------------+
    | 2015060801 | yangchao | 13112345678 |
    | 2015060802 | cuidongyang | 13212345678 |
    | 2015060803 | wangxu | 13312345678 |
    | 2015060810 | cuidongyang | 13212345678 |
    | 2015080605 | a1 | 13512346578 |

    mysql> select * from stu2;
    +------------+------+------+--------+
    | id | ule | ula | oracle |
    +------------+------+------+--------+
    | 2015060801 | 65 | 75 | 85 |
    | 2015060802 | 66 | 76 | 86 |
    | 2015060803 | 66 | 76 | 86 |
    | 2015060810 | 66 | 76 | 86 |

    mysql> select * from stu3;
    +------------+------+------+
    | id | work | sal |
    +------------+------+------+
    | 2015060801 | Y | 5000 |
    | 2015060802 | Y | 7000 |
    | 2015060803 | Y | 6500 |
    | 2015060810 | N | 0 |

    表的联结查询:
    1、2个表的联结:
    输出内容:输出每个学员的学号,名字,ULE的成绩?

    mysql> select id,name,ule from stu1,stu2;
    ERROR 1052 (23000): Column 'id' in field list is ambiguous
    当2个表中出现名字是一样的列名的时候,查询时要带上表名。

    mysql> select stu1.id,name,ule from stu1,stu2;
    出结果了,但是结果不够友好。
    这个查询没有指定查询条件,因此结果出现 笛卡尔积。

    mysql> select stu1.id,name,ule from stu1,stu2 where stu1.id=stu2.id;
    +------------+-------------+------+
    | id | name | ule |
    +------------+-------------+------+
    | 2015060801 | yangchao | 65 |
    | 2015060802 | cuidongyang | 66 |
    | 2015060803 | wangxu | 66 |
    | 2015060810 | cuidongyang | 66 |
    这是对的。
    mysql> select stu1.id,name,sal from stu1,stu3 where stu1.id=stu3.id;
    +------------+-------------+------+
    | id | name | sal |
    +------------+-------------+------+
    | 2015060801 | yangchao | 5000 |
    | 2015060802 | cuidongyang | 7000 |
    | 2015060803 | wangxu | 6500 |
    | 2015060810 | cuidongyang | 0 |

    mysql> select stu2.id,ula,sal from stu2,stu3 where stu2.id=stu3.id;
    +------------+------+------+
    | id | ula | sal |
    +------------+------+------+
    | 2015060801 | 75 | 5000 |
    | 2015060802 | 76 | 7000 |
    | 2015060803 | 76 | 6500 |
    | 2015060810 | 76 | 0 |

    这种查询方式叫做内部联结。还有另外一种写法:
    mysql> select stu1.id,name,ule
    -> from stu1 inner join stu2
    -> on stu1.id=stu2.id;

    外部联结:
    (1)左联结
    mysql> select stu1.id,name,ule from stu1 left outer join stu2 on stu1.id=stu2.id;
    +------------+-------------+------+
    | id | name | ule |
    +------------+-------------+------+
    | 2015060801 | yangchao | 65 |
    | 2015060802 | cuidongyang | 66 |
    | 2015060803 | wangxu | 66 |
    | 2015060810 | cuidongyang | 66 |
    | 2015080605 | a1 | NULL |

    (2)右联结
    mysql> select stu1.id,name,ule from stu1 right outer join stu2 on stu1.id=stu2.id;
    +------------+-------------+------+
    | id | name | ule |
    +------------+-------------+------+
    | 2015060801 | yangchao | 65 |
    | 2015060802 | cuidongyang | 66 |
    | 2015060803 | wangxu | 66 |
    | 2015060810 | cuidongyang | 66 |

    3个表联结:
    输出:id name ula sal
    mysql> select stu1.id,name,ula,sal from
    -> (
    -> ( stu1 inner join stu2 on stu1.id=stu2.id )
    -> inner join stu3 on stu1.id=stu3.id
    -> );
    +------------+-------------+------+------+
    | id | name | ula | sal |
    +------------+-------------+------+------+
    | 2015060801 | yangchao | 75 | 5000 |
    | 2015060802 | cuidongyang | 76 | 7000 |
    | 2015060803 | wangxu | 76 | 6500 |
    | 2015060810 | cuidongyang | 76 | 0 |

    ==================================================

    自增:auto_increment
    id号自动增加。
    qq 年龄
    员工编号
    使用要求:
    (1)列的数据类型是数值型,整型
    (2)列有 主键 或 唯一性约束

    mysql> create table t7 (id int unique auto_increment,name char(11));

    mysql> insert into t7 (name) values("a1"),("a2");
    mysql> select * from t7;
    +----+------+
    | id | name |
    +----+------+
    | 1 | a1 |
    | 2 | a2 |
    默认是从 1 开始 自增。

    mysql> insert into t7 values(10,"a10");
    mysql> insert into t7 (name) values("niua"),("niub");
    mysql> select * from t7;
    +----+------+
    | id | name |
    +----+------+
    | 1 | a1 |
    | 2 | a2 |
    | 10 | a10 |
    | 11 | niua |
    | 12 | niub |
    如果中间出现断档,从最大值开始自增。
    mysql> delete from t7;
    mysql> insert into t7 (name) values("b1"),("b2");
    mysql> select * from t7;
    +----+------+
    | id | name |
    +----+------+
    | 13 | b1 |
    | 14 | b2 |
    使用 delete 删掉数据之后,会保存记录,依然从最大值开始自增。

    mysql> truncate t7; 清空表中的所有操作,不支持回滚
    mysql> insert into t7 (name) values("b1"),("b2");
    mysql> select * from t7;
    +----+------+
    | id | name |
    +----+------+
    | 1 | b1 |
    | 2 | b2 |
    使用 truncate 清空表的数据之后,可以让表的数据从 1 开始 自增。
    =====================================================================
    默认值:
    注册,表格性。
    * 必填
    在数据库中,出现一些 定值。
    mysql> create table t8 (id int,name char(11) default "unknown",sal int default 10000);
    mysql> desc t8;
    +-------+----------+------+-----+---------+-------+
    | Field | Type | Null | Key | Default | Extra |
    +-------+----------+------+-----+---------+-------+
    | id | int(11) | YES | | NULL | |
    | name | char(11) | YES | | unknown | |
    | sal | int(11) | YES | | 10000 | |

    mysql> insert into t8(id) values(1);

    mysql> select * from t8;
    +------+---------+-------+
    | id | name | sal |
    +------+---------+-------+
    | 1 | unknown | 10000 |
    ============================================

  • 相关阅读:
    AngularJS XMLHttpRequest
    AngularJS服务
    angularJS过滤器
    AngularJ控制器
    angular Scope(作用域)
    angular Model 指令
    angular指令
    微信小程序调用微信支付
    微信小程序一直保持登陆状态
    微信小程序ajax请求数据及一些方法
  • 原文地址:https://www.cnblogs.com/yizhixiaowenzi/p/6258751.html
Copyright © 2011-2022 走看看