zoukankan      html  css  js  c++  java
  • MySQL数据库SQL语句基本操作

    一、用户管理:

    创建用户:

    create user '用户名'@'IP地址' identified by '密码';

    删除用户:

    drop user '用户名'@'IP地址';

    修改用户:

    rename user '用户名'@'IP地址'; to '新用户名'@'IP地址';

    修改密码:

    set password for '用户名'@'IP地址' = Password('新密码')

    二、库相关操作

    查看所有数据库: 

    1 SHOW DATABASES;

    创建数据库 :

    CREATE DATABASE cnblog(数据库名称,下同) CHARSET=UTF8; 

    删除数据库 :

    DROP DATABASE cnblog;

    切换数据库 :

    USE cnblog;

    查看当前数据库 :

    SELECT DATABASE();

    图例:

    三、表相关操作

    查看数据库中的所有表:SHOW TABLES;

    创建表:

    格式(中括号中可以不填):CREATE TABLE 表名(列名 数据类型 是否可以为空)[ ENGINE= INNODB DEFAULT CHARSET=UTF8 ]

    1.数字
         int[unsigned]  可以保存2的32次方大小的数,若有正负号,表示正负2的31次方
        bigint可以表示很大的数
    2.字符串
        char(10)定长 若数据没有10长度会用空格补缺
        varchar(10)变长  数据是多少就是多少
        两者都只能表示255字节长度的字符串,
    3.时间
        一般用DATATIME 显示XXXX-MM-DD H-i-s
    4.枚举
        enum 插入数据时只能从Enum选项中选取
     CREATE TABLE shirts (
                        name VARCHAR(40),
                        size ENUM('x-small', 'small', 'medium', 'large', 'x-large')
                    );
    INSERT INTO shirts (name, size) VALUES ('dress shirt','large'), ('t-shirt','medium'),('polo shirt','small')
        set    插入值只能是set选项中的组合
    CREATE TABLE myset (col SET('a', 'b', 'c', 'd'));
    INSERT INTO myset (col) VALUES ('a,d'), ('d,a'), ('a,d,a'), ('a,d,d'), ('d,a,d');
    5.文件
    如果文件过长,或者是图片,存取的是文件的url位置
    基本数据类型
                NOT NULL    -不能为空
                NULL           -可为空
    是否可为空
        CREATE TABLE 表名(
             num INT NOT NULL DEFAULT 6,
            ) ;     
         # 插入的这个数默认为6
    默认值
    1. 自增列为主键的情况    
    CREATE TABLE 表名(
               id  INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
            )    
    2. 自增列为索引
    CREATE TABLE 表名(
               id  INT NOT NULL AUTO_INCREMENT,
               index(id)      
            )     
    自增
    1.主键可以为单个字段
    CREATE TABLE 表名(
               id  INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
            ) 
    
    2.主键可以为组合
    CREATE TABLE 表名(
               firstname  VARCHAR(20) NOT NULL,
               lastname  VARCHAR(20) NOT NULL,
               PRIMARY KEY (firstname,lastname)
            ) 
    主键
    creat table color(
                    nid int not null primary key,
                    name char(16) not null
                )
    
    create table fruit(
                    nid int not null primary key,
                    smt char(32) null ,
                    color_id int not null,
                    constraint fk_cc foreign key (color_id) references color(nid)
                )
    外键
    SHOW CREATE TABLE 表名
    查看建表语句
    DESC 表名
    查看建表字段

    修改表:

    添加列:ALTER TABLE 表名 ADD 列名 类型
    删除列:ALTER TABLE 表名 DROP COLUMN 列名
    修改列:ALTER TABLE 表名 MODIFY COLUMN 列名 类型;  -- 类型
    修改外键:ALTER TABLE 从表 ADD CONSTRAINT 外键名称(形如:FK_从表_主表)FOREIGN KEY 从表(外键字段) REFERENCES 主表(主键字段);
    删除外键:ALTER TABLE 表名 DROP FOREIGN KEY 外键名称
     INSERT INTO 表名(列名,列名) VALUES (值,值);
    eg: INSERT INTO student(name,tel) VALUES(‘小明’,‘13111311313’);
    DELETE FROM 表名 WHERE 条件;
    eg:DELETE FROM STUDENT WHERE sid=‘1001’ AND class=‘二班’
    UPDATE 表名 SET 列=值 WHERE 条件
    eg:UPDATE student SET points = 80 WHERE class=‘三班’
    SELECT * FROM 表名
    eg:SELECT * FROM STUDENT WHERE id>1
          SELECT id,gender FROM student WHERE points>80
    ALTER TABLE 表名 AUTO_INCREMENT=10
    表示主键的值从10开始递增
    修改主键的值

     添加一个条件语句(语法case when ...then.... else .... end)

    select max(num),min(num) case when min(num)<60 then 不及格 else min(num) end from score

    最低分低于60分的会显示不及格,如果高于60分会显示最低是多少。

    按条件查询(关键词where):
    SELECT * FROM students WHERE age>10;
    SELECT * FROM students WHERE id in (1,3,5);
    SELECT * FROM students WHERE id BETWEEN 5 AND 16;(这是个闭区间)
    SELECT * FROM students WHERE age=30 AND firstname=‘张'
    SELECT * FROM students WHERE id in (SELECT id FROM male_students)(先从第二张表取id,再用此id查第一张表数据)
    通配符查询(关键词like):
    SELECT * FROM students WHERE name  like '%平’;(查找名字以平结尾的)
    SELECT * FROM students WHERE name  like '_平’;(查找名字以平结尾的,只能为两个字)
    SELECT * FROM students WHERE name  like '%平%’;(查找名字中含有平的)
    分页查找(关键字limit):
    SELECT * FROM students limit 10;      取10条数据查看
    SELECT * FROM students limit 20,10    从第20条开始向后取10条
    SELECT * FROM students limit 5 offset 7     从第7条开始向后取5条
    排序 (关键词 ORDER BY)
    SELECT * FROM students ORDER BY id DESC;降序排列
    SELECT * FROM students ORDER BY id ASC;升序排列
    分组(关键字group by 和 having):
    SELECT count(id) as mount, class_id FROM students GROUP BY cl
    ass_id HAVING count(id) > 20;(注意:where语句不能接聚合函数的,如果要对分组后的结果进行二次筛选要用having)
    连表操作(关键词LEFT JOIN ...ON):
    SELECT student.name FROM student LEFT JOIN class ON student.cid = class.id 
    
    多张表相连:
    SELECT student.name,teacher.id FROM student 
    LEFT JOIN class ON student.cid = class.id 
    LEFT JOIN teacher on class.teacher = teacher.id
    
    LEFT JOIN 与 RIGHT JOIN区别:会以LEFT或RIGHT关联的表作为主显示表,从表没有数据会显示NULL
    
    INNER JOIN 则会隐藏NULL的字段
    
    注意:多张表关联时要引用字段,字段所在的表必须是关联好的不能凭空引入一个字段

    索引:帮助我们快速的找到数据

    索引文件存储的某种格式:

    1.hash, 单值取值快, 但取多项数据时速度较慢

    2.btree,单值没有hash速度快,但单次取数据查询次数少,对于多项数据速度较快

    常见索引:
    普通索引:加速查找
    唯一索引:加速查找 + 不能重复
    主键索引:加速查找 + 不能为空 + 不能重复
    联合索引:
            - 联合主键索引
            - 联合唯一索引
            - 联合普通索引
    
    普通索引:
    
    生成表时即创建普通索引
    CREATE TABLE index_1(
        nid int not null auto_increment primary key,
        name char(32) not null,
        email char(32) not null,
        extra text,
        index ix_name(name)
    )
    
    SQL语句创建索引
    CREATE INDEX 索引名 on 表名(字段)
    
    删除索引
    DROP 索引名 on 表名;
    
    查看索引
    show index from 表名;
    
    索引的缺点:
    1.需要保存额外的索引文件
    2.更新修改新建速度慢
    3.要命中索引
        - SELECT * FROM student WHERE name='一休', 命中
        - SELECT * FROM student WHERE name LIKE '一休', 未命中
    
    唯一索引:
    创建表生成唯一索引
    CREATE TABLE index_2(
            nid int not null auto_increment primary key,
        name varchar(32) not null,
        email varchar(64) not null,
        extra text,
        unique ix_name (name)  -- 将name字段设置为唯一索引
    )
    
    
    创建唯一索引
    CREATE unique INDEX 索引名 on 表名(字段);
    
    删除唯一索引
    DROP unique INDEX 索引名 on 表名
    
    主键索引
    create table index_3(
        nid int not null auto_increment primary key,
        name varchar(32) not null,
        email varchar(64) not null,
        extra text,
        index ix_name (name)
    )
    
    OR
    
    create table index_4(
        nid int not null auto_increment,
        name varchar(32) not null,
        email varchar(64) not null,
        extra text,
        primary key(ni1),
        index ix_name (name)
    )
    
    
    创建主键
    ALTER TABLE 表名 add PRIMARY KEY(列名)
    
    删除主键
    alter table 表名 drop primary key;
    alter table 表名 modify 列名 int, drop primary key;
    
    
    联合索引:
    创建联合索引
    
    create table index_5(
        nid int not null auto_increment primary key,
        name varchar(32) not null,
        email varchar(64) not null,
        extra text
    )
    create index ix_name_email on in3(name,email);
    
    
    删除联合索引
    - drop unique index 索引名称 on 表名
    常见索引
    在索引文件中直接获得数据
    SELECT name FROM tb WHERE name='zhang'
    覆盖索引
    把多个单列索引合并使用
    SELECT * FROM tb WHERE name=‘xxx’ AND id=3
    索引合并
    在组合索引中,遵循最左前缀原则,比如索引为(name,class,tel)
    查询条件为name时走索引,(name,class),(name,tel)都会走索引
    但是如果是class或tel开头不走索引
    1.like
    select * from tb1 where name like '%cn';
    
    2.使用函数
    SELECT * FROM tb WHERE  reverse(name) = 'zhang'
    
    3.or
    SELECT * FROM tb WHERE nid=1 or email='nn@qq.com'
    注意:当or条件未建立索引才会失效或者后面接and条件是索引,也会忽略or
    
    4.类型不一致
    SELECT * FROM tb WHERE sid='999';(int类型却用字符串查找)
    
    5.!=
    SELECT * FROM tb WHERE sid != 99;
    注意:如果条件是主键依然走索引
    
    6.>
    SELECT * FROM tb WHERE sid>99;
    注意:如果条件是主键或整数类型会走索引
    
    7.order by
    SELECT name FROM tb order by sid;
    注意:如果sid是索引 name非索引 则不走索引
    如果order by接主键依然走索引
    
    8.最左前缀匹配
    不能命中索引的几种情况
    1.避免使用SELECT *
    2.创建表时尽量用char代替varchar
    3.建表时固定长度的字段往前排
    4.索引散列(重复少)不适合建索引(性别)
    5.尽量使用短索引(text字段类型格式:text18)以前18个字符建索引)
    6.连表操作是条件类型需一直
    索引应注意事项
    作用:不执行sql语句,MySQL预估SQL语句执行时间
     id
            查询顺序标识
                如:mysql> explain select * from (select nid,name from tb1 where nid < 10) as B;
                +----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
                | id | select_type | table      | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
                +----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
                |  1 | PRIMARY     | <derived2> | ALL   | NULL          | NULL    | NULL    | NULL |    9 | NULL        |
                |  2 | DERIVED     | tb1        | range | PRIMARY       | PRIMARY | 8       | NULL |    9 | Using where |
                +----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
            特别的:如果使用union连接气值可能为null
    
    
        select_type
            查询类型
                SIMPLE          简单查询
                PRIMARY         最外层查询
                SUBQUERY        映射为子查询
                DERIVED         子查询
                UNION           联合
                UNION RESULT    使用联合的结果
                ...
        table
            正在访问的表名
    
    
        type
            查询时的访问方式,性能:all < index < range < index_merge < ref_or_null < ref < eq_ref < system/const
                ALL             全表扫描,对于数据表从头到尾找一遍
                                select * from tb1;
                                特别的:如果有limit限制,则找到之后就不在继续向下扫描
                                       select * from tb1 where email = 'seven@live.com'
                                       select * from tb1 where email = 'seven@live.com' limit 1;
                                       虽然上述两个语句都会进行全表扫描,第二句使用了limit,则找到一个后就不再继续扫描。
    
                INDEX           全索引扫描,对索引从头到尾找一遍
                                select nid from tb1;
    
                RANGE          对索引列进行范围查找
                                select *  from tb1 where name < 'alex';
                                PS:
                                    between and
                                    in
                                    >   >=  <   <=  操作
                                    注意:!=> 符号
    
    
                INDEX_MERGE     合并索引,使用多个单列索引搜索
                                select *  from tb1 where name = 'alex' or nid in (11,22,33);
    
                REF             根据索引查找一个或多个值
                                select *  from tb1 where name = 'seven';
    
                EQ_REF          连接时使用primary key 或 unique类型
                                select tb2.nid,tb1.name from tb2 left join tb1 on tb2.nid = tb1.nid;
    
    
    
                CONST           常量
                                表最多有一个匹配行,因为仅有一行,在这行的列值可被优化器剩余部分认为是常数,const表很快,因为它们只读取一次。
                                select nid from tb1 where nid = 2 ;
    
                SYSTEM          系统
                                表仅有一行(=系统表)。这是const联接类型的一个特例。
                                select * from (select nid from tb1 where nid = 1) as A;
        possible_keys
            可能使用的索引
    
        key
            真实使用的
    
        key_len
            MySQL中使用索引字节长度
    
        rows
            mysql估计为了找到所需的行而要读取的行数 ------ 只是预估值
    
        extra
            该列包含MySQL解决查询的详细信息
            “Using index”
                此值表示mysql将使用覆盖索引,以避免访问表。不要把覆盖索引和index访问类型弄混了。
            “Using where”
                这意味着mysql服务器将在存储引擎检索行后再进行过滤,许多where条件里涉及索引中的列,当(并且如果)它读取索引时,就能被存储引擎检验,因此不是所有带where子句的查询都会显示“Using where”。有时“Using where”的出现就是一个暗示:查询可受益于不同的索引。
            “Using temporary”
                这意味着mysql在对查询结果排序时会使用一个临时表。
            “Using filesort”
                这意味着mysql会对结果使用一个外部索引排序,而不是按索引次序从表里读取行。mysql有两种文件排序算法,这两种排序方式都可以在内存或者磁盘上完成,explain不会告诉你mysql将使用哪一种文件排序,也不会告诉你排序会在内存里还是磁盘上完成。
            “Range checked for each record(index map: N)”
                这个意味着没有好用的索引,新的索引将在联接的每一行上重新估算,N是显示在possible_keys列中索引的位图,并且是冗余的。
    执行计划
    分页:
    最常见的分页基于 SELECT * FROM text_tb limit 0,10
    这样的分页当数据量很大时(例如千万级别的数据量),很耗费时间,解决方法有以下几点:
    1. 只给浏览用户展示固定页数,比如200页,300页,减轻mysql检索压力
    2. 用索引表(覆盖索引)
        SELECT * FROM text_tb WHERE id in(SELECT id FROM text_tb LIMIT 1000000,10)
    3.记录当前页最小id(比如150000)和最大id(150010)
        下一页: SELECT * FROM text_tb WHERE id > max_id LIMIT 10;
        上一页:SELECT * FROM text_tb WHERE id < min_id ORDER BY id DESC LIMIT 10;
    4.给URL上的页数信息加密,无法直接访问到较大页数
    
    注意:
    1.id 不一定是连续的,所以不能用id bewteen xx and xx 来进行检索
    2.中间页数的思路,根据前页的id 计算要跳到的页数的id,取到为止,倒序排列,并取头10个作为limit
    select * from userinfo where id in (
        select id from (select id from userinfo where id > max_id limit 30) as N order by N.id desc limit 10
    )
    分页相关
  • 相关阅读:
    commons
    Dozer数据对象转换神器
    xstream
    javassist
    JAVA设计模式之单例模式
    单例模式
    OC_自动引用计数器_0x04
    OC_自动引用计数器_0x03
    OC_自动引用计数器_0x02
    OC_自动引用计数器_0x01
  • 原文地址:https://www.cnblogs.com/jimmyhe/p/10426577.html
Copyright © 2011-2022 走看看