加载中...

Mysql基础

安装

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

初始化

1
2
"D:安装目录\bin\mysqld.exe" --initialize-insecure
#会创建一个初始化root账户(无密码)

配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
在安装目录创建my.ini
内容:
[mysqld]

# port 端口
port = 3306

#set basedir to your installation path安装目录
basedir = D:\\EXE\\mysql-5.7.31-winx64

#set datadir tO the location 0 f your data directory创建的文件目录
datadir = D:\\EXE\\mysql-5.7.31-winx64\\data

#非严格模式
#sql_mode=STRICT_TRANS_TABLES,NO_ZERO_in_date,NO_zero_date,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_user,NO_ENGINE_SUBSTITUTION

一些命令

1
2
3
show variables like '%time_zone%'; -- 查询当前数据库的时区

set time_zone ='0:00'; -- 改时区

启动Mysql

  • 临时启动
1
"安装目录\bin\mysqld.exe"
  • 制作成windous服务
1
2
3
4
5
6
7
8
"安装目录\bin\mysqld.exe" --install 名称可自定义
启动:
net start 名字
关闭
net stop 名字

删除服务
"安装目录"\bin\mysqld.exe" --remove 名字
  • 使用命令行连接Mysql
1
"安装目录"\bin\mysqld.exe" -h ip地址 -P 端口 -u 用户名 -p 密码
  • 设置密码
1
mysql> set password = password("root123");
  • 忘记密码
1
2
3
4
5
6
7
8
在配置文件中[mysqld节点下添加]
skip-grant-tables=1

让后重启mysql,就不用密码就可用登录了

设置密码
use mysql;
update user set authentication_string = password("新密码"),password_last_changed=now() where user ='root';

image-20230729101118772

数据库操作

  • 查看当前所有数据库: show databases;

  • 创建数据库:create database 数据库名 DEFAULT CHARSET utf8 COLLATE utf8_general_ci;

  • 删除数据库:drop database 数据库名;

  • 进入数据库: use 数据库;

数据表操作

  • 查看当前数据库下的所有数据表show tables;
  • 创建表结构
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
create table 表名(
列名 类型,
列名 类型,
列名 类型 -- 一定要记住最后一个不用加","号
) default charset=utf8;

-- 例子
create table tb1(
id int,
name varchar(16),
) default charset=utf8;

-- 定义规则
create table tb1(
userid int primary key, -- 主键 (不能为空,不能重复)
id int not null,-- 不允许为空
name varchar(16) null,-- 允许为空(默认)
age int default 3, -- 插入数据时,如果不给age值则默认为3
nbid int auto_increment primary key -- 不允许为空&主键&自增
) default charset=utf8;

-- 一个表中只能有一个自增列,一般都是主键
  • 删除表drop table 表名;
  • 清空表delete from 表名;truncate table 表名;(速度快,但无法回滚撤销等)

修改表(列操作)

  • 查看所有列: desc 表名

  • 添加列

    1
    2
    3
    4
    5
    6
    7
    8
    alter table 表名 add 列表 类型;
    alter table 表名 add 列表 类型 DEFAULT 默认值;
    alter table 表名 add 列表 类型 not null default 默认值;
    alter table 表名 add 列表 类型 not null auto_increment primary key;


    alter table 表名 add column 列名 char(1) not null default '男' check (列名 in ('男', '女'));
    -- 使用CHECK关键字可以添加约束,确保这个列的取值仅能为'男'或'女'
  • 删除列

    1
    alter table 表名 drop column 列名;
  • 修改列类型

    1
    alter table 表名 modify column 列名 类型;
  • 修改列 类型—+名称

    1
    alter table 表名 change 原列名 新列名 新类型 (后面一样可用更规则);
  • 修改列 默认值

    1
    ALTER TABLE 表名 ALTER 列名 SET DEFAULT 1000;
  • 删除列 默认值

    1
    ALTER TABLE 表名 ALTER 列名 DROP DEFAULT;

常见列类型

1
2
3
4
int[(m)][unsigned][zerofill]
int -- 表示有符号,取值范围:int的最小范围到最大范围
int unsigned -- 无符号 ,取值范围: 0~4294967295
int(5)zerofill -- 仅用于显示,当不满足5位时,按照左边补0,列如:00002;满足时,正常显示

数据操作/数据类型

  • 整数
1
2
3
4
-- 在表中添加数据
insert into 表名(列名,列名) values(数据,数据);
-- 查看表中的数据
select 列名(可用通配符比如*代表这个表中的所有数据) from 表名;
1
2
3
tinyint[(m)] [unsigned] [zerofill]
有符号,取值范围:-128 ~127
无符号 : 0~255
1
2
3
bigint[(m)][(unsigned)] [(zerofill)]
有符号: -2^63 (-9223372036854775808) 到 2^63-1 (9223372036854775807)
无符号:0到18446744073709551615
1
2
3
4
5
6
mediumint
-- 一个中等大小整数,有符号的范围是-8388608到8388607,无符号的范围是0到16777215。 一位大小为3个字节


smallint
-- 一个小整数。有符号的范围是-2^15 (-32,768) 到 2^15 - 1 (32,767) 的整型数据,无符号的范围是0到65535。一位大小为 2 个字节
  • 小数
1
2
3
4
5
6
7
decimal[(m,d)] [unsigned] [zerofill]
-- 在MySQL中,Decimal类型是一种数值类型,用于表示精确的十进制数。它通常用于存储要求高精度的和精确度的的小数,例如货币、积分等。
-- 在MySQL中,Decimal类型的可以表示很大的数值范围,具体取决于其精度和刻度。精度表示总位数,刻度表示小数点后的位数。
decimal(m,d) -- m表示整数位数 d表示小数点后的个数(m最大值=65,d最大值=30)
-- 需要注意的是,虽然Decimal类型的表示范围很大,但在实际使用时,应根据具体需求选择合适的精度和刻度,以避免数据溢出或精度损失的问题。

-- 如果超出了小数的精度,则数据库会对其作四舍五入
1
2
3
4
FLOAT [(M,D)] [UNSIGNED] [ZEROFILL]
-- 单精度浮点小数,非准确小数值,m是数字总个数,d是小数点后个数
DOUBLE [(M,D)] [UNSIGNED] [ZEROFILL]
-- 双精度浮点小数,非准确小数值,m是数字总个数,d是小数点后个数
  • 字符类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
  char(m) -- m代表字符串的长度,最多可容纳255【字符】(即使数据小于m的长度也会占用m个字符数,并且在存储的时候空的位置默认用空格补齐,但查询数据的时候会去除,如果不想去除在配置文件中的sql-mod中加入 PAD_CHAR_TO_FULL_LENGTH)
-- 查看模式sql-mod: show variables like 'sql_mode';
-- 一般用于固定长度的内容


varchar(m) -- m代表字符串的最大长度,最多可容纳65535个【字节】
-- 当内容小于m时会按照真实长度存储;如果超出(严格模式下会报错)非严格模式会截断

TINYTEXT:-- 非常小的文本类型,最大长度为255个字符。

TEXT:-- 文本类型,最大长度为65535个字符。

MEDIUMTEXT:-- 中等大小的文本类型,最大长度为16777215个字符。

LONGTEXT:-- 非常大的文本类型,最大长度为4294967295个字符。

BLOB:-- 二进制大对象类型,用于存储二进制数据,最大长度为65535个字节。

TINYBLOB:-- 非常小的二进制大对象类型,最大长度为255个字节。

MEDIUMBLOB: -- 中等大小的二进制大对象类型,最大长度为16777215个字节。

LONGBLOB:-- 非常大的二进制大对象类型,最大长度为4294967295个字节。


  • 时间
1
2
3
4
5
6
7
8
9
10
date:仅存储日期,格式为'YYYY-MM-DD'。-- '1000-01-01'到'9999-12-31',共9888天。

time:仅存储时间,格式为'HH:MM:SS'。-- '00:00:00'到'23:59:59',共838859秒。

datetime:存储日期和时间,格式为'YYYY-MM-DD HH:MM:SS'。-- '1000-01-01 00:00:00'到'9999-12-31 23:59:59',共3153583767分钟。--(不做任何改变,输入的啥输出就是啥)

timestamp:存储日期和时间,格式与DATETIME相同,但时间值以秒为单位存储,范围从'1970-01-01
00:00:01'到'2038-01-19 03:14:07' -- (会将用户输入的时间从当前时区转换成utc时间,查询时将其又转化为客户端当前的时区进行返回)

year:仅存储年份,可以使用2位('YY')或4位('YYYY')格式。--

数据行操作

  • 新增数据
1
2
3
4
5
insert into 表名 (列名,列名,列名) values(对应列的值,对应列的值,对应列的值)
-- 新增多条
insert into 表名 (列名,列名) values(值,值),(值,值);
-- 可不指定列名(默认从第一列向后添加)【必须要有与值对应数量的列】
insert into 表名 values(值,值),(值,值);
  • 删除数据
    1
    2
    3
    4
    5
    6
    7
    8
    9
    delete from 表名;
    delete from 表名 where 条件;
    -- 比如:
    delete from tb1 where name="jxms" and password ="123";
    delete from tb1 where name="jxms" or password ="123";
    delete from tb1 where id>9;

    -- 删除数据并重置自增id
    truncate table 表名;
  • 修改数据
    1
    2
    3
    4
    5
    6
    7
    8
    update 表名 set 列名=值;
    update 表名 set 列名=值 where 条件
    -- 比如:
    update tb1 set name="jxsm" where id=1;
    -- concat是一个函数,可以拼接字符串(name为数据库中的name)
    update users set name=concat(name,"123") where id=2;
    -- 可以用自身数据相加(age必须为整形)
    update tb1 set age=age+1;
  • 查询数据
    1
    2
    3
    4
    5
    6
    7
    8
    select * from 表名;
    select 列名 列名 列名 from 表名;
    select 列名,列名 as 别名,列名 from 表名; -- 别名是让最后的结果的表头变成别名
    select * from 表名 where 条件;

    -- 比如
    select * from tb1 where id !=1;
    select name,id,111 from tb1; -- 查询的时候会新曾一列,默认值为111

Python方面

  • 安装pymysql : pip install pymysql

连接数据库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import pymysql
#连接数据库
#连接信息 db参数可不加表示默认自动进入db这个数据库
conn = pymysql.connect(host='127.0.0.1',port=3306,user='root',passwd='jxsm',charset="utf8",db="数据库名")
#创建游标
cursor = conn.cursor()

#发送命令
cursor.execute("show databases")
#获取命令输出结果
result = cursor.fetchall()
print (result)


#创建数据库
cursor.execute( 'create database 数据库名 DEFAULT CHARSET utf8 COLLATE utf8_general_ci')
#必须要有才能执行(增删改查都是)
conn.commit()

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

数据操作

查询数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import pymysql
#连接数据库 #并默认进入到temp中
conn = pymysql.connect(host='127.0.0.1', port=3306,user='root',passwd='jxsm',charset="utf8" ,db="temp")
#创建游标,之后通过游标进行操作
cursor = conn.cursor()

#发送命令
# cursor.execute("insert into temp (name,age) values('jxsm',12)")
#查询数据
cursor.execute("select * from temp where id=2")
#获取命令输出结果
result = cursor.fetchall() #或 result = cursor.fetchone
#fetchone()`每次调用只获取一行数据,因此如果需要获取整个结果集,则需要调用多次。
#而fetchall()函数则用于获取查询结果集中的所有行数据,返回一个包含元组的列表。如果结果集太大,可能会消耗大量内存,因此需要谨慎使用。
print (result,type(result))
  • 储存案例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    def writeIn(username: str, password: str):  
    # 连接数据库
    conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='jxsm', charset='utf8', db='userdb')
    # 创建游标
    cursor = conn.cursor()

    # 存储数据
    cursor.execute(f"INSERT INTO `user` (`name`, `password`) VALUES ('{username}', '{password}')")
    # 提交更改
    conn.commit()

    # 打印返回结果
    result = cursor.fetchall()
    print(result)

    # 断开连接
    cursor.close()
    conn.close()
  • 查询案例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    def query(name: str, password: str) -> bool:  
    # 连接数据库
    conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='jxsm', charset='utf8', db='userdb')
    # 创建游标
    cursor = conn.cursor()
    # 发送查询命令
    cursor.execute(f"select name, password from user where name=%s and password=%s", (name, password))
    # 获取返回结果
    result = cursor.fetchall()
    if result is None or cursor.rowcount == 0:
    cursor.close()
    conn.close()
    return False
    else:
    if result[0] == name:
    if result[1] == password:
    cursor.close()
    conn.close()
    return True
    else:
    cursor.close()
    conn.close()
    return False
    else :
    cursor.close()
    conn.close()
    return False

    时间计算

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #获取时间差秒
    import datetime

    # 创建一个datetime对象
    dt = datetime.datetime(2023, 3, 14, 12, 0, 0)

    # 计算时间差
    td = dt - datetime.datetime.now()

    # 获取剩余的时间秒数
    remaining_seconds = td.total_seconds()

    print("剩余的时间秒数:", remaining_seconds)

防注入

1
2
3
4
#在sql命令拼接的时候用pymysql自带的方法,通过占位符来实现与列表或元组实现
cursor.execute("select name, password from user where name=%s and password=%s", (name, password))
#当让也可以使用字典实现
cursor.execute("select name, password from user where name=%(n1)s and password=%(n2)s", {n1:name,n2:password})

一些常用的命令

1
2
3
4
5
#获取返回结果的行数
游标名.rowcount
#获取当前时间 使用datetime
import datetime
print(datetime.datetime.now())