MySQL初学者,以及Python操作MySQL

本文深入解析MySQL数据库的基础概念、数据类型、表结构、SQL语句、事务处理、索引优化及数据库安全等内容,涵盖数据库设计、操作与管理的核心知识点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MySQL数据库

数据库(Database)是按照数据结构来组织、存储和管理数据的仓库。

关系型数据库管理系统(RDBMS)来存储和管理的大数据量。所谓的关系型数据库,是建立在关系模型基础上的数据库,借助于集合代数等数学概念和方法来处理数据库中的数据。

  • 数据库: 数据库是一些关联表的集合。
  • 数据表: 表是数据的矩阵。在一个数据库中的表看起来* 像一个简单的电子表格。
  • 列: 一列(数据元素)包含了相同的数据。字段,如果能够唯一标记某个字段,那么这就是主键。
  • 行:一行(=元组,或记录)是一组相关的数据,例如一条用户订阅的数据。
  • 主键:主键是唯一的。一个数据表中只能包含一个主键。你可以使用主键来查询数据。
  • 外键:外键用于关联两个表。

数据类型:

原则:够用就行,尽量使用取值范围小的,而不用大的,这样可以更多的节省内存空间。

数值类型:严格数值数据类型(INTEGER、SMALLINT、DECIMAL和NUMERIC),以及近似数值数据类型(FLOAT、REAL和DOUBLE PRECISION)。

  • TINYINT:小整数值
  • SMALLINT:大整数值
  • MEDIUMINT:大整数值
  • INThuoINTEGER:大整数值
  • BIGINT:极大整数值
  • FLOAT:单精度浮点数值
  • DOUBLE:双精度浮点数值
  • DECIMAL:小数值
特别说明的类型如下:
  • decimal表示浮点数,如decimal(5,2)表示共存五位数,小数占2位。
  • char表示固定长度的字符串,如char(3),如果填充’ab’时就会补一个空格
  • varchar表示可变长度的字符串,如varchar(3),填充’ab’时就会储存’ab’.
  • 字符串text表示储存大文本,当字符大于4000时推荐使用。

*链接数据库:
mysql -uroot -p
mysql -uroot -pmysql

  • 退出数据库:
    exit/quit/ctrl+d
  • 显示数据库版本:
    select version();
  • 显示时间:
    select now();
  • 查看所有数据库:
    show databases;
  • 创建数据库:
    使用create命令创建数据库。
    create database 数据库名;

create database 数据库名
charset=utf8;

  • 查看创建数据库的语句:
    show create database 数据库名;
  • 查看当前使用的数据库:
    select database();
  • 使用数据库
  • use 数据库的名字:
    use 数据库名称。
  • 删除数据库:
    drop database 数据库名;

drop table 表名;

数据表的操作

  • 查看当前数据库中所有表:
    show tables;
  • 创建表
  • auto_increment表示自动增长
  • not null 表示不能为空。
  • primary key 表示主键。
  • default 默认值。
  • creat table 数据库名称(字段 类型 约束[,字段 类型 约束])
  • 创建classes表(id,name):

create table xxxxx(id int,name varchar())

create table yyyyy(id int primary key not null auto_increment , name varchar(30))

  • desc 数据表的名字(查看表的结构的详细信息):
    desc xxxxxx;
  • 查看表的创建的语句:
    show create table 表的名字;
  • 添加字段:
    alter table 表名 add 列明 类型;
  • 修改字段:不重命名版
    alter table 表名 modify 列名 类型及约束;
  • 修改字段:重命名版
    alter table 表名 change 原名 新名 类型及约束;
  • 删除字段
    alter table 表名 drop 列名;

增删改查:

  • 增加:
  • 全列插入:

insert [into] 表名 values(…)

主键字段 可以使用 0 null default 来占位。

向classes表中插入 一个班级:

insert into classes values(…)

如果你的第一个字段为自增,插入操作要这样写:insert into 表名 (列1, 列2,…) values (值1, 值2,…)

枚举中的下标从1开始

  • 部分插入
    insert into 表名(列1,列2,…)values(值1,值2,…);

insert into students (name,gender) values (“小乔”,2)

insert into students values(全部值);

  • 修改
    udpate 表名 set 列1 = 值1,列2 = 值2… where 条件;

update students set age=22,gender=1 where id=3;

  • 删除
    物理删除
    delete from 表名 where 条件

逻辑删除

用一个字段来表示,这条信息是否已经不能再使用了。

给student表添加一个is_delete字段 bit 类型。

alter table stdents add is_delete bit default 0;

update students set is_delete=1 where id=6;

  • 查询的基本使用
    查询所有列表:

select * from 表明;

一定条件查询:

select * from students where id>3;

查询指定序列:

select 列1,列2,列3,…from 表名;

可以使用as为列或表指定别名

select 字段 as 别名,gender as 性别 from students;

字段的顺序:

select id as 序号, genter as 性别, name as 性别 from students;

查询:

  • 查询所有字段:
    select * from 表名;

  • 查询指定字段:
    select 列1,列2,…from 表名;

  • 使用as给字段起别名
    select 字段 as 名字… from 表名;
    select 表名.字段… from 表名

  • 可以通过as给表起别名:
    select 别名.字段… from 表名 as 别名;

这样写是错误的:
select students.mame,students.age from students as s;

如果起了别名就要用

  • 消除重复行
    distinct 字段;

如:select distinct time from xxxx;

条件查询

比较运算符:

>

<

>=

<=

=

!=

select 字段 from 表名 where …

例如:
select * from students where age>18;

逻辑运算符:

  • and
    如:18岁到20岁之间的所有学生信息:
    select * from students where age>18 and age<20;

18岁以上的女性
select * from students where age>18 and gender=“女”;

  • or

如:18岁以上或者身高超过180以上:
select * from students where age>18 or high >180;

  • not

不在 18岁以上的女性

select * from students where not(age >18 and gender = “女”);

模糊查询

  • like

% 替换1个或者多个

_ 替换一个

例如:查询姓名中 以“小”开始的名字:
select * from students where name like “小%”;

带有“小”的名字:
select * from students where name like “%小%”;

  • rlike 正则

如:查询以周开始:

select * from students where name rlike “^周.*$”;

范围查询:

  • in(1,8,213)表示在一个非连续的范围内

查询 年龄为18,34的姓名:

select name,age from students where age in (18,34);

select name,age from students where age = 18 or age = 34;

  • not in 不非连续的范围之内

年龄不是为18,34的姓名:

select name,age from students where not in(18,34);

  • between…and…表示在一个连续的范围内

查询 年龄在18到34之间的信息:

select name,age from students where age between 18 and 34;

  • not between … and…表示不在一个连续的范围内

查询 年龄不在18到34之间的信息

select * from students where age not between 18 and 34;

select * from students where not age between 18 and 34;

  • 空判断
    判断 is null

非空 is not null

排序

  • order by 字段
  • asc从小到大排列,即升序。
  • desc从大到小排序,即降序。

查询年龄在18到34之间的男性,按照年龄从小到大排序:

select * from students where (age between 18 and 34) and gender = “男” order by age;

order by 默认从小到到大排

select * from students where (age between 18 and 34) and gender = “男” order by age asc;

查询年龄在18到34之间的女性,按照身高从高到低排序:

select * from students where (age between 18 and 34) and gender = “女” order by height desc;

  • order by 多个字段

查询年龄在18到34之间的女性,按照身高从高到低排序,如果身高相同的情况下按照年龄从小到大排序:

select * from students where (age between 18 and 34) and gender = “女” order by height desc ,id desc;

必须先判断order by 后边的第一个再判断后边的

按照年龄从小到大,身高从高到矮的排序:

select * from students order by age asc,height desc;

having是在先排序好的再寻找。

聚合函数

  • 总数
  • count

查询男性有多少人,女性有多少人:

select count(*) as 男性人数 from students where gender = “男”;

  • 最大值
  • max

查询最大年龄:

select max(age) from students
查询女性的最高身高:

select max(height) from students where gender = “女”;

  • 最小值:min

  • 求和:sum

  • 平均值:avg

  • 四舍五入 :round(结果 , 1) 保留一位小数

计算所有人的平均年龄,保留2位小数

select round(sum(age)/count(*),2) from students;

分组

  • gruop by

按照性别分组,查询所有的性别:

select gender from students gruop by gender;

计算每种性别中的人数:

select gender,count(*) from students group by gender;

count()函数是对分组后进行处理。

计算男性的人数:

select gender,count(*) from students where gender =1 group by gender;

  • group_concat(…)

查询同种性别中的姓名:

select gender,group_concat(name,"_",age,"",id) from students where gender = 1 group by gender;

因为在group_concat()函数里面数字结果会连在一起。

分页:

  • limit start,count

限制查询出来的数据个数:

select * from students where gender = 1 limit 2;

查询前五个数:

select * from students limit 0,5;

每页显示2个,第3个页面:

select * from students limit 4,2;

规律:

limit(第n页-1)*每个的个数,每页的个数;

每页显示2个,显示第6页的信息,按年龄从小到大排序:

select * from students where gender = 2 other by height desc limit 10,2;

连接查询

  • 内连接查询:查询的结果为两个表匹配到的数据。

  • inner join … on

  • select … from 表A inner join 表B;

select * from students inner join classes;

查询有能够对应班级的学生以及班级:

select * from students inner join classes on students.cls_id=classes.id;

按要求显示姓名,班级:

select students.*,classes.name from students inner join classes on students.cls_id=classes.id;

给表起名字:

select s.name,c.name from students as s inner join classes as c on s.cls_id=c.id;

select c.xxx,s.xxx from students as s inner join classes as c on … order by …;

当同一个班级的时候,按照学生的id进行从小到大排序:

select c.name,s.* from students as s inner join classes as c on s.cls_id=c.id order by s.id;

  • 左连接查询:查询的结果为两个表匹配到的数据。
  • left join

查询每位学生对应的班级信息

select * from students as s left join classes as c on s.cls_id=c.id;

  • 右连接查询:查询的结果为两个表匹配的数据。

自关联

查询出山东省有哪些市:

select * from areas as provice inner join areas as city on city.pid=provice.aid
having province.title=“山东省”;

三范式

目前有迹可寻的共有八种范式,一般需要遵守3范式即可。

  • 第一范式:强调的是列的原子性,即列不能够再分成其他几列。
  • 第二范式:首先是第一范式,另外包含两部分,一是表必须有一个主键;二是没有包含在主键中的列必须完全依赖与主键,而不能只依赖于主键的一部分。
  • 第三范式:首先是第二范式,另外非主键列必须直接依赖于主键,不能存在传递依赖,即不能存在;非主键列A依赖于非主键列B,非主键列B依赖于主键的情况。

外键的约束:对数据的有效性进行验证。

  • 关键字:foreign kry,只有innodb数据库引擎支持外键约束。
  • 对于已经存在的数据表如何更新外键的约束:
  • reference:引用后边的内容。

alter table goods add foreign key (cate_id) reference goods_cates(id);

尽量不要使用外键,这样会大大降低性能。

用python操作MySQL数据库:

开始,创建connection,获取cursor,(执行查询,执行命令,获取数据,处理数据),关闭cursor,关闭connection,结束

  • fetchone():每次只取出一个
  • fetchmany(n):n为取出的个数
  • fetchall():取出所有

查询一行数据

from pymysql import *
# 创建Connect连接
coon = connect(host='local host',port=3306,user='root',password='mysql',database='jing_dong')
# 获得Cursor对象
cs1 =conn.cursor()
# 执行select语句,并返回受影响的行数,查询一条数据
count = cs1.execute('select id,name from goods where id>=4')
# 打印受影响的行数
print("查询到的%d条数据:" % count)

for i in range(count):
# 获取查询的结果
    result = cs1.fetchone()
#打印结果
    print(result)

关闭Cursor对象
cs1.close()
conn.close()

if __name__ == "__main__":
    main()

模拟京东

from pymysql import connect


class JD(object):
    def __init__(self):
        # 创建Connection连接
        self.conn = connect(host='localhost', port=3306, user='root', password='mysql', database='jing_dong', charset='utf8')
        # 获得Cursor对象
        self.cursor = self.conn.cursor()

    def __del__(self):
        # 关闭Cursor对象
        self.cursor.close()
        self.conn.close()

    def execute_sql(self, sql):
        self.cursor.execute(sql)
        for temp in self.cursor.fetchone():
            print(temp)

    def show_all_items(self):
        """显示所有的商品"""
        sql = "select * from goods;"
        self.execute_sql(sql)

    def show_cates(self):
        sql = "select name from goods_cates;"
        self.execute_sql(sql)

    def show_brands(self):
        sql = "select name from goods_brands;"
        self.execute_sql(sql)

    def add_brands(self):
        item_name = input("输入新商品分类的名称")
        sql = """insert into goods_brands (name) values("%s")""" % item_name
        self.cursor.execute(sql)
        self.conn.commit()

    def get_info_by_name(self):
        find_name = input("请输入要查询的商品的名字")
        # sql = """select * from goods where name='%s';""" % find_name
        # self.execute_sql(sql)
        sql = "select * from goods where name=%s"
        self.cursor.execute(sql, [find_name])
        print(self.cursor.fetchall())

    @staticmethod
    def print_menu():
        print("---京东----")
        print("1: 所有商品")
        print("2: 所有的商品分类")
        print("3: 所有的商品品牌分来")
        print("4: 添加一个商品分类")
        print("5: 根据名字查询一个商品")
        return input("请输入功能对应的序号:")

    def run(self):
        while True:
            num = self.print_menu()
            if num == "1":
                # 查询所有商品
                self.show_all_items()
            elif num == "2":
                # 查询分类
                self.show_cates()
            elif num == "3":
                # 查询品牌分类
                self.show_brands()
            elif num == "4":
                # 添加商品分类
                self.add_brands()
            elif num == "5":
                # 根据名字查询商品
                self.get_info_by_name()
            else:
                print("输入有误,重新输入...")


def main():
    # 1.创建一分京东商城对象
    jd = JD()

    # 2.调用这个对象的run方法,让其运行
    jd.run()


if __name__ == '__main__':
    main()

视图

  • 通俗的讲视图就是一条SELECT语句执行后返回的结果集,所以我们在创建视图的时候,主要的工作就落在创建这条SELECT查询语句上。

  • 视图是对若干张基本表的引用,一张虚表,查询语句执行的结果,不存储具体的数据(数据表数据发生了改变,视图也会跟着改变)

  • 提高了重用性,就像一个函数。

  • 对数据库重构,却不影响程序的运行。

  • 提高了安全性能,可以对不同的用户

  • 让数据更加清晰。

create view 想要起的名字 as 想要查询的结果。

将刚刚查询的结果,只作为一张虚拟表,这就是视图。

事务

  • 开启事务,变更会维护到本地缓存中:
    begin 或者 start transaction;

  • 提交事务,将缓存中的数据变更维护到物理表中:
    commit

回滚事务:

  • 放弃缓存中变更的数据:
    rollback;

索引:

  • 开启运行时间监测:

set profiling=1;

  • 查看运行的时间:

show profiling;

  • 查看索引:
    show index from 表名;

  • 创建索引:
    如果指定的字段是字符串,需要指定长度,建议长度与定义字段时的长度一致。

字段类型如果不是字符串,可以不用填写长度部分

create index 索引名称 on 表明(字段名称(长度));

  • 删除索引:
    drop index 索引名称 on 表名;

这里需要特别注意的是,执行完excute那一行语句以后,一定一定要记得写commit语句,不然的话,数据库插入操作是不会成功的!!!

如:cursor.connection.commit();
y

创建账户&授权

grant 权限列表 on 数据库 to ‘用户名’@‘访问主机’ identified by ‘密码’;
示例1

创建一个laowang帐号,密码为123456,只能通过本地访问,并且只能对jing_dong数据库中的所有表进行读操作
step1:使用root登录

回车后写密码,然后回车

step2:创建账户并授予所有权限

grant select on jing_dong.* to 'laowang'@'localhost' identified by '123456';

说明

  • 可以操作Python数据库的所有表,方式为:jing_dong.*
  • 访问主机通常使用百分号%表示此账户可以使用任何ip的主机登录访问此数据库
  • 访问主机可以设置成localhost或具体的ip,表示只允许本机或特定主机访问
  • 查看用户有哪些权限
show grants for laowang@localhost;

step3:退出登录
quit

刷新权限
flush privileges
修改密码

使用root登录,修改mysql数据库的user表

  • 使用password()函数进行密码加密
update user set authentication_string=password('新密码') where user='用户名'
例:
update user set authentication_string=password('123') where user='laowang';
  • 注意修改完成后需要刷新权限
刷新权限:flush privileges
删除账户
  • 语法1:使用root登录
drop user '用户名'@'主机';
例:
drop user 'laowang'@'%';
  • 语法2:使用root登录,删除mysql数据库的user表中数据
delete from user where user='用户名';
例:
delete from user where user='laowang';

—— 操作结束之后需要刷新权限
flush privileges
  • 推荐使用语法1删除用户,如果使用语法1删除失败,采用语法2方式
mysql主从
  • 读写分类
  • 数据备份
  • 负载均衡

备份
运行mysqldump命令

mysqldump -uroot -p 数据库名 > python.sql
# 按提示输入mysql的密码

恢复

  • 连接mysql,创建新的数据库
  • 退出连接,执行如下命令
mysql -uroot -p 新数据库名 < python.sql
# 根据提示输入mysql密码

在主服务器Ubuntu上进行备份,执行命令:

mysqldump -uroot -pmysql --all-databases --lock-all-tables > ~/master_db.sql

说明

  • -u:用户名
  • -p:示密码
  • –all-databases:导出所有数据库
  • –lock-all-tables:执行操作时锁住所有表,防止操作时有数据修改
  • ~-master_db.sql:导出的备份数据(sql文件)位置,可自己指定
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值