美文网首页
MySql基础

MySql基础

作者: 像小象的云 | 来源:发表于2018-11-30 19:11 被阅读0次

    数据库

    1、定义

    数据库,简单的解释就是存储数据的仓库

    2、分类

    现在常用数据库主要分为两类:关系型数据库(SQL)和非关系型数据库(NoSQL,Not only Sql)

    3、常用数据库

    关系型数据库:Oracle、MySql、SQL Server
    非关系型数据库:MongoDB、Redis

    关系型数据库

    1、定义

    关系型数据库是一种建立在关系模型上的数据库。其理论基础是集合论与关系代数,表象为:
    (1)数据结构,二维数据表
    (2)操作指令,SQL
    (3)约束完整性,表内数据约束(字段与字段)和表与表之间的约束(外键)。
    关系型数据库如何保证数据的完整性:
    (1)实体完整性 - 每一条数据都是独一无二的,没有冗余数据 主键 / 唯一索引 保证
    (2)参照完整性/ 引用完整性 - 外键保证
    (3)领域完整性 - 没有无效的数据 - 数据类型 / 非空约束 / 默认值约束 / 检查约束(MySql不支持检查约束)

    2、SQL

    SQL:Structured Query Language,结构化查询语言(数据以查询为主,99% 都是在进行查询操作)。
    SQL 主要分为三种:

    • DDL:Data Definition Language,数据定义语言,用来维护存储数据的结构(数据库、表),代表指令为create、drop和alter等。
    • DML:Data Manipulation Language,数据操作语言,用来对数据进行操作(表中的内容)代表指令为insert、delete、update和select。
    • DCL:Data Control Language,数据控制语言,主要是负责(用户)权限管理,代表指令为grant和revoke等。
      SQL 是关系型数据库的操作指令,是一种约束,但不强制,类似于 W3C,因此这意味着:不同的数据库产品(如 Oracle 和 MySQL)内部可能会有一些细微的区别。

    库操作

    1、新增数据库

    基本语法:create database + 数据库名称 + [库选项];
    其中,库选项是用来约束数据库的,为可选项(有默认值),共有两种,分别为:

    • 字符集设定:charset/ character set+ 具体字符集,用来表示数据存储的编码格式,常用的字符集包括GBK和UTF8等。
    • 校对集设定:collate+ 具体校对集,表示数据比较的规则,其依赖字符集。
    create database tb_student charset utf8;
    

    其中,数据库的名字不能用关键字(已经被占用的字符,例如 update 和 insert 等)或者保留字(将来可能会用的,例如 access 和 cast 等)。
    如果还想使用中文作为数据库的名称,那就得保证数据库能够识别中文(强烈建议不要用中文命名数据库的名称),例如:

    -- 设置中文名称的方法,其中 gbk 为当前数据库的默认字符集
    set names gbk;
    create database 成都 charset gbk;
    

    2、查询数据库

    查看全部基本语法:show databases;
    查看部分(模糊查询基本语法:show databases like 'pattern';
    其中,pattern是匹配模式,有两种,分别为:

    • "%":表示匹配多个字符;
    • "_":表示匹配单个字符。
      此外,在匹配含有下划线_的数据库名称的时候,需要在下划线前面加上反斜线\_进行转义操作。
    示例:show databases like 'tb%';表示匹配所有tb开头的数据库。
    

    查看数据库的创建语句基本语法:show create database + 数据库名称;
    在这里,查看的结果有可能与咱们书写的 SQL 语句不同,这是因为数据库在执行 SQL 语句之前会优化 SQL,系统保存的是优化后的结果。

    查询当前连接数据库:

    select database();
    

    切换数据库:
    语法:use 数据库名;

    3、更新数据库

    在这里,需要注意:数据库的名字不可以修改
    数据库的修改仅限库选项,即字符集和校对集(校对集依赖字符集)。
    基本语法:alter database + 数据库名称 + [库选项];
    charset/character set[=] 字符集;
    collate[=] 校对集;

    alter database tb_student charset gbk; /*表示修改此数据库的字符集为gbk.*/
    

    4、删除数据库

    基本语法:drop database + 数据库名称;
    在这里,需要注意:在删除数据库之前,应该先进行备份操作,因为删除为不可逆操作,所以不要随意删除数据库。

    表操作

    1、创建表

    基本语法:create table [if not exists] +表名(字段1, 字段2, ...)[表选项]
    其中 if not exists 可选表示,如果表存在就不创建,不存在才创建。
    表选项有三种变现形式:

    • 字符集设定:charset/ character set+ 具体字符集,用来表示数据存储的编码格式,常用的字符集包括GBK和UTF8等。
    • 校对集设定:collate+ 具体校对集,表示数据比较的规则,其依赖字符集。
    • 存储引擎:engine+具体存储引擎,默认为InnoDB,常用的还有MyISAM.

    因为表都归属于数据库,所以在创建表的时候需要指定数据库,有两种指定方法:
    1.显示指定

    create table if not exists test.student(
        name varchar(10),
        age int,            /* 整型不需要指定具体的长度 */
        grade varchar(10)   /* 最后后一行,不需要加逗号 */
    )charset utf8;
    

    2.隐式指定

    use test;               /* use + 数据库名称,表示切换到指定的数据库,这句命令其实不加分号也可以,但不建议这么做 */
    create table if not exists student(
        name varchar(10),
        age int,            /* 整型不需要指定具体的长度 */
        grade varchar(10)   /* 最后后一行,不需要加逗号 */
    )charset utf8;
    

    2、删除表

    基本语法:drop table + 表1,[ 表2 ...] ;
    在这里,需要注意:此删除为不可逆操作,希望大家谨慎使用。

    3、查询表

    查看当前库中所有表基本语法: show tables;
    同查询库操作一样,也支持模糊查询。
    查看建表语句: show create table 表名;
    查看表结构(所有字段):desc 表名;

    4、修改表

    在这里,需要注意:表的修改,分为修改表本身和修改表中的字段。
    第 1 类:修改表本身
    修改表名,基本语法:rename table 旧表名 to 新表名;
    修改表选项,基本语法:alter table + 表名 + 表选项[=] + 值;

    第 2 类:修改表中的字段,新增、修改、重命名和删除

    • 新增字段基本语法:alter table + 表名 + add + [column] + 字段名 + 数据类型 + [列属性][位置];
      其中,位置表示此字段存储的位置,分为first(第一个位置)和after + 字段名(指定的字段后,默认为最后一个位置).
    alter table student add column id int first;
    
    • 修改字段基本语法:alter table + 表名 + modify + 字段名 + 数据类型 + [列属性][位置];
    alter table student modify name char(10) after id;
    
    • 重命名字段基本语法:alter table + 表名 + change + 旧字段名 + 新字段名 + 数据类型 + [列属性][位置];
    alter table tb_student change column stuname stuname varchar(20) not null comment '姓名'; 
    
    • 删除字段基本语法:alter table + 表名 + drop+ 字段名;
    alter table tb_student drop stutel;
    

    注意:如果表中已经存在数据,那么删除该字段会清空该字段的所有数据,而且不可逆,慎用。

    数据的增删改

    1、增加数据

    基本语法:
    1. 给全表字段增加数据:insert into +表名 values(数据)[,(数据)]
    注意这种方法,需要使数据的顺序与字段顺序一致,且非数字值都要用引号引起来。

    insert into tb_student values (1001, '王大锤', '男', '1981-01-04', ' 地球村');
    

    2. 给指定字段增加数据:insert into +表名(字段1[,字段2,...]) values(数据)[,数据]

    insert into tb_student (stuid, stuname, stubrithday) values (1002, '王小锤', '1981-01-04');
    

    2、更新数据

    基本语法:update +表名 set 字段=修改值 [修改数据];
    注意如果不指定具体修改数据,则默认修改全表该字段值

    -- 更新一条数据的一个字段
    UPDATE tb_student set stuaddr='太阳系' where stuid=1002;
    -- 更新一条数据的两个字段
    UPDATE tb_student set stuaddr='太阳系',stubrithday='1981-01-05' where stuid=1002;
    -- 更新两条条数据的一个字段
    UPDATE tb_course set credit=3 where cid=1802 or cid=1803;
    -- 更新两条条数据的一个字段
    UPDATE tb_course set credit=4 where cid in (1802,1803);
    

    3、删除数据

    基本语法:delete from +表名 +删除数据

    -- 删除数据 从tb_student中删除stuid为1003的记录 
    delete from tb_student where stuid=1003;
    

    删除全表数据:

    TRUNCATE table tb_student;
    

    且行且珍惜,慎用

    数据的查询

    1、基本查询

    基本语法: select 查询字段 from 查询表 [查询条件]

    -- 查询全表 
    SELECT *  from tb_student;
    
    -- 查询指定字段
    SELECT  stuname, stuaddr  from tb_student;
    
    -- 查询结果重命名
    SELECT  stuname as  姓名, stuaddr as 地址  from tb_student;
    
    -- 查询结果筛序
    SELECT  stuname as  姓名, stuaddr as 地址  from tb_student where stuid between 1002 and 1004;
    
    -- 判断空使用 is 
    SELECT  stuname, stuaddr  from tb_student where stuaddr is null;
    SELECT  stuname, stuaddr  from tb_student where stuaddr is not null;
    
    -- 模糊查询 like  %通配符,匹配0个或多个字符  _匹配一个字符
    SELECT  stuname, stuaddr  from tb_student where stuaddr like '太%';
    SELECT  stuname, stuaddr  from tb_student where stuname like '_五_';
    
    -- 查询排序 order by   降序desc 升序asc
    SELECT  stuname, stuaddr  from tb_student order by stuid desc, stubrithday asc;
    -- 默认升序
    SELECT  stuname, stuaddr  from tb_student order by stuid;
    
    -- 只看前三条记录
    SELECT *  from tb_student limit 3;
    
    
    -- 分页查询,查看第4到6条数据
    SELECT *  from tb_student limit 3 offset 3;
    SELECT *  from tb_student limit 3,3;
    -- 查看第7到9条数据
    SELECT *  from tb_student limit 3 offset 6;
    SELECT *  from tb_student limit 6,3;
    
    -- 函数查询 DISTINCT 去重  SUBSTR(stuname, 1, 2) 取前两个字符
    SELECT DISTINCT SUBSTR(stuname, 1, 2) FROM tb_student;
    
    -- 聚合函数(统计函数)
    SELECT MAX(credit) FROM tb_course;
    SELECT MIN(credit) FROM tb_course;
    SELECT SUM(credit) FROM tb_course;
    SELECT AVG(credit) FROM tb_course;
    SELECT COUNT(credit) FROM tb_course;
    
    -- 分组查询 GROUP BY
    SELECT stusex, count(stuid) FROM tb_student GROUP BY stusex;
    
    -- 分组后的筛选用having
    SELECT sid, avg(mark) as m FROM tb_score  GROUP BY sid HAVING m>=90;
      
    -- 创建用户 wang 密码 123456 可以从任意地方登录
    CREATE USER 'wang' @'%' IDENTIFIED BY '123456';
    
    -- 创建用户 wang 密码 123456 只能从IP为 10.10.21.21 登录 
    CREATE USER 'wang' @'10.10.21.21' IDENTIFIED BY '123456';
    
    -- 授权 grant ... to ... 授权所有权限,但是不能给别人授权
    GRANT ALL PRIVILEGES ON *.* TO 'wang'@'%';
    
    -- 授权所有权限,能给别人授权
    GRANT ALL PRIVILEGES ON *.* TO 'wang'@'%' with GRANT option;
    
    
    -- 移除权限
    REVOKE ALL PRIVILEGES ON *.* FROM 'wang'@'%';
    
    -- 授权 school数据库中 tb_course 数据表的 select 权限
    GRANT select ON school.tb_course TO 'wang'@'%';
    
    -- 授权 school数据库中 select, insert, update, delete 权限
    GRANT select, insert, update, delete ON school.* TO 'wang'@'%';
    
    -- 授权 school数据库中 alter, create, drop 权限
    GRANT alter, create, drop ON school.* TO 'wang'@'%';
      
    -- 表与表之间的关系:
    -- 一对一
    -- 一对多 / 多对一 外键是多的表
    -- 多对多  需要建立中间表
    
    
    
    CREATE TABLE tb_teacher (
    tid INT COMMENT '教师编号',
    tname VARCHAR ( 20 ) NOT NULL COMMENT '教师名字',
    title enum ( '教授', '副教授', '讲师', '助教' ) DEFAULT '讲师' COMMENT '教师职称',
    cid INT NOT NULL COMMENT '教师所属学院' 
    );
    -- 修改表,添加主键
    ALTER TABLE tb_teacher ADD CONSTRAINT pk_teacher_id PRIMARY KEY ( tid );
    
    -- 修改表,添加外键
    ALTER TABLE tb_teacher ADD CONSTRAINT fk_teacher_id FOREIGN KEY ( cid ) REFERENCES tb_college ( collid );
    
    -- 外键约束
    -- district:严格模式(默认),父表不能删除或更新一个已经被子表数据引用的记录;
    -- cascade:级联模式,父表的操作,对应子表关联的数据也跟着被删除;
    -- set null:置空模式,父表的操作之后,子表对应的数据(外键字段)被置空。
    
    -- 设置外键为级联模式 cascade
    ALTER TABLE tb_teacher ADD CONSTRAINT fk_teacher_id FOREIGN KEY ( cid ) REFERENCES tb_college ( collid ) on delete cascade on update cascade;
    
    -- 取消外键约束
    alter table tb_teacher drop FOREIGN KEY (fk_teacher_id);
    
    
    -- 查询平均成绩大于等于90分的学生的学号和平均成绩
    SELECT sid, avg(mark) as m FROM tb_score  GROUP BY sid HAVING m>=90;
    
    -- 子查询 - 在一个查询中又使用到了另外一个查询的结果
    -- 查询年龄最大的学生的姓名(子查询)
     SELECT sname from tb_student WHERE birth=(SELECT min(birth) FROM tb_student);
    
    -- 查询年龄最大的学生姓名和年龄(子查询+运算)
     SELECT sname, year(now())-year(birth) from tb_student WHERE birth=(SELECT min(birth) FROM tb_student);
    
    -- 查询选了两门以上的课程的学生姓名(子查询/分组条件/集合运算)
    SELECT sname FROM tb_student WHERE stuid=any(SELECT sid FROM tb_score GROUP BY sid HAVING COUNT(sid)>2);
    SELECT sname FROM tb_student WHERE stuid in (SELECT sid FROM tb_score GROUP BY sid HAVING COUNT(sid)>2);
    
    -- 查询学生姓名以及所在学院的名称
    SELECT sname, collname FROM tb_student, tb_college WHERE tb_student.collid=tb_college.collid;
    SELECT sname, collname FROM tb_student t1, tb_college t2 WHERE t1.collid=t2.collid;
    SELECT sname, collname FROM tb_student t1 INNER JOIN  tb_college t2 on t1.collid=t2.collid;
    
    -- 连接查询(联结查询/联接查询)
    -- 查询学生姓名、课程名称以及成绩
    SELECT sname, cname, mark FROM tb_student, tb_course, tb_score where stuid=sid and couid=cid;
    SELECT sname, cname, mark FROM tb_student INNER JOIN tb_score on stuid=sid INNER JOIN tb_course on couid=cid; 
    
    -- 查询选课学生的姓名和平均成绩(子查询和连接查询)
    SELECT sname, avgmark FROM tb_student t1 INNER JOIN 
    (SELECT sid, avg(mark) as avgmark FROM tb_score GROUP BY sid) t2 on t1.stuid=t2.sid;
    
    -- 查询每个学生的姓名和选课数量(左外连接和子查询)
    SELECT sname, coursenum FROM tb_student t1 LEFT OUTER JOIN 
    (SELECT sid, count(cid) as coursenum FROM tb_score GROUP BY sid) t2 on t1.stuid=t2.sid;
    
    -- 查询主管的姓名和职位
    SELECT ename, job from tbemp t1 WHERE EXISTS (SELECT 'X' FROM tbemp t2 WHERE t1.eno=t2.mgr);
    

    python连接mysql

    实例一

    import pymysql
    
    
    def main():
        # 创建数据库连接
        con = pymysql.connect(
            host='localhost', port=3306, user='root', password='123456', database='hrs', charset='utf8', autocommit=True)
        no = int(input('请输入部门编号:'))
        name = input('请输入部门名称:')
        loc = input('请输入部门地址:')
        try:
            # 获取游标
            with con.cursor() as cursor:
                # 向数据库发出SQL指令,cursor.execute() 增删改的操作返回受影响的数据行数
                res = cursor.execute('insert into TbDept values  (%s, %s, %s)', (no, name, loc))
                # 处理返回信息
                if res == 1:
                    print('添加成功')
        except pymysql.MySQLError as e:
            print(e)
        finally:
            # 关闭连接
            con.close()
    
    
    if __name__ == '__main__':
        main()
    
    

    实例二

    import pymysql
    
    
    def main():
        # 创建数据库连接
        con = pymysql.connect(
            host='localhost', port=3306, user='root', password='123456', database='hrs', charset='utf8', autocommit=True)
        no = int(input('请输入部门编号:'))
        name = input('请输入部门名称:')
        loc = input('请输入部门地址:')
        try:
            # 获取游标
            with con.cursor() as cursor:
                # 向数据库发出SQL指令
                # res = cursor.execute('delete from tbdept where dno=%s', (no,))
                res = cursor.execute('update tbdept set dname=%s, dloc=%s where dno=%s', (name, loc, no))
                # 处理返回信息
                if res == 1:
                    print('更新成功')
        except pymysql.MySQLError as e:
            print(e)
        finally:
            # 关闭连接
            con.close()
    
    
    if __name__ == '__main__':
        main()
    

    实例三

    import pymysql
    
    
    class Dept(object):
        def __init__(self, no, name, loc):
            self.no = no
            self.name = name
            self.loc = loc
    
        def __str__(self):
            return f'{self.no}\t{self.name}\t{self.loc}'
    
    
    def main():
        con = pymysql.connect(
            host='localhost',
            port=3306,
            user='root',
            passwd='123456',
            charset='utf8',
            database='hrs',
            cursorclass=pymysql.cursors.DictCursor)
        try:
            with con.cursor() as cursor:
                cursor.execute('select dno no, dname name, dloc loc from tbdept')
                depts = cursor.fetchall()
                print('部门编号', '部门名称', '部门地址', sep='\t')
                for dept in depts:
                    print(Dept(**dept))
    
        except pymysql.MySQLError as e:
            print(e)
        finally:
            con.close()
    
    
    if __name__ == "__main__":
        main()
    
    

    相关文章

      网友评论

          本文标题:MySql基础

          本文链接:https://www.haomeiwen.com/subject/gdgzqqtx.html