• mysql基础


     

    一.sql的基本语法

    1.对数据库


    (1)系统数据库
    show databases;
    查看数据库
    +--------------------+
    | Database |
    +--------------------+
    | information_schema |
    | db1 |
    | mysql |
    | performance_schema |
    | sys |
    +--------------------+
    information_schema:虚拟库,不占用磁盘空间,存储的是数据库启动后的一些参数,如用户表信息,权限信息等
    performance_schema:MySQL 5.5开始新增一个数据库:主要用于收集数据库服务器性能参数,记录处理查询请求时发生的各种事件、锁等现象
    mysql:授权库,主要存储系统用户的授权信息
    test: MySQL数据库系统自动创建的测试数据库
    (2)数据库相关操作
    求救语法:
    help +mysql语法;
    查看当前语法的使用规则
    创建数据库:
    create database + 数据库名;
    数据库命名规则:
    可以由字母、数字、下划线、@、#、$
    区分大小写
    唯一性
    不能使用关键字如 create select
    不能单独使用数字
    最长128位
    查看数据库详细信息:
    show create database + 数据库名;
    +----------+--------------------------------------------------------------+
    | Database | Create Database |
    +----------+--------------------------------------------------------------+
    | db1 | CREATE DATABASE `db1` /*!40100 DEFAULT CHARACTER SET utf8 */ |
    +----------+--------------------------------------------------------------+
    查看所在的库:
    select database();
    +------------+
    | database() |
    +------------+
    | db1 |
    +------------+
    使用数据库:
    use + 数据库名;
    删除数据库:
    drop database + 数据库名;
    修改数据库的编码:
    alter database db1 charset + 编码方式;
    +----------+--------------------------------------------------------------+
    | Database | Create Database |
    +----------+--------------------------------------------------------------+
    | db2 | CREATE DATABASE `db2` /*!40100 DEFAULT CHARACTER SET utf8 */ |
    +----------+--------------------------------------------------------------+
    sql语言分类:
    SQL语言主要用于存取数据、查询数据、更新数据和管理关系数据库系统,SQL语言由IBM开发。SQL语言分为3种类型:
    DDL语句 数据库定义语言: 数据库、表、视图、索引、存储过程,例如CREATE DROP ALTER
    DML语句 数据库操纵语言: 插入数据INSERT、删除数据DELETE、更新数据UPDATE、查询数据SELECT
    DCL语句 数据库控制语言: 例如控制用户的访问权限GRANT、REVOKE

    2.对表

            增加表
    create table 表名(
    字段名1 类型[(宽度) 约束条件],
    字段名2 类型[(宽度) 约束条件],
    字段名3 类型[(宽度) 约束条件]
    );
    删除表
    drop table + 表名;
    修改表
    alter table t1 modify name char(6);
    修改表的数据类型信息

    alter table t1 change name NAMA char(7);
    修改表中列的名称
    查看表
    show create table + 表名;
    查看表的创建信息
    +-------+---------------------------------------------------------------------------------------+
    | Table | Create Table |
    +-------+---------------------------------------------------------------------------------------+
    | t1 | CREATE TABLE `t1` (
    `id` int(10) DEFAULT NULL
    `name` char(7) DEFAULT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
    +-------+---------------------------------------------------------------------------------------+

    show tables;
    查看该数据库中的所有表

    desc + 表名;
    查看表的结构详细信息
    +-------+---------+------+-----+---------+-------+
    | Field | Type | Null | Key | Default | Extra |
    +-------+---------+------+-----+---------+-------+
    | id | int(10) | YES | | NULL | |
    | name | char(7) | YES | | NULL | |
    +-------+---------+------+-----+---------+-------+
    复制表
    复制表的结构和数据
    create table a1 select * from db2.t1;
    只复制表的结构
    create table a2 select * from db2.t1 where 1>2;
    create table a3 like db2.t1;

    3.对数据


    insert + 表名(列的名称,列的名称) values(数据,数据),(数据,数据);
    insert into + 表名(列的名称,列的名称) values(数据,数据),(数据,数据);

    select id from t1;
    查询某一列

    select id,name from db1.t1;
    查询多列

    select name from t1 where id=1;
    精确查询某一个

    update t1 set name='huoyu';
    更改某一列的所有制

    update t1 set name='小乔' where id=2;
    精确更改某一个值

    delete from t1 where id=2;
    精确删除某一个值

    delete from t1;
    删除某一个表

    二.存储引擎

        存储引擎说白了就是如何存储数据、如何为存储的数据建立索引和如何更新、查询数据等技术的实现方法。
    mysql 5.5版本之后默认为innodb存储引擎

    mysql支持的存储引擎
    1.InnoDB存储引擎
    支持事务
    2.MyISAN存储引擎
    不支持事务
    3.Memory存储引擎
    正如其名,Memory 存储引擎中的数据都存放在内存中,数据库重 启或发生崩溃,表中的数据都将消失。
    在重启mysql或者重启机器后,表内数据清空
    4.BLACKHOLE存储引擎
    往表内插入任何数据,都相当于丢入黑洞,表内永远不存记录

    #.frm是存储数据表的框架结构
    # .ibd是mysql数据文件
    #.MYD是MyISAM表的数据文件的扩展名
    #.MYI是MyISAM表的索引的扩展名

    三.数据类型

    1.数字

            整形:
    tinyint:
    有符号:-128-127
    无符号:0-255
    int:
    有符号: -2147483648 ~ 2147483647
    无符号: 0 ~ 4294967295
    bigint:
    有符号:-9223372036854775808 ~ 9223372036854775807
    无符号:0 ~ 18446744073709551615

    sql中没有boolean类型 使用tinyint(1)来表示boolean值 1 表示true 0 表示false

    默认有符号,无符号unsigned
    zerofill,用0填充不足的位数
    int类型后面的数字是显示宽度,而不是存储宽度(显示宽度是指最少显示宽度)
    默认的显示宽度,都是在最大值的基础上加1
    总结一句话,定义int类型不需要加宽度,使用默认就可以

    浮点型:
    float:
    有符号: -3.402823466E+38 to -1.175494351E-38,1.175494351E-38 to 3.402823466E+38
    无符号:1.175494351E-38 to 3.402823466E+38
    随着小数的增多,精度变得不准确
    double:
    有符号:-1.7976931348623157E+308 to -2.2250738585072014E-308, 2.2250738585072014E-308 to 1.7976931348623157E+308
    无符号:2.2250738585072014E-308 to 1.7976931348623157E+308
    随着小数的增多,精度比float要高,但也会变得不准确
    decimal:
    随着小数的增多,精度始终准确
    decaimal能够存储精确值的原因在于其内部按照字符串存储
    范围同double

    2.字符串

            char:
    定长,简单粗暴,浪费空间,存取速度快
    存储char类型的值时,会往右填充空格来满足长度
    varchar:
    变长,精准,节省空间,存取速度慢
    尾部有空格会保存下来,在检索或者说查询时,也会正常显示包含空格在内的内容

    3.时间

            year
    YYYY(1901/2155)

    data
    YYYY-MM-DD(1000-01-01/9999-12-31)

    time
    HH:MM:SS('-838:59:59'/'838:59:59')

    datatime
    YYYY-MM-DD HH:MM:SS(1000-01-01 00:00:00/9999-12-31 23:59:59)
    注:new()是mysql的内置函数,自动获取当前的年月日,时分秒,根据数据类型生成对应的时间格式

    4.枚举和集合

            enum:单选,只能在给定范围内选择一个值
    set:多选,在给定范围内选择一个或多个

    create table t5(x enum('a','b'),y set('a','b','c'));//创建一个新的表格,x只能单选,y能多选
    insert into t5(x,y) values('a','b,c');
    insert into t5(x,y) values('a','b');
    +------+------+
    | x | y |
    +------+------+
    | a | b |
    | a | b,c |
    +------+------+

    四.约束

        约束条件与数据类型的宽度一样,都是可选参数
    作用:用于保证数据的完整性和一致性

    1.not null与default:不能为空

    create table t7(x char(10) not null,y char(10) null,z char(10) not null default 'aaa');创建一个表,x不能为空,y可以为空,z为空显示aaa
    insert into t7 values(null,null,null);//Column 'x' cannot be null
    insert into t7(x,y) values('a',null);
    select * from t7;
    +------------+------------+------------+
    | x | y | z |
    +------------+------------+------------+
    | | | |
    | a | NULL | aaa |
    +------------+------------+------------+

    2.unique:

            单列唯一:
    create table t8(name char(10) unique);
    insert into t8 values('市场部');
    insert into t8 values('市场部');//error
    多列唯一:
    create table t9(a char(10) unique,b char(10) unique);
    insert into t9 values('a','b');
    insert into t9 values('a','c');//error
    insert into t9 values('c','b');//error
    insert into t9 values('d','d');//OK
    组合唯一(联合唯一):只要有一列不同,就可以插入数据
    create table t10(a char(10),b char(10),unique(a,b));
    insert into t10 values('a','a');
    insert into t10 values('b','a');//ok
    insert into t10 values('a','b');//OK
    insert into t10 values('a','a');//error

    3.primary key

            一张表中只能有一个主键
    单列主键:
    create table t11(id int primary key,name char(10) unique);
    多列做主键(复合主键):
    create table t12(a int,b int,primary key(a,b));
    insert into t11 values(1,1);
    insert into t11 values(1,2);//error
    insert into t11 values(2,1);//error
    insert into t11 values(2,2);//OK
    primary key和not null + unique能实现的功能是一样的,但是primary key能索引优化,处理大量数据时,效果更好

    4.auto_increment:约束的字段为自动增长,约束的字段必须同时被key约束

            注:只能有一个自增列,且必须与主键同时用。
    id也可以不用自增的,自己制定
    对于自增的字段,在用delete删除后,再插入值,该字段仍按照删除前的位置继续增长
    create table t13(id int primary key auto_increment,name char(10));
    insert into t13(name) values('hua');
    insert into t13(name) values('huxa');
    +----+------------+
    | id | name |
    +----+------------+
    | 1 | hua |
    | 2 | huxa |
    +----+------------+

    5.foreign key

            建立两张表之间的关系

    先创建被关联的表(主表)def
    create table dep(
    id int primary key auto_increment,
    name char(20) not null,
    des char(30) not null
    );
    再创建关联表(从表)emp
    create table emp(
    id int primary key auto_increment,
    name char(20) not null,
    age int not null,
    def_id int not null,
    constraint fk_dep foreign key(def_id) references dep(id)
    );
    先给被关联的表插入数据
    insert into dep(name,des) values
    ('IT','IT技术有限部门'),
    ('销售部','销售部门'),
    ('财务部','花钱太多部门');
    再给关联表(从表)插入数据
    insert into emp(name,age,def_id) values
    ('张三',18,1),
    ('李四',19,1),
    ('二宫',20,2),
    ('袁浩',40,3),
    ('alex',18,2)
    ;
    此时想先删除部门表中的数据,再删除员工表中的数据会发生错误
    delete from dep where id=3;
    ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails
    (`db5`.`emp`, CONSTRAINT `fk_dep` FOREIGN KEY (`def_id`) REFERENCES `dep` (`id`))
    先删除员工表中的数据,再删除部门表中的数据是没有问题的
    delete from emp where id=4;
    delete from dep where id=3;
    +----+-----------+----------------------+
    | id | name | des |
    +----+-----------+----------------------+
    | 1 | IT | IT技术有限部门 |
    | 2 | 销售部 | 销售部门 |
    +----+-----------+----------------------+
    同步更新,同步删除
    on delete cascade 同步删除
    on update cascade 同步更新

    先创建被关联的表(主表)dep
    create table dep(
    id int primary key auto_increment,
    name char(20) not null,
    des char(30) not null
    );
    再创建关联表(从表)emp
    create table emp(
    id int primary key auto_increment,
    name char(20) not null,
    age int not null,
    def_id int not null,
    constraint fk_dep foreign key(def_id) references dep(id)
    on delete cascade
    on update cascade
    );
    添加数据
    insert into dep(name,des) values
    ('IT','IT技术有限部门'),
    ('销售部','销售部门'),
    ('财务部','花钱太多部门');

    insert into emp(name,age,def_id) values
    ('张三',18,1),
    ('李四',19,1),
    ('二宫',20,2),
    ('袁浩',40,3),
    ('alex',18,2)
    ;
    同步删除
    delete from dep where id=3;
    select * from emp;
    +----+--------+-----+--------+
    | id | name | age | def_id |
    +----+--------+-----+--------+
    | 1 | 张三 | 18 | 1 |
    | 2 | 李四 | 19 | 1 |
    | 3 | 二宫 | 20 | 2 |
    | 5 | alex | 18 | 2 |
    +----+--------+-----+--------+
    同步更新
    update dep set id=111 where id=2;
    select * from emp;
    +----+--------+-----+--------+
    | id | name | age | def_id |
    +----+--------+-----+--------+
    | 1 | 张三 | 18 | 1 |
    | 2 | 李四 | 19 | 1 |
    | 3 | 二宫 | 20 | 111 |
    | 5 | alex | 18 | 111 |
    +----+--------+-----+--------+
    外键的变种
    1.先站在左表的角度去找,是否左表的多条记录可以对应右表的一条记录,如果是,则证明左表的一个字段foreign key 右表一个字段(通常是id)
    2.再站在右表的角度去找,是否右表的多条记录可以对应左表的一条记录,如果是,则证明右表的一个字段foreign key 左表一个字段(通常是id)
    多对一,一对多
    1或2成立
    如,书和出版社的关系
    多对多
    1和2同时成立
    如作者和书的关系
    关联方式:foreign key+一张新的表
    一对一
    如果1和2都不成立,而是左表的一条记录唯一对应右表的一条记录,反之亦然。这种情况很简单,就是在左表foreign key右表的基础上,将左表的外键字段设置成unique即可
    如人和身份证号的关系
    关联方式:foreign key+unique

    例:一对一
    分别创建两张表
    create table card(
    id int primary key auto_increment,
    cardid int not null unique);

    create table people(
    id int primary key auto_increment,
    name char(20),
    card_id int unique,
    constraint fk_card foreign key(card_id) references card(id)
    on delete cascade
    on update cascade);
    分别插入数据
    insert into card(cardid) values(11111),(22222),(333333);
    insert into people(name,card_id) values('aaa',1),('bbb',2),('ccc',3);
    select * from people;
    +----+------+---------+
    | id | name | card_id |
    +----+------+---------+
    | 1 | aaa | 1 |
    | 2 | bbb | 2 |
    | 3 | ccc | 3 |
    +----+------+---------+
    例:多对多(作者和书实例)
    create table autor(
    id int primary key auto_increment,
    name char(20)
    );

    create table book(
    id int primary key auto_increment,
    name char(20)
    );

    create table autor_book(
    id int primary key auto_increment,
    book_id int not null,
    autor_id int not null,
    constraint fk_book foreign key(book_id) references book(id)
    on delete cascade
    on update cascade,
    constraint fk_autor foreign key(autor_id) references autor(id)
    on delete cascade
    on update cascade
    );

    insert into autor(name) values ('egon'),('alex'),('wusir'),('yuanhao');
    insert into book(name) values ('独孤九剑'),('葵花宝典'),('慕容秘籍'),('想不出来');
    insert into autor_book(book_id,autor_id) values
    (1,1),
    (1,2),
    (1,3),
    (1,4),
    (2,1),
    (3,4),
    (4,1)
    ;
    select * from autor_book;
    +----+---------+----------+
    | id | book_id | autor_id |
    +----+---------+----------+
    | 13 | 1 | 1 |
    | 25 | 1 | 2 |
    | 26 | 1 | 3 |
    | 49 | 1 | 4 |
    | 51 | 1 | 4 |
    | 52 | 2 | 1 |
    | 53 | 3 | 4 |
    | 54 | 4 | 1 |
    +----+---------+----------+

    五.单表查询

    1.单表查询的语法

            select 字段1.字段2...form 表名
    where 条件
    group by field
    having 筛选
    order by field
    limit 限制条数

    2.关键字的执行优先级

                from
    where
    group by
    having
    select
    distinct
    order by
    limit

    1.找到表:from
    2.拿着where指定的约束条件,去文件/表中取出一条条记录
    3.将取出的一条条记录进行分组group by,如果没有group by,则整体作为一组
    4.将分组的结果进行having过滤
    5.执行select
    6.去重
    7.将结果按条件排序:order by
    8.限制结果的显示条数
    (1)where约束
    比较运算符:>、<、>=、<=、<>、!=
    select id, name,age from employee where id>5;
    +----+------------+-----+
    | id | name | age |
    +----+------------+-----+
    | 6 | jingliyang | 18 |
    | 7 | jinxin | 18 |
    | 8 | xiaomage | 48 |
    | 9 | 歪歪 | 48 |
    | 10 | 丫丫 | 38 |
    | 11 | 丁丁 | 18 |
    | 12 | 星星 | 18 |
    | 13 | 格格 | 28 |
    | 14 | 张野 | 28 |
    | 15 | 程咬金 | 18 |
    | 16 | 程咬银 | 18 |
    | 17 | 程咬铜 | 18 |
    | 18 | 程咬铁 | 18 |
    +----+------------+-----+
    关键字between and
    select id, name,age from employee where salary between 10000 and 50000;
    +----+-----------+-----+
    | id | name | age |
    +----+-----------+-----+
    | 7 | jinxin | 18 |
    | 8 | xiaomage | 48 |
    | 14 | 张野 | 28 |
    | 15 | 程咬金 | 18 |
    | 16 | 程咬银 | 18 |
    | 17 | 程咬铜 | 18 |
    | 18 | 程咬铁 | 18 |
    +----+-----------+-----+
    关键字in集合查询
    select id, name,age from employee where age in(18,28);
    +----+------------+-----+
    | id | name | age |
    +----+------------+-----+
    | 1 | egon | 18 |
    | 5 | liwenzhou | 28 |
    | 6 | jingliyang | 18 |
    | 7 | jinxin | 18 |
    | 11 | 丁丁 | 18 |
    | 12 | 星星 | 18 |
    | 13 | 格格 | 28 |
    | 14 | 张野 | 28 |
    | 15 | 程咬金 | 18 |
    | 16 | 程咬银 | 18 |
    | 17 | 程咬铜 | 18 |
    | 18 | 程咬铁 | 18 |
    +----+------------+-----+
    关键字like模糊查询
    通配符%表示人任意多字符
    通配符_表示一个字符
    select id, name,age from employee where name like 'j%';
    +----+------------+-----+
    | id | name | age |
    +----+------------+-----+
    | 6 | jingliyang | 18 |
    | 7 | jinxin | 18 |
    +----+------------+-----+
    逻辑运算符:在多个条件直接可以使用逻辑运算符 and or not
    select id, name,age from employee where name like 'j%' and sex='female';
    +----+------------+-----+
    | id | name | age |
    +----+------------+-----+
    | 6 | jingliyang | 18 |
    +----+------------+-----+
    (2)group by分组查询
    为什么要分组?
    取每个部门的最高工资
    取每个部门的员工数
    取男人数和女人数
    小窍门:‘每’这个字后面的字段,就是我们分组的依据

    select * from employee group by post;
    这句代码得到的是每组中的第一条数据,没有任何意义,因为我们现在想查的是每组的多条数据
    由于没有设置ONLY_FULL_GROUP_BY,默认都是组内的第一条记录
    如果想分组,则必须要设置全局的sql的模式为ONLY_FULL_GROUP_BY
    set global sql_mode='ONLY_FULL_GROUP_BY';
    或者将ONLY_FULL_GROUP_BY添加到my,ini中
    设置成功后,一定要退出,然后重新登录方可生效
    如果想查看组内信息,需要借助于聚合函数
    max()求最大值
    min()求最小值
    avg()求平均值
    sum() 求和
    count() 求总个数
    select post,count(id),max(salary) from employee group by post;
    +-----------------------------------------+-----------+-------------+
    | post | count(id) | max(salary) |
    +-----------------------------------------+-----------+-------------+
    | operation | 5 | 20000.00 |
    | sale | 5 | 4000.33 |
    | teacher | 7 | 1000000.31 |
    | 老男孩驻沙河办事处外交大使 | 1 | 7300.33 |
    +-----------------------------------------+-----------+-------------+
    (3)having过滤
    Where 发生在分组group by之前,因而Where中可以有任意字段,但是绝对不能使用聚合函数。
    Having发生在分组group by之后,因而Having中可以使用分组的字段,无法直接取到其他字段,可以使用聚合函数

    group_concat()函数
    必须使用group by才能使用此函数

    练习:
    查询各岗位内包含的员工个数小于2的岗位名、岗位内包含员工名字、个数
    mysql> select post,group_concat(name),count(1) from employee group by post having count(1)<2;
    +-----------------------------------------+--------------------+----------+
    | post | group_concat(name) | count(1) |
    +-----------------------------------------+--------------------+----------+
    | 老男孩驻沙河办事处外交大使 | egon | 1 |
    +-----------------------------------------+--------------------+----------+
    查询各岗位平均薪资大于10000的岗位名、平均工资
    select post,avg(salary) from employee group by post having avg(salary)>10000;
    +-----------+---------------+
    | post | avg(salary) |
    +-----------+---------------+
    | operation | 16800.026000 |
    | teacher | 151842.901429 |
    +-----------+---------------+
    查询各岗位平均薪资大于10000且小于20000的岗位名、平均工资
    select post,avg(salary) from employee group by post having avg(salary)>10000 and avg(salary)<20000;
    +-----------+--------------+
    | post | avg(salary) |
    +-----------+--------------+
    | operation | 16800.026000 |
    +-----------+--------------+
    (4)order by查询排序
    asc 升序
    desc 降序

    例:先按照age升序排序,如果年纪相同,则按照id降序
    select * from employee order by age asc,id desc;
    查询各岗位平均薪资大于10000的岗位名、平均工资,结果按平均薪资降序排列 
    select post,avg(salary) from employee group by post having avg(salary)>10000 order by avg(salary) desc;
    +-----------+---------------+
    | post | avg(salary) |
    +-----------+---------------+
    | teacher | 151842.901429 |
    | operation | 16800.026000 |
    +-----------+---------------+
    (5)限制查询的记录数
    第一个参数起始位置,第二个参数显示的个数

    select * from employee limit 3;如果只有一个参数,默认第一个参数是0
    select * from employee limit 3,4;

    六.多表查询

    1.多表链接查询

            (0)交叉链接:不适用任何匹配条件。生成笛卡尔积
    select * from employee,department;
    (1)外链接
    内连接:只连接匹配的行
    语法:select 表1 inner join 表2 on 表1.字段=表2.字段;
    select * from employee inner join department on employee.dep_id=department.id;
    +----+---------+--------+------+--------+------+--------------+
    | id | name | sex | age | dep_id | id | name |
    +----+---------+--------+------+--------+------+--------------+
    | 1 | egon | male | 18 | 200 | 200 | 技术 |
    | 2 | alex | female | 48 | 201 | 201 | 人力资源 |
    | 3 | wupeiqi | male | 38 | 201 | 201 | 人力资源 |
    | 4 | yuanhao | female | 28 | 202 | 202 | 销售 |
    | 5 | nvshen | male | 18 | 200 | 200 | 技术 |
    +----+---------+--------+------+--------+------+--------------+
    外链接之左连接:优先显示左表全部记录
    select * from employee left join department on employee.dep_id=department.id;
    +----+----------+--------+------+--------+------+--------------+
    | id | name | sex | age | dep_id | id | name |
    +----+----------+--------+------+--------+------+--------------+
    | 1 | egon | male | 18 | 200 | 200 | 技术 |
    | 5 | nvshen | male | 18 | 200 | 200 | 技术 |
    | 2 | alex | female | 48 | 201 | 201 | 人力资源 |
    | 3 | wupeiqi | male | 38 | 201 | 201 | 人力资源 |
    | 4 | yuanhao | female | 28 | 202 | 202 | 销售 |
    | 6 | xiaomage | female | 18 | 204 | NULL | NULL |
    +----+----------+--------+------+--------+------+--------------+
    外链接之右连接:优先显示右表全部记录
    select * from employee right join department on employee.dep_id=department.id;
    +------+---------+--------+------+--------+------+--------------+
    | id | name | sex | age | dep_id | id | name |
    +------+---------+--------+------+--------+------+--------------+
    | 1 | egon | male | 18 | 200 | 200 | 技术 |
    | 2 | alex | female | 48 | 201 | 201 | 人力资源 |
    | 3 | wupeiqi | male | 38 | 201 | 201 | 人力资源 |
    | 4 | yuanhao | female | 28 | 202 | 202 | 销售 |
    | 5 | nvshen | male | 18 | 200 | 200 | 技术 |
    | NULL | NULL | NULL | NULL | NULL | 203 | 运营 |
    +------+---------+--------+------+--------+------+--------------+
    全外链接:显示左右两个表全部记录
    select * from employee left join department on employee.dep_id = department.id
    union
    select * from employee right join department on employee.dep_id = department.id;
    +------+----------+--------+------+--------+------+--------------+
    | id | name | sex | age | dep_id | id | name |
    +------+----------+--------+------+--------+------+--------------+
    | 1 | egon | male | 18 | 200 | 200 | 技术 |
    | 5 | nvshen | male | 18 | 200 | 200 | 技术 |
    | 2 | alex | female | 48 | 201 | 201 | 人力资源 |
    | 3 | wupeiqi | male | 38 | 201 | 201 | 人力资源 |
    | 4 | yuanhao | female | 28 | 202 | 202 | 销售 |
    | 6 | xiaomage | female | 18 | 204 | NULL | NULL |
    | NULL | NULL | NULL | NULL | NULL | 203 | 运营 |
    +------+----------+--------+------+--------+------+--------------+

    七.符合条件查询

        即:将链接之后的表作为一张大表,继续做单表查询
    例:以内连接的方式查询employee和department表,并且employee表中的age字段值必须大于25,并且以age字段的升序方式显示。
    select * from employee inner join department on employee.dep_id=department.id where employee.age>25 order by age asc;
    +----+---------+--------+------+--------+------+--------------+
    | id | name | sex | age | dep_id | id | name |
    +----+---------+--------+------+--------+------+--------------+
    | 4 | yuanhao | female | 28 | 202 | 202 | 销售 |
    | 3 | wupeiqi | male | 38 | 201 | 201 | 人力资源 |
    | 2 | alex | female | 48 | 201 | 201 | 人力资源 |
    +----+---------+--------+------+--------+------+--------------+

    八.子查询

        子查询是将一个查询语句嵌套在另一个查询语句中。
    内层查询语句的查询结果,可以为外层查询语句提供查询条件。

    1.带in关键字的子查询
    例:查看技术部员工姓名
    select name from employee where dep_id in( select id from department where name='技术');
    +--------+
    | name |
    +--------+
    | egon |
    | nvshen |
    +--------+
    2.带比较运算的子查询
    例:查看大于部门内平均年龄的员工名,年龄
    select name,age from employee inner join (select dep_id,avg(age) as a from employee group by dep_id) as t1 on employee.dep_id=t1.dep_id where age>a;
    +------+------+
    | name | age |
    +------+------+
    | alex | 48 |
    +------+------+

    select name,age from employee where age > (select avg(age) from employee);
    +---------+------+
    | name | age |
    +---------+------+
    | alex | 48 |
    | wupeiqi | 38 |
    +---------+------+
    3.带exist关键字的子查询
    EXISTS关字键字表示存在。在使用EXISTS关键字时,内层查询语句不返回查询的记录。而是返回一个真假值。True或False
    当返回True时,外层查询语句将进行查询;当返回值为False时,外层查询语句不进行查询
    select * from employee where exists (select id from department where id=200);
    +----+----------+--------+------+--------+
    | id | name | sex | age | dep_id |
    +----+----------+--------+------+--------+
    | 1 | egon | male | 18 | 200 |
    | 2 | alex | female | 48 | 201 |
    | 3 | wupeiqi | male | 38 | 201 |
    | 4 | yuanhao | female | 28 | 202 |
    | 5 | nvshen | male | 18 | 200 |
    | 6 | xiaomage | female | 18 | 204 |
    +----+----------+--------+------+--------+

    九.pymysql模块的使用

        1.pymysql模块的下载
    pip3 install pymysql
    2.pymysql的使用
            import pymysql
            username=input('请输入用户名:')
            pwd=input('请输入密码:')
    
            # 1.连接
            conn=pymysql.connect(
                host='localhost',
                user='root',
                password='',
                database='db16',
                port=3306
            )
            # 2.创建游标
            cur=conn.cursor()
            sql='select * from userinfo where username="%s" and pwd="%s"'% (username,pwd)
            print(sql)
            # 3.执行sql语句
            res=cur.execute(sql)
            print(res)
            # 4.关闭连接
            cur.close()
            conn.close()
    
            if res:
                print('登录成功')
            else:
                print('登录失败')
        3.execute()之sql注入
    当用户名输入成这样时:sss " or 1=1 --
    不用输入密码都能登录

    解决方案
    sql='select * from userinfo where username=%s and pwd=%s' #去掉%s两边的双引号
    res=cur.execute(sql,(username,pwd)) # 用元组或列表都可以
    4.增删该:conn.commit() 提交
    在对数据进行增删改时,必须要提交,否则更改的数据不生效
                import pymysql
                conn=pymysql.connect(
                    host='localhost',
                    user='root',
                    password='',
                    database='db16',
                    port=3306
                )
                cur=conn.cursor()
                sql='insert into userinfo values(2,"aaa","456")'
                res=cur.execute(sql)
                print(res)
                conn.commit()
                cur.close()
                conn.close()
        5.查:fetchone、fetchmany、fetchall
    (1)fetchone
                import pymysql
                conn=pymysql.connect(
                    host='localhost',
                    user='root',
                    password='',
                    database='db16',
                    port=3306
                )
                cur=conn.cursor()
                sql='select * from userinfo'
                res=cur.execute(sql)
                row=cur.fetchone()
                print(row)   #(1, 'mjj', '123')
                cur.close()
                conn.close()
            (2)fetchall()
                import pymysql
                conn=pymysql.connect(
                    host='localhost',
                    user='root',
                    password='',
                    database='db16',
                    port=3306
                )
                cur=conn.cursor()
                sql='select * from userinfo'
                res=cur.execute(sql)
                row=cur.fetchall()
                print(row)
                #((1, 'mjj', '123'), (2, 'aaa', '456'), (3, 'bbb', '456'), (4, 'ccc', '456'))
                cur.close()
                conn.close()
            (3)fetchmany(a) 括号中的数字是获取几条数据
                import pymysql
                conn=pymysql.connect(
                    host='localhost',
                    user='root',
                    password='',
                    database='db16',
                    port=3306
                )
                cur = conn.cursor(cursor=pymysql.cursors.DictCursor)#让下面的fetchall返回的数据是一个字典
                sql='select * from userinfo'
                res=cur.execute(sql)
                row=cur.fetchmany(2)
                print(row)
                # [{'id': 1, 'username': 'mjj', 'pwd': '123'}, {'id': 2, 'username': 'aaa', 'pwd': '456'}]
                cur.close()
                conn.close()
            注:cursor.scroll(1,mode='relative') 相对当前位置移动
    cursor.scroll(1,mode='absolute') 相对绝对位置移动
                    import pymysql
                    conn=pymysql.connect(
                        host='localhost',
                        user='root',
                        password='',
                        database='db16',
                        port=3306
                    )
                    cur = conn.cursor(cursor=pymysql.cursors.DictCursor)#让下面的fetchall返回的数据是一个字典
                    sql='select * from userinfo'
                    res=cur.execute(sql)
                    cur.scroll(1,mode='absolute')
                    row=cur.fetchmany(2)
                    print(row)
                    # [{'id': 2, 'username': 'aaa', 'pwd': '456'}, {'id': 3, 'username': 'bbb', 'pwd': '456'}]
                    cur.close()
                    conn.close()

    十.索引

       概念:数据库中专门用于帮助用户快速查找数据的一种数据结构。
    类似于字典中的目录,查找字典内容时可以根据目录查找到数据的存放位置吗,然后直接获取。
    索引的作用:约束和加速查找
    常见的几种索引:
    1.普通索引
    作用:仅有一个加速查找
    创建索引:
    创建表时直接设定
    语法:index 索引名(要添加索引的列)
    create table userinfo(
    id int primary key auto_increment,
    name varchar(32) not null,
    email varchar(64) not null,
    index ix_name(name)
    )
    后追加的索引
    语法:create index 索引的名字 on 表名(列名)
    删除索引:
    语法:drop index 索引的名字 on 表名
    查看所以:
    show index from 表名
    2.唯一索引
    功能:加速查找和唯一约束(可含null)
    创建索引
    创建表时直接设定
    create table userinfo(
    id int primary key auto_increment,
    name varchar(32) not null,
    email varchar(64) not null,
    unique index ix_name(name)
    )
    后追加的索引
    语法:create unique index 索引的名字 on 表名(列名)
    删除索引:
    语法:drop index 索引的名字 on 表名
    3.主键索引
    功能: 加速查找和唯一约束(不含null)
    创建索引
    创建表时直接设定
    设定主键就相当于创建了主键索引
    后追加的索引
    alter table 表名 add primary key(列名);
    也是创建主键就相当于创建了主键索引
    删除主键索引
    alter table 表名 drop primary key;
    alter table 表名 modify 列名 int, drop primary key;
    即删除主键
    4.组合索引:组合索引是将n个列组合成一个索引
    创建索引:
    create index 索引名 on 表名(列名1,列名2);
    注:正确使用索引的情况
        (1)创建索引
        (2)命中索引
        (3)正确使用索引
  • 相关阅读:
    C#(99):Queue<T>队列与Stack<T>堆栈
    C#(99):字典Dictionary<Tkey.TValue>与SortedList
    C#(99):列表:List<T>与HashSet和只读集合
    C#(99):C#数组Array
    C#(99):枚举类型与位域枚举Enum
    C#(99):结构类型:Struct
    C#(99):定义类成员(属性、方法、索引、运算符、事件)、接口实现
    C#(99):定义类、System.Object对象、构造函数与析构函数、抽象类与静态类
    SuperSocket.ClientEngine介绍
    C#(99):五、并行编程
  • 原文地址:https://www.cnblogs.com/shanghongyun/p/9772862.html
Copyright © 2020-2023  润新知