数据库学习

  • Python相关:基础、函数、数据类型、面向对象、模块

  • 前端开发:HTML、css、JavaScript、jQuery、BootStrap【静态】

    • Java+前端、Python+前端、Go+前端...  ---》【动态】
      

直观:

  • 静态:写死,除非手动更新,否则永远长一个样
  • 动态页面:页面上的数据可以实时修改更新展示

1.初试网站

  • 默认编写的是静态的效果
  • 动态:需要用到web框架的功能
from flask import Flask,render_template

app = Flask(__name__)


@app.route('/index')
def index():
    users = ["舞阳君", "弄援军", "一课一得", "张皆兵"]

    # 1. 找到index.html的文件,读取所有的内容
    # 2. 找到内容中的`特殊的`占位符,将数据替换
    # 3. 将替换完成的字符串返回给用户的浏览器
    return render_template('index.html',title="中国联通",data_list=users)


if __name__ == "__main__":
    app.run()
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link rel="stylesheet" href="/static/plugins/bootstrap-3.4.1-dist/css/bootstrap.css">
    </head>
    <body>
        <nav class="navbar navbar-default">
            <div class="container">
              <div class="navbar-header">
                <a class="navbar-brand" href="#">
                    <img alt="Brand" width="20" height="20" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAB+0lEQVR4AcyYg5LkUBhG+1X2PdZGaW3btm3btm3bHttWrPomd1r/2Jn/VJ02TpxcH4CQ/dsuazWgzbIdrm9dZVd4pBz4zx2igTaFHrhvjneVXNHCSqIlFEjiwMyyyOBilRgGSqLNF1jnwNQdIvAt48C3IlBmHCiLQHC2zoHDu6zG1iXn6+y62ScxY9AODO6w0pvAqf23oSE4joOfH6OxfMoRnoGUm+de8wykbFt6wZtA07QwtNOqKh3ZbS3Wzz2F+1c/QJY0UCJ/J3kXWJfv7VhxCRRV1jGw7XI+gcO7rEFFRvdYxydwcPsVsC0bQdKScngt4iUTD4Fy/8p7PoHzRu1DclwmgmiqgUXjD3oTKHbAt869qdJ7l98jNTEblPTkXMwetpvnftA0LLHb4X8kiY9Kx6Q+W7wJtG0HR7fdrtYz+x7iya0vkEtUULIzCjC21wY+W/GYXusRH5kGytWTLxgEEhePPwhKYb7EK3BQuxWwTBuUkd3X8goUn6fMHLyTT+DCsQdAEXNzSMeVPAJHdF2DmH8poCREp3uwm7HsGq9J9q69iuunX6EgrwQVObjpBt8z6rdPfvE8kiiyhsvHnomrQx6BxYUyYiNS8f75H1w4/ISepDZLoDhNJ9cdNUquhRsv+6EP9oNH7Iff2A9g8h8CLt1gH0Qf9NMQAFnO60BJFQe0AAAAAElFTkSuQmCC">
                </a>
              </div>
            </div>
        </nav>

        <div class="container">
            <h3>{{title}}</h3>
            <table class="table table-bordered">
                <thead>
                  <tr>
                    <th>#</th>
                    <th>First Name</th>
                    <th>Last Name</th>
                    <th>Username</th>
                  </tr>
                </thead>
                <tbody>
                    {% for item in data_list %}
                        
                            1
                            {{item}}
                            Otto
                            @mdo
                        
                    {% endfor %}
                  <!-- <tr>
                    <th scope="row">2</th>
                    <td>Jacob</td>
                    <td>Thornton</td>
                    <td>@fat</td>
                  </tr>
                  <tr>
                    <th scope="row">3</th>
                    <td>Larry</td>
                    <td>the Bird</td>
                    <td>@twitter</td>
                  </tr> -->
                </tbody>
              </table>
        </div>

        <script src="/static/js/jquery-3.7.1.min.js"></script>
        <script src="/static/plugins/bootstrap-3.4.1-dist/js/bootstrap.js"></script>
    </body>
</html>
  • 数据库管理系统
MySQL(*)免费
Oracle/SQLServer/DB2/Access...

2. 今日概要

  1. MySQL安装 & 配置
  2. MySQL的启动 & 关闭
  3. 指令
  4. Python第三方模块

3. 安装 & 配置

  • 5.×
  • 8.×

3.1 下载/安装

https://downloads.mysql.com/archives/community

3.2 创建配置文件

[mysqld]

# port
port=3306

# set basedir to your installation path
basedir=C:\\Program Files\\mysql-8.0.31-winx64

# set datadir to the location of your data directory
datadir=F:\\MySQLData

3.3 初始化

  • 打开终端 & 以管理员的权限运行
  • 输入初始化的命令
"C:\Program Files\mysql-8.0.31-winx64\bin\mysqld.exe" --initialize-insecure

4. 启动&关闭MySQL

  • 临时启动—> 控制台运行(不建议)
    • …\mysqld.exe
  • 制作为Windows服务,来对服务进行关闭和开启

4.1 制作服务

"C:\Program Files\mysql-8.0.31-winx64\bin\mysqld.exe" --install mysql15963

4.2 启动服务

net start mysql15963

4.3 关闭服务

net stop mysql15963

4.4 链接测试

  • 自带工具
"C:\Program Files\mysql-8.0.31-winx64\bin\mysql.exe" -h 127.0.0.1 -P 3306 -u root -p 
  • 省略版(默认链接本地主机)
"C:\Program Files\mysql-8.0.31-winx64\bin\mysql.exe" -u root -p 
  • 极简版(需要将MySQL安装目录中的bin目录添加到系统环境变量)
mysql -u root -p 
  • 设置密码(8.*版本未生效),可使用图形管理设置
set password = password('root123');

4.5 查看已有的文件夹(数据库)

show databases;

4.6 退出(关闭连接)

exit;

4.7 忘记密码时如何处理

默认情况下,启动MySQL时,需要用户输入账户名、密码

修改MySQL配置,重新启动MySQL(无账号模式)
    - mysql -u root -p
    - 重新设置密码
    - 退出
在重新修改MySQL配置文件,重新启动MySQL(需要账号模式)
    - mysql -u root -p
    - 新密码
    1. 停止目前的MySQL服务
    2. 修改MySQL配置文件(以无账号模式启动)
    skip-grant-tables=1
    
    1. 重新启动MySQL

    2. 再次登录mysql

    3. 执行命令设置密码

    - use mysql;
    
    - update user set authentication_string = password('root123'),password_last_changed=now() where user='root';
    
    1. 重新修改配置文件(需要账号的模式登录;需停止mysql服务)
      • 删除前面添加的无账号进入模式配置代码
    2. 重新启动MySQL

5. MySQL指令

MySQL 认知
数据库 文件夹
数据表 文件(Excel文件)

5.1 数据库管理

  • 查看已有的数据库
show databases;
  • 创建数据库
create database 数据库名称 DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
  • 删除数据库
drop database djangotest02;
  • 进入数据库
use 数据库名称;
  • 查看数据库中所有的数据表
show tables;

5.2 数据表管理

  • 创建表
create table 表名(
    列名称 类型,
    列名称 类型,
    ...
)default charset=utf8;
create table 表名(
    id int,
    name varchar(16) not null,  -- 不允许为空
    age int null,                -- 允许为空(默认)
)default charset=utf8;
create table 表名(
    id int,
    name varchar(16),
    age int default 3,                -- 插入数据是,age列的值默认是3(未传入值时)
)default charset=utf8;
  • 主键一般用于表示当前行的数据编号;类似于人的身份证
create table 表名(
    列名称 类型 primary key,        --主键(不允许为空,也不允许重复)
    列名称 类型,
    ...
)default charset=utf8;
create table 表名(
    列名称 类型 auto_increment primary key,    -- 自增的累加主键,内部维护
    列名称 类型,
    ...
)default charset=utf8;
  • 一般情况下,我们在创建表时都会这样写:【标准】
    create table 表名(
        id int not null auto_increment primary key,
        列名称 类型,
        ...
    )default charset=utf8;
    
DESC 表名;
  • 删除表
drop table 表名;
  • 修改列的类型
ALTER TABLE admin MODIFY password VARCHAR(64);
ALTER TABLE admin MODIFY mobile char(11);

5.3 常用数据类型

类型 说明
tinyint 整数;
有符号(有正 有负),取值范围:-128 ~ 127
无符号(只有正),取值范围:0 ~ 255【默认】
int 整数;
int 表示有符号,取值范围:-2147483648 ~ 2147483647
int unsigned 表示无符号,取值范围:0 ~ 4294967295
bigint 整数;
有符号,取值范围:-9223372036854775808 ~ 9223372036854775807
无符号,取值范围:0 ~ 18446744073709551615
float 小数;
double 小数;
decimal 高精度小数;查询速度快
m是数字总个数(负号不算),d是小数点后个数;m最大值为65,d最大值为30
char 定长字符串;
m代表字符串的长度,最多可容纳255个字符
varchar 变长字符串;更节省空间
m代表字符串的长度,最大65535字节/3 = 最大的m
text 字符串;
用于保存变长的大字符串,可以最多到65535(2**16 - 1)个字符;一般情况下,长文本会用text类型。例如:文章、新闻等
mediumtext 字符串;最长 16,777,215(2**24 - 1)
longtext 字符串;最长 4,294,967,295 or 4GB (2*32 -1)
datetime 时间;YYYY-MM-DD HH:MM:SS
date 时间;YYYY-MM-DD
create table tb3(
    id int not null auto_increment primary key,
    age tinyint unsigned   -- 无符号(有符号则去掉unsigned)
)default charset=utf8;
create table tb3(
    id int not null auto_increment primary key,
    salary decimal(8,2)    -- 总长度8位,小数点前6位,小数点后2位
)default charset=utf8;
create table tb4(
    id int not null auto_increment primary key,
    mobile char(11)            -- 固定使用11个字符进行存储,真实没有11个字符时也会按照11个字符存储
)default charset=utf8;
create table tb5(
    id int not null auto_increment primary key,
    mobile varchar(11)        --真实数据有多长,就按照多长存储(不能超过设定的值)
)default charset=utf8;
create table tb6(
    id int not null auto_increment primary key,
    title varchar(128),
    content text
)default charset=utf8;

练习

-- 创建表
create table tb2(
    id BIGINT not null auto_increment primary key,
    salary int,
  age tinyint
)default charset=utf8;

-- 插入数据
INSERT INTO tb2(salary, age) VALUES(10000,18);
INSERT INTO tb2(salary, age) VALUES(20000,28);
INSERT INTO tb2(salary, age) VALUES(30000,38),(40000,48);

-- 查看表中的数据内容
SELECT * FROM tb2;

案例:用户表

create table tb7(
    id int not null primary key auto_increment,
    username varchar(64) not null,
    password char(64) not null,
    email varchar(64) not null,
    age tinyint,
    salary decimal(10,2),
    ctime datetime
)


insert into tb7(name,username,password,email,age,salary,ctime) values("徐泽林", "123", "[email protected]", 19, 1000.20, "2011-11-11 11:11:10")
  • 平时开发系统时,一般情况下

    • 创建数据库
    • 创建表结果

    需要提前通过上述命令提前操作好

5.4 数据行操作

  1. 新增数据
insert into 表名(列名) values(值);
insert into 表名(列名,列名) values(值,值),(值,值),(值,值),(值,值);
  1. 删除数据
delete from 表名;
delete from 表名 where 条件;
DELETE FROM tb7 WHERE id = 3;
DELETE FROM tb7 WHERE id = 4 AND name = "徐泽林";
DELETE FROM tb7 WHERE id > 4;
DELETE FROM tb7 WHERE id != 4;
DELETE FROM tb7 WHERE id in (1,5);
  1. 修改数据
update 表名 set 列名称=值;
update 表名 set 列名称=值,列=值;
update 表名 set 列名称=值 where 条件;
UPDATE tb7 SET password="哈哈哈";
UPDATE tb7 SET email="哈哈哈" WHERE id > 5;

UPDATE tb7 SET age=age+10 WHERE id > 5;
  1. 查询数据
SELECT * FROM 表名称;
SELECT 列名称,列名称 FROM 表名称;
SELECT 列名称,列名称 FROM 表名称 WHERE 条件;
SELECT * FROM tb7;
SELECT username,age FROM tb7;
SELECT * FROM tb7 WHERE id > 3;
SELECT id,username FROM tb7 WHERE username = "阿九筒" and age = 29;

案例:员工管理

  • 使用MySQL内置工具
    • 创建数据库 unicom
    • 创建一张数据表 admin
      • 表名:admin
        • ID;整型;自增;主键;
        • username;字符串;不允许为空;
        • password;字符串;不为空
        • mobile;字符串;不允许为空
CREATE DATABASE unicom DEFAULT CHARSET utf8 COLLATE utf8_general_ci;

USE unicom;

SHOW TABLES;
DESC admin;

CREATE TABLE admin(
    id INT NOT NULL PRIMARY KEY auto_increment,
    username VARCHAR(16) NOT NULL,
    password VARCHAR(16) NOT NULL,
    mobile VARCHAR(16) NOT NULL
)DEFAULT CHARSET=utf8;

SELECT * FROM admin;

ALTER TABLE admin MODIFY password VARCHAR(64) NOT NULL;
ALTER TABLE admin MODIFY mobile char(11) NOT NULL;
  • 用Python代码实现:
    • 添加用户
    • 删除用户
    • 查看用户
    • 更新用户

用Python代码连接MySQL数据库并发送指令

pip install pymysql
  1. 链接数据库并添加一条数据
import pymysql

# 1. 链接MySQL
conn = pymysql.connect(host='127.0.0.1',port=3306,user='root',password='root123',db='unicom',charset='utf8')
# 创建游标对象
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)

# 2. 发送指令
cursor.execute("insert into admin(username,password,mobile) values('徐泽林','123456','13100204183')")
conn.commit()

# 3. 关闭连接
cursor.close()
conn.close()
# 其他写法

sql = "insert into admin(username,password,mobile) values(%s,%s,%s)"
cursor.execute(sql, ["寒潮","root123","12345679801"])

sql = "insert into admin(username,password,mobile) values(%(n1)s,%(n2)s,%(n3)s)"
cursor.execute(sql, {"n1":"哈哈哈哈","n2":"root123","n3":"12345679801"})
  1. 输入内容动态添加到数据表
import pymysql


while True:
    username = input("要添加的用户名:")
    if username.upper() == 'Q':
        break
    pwd = input("要添加的密码:")
    phone_num = input("要添加的手朷号:")



    # 1. 链接MySQL
    conn = pymysql.connect(host='127.0.0.1',port=3306,user='root',password='root123',db='unicom',charset='utf8')
    # 创建游标对象
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)

    # 2. 发送指令(不能用字符串格式化做sql的拼接,有安全隐患,可能会被sql注入) ---> 正确做法如下:
    sql = "insert into admin(username,password,mobile) values(%s,%s,%s)"
    cursor.execute(sql, [username,pwd,phone_num])

    # sql = "insert into admin(username,password,mobile) values(%(n1)s,%(n2)s,%(n3)s)"
    # cursor.execute(sql, {"n1":"哈哈","n2":"root123","n3":"12345679801"})

    # 提交变更
    conn.commit()

    # 3. 关闭连接
    cursor.close()
    conn.close()
  1. 查询数据
import pymysql


# 1. 链接MySQL
conn = pymysql.connect(host='127.0.0.1',port=3306,user='root',password='root123',db='unicom',charset='utf8')
# 创建游标对象
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)


# 2. 执行查询命令
sql = "select * from admin where id > %s"
cursor.execute(sql, [6,])

# 获取返回值
data_list = cursor.fetchall()
for row_dict in data_list:
    print(row_dict)


# 3. 关闭连接
cursor.close()
conn.close()
cursor.fetchall() # 获取筛选后的所有数据;没有数据时,返回空字典
cursor.fetchone() # 获取筛选后的第一条数据;没有数据时,返回NONE
  1. 删除数据
import pymysql

# 1. 链接MySQL
conn = pymysql.connect(host='127.0.0.1',port=3306,user='root',password='root123',db='unicom',charset='utf8')
# 创建游标对象
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)

# 2. 执行查询命令
sql = "delete from admin where id = %s"
cursor.execute(sql, [6,])
conn.commit()

# 3. 关闭连接
cursor.close()
conn.close()
  1. 修改数据
import pymysql

# 1. 链接MySQL
conn = pymysql.connect(host='127.0.0.1',port=3306,user='root',password='root123',db='unicom',charset='utf8')
# 创建游标对象
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)

# 2. 执行查询命令
sql = "update admin set mobile = %s where id = %s"
cursor.execute(sql, ["18888888888",1,])
conn.commit()

# 3. 关闭连接
cursor.close()
conn.close()

5.5 小结

  • 在进行 增删改 时,一定要记得commit,不然数据库么有数据
cursor.execute(...)
conn.commit()
  • 查询 时不需要commit,执行fetchall() / fetchone()
cursor.execute(sql, [2,])

# 获取第一条数据;字典;无数据时返回NONE
v1 = cursor.fetchone()

# 获取所有数据;列表内套字典;无数据时返回空列表
v2 = cursor.fetchall()
  • 对于SQL语句不要用Python的字符串格式化进行拼接(会被SQL注入,一定要用execute+参数
sql = "select * from admin where id > %s"
cursor.execute(sql, [2,])

6. Flask+MySQL+前端

6.1 新增用户

from flask import Flask,render_template,request
import pymysql

app = Flask(__name__)


@app.route('/add/user', methods=['GET', 'POST'])
def add_user():
    if request.method == 'GET':
        return render_template('add_user.html')
    
    username = request.form.get("user")
    pwd = request.form.get("pwd")
    mobile = request.form.get("mobile")

    # 1. 连接MySQL
    conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='root123', database='unicom', charset='utf8')
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)

    # 2. 执行SQL
    sql = "insert into admin(username,password,mobile) values(%s,%s,%s)"
    cursor.execute(sql, [str(username),str(pwd),str(mobile)])
    conn.commit()

    # 3. 关闭连接
    cursor.close()
    conn.close()

    return "添加成功"

if __name__ == '__main__':
    app.run()
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>添加用户</title>
    </head>
    <body>
        <h1>添加用户</h1>
        <form method="post" action="/add/user">
            <input type="text" name="user" placeholder="请输入用户名">
            <input type="password" name="pwd" placeholder="请输入密码">
            <input type="number" name="mobile" placeholder="请输入手机号">
            <input type="submit" value="提交">
        </form>
    </body>
</html>

6.2 查询用户

from flask import Flask,render_template,request
import pymysql

app = Flask(__name__)

@app.route('/get/user', methods=['GET', 'POST'])
def get_user():

    # 1. 连接MySQL
    conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='root123', database='unicom', charset='utf8')
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)

    # 2. 执行SQL
    sql = "select * from admin"
    cursor.execute(sql)
    data_list = cursor.fetchall()

    # 3. 关闭连接
    cursor.close()
    conn.close()

    print(data_list)

    return render_template('get_user.html', data_list=data_list)

if __name__ == '__main__':
    app.run()
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>添加用户</title>
    </head>
    <body>
        <h1>用户列表</h1>
        <table border="1px">
            <thead>
                <tr>
                    <th>ID</th>
                    <th>姓名</th>
                    <th>密码</th>
                    <th>手机号</th>
                </tr>
            </thead>
            <tbody>
                {% for item in data_list %}
                    
                        {{ item.id }}
                        {{ item.username }}
                        {{ item.password }}
                        {{ item.mobile }}
                    
                {% endfor %}
            </tbody>
        </table>
        
    </body>
</html>

评论