Python开发-039_关系型数据库MySQL概述
在学习Python的过程中,已经很多次的和数据存储打交道,那时候的做法是将数据随意的存储到某个文件中,数据格式完全取决于我们自己,但是这样很可能导致每个人存储数据的格式不同位置不同导致无法公用
后来我们学到了软件目录规范,严格限制了存储数据的位置,却没能解决公用的问题,并且此方案只能本地使用,不方便联网
bin 启动文件
conf 配置文件
lib 公共方法
core 业务逻辑
db 存储所有的数据
log 日志
如果要联网,我们就需要在网络中找到一台服务器进行数据库的统一存储,所有用户都使用一台服务器存储,并且为他们限制某种统一标准,让每个人都能按照此标准存取数据
1 数据库的概述
数据库软件在此基础上应运而生,数据库软件本质其实就是一个能够进行网络通信并且有某种固定标准存储数据的应用程序
1.1 数据库软件分类
数据库根据存储方式的不同,分为关系型数据库和非关系型数据库
1.1.1 关系型数据库
关系型数据库的数据之间彼此有关系或者约束,存储数据库的表现形式通常是以表格存储,并且能够对存储数据进行限制,主要用于存储具体的业务数据
Mysql、oracle、db2、access、sqlserver
1.1.2 非关系型数据库
非关系型数据库存储通常是以k,v
键值对形式,主要用于缓存,减轻关系型数据库压力
2 Mysql数据库
mysql数据库是一个开源的数据库软件,因此他在市场的占有率很高,我们也能够很便捷的进行分析学习
2.1 Mysql数据库的安装
tips:在业务环节,一般都不会轻易使用最新版本的软件,因为新版本可能会出现各种问题
2.1.1 windows安装mysql
官网:https://mysql.com
开源版本下载:https://dev.mysql.com/downloads/
下载[MySQL Community Downloads](https://dev.mysql.com/downloads/)社区版本,选择更多版本,下载5.6.7版本(5.x版本较为经典,不过其他版本也可以)
如果下载的是文件版本,会直接将服务端和客户端都下载下来
服务端
bin/mysqld.exe
客户端
bin/mysql.exe
在命令行启动,在前期配置mysql的时候,终端尽量管理员运行
2.1.2 Linux系统安装mariadb
在mysql被甲骨文收购之后,mysql创始人Michael Widenius作为一个资深老六,又搞出来了一个和mysql几乎百分之百相同的数据库软件mariadb进行全免费开源,在linux平台,我们使用它进行学习
0. 安装 yum install mariadb-server
1. 启动命令 systemctl start mariadb
2. 重启命令 systemctl restart mariadb
3. 关闭命令 systemctl stop mariadb
4. 开机自起 systemctl enable mariadb
5. 关闭自起 systemctl disable mariadb
6. 进入数据库(首次进入密码为空,直接回车即可) mysql -uroot -p
2.2 数据库连接
Mysql中的sql语句是以分号作为结束的标志
无论mysql还是mariadb都可以使用mysql客户端进行连接
# mariadb同样也是使用mysql作为服务端连接命令
mysql -h 127.0.0.1 -P 3306 -uroot -p
# 连接本地 默认端口 root用户 可以简写为
mysql -uroot -p
游客模式连接(超低权限)
# bash命令行直接执行mysql 即可进入游客模式
2.3 数据库的基础命令
前文提到过,数据库就是一个支持socket通信支持存取数据的应用软件
服务端(Mysqld mariadb)
-支持socket通信
-支持数据存储
客户端
-Mysql客户端
-任意支持socket通信并且能够兼容SQL语句的平台都能作为客户端
2.3.1 查看数据库列表
下图可以看到每个数据库对应着一个文件夹
information_schema库为mysql5.0之后诞生,它是保存着关于MySQL服务器所维护的所有其他数据库的信息,如数据库名,数据库的表,表栏的数据类型与访问权,他存储于内存中所以在文件中看不到它
MariaDB [(none)]> show databases; # 查看数据库列表
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
4 rows in set (0.01 sec)
2.3.2 查看数据表列表
每个数据表也对应一个文件
MariaDB [(none)]> use mysql # 进入mysql数据库
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
MariaDB [mysql]> show tables; # 查看mysql数据库 数据表
+---------------------------+
| Tables_in_mysql |
+---------------------------+
| columns_priv |
| db |
| event |
| func |
| general_log |
| help_category |
| help_keyword |
| help_relation |
| help_topic |
| host |
| ndb_binlog_index |
| plugin |
| proc |
| procs_priv |
| proxies_priv |
| servers |
| slow_log |
| tables_priv |
| time_zone |
| time_zone_leap_second |
| time_zone_name |
| time_zone_transition |
| time_zone_transition_type |
| user |
+---------------------------+
24 rows in set (0.00 sec)
2.3.3 查看记录
记录就相当于是数据,在它内部会形成一个表格,类似于excel
select * from TABLES;
补充:
表头就是表格的第一行
字段就是表头的数据,对应每一列 例如name、password、hobby
2.3.4 取消命令执行
当输入命令不对,可以在语句后方加入\c
直接取消命令执行,不会返回报错
MariaDB [(none)]> admin\c
MariaDB [(none)]>
2.3.5 客户端退出
退出命令加不加分号都可以执行
MariaDB [(none)]> quit
MariaDB [(none)]> exit
2.3.5 服务端退出
Linux环境:
systemctl stop mariadb
windows环境:
查看进程
tasklist
查看具体某一进程(以mysqld为例)
tasklist | findstr mysqld
如何杀死进程(cmd窗口需要管理员模式)
taskkill \F \PID PID号
2.4 Mysql数据库配置
2.4.1 mysqld配置为系统服务
配置成系统服务的目的是为了windows自启动,linux可直接设置systemctl enable mariadb
查看当前计算机的运行进程
services.msc
也可以直接任务管理器找到服务
# 将mysql制作成系统服务
mysqld --install
# 将mysqld移除系统服务
mysqld --remove
将mysqld添加到系统服务后,打开services.msc,找到mysql,鼠标右键,属性,启动类型修改为自动,就完成了开机自启的设置
2.4.2 设置SQL密码
在终端输入
mysqladmin -uroot -p原密码 password 新密码
[root@bogon /]# mysqladmin -uroot -p password root
Enter password:输入原密码(原密码为空直接回车)
2.4.3 忘记SQL密码
可以将Mysql获取用户名和密码校验的功能看成一个装饰器,装饰在客户端请求访问的功能之上
如果将装饰器移除 那么mysql服务端就不会校验用户名和密码了
1 关闭当前mysql服务端
systemctl stop mariadb
2 maridb使用mysqld_safe 跳过授权表启动
[root@bogon ~]# mysqld_safe --skip-grant-tables
如果是windows,直接使用mysqld即可
mysqld --skip-grant-tables
3 就可以不用输入密码直接进了 输入密码那里直接回车
[root@bogon /]# mysql -uroot -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 1
Server version: 5.5.68-MariaDB MariaDB Server
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]>
4 修改当前用户的密码
# 在数据库客户端中修改密码其实就是修改mysql库下的user表的password字段
## password=password(123456) 数据库存储密码应该是密文 所以需要password(密码)进行加密
## 并且添加限制条件 where user='root' and host='localhost';
MariaDB [(none)]> update mysql.user set password=password(123456) where user='root' and host='localhost';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
5 立即将修改数据刷到硬盘
MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.00 sec)
6 关闭当前服务端 以正常校验数据表的模式启动
直接ctrl+c关闭服务
[root@bogon ~]# systemctl start mariadb
2.5 Mysql配置文件修改
2.5.1 修改编码
\s
命令 查看系统状态
MariaDB [(none)]> \s
--------------
mysql Ver 15.1 Distrib 5.5.68-MariaDB, for Linux (x86_64) using readline 5.1
Connection id: 3
Current database:
Current user: root@localhost
SSL: Not in use
Current pager: stdout
Using outfile: ''
Using delimiter: ;
Server: MariaDB
Server version: 5.5.68-MariaDB MariaDB Server
Protocol version: 10
Connection: Localhost via UNIX socket
Server characterset: latin1
Db characterset: latin1
Client characterset: utf8
Conn. characterset: utf8
UNIX socket: /var/lib/mysql/mysql.sock
Uptime: 2 min 26 sec
Threads: 1 Questions: 5 Slow queries: 0 Opens: 0 Flush tables: 2 Open tables: 26 Queries per second avg: 0.034
--------------
统一编码
Server characterset: latin1
Db characterset: latin1
Client characterset: utf8
Conn. characterset: utf8
在\s
中我们发现了编码不一致的问题,可能会导致乱码
2.5.1.1 配置文件地址
程序启动会先加载配置文件中的配置才真正启动
1、Windows下MySQL的配置文件是my.ini,在安装目录的根目录会有my-default.ini文件,需要根据他为模板自己创建
[mysqld] # 服务端一旦启动立即加载配置
[mysql] # 客户端一旦启动立即加载配置
[client] # 其他客户端
2、Linux下MySQL的配置文件是my.cnf,一般会放在/etc/my.cnf,具体的配置文件会放置在my.cnf.d文件夹下
[root@bogon my.cnf.d]# pwd
/etc/my.cnf.d
[root@bogon my.cnf.d]# ls -al
total 24
drwxr-xr-x. 2 root root 67 Nov 3 21:28 .
drwxr-xr-x. 139 root root 8192 Nov 3 21:27 ..
-rw-r--r--. 1 root root 295 May 6 2020 client.cnf
-rw-r--r--. 1 root root 232 May 6 2020 mysql-clients.cnf
-rw-r--r--. 1 root root 744 Nov 3 21:28 server.cnf
2.5.1.2 修改字符集
例如修改server为utf-8
1、windows字符集直接在my.ini文件中修改即可
[mysqld]
character-set-server=utf-8
collation-server=utf8_general_ci
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
2、Linux字符集需要在对应的配置文件中修改
[root@bogon my.cnf.d]# pwd
/etc/my.cnf.d
[root@bogon my.cnf.d]# ls
client.cnf mysql-clients.cnf server.cnf
[root@bogon my.cnf.d]# vim server.cnf
[mysqld]
default-storage-engine = innodb
innodb_file_per_table
max_connections = 4096
collation-server = utf8_general_ci
character-set-server = utf8
重启查看最新的字符集
[root@bogon my.cnf.d]# systemctl restart mariadb
[root@bogon my.cnf.d]# mysql -uroot -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 2
Server version: 5.5.68-MariaDB MariaDB Server
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> \s
--------------
mysql Ver 15.1 Distrib 5.5.68-MariaDB, for Linux (x86_64) using readline 5.1
Connection id: 2
Current database:
Current user: root@localhost
SSL: Not in use
Current pager: stdout
Using outfile: ''
Using delimiter: ;
Server: MariaDB
Server version: 5.5.68-MariaDB MariaDB Server
Protocol version: 10
Connection: Localhost via UNIX socket
Server characterset: utf8
Db characterset: utf8
Client characterset: utf8
Conn. characterset: utf8
UNIX socket: /var/lib/mysql/mysql.sock
Uptime: 39 sec
Threads: 1 Questions: 5 Slow queries: 0 Opens: 0 Flush tables: 2 Open tables: 26 Queries per second avg: 0.128
--------------
到此字符集全部修改为utf-8了
2.5.2 配置文件配置账号密码
通过修改配置文件达到客户端连接默认管理员登录
1、windows字符集直接在my.ini文件中修改即可
[mysql]
user='root'
password=123456
2、Linux客户端修改客户端配置文件mysql-clients.cnf
[root@bogon my.cnf.d]# vim mysql-clients.cnf
[mysql]
user="root"
password=123456
3、输入mysql直接以root用户登录了
[root@bogon my.cnf.d]# mysql
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 7
Server version: 5.5.68-MariaDB MariaDB Server
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]>
3 基本SQL语句
TIPS:大部分程序的业务逻辑都是增删改查
辛苦工作一个月,只是为了一条SQL语句,将自己账户的余额增加一点
3.1 针对库的增删改查
3.1.1 增-创建数据库
# create database 数据库名字;
MariaDB [(none)]> create database db1;
Query OK, 1 row affected (0.00 sec)
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| db1 |
| mysql |
| performance_schema |
| test |
+--------------------+
5 rows in set (0.00 sec)
# 可以在创建数据库时指定编码
MariaDB [(none)]> create database db2 charset='gbk';
Query OK, 1 row affected (0.00 sec)
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| db1 |
| db2 |
| mysql |
| performance_schema |
| test |
+--------------------+
6 rows in set (0.00 sec)
3.1.2 查-查询数据库
# 查询所有数据库
show databases;
# 查询某一个数据库
MariaDB [(none)]> show create database db2;
+----------+-------------------------------------------------------------+
| Database | Create Database |
+----------+-------------------------------------------------------------+
| db2 | CREATE DATABASE `db2` /*!40100 DEFAULT CHARACTER SET gbk */ |
+----------+-------------------------------------------------------------+
1 row in set (0.00 sec)
3.1.3 改-修改库的编码
# 将db2的编码修改为utf-8
MariaDB [(none)]> alter database db2 charset='utf8';
Query OK, 1 row affected (0.00 sec)
3.1.4 删-删除数据库
MariaDB [(none)]> drop database db2;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| db1 |
| mysql |
| performance_schema |
| test |
+--------------------+
5 rows in set (0.00 sec)
3.2 针对表的增删改查
在操作表的时候,需要先指定所在的库
# 查看当前所在的库名 在mariadb中命令行引导括号内就是库名
MariaDB [(none)]> select database();
+------------+
| database() |
+------------+
| NULL |
+------------+
1 row in set (0.00 sec)
# 切换库
MariaDB [(none)]> use db1;
Database changed
MariaDB [db1]>
操作其他数据库的数据表,可以使用数据库名.数据表名的形式
MariaDB [(none)]> show create table db1.t1;
3.2.1 增-创建数据表
# 创建一张表 两个字段 id字段内部存储整型 name字段内部存储字符型最多4个字符
MariaDB [db1]> create table t1(id int,name char(4));
Query OK, 0 rows affected (0.00 sec)
3.2.2 查-查看表的信息
# 查看当前库下所有的表名
MariaDB [db1]> show tables;
+---------------+
| Tables_in_db1 |
+---------------+
| t1 |
+---------------+
1 row in set (0.00 sec)
# 查看某一个表的信息
MariaDB [db1]> show create table t1;
+-------+---------------------------------------------------------------------------------------------------------------------+
| Table | Create Table
|
+-------+---------------------------------------------------------------------------------------------------------------------+
| t1 | CREATE TABLE `t1` (
`id` int(11) DEFAULT NULL,
`name` char(4) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+-------+---------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
# 查看表的描述信息
MariaDB [db1]> describe t1;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | char(4) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)
## 支持简写
desc t1;
3.2.3 改-修改数据表的配置
# 将表t1的name类型修改为字符串16个字符
MariaDB [db1]> alter table t1 modify name char(16);
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
MariaDB [db1]> describe t1;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | char(16) | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)
3.2.4 删-删除数据表
MariaDB [db1]> drop table t1;
Query OK, 0 rows affected (0.00 sec)
3.3 针对数据的增删改查
数据是建立在已经有库有表的基础之上 才能操作记录
MariaDB [db1]> create table t1(id int,name char(4));
Query OK, 0 rows affected (0.01 sec)
3.3.1 增-插入数据
# 插入t1表 (id,name) 以逗号分隔插入多条数据
MariaDB [db1]> insert into t1 values(1,'kinght'),(2,'AYM'),(3,'tank');
Query OK, 3 rows affected, 1 warning (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 1
# insert into 可以简写为 insert
3.3.2 查-查询数据
# select 查询 * 所有的通配符 from t1表
## 该命令数据量特别大的时候不建议使用
MariaDB [db1]> select * from t1;
+------+------+
| id | name |
+------+------+
| 1 | king |
| 2 | AYM |
| 3 | tank |
+------+------+
3 rows in set (0.00 sec)
# * 通配符可以换为具体的查询内容
MariaDB [(none)]> select name from db1.t1;
+------+
| name |
+------+
| king |
| AYM |
| tank |
+------+
3 rows in set (0.00 sec)
3.3.3 改-修改数据
# 修改t1表数据 将name字段内容改为DSB 只改id>2的
MariaDB [db1]> update t1 set name='DSB' where id > 2;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
MariaDB [db1]> select * from t1;
+------+------+
| id | name |
+------+------+
| 1 | king |
| 2 | AYM |
| 3 | DSB |
+------+------+
3 rows in set (0.00 sec)
3.3.4 删-删除数据
# 删除t1表中id等于3的行
MariaDB [db1]> delete from t1 where id = 3;
Query OK, 1 row affected (0.00 sec)
MariaDB [db1]> select * from t1;
+------+------+
| id | name |
+------+------+
| 1 | king |
| 2 | AYM |
+------+------+
2 rows in set (0.00 sec)
# 限制条件也可以是name
MariaDB [db1]> delete from t1 where name='king';
Query OK, 1 row affected (0.00 sec)
MariaDB [db1]> select * from t1;
+------+------+
| id | name |
+------+------+
| 2 | AYM |
+------+------+
1 row in set (0.00 sec)
# 清空表的所有数据
MariaDB [db1]> delete from t1;
Query OK, 1 row affected (0.00 sec)
MariaDB [db1]> select * from t1;
Empty set (0.00 sec)
4 存储引擎
日常生活中文件格式有很多种,并且针对不同的文件格式会有对应不同的存储方式和处理机制
txt\pdf\word\mp4\...
存储引擎就是不同的处理机制
4.1 Mysql主要存储引擎
1.innodb
Mysql5.5版本及之后的默认存储引擎
存储数据更加的安全
2.myisam
Mysql5.5版本之前的默认存储引擎
速度逼innodb更快 但是更加注重的是数据安全
3.memory
内存引擎
特点:数据全部存储在内存中 速度快 断电即数据丢失
4.blakhole
无论存储什么,都立刻消失
查看所有数据库所有的存储引擎
MariaDB [(none)]> show engines;
4.2 不同存储引擎的区别
不同的存储引擎在存储表的时候 异同点
# 创建测试数据库
MariaDB [(none)]> create database engine_demo;
MariaDB [(none)]> use engine_demo;
# 创建不同引擎的四张表
MariaDB [engine_demo]> create table t1(id int) engine=innodb;
MariaDB [engine_demo]> create table t2(id int) engine=myisam;
MariaDB [engine_demo]> create table t3(id int) engine=blackhole;
MariaDB [engine_demo]> create table t4(id int) engine=memory;
在文件存储的时候,他们也是有不一样的地方
[root@localhost engine_demo]# pwd
/var/lib/mysql/engine_demo
[root@localhost engine_demo]# ls -al
total 152
drwx------. 2 mysql mysql 118 Nov 5 16:25 .
drwxr-xr-x. 7 mysql mysql 207 Nov 5 16:25 ..
-rw-rw----. 1 mysql mysql 61 Nov 5 16:25 db.opt
-rw-rw----. 1 mysql mysql 8556 Nov 5 16:25 t1.frm
-rw-rw----. 1 mysql mysql 98304 Nov 5 16:25 t1.ibd
-rw-rw----. 1 mysql mysql 8556 Nov 5 16:25 t2.frm
-rw-rw----. 1 mysql mysql 0 Nov 5 16:25 t2.MYD
-rw-rw----. 1 mysql mysql 1024 Nov 5 16:25 t2.MYI
-rw-rw----. 1 mysql mysql 8556 Nov 5 16:25 t3.frm
-rw-rw----. 1 mysql mysql 8556 Nov 5 16:25 t4.frm
我们进行一个对应
t1表 innodb引擎
t1.frm 表结构
t1.ibd 表数据
t2表 myisam引擎
t2.frm 表结构
t2.MYD 表数据
t2.MYI 索引 类似于书的目录 基于目录查找对应数据速度更快
t3表 blackhole引擎
t3.frm 表结构
数据都被丢弃了无需文件
t4表 memory引擎
t4.frm 表结构
数据在内存中无需文件
每一行插入数据,看看每个存储引擎的结果
MariaDB [engine_demo]> insert into t1 values(1);
MariaDB [engine_demo]> insert into t2 values(1);
MariaDB [engine_demo]> insert into t3 values(1);
MariaDB [engine_demo]> insert into t4 values(1);
查看数据
MariaDB [engine_demo]> select * from t1;
+------+
| id |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
MariaDB [engine_demo]> select * from t2;
+------+
| id |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
# t3 是直接丢掉
MariaDB [engine_demo]> select * from t3;
Empty set (0.00 sec)
# t4 存储在内存中
MariaDB [engine_demo]> select * from t4;
+------+
| id |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
# 重启服务端,再看看t4
MariaDB [engine_demo]> exit
Bye
[root@localhost ~]# systemctl restart mariadb
[root@localhost ~]# mysql
MariaDB [(none)]> select * from engine_demo.t4;
Empty set (0.00 sec)
5 创建表的完整语法
# 语法
create table 表名(
字段名1 类型(宽度) 约束条件,
字段名2 类型(宽度) 约束条件,
字段名3 类型(宽度) 约束条件
)
# 注意
1 在同一张表中字段名不能重复
2 宽度和约束条件是可选的(可写可不写) 而字段名和字段类型是必须的
约束条件可以有多个
例如 字段名1 类型(宽度) 约束条件1 约束条件2...,
3 最后一条字段不能有逗号
# 补充说明
1 宽度 一般情况下指的是对存储数据的限制 默认宽度是1 即1个字符
MariaDB [engine_demo]> create table t7(name char);
MariaDB [engine_demo]> insert into t7 values('kinght');
MariaDB [engine_demo]> select * from t7;
+------+
| name |
+------+
| k |
+------+
1 row in set (0.00 sec)
针对不同版本会出现不同效果:
MYSQL为例:
5.6版本未开启严格模式 若数据超出宽度 则只存储在宽度内的字符
5.7版本开启严格模式 若数据超出宽度 则直接报错
2 约束 NULL 或 NOT NULL
MariaDB [engine_demo]> create table t8(id int,name char not null);
# 即name为字符型并且不能为空或者null
MariaDB [engine_demo]> insert into t8 values(1,NULL);
ERROR 1048 (23000): Column 'name' cannot be null
6 严格模式
对于超出数据范围的值,严格模式会直接报错,而非截取符合要求的值
# 如何查看严格模式
show variables like "%mode";
模糊匹配 like
%:匹配任意多个字符
_:匹配任意单个字符
以上语句表示查询 任意多个字符后跟mode
# 案例
MariaDB [engine_demo]> show variables like "%mode";
+--------------------------+--------+
| Variable_name | Value |
+--------------------------+--------+
| innodb_autoinc_lock_mode | 1 |
| innodb_strict_mode | OFF |
| old_mode | |
| pseudo_slave_mode | OFF |
| slave_exec_mode | STRICT |
| sql_mode | |
+--------------------------+--------+
6 rows in set (0.00 sec)
对于数据库应用有个原则:尽量减少数据库的运算量,所以,建议开启严格模式,不匹配的让数据库直接报错,而不是去计算截取的值
# 将存储模式修改为严格模式
set session sql_mode = 'STRICT_TRANS_TABLES'; 只在当前窗口有效
set global sql_mode = 'STRICT_TRANS_TABLES'; 全局有效
# 案例
MariaDB [engine_demo]> set global sql_mode = 'STRICT_TRANS_TABLES';
## 注意 修改完成后需要重启客户端生效
MariaDB [(none)]> show variables like "%mode";
+--------------------------+---------------------+
| Variable_name | Value |
+--------------------------+---------------------+
| innodb_autoinc_lock_mode | 1 |
| innodb_strict_mode | OFF |
| old_mode | |
| pseudo_slave_mode | OFF |
| slave_exec_mode | STRICT |
| sql_mode | STRICT_TRANS_TABLES |
+--------------------------+---------------------+
6 rows in set (0.00 sec)
# 测试
MariaDB [engine_demo]> create table t14(name char);
MariaDB [engine_demo]> desc t14;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| name | char(1) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)
MariaDB [engine_demo]> insert into t14 value('kinght');
ERROR 1406 (22001): Data too long for column 'name' at row 1
MariaDB [engine_demo]> insert into t14 value('k');
Query OK, 1 row affected (0.00 sec)
7 基本数据类型
7.1 整型
SQL语句的数据类型分类非常详细,整型就有5种:tinyint
、smallint
、meduimint
、int
、bigint
数据类型 | 字节数(Byte) | 位(bit) | 表示范围 | 无符号(unsigned)表示范围 |
---|---|---|---|---|
tinyint | 1 | 8 | (-128,127) | (0,255) |
smallint | 2 | 16 | (-32768,32767) | (0,65535) |
mediumint | 3 | 24 | (-8388608,8388607) | (0,16777215) |
int(integer) | 4 | 32 | (-2147483648,2147483647) | (0,4294967295) |
bigint | 8 | 64 | (-9233372036854775808,9233372036854775807) | (0,18446744073709551615) |
Mysql的数据类型默认情况下是带符号的,超出限制只存最大可接受值
# 建立一个表t9,数据类是使用tinyint
MariaDB [engine_demo]> create table t9(id tinyint);
# 查看t9的表格数据
MariaDB [engine_demo]> desc t9;
+-------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| id | tinyint(4) | YES | | NULL | |
+-------+------------+------+-----+---------+-------+
1 row in set (0.00 sec)
# 在t9表中存储两个超范围的值 -129和256
MariaDB [engine_demo]> insert into t9 values(-129),(256);
# 查看结果
MariaDB [engine_demo]> select * from t9;
+------+
| id |
+------+
| -128 |
| 127 |
+------+
2 rows in set (0.00 sec)
# 被存储的数据为-128和127更大的数值被直接替换掉了
设置让数据类型无符号
# 添加约束条件 unsigned
MariaDB [engine_demo]> create table t10(id tinyint unsigned);
# 查看t10的表格数据
MariaDB [engine_demo]> desc t10;
+-------+---------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------------------+------+-----+---------+-------+
| id | tinyint(3) unsigned | YES | | NULL | |
+-------+---------------------+------+-----+---------+-------+
1 row in set (0.00 sec)
# 插入数据 -129,200,300
MariaDB [engine_demo]> insert into t10 values(-129),(200),(300);
# 查看结果
MariaDB [engine_demo]> select * from t10;
+------+
| id |
+------+
| 0 |
| 200 |
| 255 |
+------+
3 rows in set (0.00 sec)
整型在表宽度设置中是显示长度
只有整型的宽度数字表示的不是限制的位数而是显示长度
id int(8)
如果数字没有8位 那么用空格进行填充
如果数字超过8位 那么有几位就存几位
MariaDB [engine_demo]> create table t12(id int(8) unsigned);
MariaDB [engine_demo]> desc t12;
+-------+-----------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------------+------+-----+---------+-------+
| id | int(8) unsigned | YES | | NULL | |
+-------+-----------------+------+-----+---------+-------+
MariaDB [engine_demo]> insert into t12 values(1);
MariaDB [engine_demo]> select * from t12;
+------+
| id |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
填充数字是可以被修改的
MariaDB [engine_demo]> create table t13(id int(8) unsigned zerofill);
MariaDB [engine_demo]> desc t13;
+-------+--------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------------------+------+-----+---------+-------+
| id | int(8) unsigned zerofill | YES | | NULL | |
+-------+--------------------------+------+-----+---------+-------+
MariaDB [engine_demo]> insert into t13 values(1);
MariaDB [engine_demo]> select * from t13;
+----------+
| id |
+----------+
| 00000001 |
+----------+
1 row in set (0.00 sec)
针对整型字段 括号内无需指定宽度 默认宽度已足够显示数据
7.2 浮点型
浮点数就是小数,mysql的浮点数分为三个部分
浮点类型 | 存储限制 | 备注 |
---|---|---|
float | float(255,30) | 存储255位,小数部分占30位 |
double | double(255,30) | 存储255位,小数部分占30位 |
decimal | decimal(65,30) | 存储65位,小数部分占30位 |
# 精确度验证
MariaDB [engine_demo]> create table float_t1(id float(255,30));
MariaDB [engine_demo]> create table float_t2(id double(255,30));
MariaDB [engine_demo]> create table float_t3(id decimal(64,30));
# 插入30位小数的数据
MariaDB [engine_demo]> insert into float_t1 values(1.111111111111111111111111111111);
MariaDB [engine_demo]> insert into float_t2 values(1.111111111111111111111111111111);
MariaDB [engine_demo]> insert into float_t3 values(1.111111111111111111111111111111);
# 查看结果
MariaDB [engine_demo]> select * from float_t1;
+----------------------------------+
| id |
+----------------------------------+
| 1.111111164093017600000000000000 |
+----------------------------------+
1 row in set (0.01 sec)
MariaDB [engine_demo]> select * from float_t2;
+----------------------------------+
| id |
+----------------------------------+
| 1.111111111111111200000000000000 |
+----------------------------------+
1 row in set (0.00 sec)
MariaDB [engine_demo]> select * from float_t3;
+----------------------------------+
| id |
+----------------------------------+
| 1.111111111111111111111111111111 |
+----------------------------------+
1 row in set (0.00 sec)
float
精确度大概7-8
位,double
精确度大概15-16
位,而decimal
能够做到存储完全精确
# 精确度对比
float < double < decimal
7.3 字符型
字符型在MySQL中有两种char
和varchar
字符型 | 解释 |
---|---|
char(4) | 数据超过4个直接报错,不超过4个空格补全 |
varchar(4) | 数据超过4个直接报错,不超过4个并不补全 |
假如:只存储一个字符,是否varchar比char更节省空间?
# 创建char和varchar两张表
MariaDB [engine_demo]> create table char_t1(name char(4));
MariaDB [engine_demo]> create table char_t2(name varchar(4));
# 插入同一个数据
MariaDB [engine_demo]> insert into char_t1 values('g');
MariaDB [engine_demo]> insert into char_t2 values('g');
通过char_length统计字段长度
MariaDB [engine_demo]> select char_length(name) from char_t1;
+-------------------+
| char_length(name) |
+-------------------+
| 1 |
+-------------------+
1 row in set (0.01 sec)
MariaDB [engine_demo]> select char_length(name) from char_t2;
+-------------------+
| char_length(name) |
+-------------------+
| 1 |
+-------------------+
1 row in set (0.00 sec)
char在硬盘上存储的肯定会补空格,但是在mysql客户端,会将空格给自动剔除
# 修改sql_mode 让mysql不要做自动剔除
# 注意 使用set global进行配置实质会对原有内容进行覆盖,所以,需要加上之前的配置
set global sql_mode = "STRICT_TRANS_TABLES,PAD_CHAR_TO_FULL_LENGTH";
# PAD_CHAR_TO_FULL_LENGTH 不要做自动剔除操作
# STRICT_TRANS_TABLES 严格模式
char与varchar的区别
char相对来说会浪费空间,但是他的存取会非常简单,直接按照固定的字符进行存取即可。
varchar节省空间,但是进行数据存取的时候,需要解决'数据粘包'问题,需要提前读取报头,才能获取真实的数据
7.4 时间类型
时间类型 | |
---|---|
date | 年月日 2022-11-8 |
tatetime | 年月日时分秒 2022-11-8 11:11:11 |
time | 时分秒 11:11:11 |
Year | 年份 2022 |
案例:
create table student(
id int,
name varchar(16), # 姓名
born_year year, # 出生年
birth date, # 生日
study_time time, # 学习时间
reg_time datetime # 注册时间
);
MariaDB [engine_demo]> insert into student values(1,'kinght','1998','1998-1-1','20:00:00','2022-11-08 03:16:11');
MariaDB [engine_demo]> select * from student;
+------+--------+-----------+------------+------------+---------------------+
| id | name | born_year | birth | study_time | reg_time |
+------+--------+-----------+------------+------------+---------------------+
| 1 | kinght | 1998 | 1998-01-01 | 20:00:00 | 2022-11-08 03:16:11 |
+------+--------+-----------+------------+------------+---------------------+
1 row in set (0.00 sec)
7.5 枚举和集合类型
枚举和集合类型属于给出选项,数据只能插入选项中的值
类别 | 作用 | 案例场景 |
---|---|---|
枚举(enum) | 多选一 | 性别选择(男或女) |
集合(set) | 多选多 | 爱好(可以有多个) |
案例:
create table user(
id int,
name char(16),
gender enum('male','female'), # 性别 多选一
hobby set('read','tea','basketball','computer') # 爱好 多选多
);
# 枚举字段 后期在存储数据的时候只能从枚举中选一个存储
# 集合字段 后期在存储数据的时候只能从已有集合目录中选择一个或多个进行存储 多个选项在同一引号内逗号隔开
MariaDB [engine_demo]> insert into user values(1,'kinght','male','read,computer');
MariaDB [engine_demo]> insert into user values(2,'AYM','female','read');
MariaDB [engine_demo]> insert into user values(3,'kkkk','other','other'); # 报错
MariaDB [engine_demo]> select * from user;
+------+------------------+--------+---------------+
| id | name | gender | hobby |
+------+------------------+--------+---------------+
| 1 | kinght | male | read,computer |
| 2 | AYM | female | read |
+------+------------------+--------+---------------+
2 rows in set (0.01 sec)