上传文件至 /

This commit is contained in:
kongziyu 2024-09-04 09:41:28 +08:00
commit 3e6f26362a
5 changed files with 2942 additions and 0 deletions

173
Mysql常见配置.md Normal file
View File

@ -0,0 +1,173 @@
<h1><center>Mysql常见配置</center></h1>
作者:行癫(盗版必究)
------
```
back_log = 600
#在MYSQL暂时停止响应新请求之前短时间内的多少个请求可以被存在堆栈中。如果系统在短时间内有很多连接则需要增大该参数的值该参数值指定到来的TCP/IP连接的监听队列的大小。默认值50。
max_connections = 3000
#MySQL允许最大的进程连接数如果经常出现Too Many Connections的错误提示则需要增大此值。
max_connect_errors = 6000
#设置每个主机的连接请求异常中断的最大次数当超过该次数MYSQL服务器将禁止host的连接请求直到mysql服务器重启或通过flush hosts命令清空此host的相关信息。
table_cache = 614
#指示表调整缓冲区大小。# table_cache 参数设置表高速缓存的数目。每个连接进来,都会至少打开一个表缓存。#因此, table_cache 的大小应与 max_connections 的设置有关。例如,对于 200 个#并行运行的连接,应该让表的缓存至少有 200 × N ,这里 N 是应用可以执行的查询#的一个联接中表的最大数量。此外,还需要为临时表和文件保留一些额外的文件描述符。
# 当 Mysql 访问一个表时,如果该表在缓存中已经被打开,则可以直接访问缓存;如果#还没有被缓存,但是在 Mysql 表缓冲区中还有空间,那么这个表就被打开并放入表缓#冲区;如果表缓存满了,则会按照一定的规则将当前未用的表释放,或者临时扩大表缓存来存放,使用表缓存的好处是可以更快速地访问表中的内容。执行 flush tables 会#清空缓存的内容。一般来说,可以通过查看数据库运行峰值时间的状态值 Open_tables #和 Opened_tables ,判断是否需要增加 table_cache 的值(其中 open_tables 是当#前打开的表的数量, Opened_tables 则是已经打开的表的数量。即如果open_tables接近table_cache的时候并且Opened_tables这个值在逐步增加那就要考虑增加这个#值的大小了。还有就是Table_locks_waited比较高的时候也需要增加table_cache。
external-locking = FALSE
#使用skip-external-locking MySQL选项以避免外部锁定。该选项默认开启
max_allowed_packet = 32M
#设置在网络传输中一次消息传输量的最大值。系统默认值 为1MB最大值是1GB必须设置1024的倍数。
sort_buffer_size = 2M
# Sort_Buffer_Size 是一个connection级参数在每个connectionsession第一次需要使用这个buffer的时候一次性分配设置的内存。
#Sort_Buffer_Size 并不是越大越好由于是connection级的参数过大的设置+高并发可能会耗尽系统内存资源。例如500个连接将会消耗 500*sort_buffer_size(8M)=4G内存
#Sort_Buffer_Size 超过2KB的时候就会使用mmap() 而不是 malloc() 来进行内存分配,导致效率降低。
#技术导读 http://blog.webshuo.com/2011/02/16/mysql-sort_buffer_size/
#dev-doc: http://dev.mysql.com/doc/refman/5.5/en/server-parameters.html
#explain select*from table where order limit出现filesort
#属重点优化参数
join_buffer_size = 2M
#用于表间关联缓存的大小和sort_buffer_size一样该参数对应的分配内存也是每个连接独享。
thread_cache_size = 300
# 服务器线程缓存这个值表示可以重新利用保存在缓存中线程的数量,当断开连接时如果缓存中还有空间,那么客户端的线程将被放到缓存中,如果线程重新被请求,那么请求将从缓存中读取,如果缓存中是空的或者是新的请求,那么这个线程将被重新创建,如果有很多新的线程,增加这个值可以改善系统性能.通过比较 Connections 和 Threads_created 状态的变量可以看到这个变量的作用。设置规则如下1GB 内存配置为82GB配置为163GB配置为324GB或更高内存可配置更大。
thread_concurrency = 8
# 设置thread_concurrency的值的正确与否, 对mysql的性能影响很大, 在多个cpu(或多核)的情况下错误设置了thread_concurrency的值, 会导致mysql不能充分利用多cpu(或多核), 出现同一时刻只能一个cpu(或核)在工作的情况。thread_concurrency应设为CPU核数的2倍. 比如有一个双核的CPU, 那么thread_concurrency的应该为4; 2个双核的cpu, thread_concurrency的值应为8
#属重点优化参数
query_cache_size = 64M
## 对于使用MySQL的用户对于这个变量大家一定不会陌生。前几年的MyISAM引擎优化中这个参数也是一个重要的优化参数。但随着发展这个参数也爆露出来一些问题。机器的内存越来越大人们也都习惯性的把以前有用的参数分配的值越来越大。这个参数加大后也引发了一系列问题。我们首先分析一下 query_cache_size的工作原理一个SELECT查询在DB中工作后DB会把该语句缓存下来当同样的一个SQL再次来到DB里调用时DB在该表没发生变化的情况下把结果从缓存中返回给Client。这里有一个关建点就是DB在利用Query_cache工作时要求该语句涉及的表在这段时间内没有发生变更。那如果该表在发生变更时Query_cache里的数据又怎么处理呢首先要把Query_cache和该表相关的语句全部置为失效然后在写入更新。那么如果Query_cache非常大该表的查询结构又比较多查询语句失效也慢一个更新或是Insert就会很慢这样看到的就是Update或是Insert怎么这么慢了。所以在数据库写入量或是更新量也比较大的系统该参数不适合分配过大。而且在高并发写入量大的系统建议把该功能禁掉。
#重点优化参数(主库 增删改-MyISAM
query_cache_limit = 4M
#指定单个查询能够使用的缓冲区大小缺省为1M
query_cache_min_res_unit = 2k
#默认是4KB,设置值大对大数据查询有好处,但如果你的查询都是小数据查询,就容易造成内存碎片和浪费
#查询缓存碎片率 = Qcache_free_blocks / Qcache_total_blocks * 100%
#如果查询缓存碎片率超过20%可以用FLUSH QUERY CACHE整理缓存碎片或者试试减小query_cache_min_res_unit如果你的查询都是小数据量的话。
#查询缓存利用率 = (query_cache_size Qcache_free_memory) / query_cache_size * 100%
#查询缓存利用率在25%以下的话说明query_cache_size设置的过大可适当减小;查询缓存利用率在80%以上而且Qcache_lowmem_prunes > 50的话说明query_cache_size可能有点小要不就是碎片太多。
#查询缓存命中率 = (Qcache_hits Qcache_inserts) / Qcache_hits * 100%
default-storage-engine = MyISAM
#default_table_type = InnoDB
thread_stack = 192K
#设置MYSQL每个线程的堆栈大小默认值足够大可满足普通操作。可设置范围为128K至4GB默认为192KB。
transaction_isolation = READ-COMMITTED
# 设定默认的事务隔离级别.可用的级别如下:
# READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE
# 1.READ UNCOMMITTED-读未提交2.READ COMMITTE-读已提交3.REPEATABLE READ -可重复读4.SERIALIZABLE -串行
tmp_table_size = 256M
# tmp_table_size 的默认大小是 32M。如果一张临时表超出该大小MySQL产生一个 The table tbl_name is full 形式的错误,如果你做很多高级 GROUP BY 查询,增加 tmp_table_size 值。如果超过该值,则会将临时表写入磁盘。
max_heap_table_size = 256M
long_query_time = 2
log_long_format
log-slow-queries=/data/3306/slow-log.log
#log-bin = /data/3306/mysql-bin
log-bin
binlog_cache_size = 4M
max_binlog_cache_size = 8M
max_binlog_size = 512M
expire_logs_days = 7
key_buffer_size = 2048M
#批定用于索引的缓冲区大小增加它可以得到更好的索引处理性能对于内存在4GB左右的服务器来说该参数可设置为256MB或384MB。
read_buffer_size = 1M
# MySql读入缓冲区大小。对表进行顺序扫描的请求将分配一个读入缓冲区MySql会为它分配一段内存缓冲区。read_buffer_size变量控制这一缓冲区的大小。如果对表的顺序扫描请求非常频繁并且你认为频繁扫描进行得太慢可以通过增加该变量值以及内存缓冲区大小提高其性能。和sort_buffer_size一样该参数对应的分配内存也是每个连接独享。
read_rnd_buffer_size = 16M
# MySql的随机读查询操作缓冲区大小。当按任意顺序读取行时(例如,按照排序顺序)将分配一个随机读缓存区。进行排序查询时MySql会首先扫描一遍该缓冲以避免磁盘搜索提高查询速度如果需要排序大量数据可适当调高该值。但MySql会为每个客户连接发放该缓冲空间所以应尽量适当设置该值以避免内存开销过大。
bulk_insert_buffer_size = 64M
#批量插入数据缓存大小可以有效提高插入效率默认为8M
myisam_sort_buffer_size = 128M
# MyISAM表发生变化时重新排序所需的缓冲
myisam_max_sort_file_size = 10G
# MySQL重建索引时所允许的最大临时文件的大小 (当 REPAIR, ALTER TABLE 或者 LOAD DATA INFILE).
# 如果文件大小比此值更大,索引会通过键值缓冲创建(更慢)
myisam_max_extra_sort_file_size = 10G
myisam_repair_threads = 1
# 如果一个表拥有超过一个索引, MyISAM 可以通过并行排序使用超过一个线程去修复他们.
# 这对于拥有多个CPU以及大量内存情况的用户,是一个很好的选择.
myisam_recover
#自动检查和修复没有适当关闭的 MyISAM 表
skip-name-resolve
lower_case_table_names = 1
server-id = 1
innodb_additional_mem_pool_size = 16M
#这个参数用来设置 InnoDB 存储的数据目录信息和其它内部数据结构的内存池大小类似于Oracle的library cache。这不是一个强制参数可以被突破。
innodb_buffer_pool_size = 2048M
# 这对Innodb表来说非常重要。Innodb相比MyISAM表对缓冲更为敏感。MyISAM可以在默认的 key_buffer_size 设置下运行的可以然而Innodb在默认的 innodb_buffer_pool_size 设置下却跟蜗牛似的。由于Innodb把数据和索引都缓存起来无需留给操作系统太多的内存因此如果只需要用Innodb的话则可以设置它高达 70-80% 的可用内存。一些应用于 key_buffer 的规则有 — 如果你的数据量不大,并且不会暴增,那么无需把 innodb_buffer_pool_size 设置的太大了
innodb_data_file_path = ibdata1:1024M:autoextend
#表空间文件 重要数据
innodb_file_io_threads = 4
#文件IO的线程数,一般为 4但是在 Windows 下,可以设置得较大。
innodb_thread_concurrency = 8
#服务器有几个CPU就设置为几建议用默认设置一般为8.
innodb_flush_log_at_trx_commit = 2
# 如果将此参数设置为1将在每次提交事务后将日志写入磁盘。为提供性能可以设置为0或2但要承担在发生故障时丢失数据的风险。设置为0表示事务日志写入日志文件而日志文件每秒刷新到磁盘一次。设置为2表示事务日志将在提交时写入日志但日志文件每次刷新到磁盘一次。
innodb_log_buffer_size = 16M
#此参数确定些日志文件所用的内存大小以M为单位。缓冲区更大能提高性能但意外的故障将会丢失数据.MySQL开发人员建议设置为18M之间
innodb_log_file_size = 128M
#此参数确定数据日志文件的大小以M为单位更大的设置可以提高性能但也会增加恢复故障数据库所需的时间
innodb_log_files_in_group = 3
#为提高性能MySQL可以以循环方式将日志文件写到多个文件。推荐设置为3M
innodb_max_dirty_pages_pct = 90
#推荐阅读 http://www.taobaodba.com/html/221_innodb_max_dirty_pages_pct_checkpoint.html
# Buffer_Pool中Dirty_Page所占的数量直接影响InnoDB的关闭时间。参数innodb_max_dirty_pages_pct 可以直接控制了Dirty_Page在Buffer_Pool中所占的比率而且幸运的是innodb_max_dirty_pages_pct是可以动态改变的。所以在关闭InnoDB之前先将innodb_max_dirty_pages_pct调小强制数据块Flush一段时间则能够大大缩短 MySQL关闭的时间。
innodb_lock_wait_timeout = 120
# InnoDB 有其内置的死锁检测机制能导致未完成的事务回滚。但是如果结合InnoDB使用MyISAM的lock tables 语句或第三方事务引擎,则InnoDB无法识别死锁。为消除这种可能性可以将innodb_lock_wait_timeout设置为一个整数值指示 MySQL在允许其他事务修改那些最终受事务回滚的数据之前要等待多长时间(秒数)
innodb_file_per_table = 0
#独享表空间(关闭)
[mysqldump]
quick
max_allowed_packet = 32M
[mysqld_safe]
log-error=/data/3306/mysql_oldboy.err
pid-file=/data/3306/mysqld.pid
#补充
#wait_timeout = 10
#指定一个请求的最大连接时间对于4GB左右的内存服务器来说可以将其设置为5-10。
#skip_networking
#开启该选可以彻底关闭MYSQL的TCP/IP连接方式如果WEB服务器是以远程连接的方式访问MYSQL数据库服务器的则不要开启该选项否则将无法正常连接。
#log-queries-not-using-indexes
将没有使用索引的查询也记录下来
```

View File

@ -0,0 +1,412 @@
<h1><center>数据库基础</center></h1>
**作者:行癫(盗版必究)**
------
## 一:数据库简介
#### 1.数据库技术构成
数据库系统 DBS
数据库管理系统DataBase Management System DBMS
SQL(RDS): ORACLE、 MySQL、MariaDB、SQL-SERVER
NoSQL: Redis、MongoDB、Memcache
数据库管理员DBA
SQL语言Structured Query Language 即结构化查询语言)
DDL语句 数据库定义语言: 数据库、表、视图、索引、存储过程、函数, CREATE ALTER //开发人员
DML语句 数据库操纵语言: 插入数据INSERT、删除数据DELETE,DROP、更新数据UPDATE //开发人员
DQL语句 数据库查询语言: 查询数据 SELECT
DCL语句 数据库控制语言: 例如控制用户的访问权限GRANT、REVOKE
数据访问技术
ODBC PHP <.php>
JDBC JAVA <.jsp>
settings.py python <.py>
#### 2.数据库部署
##### 版本
mysql8.0
mysql5.7
##### 网址
www.mysql.com
##### yum安装
下载mysql的yum仓库
```shell
[root@xingdian ~]# wget https://dev.mysql.com/get/mysql80-community-release-el7-7.noarch.rpm
```
安装mysql的yum仓库
```shell
[root@xingdian ~]# rpm -ivh https://dev.mysql.com/get/mysql80-community-release-el7-7.noarch.rpm
```
修改安装版本:
```shell
方法一:命令方式
[root@xingdian ~]# yum repolist all | grep mysql
[root@xingdian ~]# yum -y install yum-utils
[root@xingdian ~]# yum-config-manager --enable mysql57-community
[root@xingdian ~]# yum-config-manager --disable mysql80-community
方法二:修改文件
[root@xingdian ~]# vim /etc/yum.repos.d/mysql-community.repo
```
安装mysql
```shell
[root@xingdian ~]# yum -y install mysql mysql-server
```
查看初始密码
```shell
[root@xingdian ~]# grep 'password' /var/log/mysqld.log
2019-07-13T15:14:31.176905Z 1 [Note] A temporary password is generated for root@localhost: k12zPB1r;2Ta
```
修改密码
```shell
[root@xingdian ~]# mysqladmin -u root -p'k12zPB1r;2Ta' password 'QianFeng@123'
密码:大小写有特殊字符数字
```
##### 编译安装
准备编译所需的环境
```shell
[root@xingdian ~]# yum -y install ncurses ncurses-devel openssl-devel bison gcc gcc-c++ make cmake
```
准备编译所需的安装包
```shell
[root@xingdian ~]# wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-boost-5.7.39.tar.gz
[root@xingdian ~]# tar xf mysql-boost-5.7.39.tar.gz
```
![image-20220919132739384](https://xingdian-image.oss-cn-beijing.aliyuncs.com/xingdian-image/image-20220919132739384.png)
![image-20220919132806056](https://xingdian-image.oss-cn-beijing.aliyuncs.com/xingdian-image/image-20220919132806056.png)
![image-20220919132826328](https://xingdian-image.oss-cn-beijing.aliyuncs.com/xingdian-image/image-20220919132826328.png)
![](https://xingdian-image.oss-cn-beijing.aliyuncs.com/xingdian-image/image-20220919133151912.png)
清理系统残留并创建新用户【可选操作】
```shell
删除:
[root@xingdian ~]# userdel -r mysql
[root@xingdian ~]# yum -y remove mariadb mariadb-libs mariadb-server mariadb-devel
[root@xingdian ~]# rm -rf /etc/my*
[root@xingdian ~]# rm -rf /var/lib/mysql
[root@xingdian ~]# rm -rf /var/log/mysql*
创建:
[root@xingdian ~]# groupadd mysql
[root@xingdian ~]# useradd -r -g mysql -s /bin/nolgin mysql
```
配置
```shell
[root@mysql-5.7.26 ~]# cmake . \
-DWITH_BOOST=boost_1_59_0/ \
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
-DSYSCONFDIR=/etc \指定安装目录配置文件的位置,默认就是etc
-DMYSQL_DATADIR=/usr/local/mysql/data \数据目录 错误日志文件
-DINSTALL_MANDIR=/usr/share/man \ 帮助文档的目录
-DMYSQL_TCP_PORT=3306 \ 默认端口号3306
-DMYSQL_UNIX_ADDR=/tmp/mysql.sock \ 用来做网络通信,启动的时候才会产生
-DDEFAULT_CHARSET=utf8 \默认字符集
-DEXTRA_CHARSETS=all \
-DDEFAULT_COLLATION=utf8_general_ci \
-DWITH_READLINE=1 \可以上下翻历史命令
-DWITH_SSL=system \
-DWITH_EMBEDDED_SERVER=1 \ 嵌入式服务器
-DENABLED_LOCAL_INFILE=1 \ 支持从本机导入
-DWITH_INNOBASE_STORAGE_ENGINE=1 //默认存储引擎
提示:boost也可以使用如下指令自动下载
-DDOWNLOAD_BOOST=1
模板:
cmake . \
-DWITH_BOOST=boost/boost_1_59_0/ \
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
-DSYSCONFDIR=/etc \
-DMYSQL_DATADIR=/usr/local/mysql/data \
-DINSTALL_MANDIR=/usr/share/man \
-DMYSQL_TCP_PORT=3306 \
-DMYSQL_UNIX_ADDR=/tmp/mysql.sock \
-DDEFAULT_CHARSET=utf8 \
-DEXTRA_CHARSETS=all \
-DDEFAULT_COLLATION=utf8_general_ci \
-DWITH_READLINE=1 \
-DWITH_SSL=system \
-DWITH_EMBEDDED_SERVER=1 \
-DENABLED_LOCAL_INFILE=1 \
-DWITH_INNOBASE_STORAGE_ENGINE=1
```
编译和安装
```shell
[root@mysql-5.7.26 ~]# make && make install
```
初始化
```shell
[root@xingdian ~]# cd /usr/local/mysql 把这个删了就相当于卸载
[root@xingdian ~]# mkdir mysql-files
[root@xingdian ~]# chown -R mysql.mysql /usr/local/mysql
[root@xingdian ~]# ./bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data
初始化,只需要初始化一次
```
启动mysql
```shell
[root@xingdian ~]# ./bin/mysqld_safe --user=mysql & (后台运行)
[root@xingdian ~]# ./bin/mysqladmin -u root -p'原密码' password 123
```
客户端测试
```shell
[root@xingdian ~]# ./bin/mysql -u root -p '密码'
```
扩展
```shell
设置环境变量可以直接使用mysql相关命令
[root@xingdian ~]# echo "export PATH=$PATH:/usr/local/mysql/bin" >> /etc/profile
[root@xingdian ~]# source /etc/profile
设置开机启动并用systemctl管理mysql服务
[root@xingdian ~]# cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
[root@xingdian ~]# chkconfig mysqld on //做开机启动
[root@xingdian ~]# systemctl start mysqld
[root@xingdian ~]# systemctl stop mysqld
```
#### 3.mysql基础
##### 编译安装
```shell
[root@47ed2bec974d mysql]# ls
COPYING README bin include mysql-test support-files
COPYING-test README-test docs lib share
```
bin目录用于放置一些可执行文件如mysql、mysqld、mysqlbinlog等
include目录用于放置一些头文件mysql.h、mysql_ername.h等
lib目录用于放置一系列库文件
share目录用于存放字符集、语言等信息。
##### yum安装
/var/lib/mysql 存放数据文件
/usr/share/mysql 用于存放字符集、语言等信息
##### 配置文件基本参数
```shell
[root@mysql1 mysql]# vim /etc/my.cnf
[mysqld]
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
validate_password=off 添加后可设置弱密码强度
lower_case_table_names=1 不区分大小写
扩展:
key_buffer = 384M //key_buffer是用于索引块的缓冲区大小增加它可得到更好处理的索引(对所有读和多重写)。索引被所有的线程共享key_buffer的大小视内存大小而定
table_open_cache = 512 //MySQL每打开一个表都会读入一些数据到table_open_cache缓存中当MySQL在这个缓存中找不到相应信息时才会去磁盘上读取。默认值64, 假定系统有200个并发连接则需将此参数设置为200*N(N为每个连接所需的文件描述符数目)当把table_open_cache设置为很大时如果系统处理不了那么多文件描述符那么就会出现客户端失效连接不上
max_allowed_packet = 4M //接受的数据包大小增加该变量的值十分安全这是因为仅当需要时才会分配额外内存。例如仅当你发出长查询或MySQLd必须返回大的结果行时MySQLd才会分配更多内存。 该变量之所以取较小默认值是一种预防措施,以捕获客户端和服务器之间的错误信息包,并确保不会因偶然使用大的信息包而导致内存溢出
sort_buffer_size = 2M //MySQL执行排序使用的缓冲大小。如果想要增加ORDER BY的速度首先看是否可以让MySQL使用索引而不是额外的排序阶段。如果不能可以尝试增加sort_buffer_size变量的大小
read_buffer_size = 2M //读查询操作所能使用的缓冲区大小。和sort_buffer_size一样该参数对应的分配内存也是每连接独享。对表进行顺序扫描的请求将分配一个读入缓冲区MySQL会为它分配一段内存缓冲区。 如果对表的顺序扫描请求非常频繁,并且你认为频繁扫描进行得太慢,可以通过增加该变量值以及内存缓冲区大小提高其性能
thread_concurrency = 8 //最大并发线程数取值为服务器逻辑CPU数量×2
max_connections = 1000 //MySQL的最大连接数如果服务器的并发连接请求量比较大建议调高此值以增加并行连接数量当然这建立在机器能支撑的情况下因为如果连接数越多介于MySQL会为每个连接提供连接缓冲区就会开销越多的内存所以要适当调整该值不能盲目提高设值
```
#### 4.数据库引擎
数据库存储引擎是数据库底层软件组织数据库管理系统DBMS使用数据引擎进行创建、查询、更新和删除数据。不同的存储引擎提供不同的存储机制、索引技巧、锁定水平等功能使用不同的存储引擎还可以 获得特定的功能。现在许多不同的数据库管理系统都支持多种不同的数据引擎。MySQL的核心就是存储引擎
##### InnoDB存储引擎
InnoDB是事务型数据库的首选引擎支持事务安全表ACID支持行锁定和外键;InnoDB是默认的MySQL引擎
特点:
支持事务处理支持外键支持崩溃修复能力和并发控制。如果需要对事务的完整性要求比较高比如银行要求实现并发控制比如售票那选择InnoDB有很大的优势。如果需要频繁的更新、删除操作的数据库也可以选择InnoDB因为支持事务的提交和回滚
##### MyISAM存储引擎
MyISAM基于ISAM存储引擎并对其进行扩展。它是在Web、数据仓储和其他应用环境下最常使用的存储引擎之一。MyISAM拥有较高的插入、查询速度但不支持事务
特点:
插入数据快空间和内存使用比较低。如果表主要是用于插入新记录和读出记录那么选择MyISAM能实现处理高效率。如果应用的完整性、并发性要求比较低也可以使用
##### MEMORY存储引擎
MEMORY存储引擎将表中的数据存储到内存中为查询和引用其他表数据提供快速访问
特点:
所有的数据都在内存中数据的处理速度快但是安全性不高。如果需要很快的读写速度对数据的安全性要求较低可以选择MEMOEY。它对表的大小有要求不能建立太大的表。所以这类数据库只使用在相对较小的数据库表
##### 如何选择引擎
如果要提供提交、回滚、崩溃恢复能力的事物安全ACID兼容能力并要求实现并发控制InnoDB是一个好的选择如果数据表主要用来插入和查询记录则MyISAM引擎能提供较高的处理效率如果只是临时存放数据数据量不大并且不需要较高的数据安全性可以选择将数据保存在内存中的Memory引擎MySQL中使用该引擎作为临时表存放查询的中间结果如果只有INSERT和SELECT操作可以选择ArchiveArchive支持高并发的插入操作但是本身不是事务安全的。Archive非常适合存储归档数据如记录日志信息可以使用Archive。
使用哪一种引擎需要灵活选择,一个数据库中多个表可以使用不同引擎以满足各种性能和实际需求,使用合适的存储引擎,将会提高整个数据库的性能
##### 存储引擎查看
```shell
MySQL [(none)]> show engines;
+--------------------+---------+----------------------------------------------------------------+-----
| Engine | Support | Comment | Transactions | XA | Savepoints |
+--------------------+---------+----------------------------------------------------------------+-----
| InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES |
| MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
| BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO |
| MyISAM | YES | MyISAM storage engine | NO | NO | NO |
| CSV | YES | CSV storage engine | NO | NO | NO |
| ARCHIVE | YES | Archive storage engine | NO | NO | NO |
| PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO |
| FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL |
```
Support列的值表示某种引擎是否能使用YES表示可以使用、NO表示不能使用、DEFAULT表示该引擎为当前默认的存储引擎
#### 5.mysql事务
MySQL 事务主要用于处理操作量大,复杂度高的数据。比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务!
在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务
事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行
事务用来管理 insert,update,delete 语句
##### 满足事务条件
原子性一个事务transaction中的所有操作要么全部完成要么全部不完成不会结束在中间某个环节。事务在执行过程中发生错误会被回滚Rollback到事务开始前的状态就像这个事务从来没有执行过一样
一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作
隔离性数据库允许多个并发事务同时对其数据进行读写和修改的能力隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别包括读未提交Read uncommitted、读提交read committed、可重复读repeatable read和串行化Serializable
持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失
##### 了解
```sshell
MYSQL 事务处理主要有两种方法:
1、用 BEGIN, ROLLBACK, COMMIT来实现
• BEGIN 开始一个事务
• ROLLBACK 事务回滚
• COMMIT 事务确认
2、直接用 SET 来改变 MySQL 的自动提交模式:
• SET AUTOCOMMIT=0 禁止自动提交
• SET AUTOCOMMIT=1 开启自动提交
>show variables like 'autocommit'; //查看是否修改成功
注意:在编写应用程序时,最好事务的控制权限交给开发人员
```
#### 6.数据库锁
【阅读了解】
锁是计算机协调多个进程或纯线程并发访问某一资源的机制。在数据库中除传统的计算资源CPU、RAM、I/O的争用以外数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所在有数据库必须解决的一个问题锁冲突也是影响数据库并发访问性能的一个重要因素。从这个角度来说锁对数据库而言显得尤其重要也更加复杂相对其他数据库而言MySQL的锁机制比较简单其最显著的特点是不同的存储引擎支持不同的锁机制
MyISAM在执行查询语句SELECT会自动给涉及的所有表加读锁在执行更新操作UPDATE、DELETE、INSERT等会自动给涉及的表加写锁这个过程并不需要用户干预因此用户一般不需要直接用LOCK TABLE命令给MyISAM表显式加锁。给MyISAM表显示加锁一般是为了一定程度模拟事务操作实现对某一时间点多个表的一致性读取
##### 锁分类
表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低
行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高
页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般
##### 案例
有一个订单表orders其中记录有订单的总金额total同时还有一个订单明细表order_detail其中记录有订单每一产品的金额小计subtotal假设我们需要检查这两个表的金额合计是否相等可能就需要执行如下两条SQL
```shell
MySQL [(none)]> SELECT SUM(total) FROM orders;
MySQL [(none)]> SELECT SUM(subtotal) FROM order_detail;
```
这时如果不先给这两个表加锁就可能产生错误的结果因为第一条语句执行过程中order_detail表可能已经发生了改变。因此正确的方法应该是
```shell
MySQL [(none)]> LOCK tables orders read local,order_detail read local;
MySQL [(none)]> SELECT SUM(total) FROM orders;
MySQL [(none)]> SELECT SUM(subtotal) FROM order_detail;
MySQL [(none)]> Unlock tables;
```
上面的例子在LOCK TABLES时加了local选项其作用就是在满足MyISAM表并发插入条件的情况下允许其他用户在表尾插入记录
在用LOCKTABLES给表显式加表锁是时必须同时取得所有涉及表的锁并且MySQL支持锁升级也就是说在执行LOCK TABLES后只能访问显式加锁的这些表不能访问未加锁的表同时如果加的是读锁那么只能执行查询操作而不能执行更新操作。其实在自动加锁的情况下也基本如此MySQL问题一次获得SQL语句所需要的全部锁
#### 7.外键
【阅读了解】
在实际开发的项目中,一个健壮数据库中的数据一定有很好的参照完整性。例如学生档案和成绩单两张表,如果成绩单中有张三的成绩,学生档案中张三的档案却被删除了,这样就会产生垃圾数据或者错误数据。为了保证数据的完整性,将两张表之间的数据建立关系,因此就需要在成绩表中添加外键约束
外键是指引用另外一个表中的一列或多列数据,被引用的列应该具有主键约束或者唯一性约束。外键用来建立和加强两个表数据之间的连接
##### 外键的定义
外键是某个表中的一列,它包含在另一个表的主键中
外键也是索引的一种,是通过一张表中的一列指向另一张表中的主键,来对两张表进行关联
一张表可以有一个外键,也可以存在多个外键,与多张表进行关联
##### 外键的作用
外键的主要作用是保证数据的一致性和完整性,并且减少数据冗余

521
第七章:读写分离.md Normal file
View File

@ -0,0 +1,521 @@
<h1><center>读写分离</center></h1>
**作者:行癫(盗版必究)**
------
## 一:读写分离部署
#### 1.环境介绍
![image-20221006131313211](https://xingdian-image.oss-cn-beijing.aliyuncs.com/xingdian-image/image-20221006131313211.png)
#### 2.读写分离集群部署
##### A数据库集群部署
单主单从;多主多从等均可
##### BMycat部署
新机器不需要安装mysql
安装jdk环境
```shell
[root@mycat ~]# tar xf jdk-8u211-linux-x64.tar.gz -C /usr/local/
[root@mycat ~]# mv /usr/local/jdk1.8.0_211/ /usr/local/java
```
设置环境变量:
```shell
[root@mycat ~]# vi /etc/profile
JAVA_HOME=/usr/local/java
PATH=$JAVA_HOME/bin:$PATH
export JAVA_HOME PATH
[root@mycat ~]# source /etc/profile
[root@mycat ~]# java -version
java version "1.8.0_211"
Java(TM) SE Runtime Environment (build 1.8.0_211-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.211-b12, mixed mode)
```
安装mycat
```shell
[root@mycat ~]# tar xf Mycat-server-1.6.7.1-release-20190627191042-linux.tar.gz -C /usr/local/
```
设置环境变量:
```shell
[root@mycat ~]# vi ~/.bash_profile
PATH=$PATH:$HOME/bin:/usr/local/mycat/bin
[root@mycat ~]# source ~/.bash_profile
```
##### C数据库部署
Mysql中添加数据库和账户
```shell
[root@master-1 ~]# mysql -u root -pQianFeng@123
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 10
Server version: 5.7.39-log MySQL Community Server (GPL)
Copyright (c) 2000, 2022, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> create database shop;
Query OK, 1 row affected (0.00 sec)
mysql> create database bbs;
Query OK, 1 row affected (0.00 sec)
mysql> create database blog;
Query OK, 1 row affected (0.00 sec)
mysql> grant all on shop.* to shop@'%' identified by 'QianFeng@123';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> grant all on bbs.* to bbs@'%' identified by 'QianFeng@123';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> grant all on blog.* to blog@'%' identified by 'QianFeng@123';
Query OK, 0 rows affected, 1 warning (0.00 sec)
```
注意:
创建的库跟mycat关联原则上一个库对应一个项目根据实际情况创建
创建的库需要单独授权用户进行管理,用户名和库名根据实际情况决定
##### DMycat配置
server.xmlMycat的配置文件设置账号、参数等
```shell
[root@mycat conf]# vim server.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
<system>
<property name="nonePasswordLogin">0</property>
<property name="useHandshakeV10">1</property>
<property name="useSqlStat">0</property>
<property name="useGlobleTableCheck">0</property>
<property name="sequnceHandlerType">2</property>
<property name="sequnceHandlerPattern">(?:(\s*next\s+value\s+for\s*MYCATSEQ_(\w+))(,|\)|\s)*)+</property>
<property name="subqueryRelationshipCheck">false</property>
<property name="processorBufferPoolType">0</property>
<property name="handleDistributedTransactions">0</property>
<property name="useOffHeapForMerge">0</property>
<property name="memoryPageSize">64k</property>
<property name="spillsFileBufferSize">1k</property>
<property name="useStreamOutput">0</property>
<property name="systemReserveMemorySize">384m</property>
<property name="useZKSwitch">false</property>
<property name="strictTxIsolation">false</property>
<property name="useZKSwitch">true</property>
</system>
<user name="root" defaultAccount="true">
<property name="password">123456</property>
<property name="schemas">TESTDB</property>
</user>
<user name="shop">
<property name="password">123456</property>
<property name="schemas">shop</property>
</user>
<user name="bbs">
<property name="password">123456</property>
<property name="schemas">bbs</property>
</user>
<user name="blog">
<property name="password">123456</property>
<property name="schemas">blog</property>
</user>
</mycat:server>
```
注意:
```shell
user 用户配置节点
name 登录的用户名也就是连接Mycat的用户名
password 登录的密码也就是连接Mycat的密码
schemas 数据库名这里会和schema.xml中的配置关联多个用逗号分开例如需要这个用户需要管理两个数据库db1,db2则配置db1,db2
```
schema.xmlMycat对应的物理数据库和数据库表的配置
```shell
[root@mycat conf]# cat schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="shop" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1"> </schema>
<schema name="bbs" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn2"> </schema>
<schema name="blog" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn3"> </schema>
<dataNode name="dn1" dataHost="localhost1" database="shop" />
<dataNode name="dn2" dataHost="localhost2" database="bbs" />
<dataNode name="dn3" dataHost="localhost3" database="blog" />
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>show status like 'wsrep%'</heartbeat>
<writeHost host="mysql-1" url="mysql-1:3306" user="shop" password="QianFeng@123">
<readHost host="slave-1" url="slave-1:3306" user="shop" password="QianFeng@123" />
<readHost host="slave-2" url="slave-2:3306" user="shop" password="QianFeng@123" />
</writeHost>
<writeHost host="mysql-2" url="mysql-2:3306" user="shop" password="QianFeng@123">
<readHost host="slave-1" url="slave-1:3306" user="shop" password="QianFeng@123" />
<readHost host="slave-2" url="slave-2:3306" user="shop" password="QianFeng@123" />
</writeHost>
</dataHost>
<dataHost name="localhost2" maxCon="1000" minCon="10" balance="1"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>show status like 'wsrep%'</heartbeat>
<writeHost host="mysql-1" url="mysql-1:3306" user="bbs" password="QianFeng@123">
<readHost host="slave-1" url="slave-1:3306" user="bbs" password="QianFeng@123" />
<readHost host="slave-2" url="slave-1:3306" user="bbs" password="QianFeng@123" />
</writeHost>
<writeHost host="mysql-2" url="mysql-2:3306" user="bbs" password="QianFeng@123">
<readHost host="slave-1" url="slave-1:3306" user="bbs" password="QianFeng@123" />
<readHost host="slave-2" url="slave-2:3306" user="bbs" password="QianFeng@123" />
</writeHost>
</dataHost>
<dataHost name="localhost3" maxCon="1000" minCon="10" balance="1"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>show status like 'wsrep%'</heartbeat>
<writeHost host="mysql-1" url="mysql-1:3306" user="blog" password="QianFeng@123">
<readHost host="slave-1" url="slave-1:3306" user="blog" password="QianFeng@123" />
<readHost host="slave-2" url="slave-1:3306" user="blog" password="QianFeng@123" />
</writeHost>
<writeHost host="mysql-2" url="mysql-2:3306" user="blog" password="QianFeng@123">
<readHost host="slave-1" url="slave-1:3306" user="blog" password="QianFeng@123" />
<readHost host="slave-2" url="slave-2:3306" user="blog" password="QianFeng@123" />
</writeHost>
</dataHost>
</mycat:schema>
```
注意:
```shell
balance=1 开启读写分离机制,所有读操作都发送到当前备用的 writeHost 上。
wirteType=0 所有写操作发送到第一个writeHost第一个挂了切换到第二个
switchType=3 基于MySQL Galera cluster的切换机制心跳语句为show status like 'wsrep%'
```
##### E启动服务
```shell
[root@mycat conf]# mycat start
Starting Mycat-server...
[root@mycat conf]# jps
1494 WrapperSimpleApp
1528 Jps
```
查看端口:
```shell
[root@mycat conf]# ss -antpl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:22 *:* users:(("sshd",pid=837,fd=3))
LISTEN 0 100 127.0.0.1:25 *:* users:(("master",pid=933,fd=13))
LISTEN 0 1 127.0.0.1:32000 *:* users:(("java",pid=1494,fd=4))
LISTEN 0 50 :::37680 :::* users:(("java",pid=1494,fd=57))
LISTEN 0 128 :::22 :::* users:(("sshd",pid=837,fd=4))
LISTEN 0 100 ::1:25 :::* users:(("master",pid=933,fd=14))
LISTEN 0 50 :::1984 :::* users:(("java",pid=1494,fd=58))
LISTEN 0 100 :::8066 :::* users:(("java",pid=1494,fd=79))
LISTEN 0 50 :::32834 :::* users:(("java",pid=1494,fd=59))
LISTEN 0 100 :::9066 :::* users:(("java",pid=1494,fd=75))
```
##### F客户端测试
mycat连接测试
```shell
[root@master-1 ~]# mysql -u shop -p123456 -P 8066 -h 10.0.0.47
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.6.29-mycat-1.6.7.1-release-20190627191042 MyCat Server (OpenCloudDB)
Copyright (c) 2000, 2022, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+----------+
| DATABASE |
+----------+
| shop |
+----------+
1 row in set (0.00 sec)
mysql> use shop
Database changed
mysql> create table t1(id int);
Query OK, 0 rows affected (0.01 sec)
mysql> show tables;
+----------------+
| Tables_in_shop |
+----------------+
| t1 |
+----------------+
1 row in set (0.01 sec)
mysql> insert into t1 values(1);
Query OK, 1 row affected (0.03 sec)
mysql> insert into t1 values(2);
Query OK, 1 row affected (0.01 sec)
```
从服务数据验证:
```shell
[root@slave-2 ~]# mysql -u root -pQianFeng@123
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 7
Server version: 5.7.39-log MySQL Community Server (GPL)
Copyright (c) 2000, 2022, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| qfcloud |
| sys |
+--------------------+
5 rows in set (0.00 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| bbs |
| blog |
| mysql |
| performance_schema |
| qfcloud |
| shop |
| sys |
+--------------------+
8 rows in set (0.00 sec)
mysql> use shop
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
mysql> show tables;
+----------------+
| Tables_in_shop |
+----------------+
| t1 |
+----------------+
1 row in set (0.00 sec)
mysql> select * from t1;
+------+
| id |
+------+
| 1 |
| 2 |
+------+
2 rows in set (0.00 sec)
```
#### 3.Mycat配置文件
##### server.xml
```shell
server.xml 配置文件
1.privileges标签
对用户的 schema以及表进行精细化的DML(数据操纵语言)权限控制
<privileges check="false"> </privileges> --check 表示是否开启DML权限检查。默认是关闭。
--dml 顺序说明insert,update,select,delete
<schema name="db1" dml="0110" >
<table name="tb01" dml="0000"></table>
<table name="tb02" dml="1111"></table> </schema>
db1的权限是update,select。
tb01的权限是啥都不能干。
tb02的权限是insert,update,select,delete。
其他表默认是udpate,select。
2.system标签
这个标签内嵌套的所有 property 标签都与系统配置有关。
<property name="charset">utf8</property>
字符集
<property name="processors">1</property>
处理线程数量默认是cpu数量。
<property name="processorBufferChunk">4096</property>
每次读取留的数量默认4096。
<property name="processorBufferPool">409600</property>
创建共享buffer需要占用的总空间大小。processorBufferChunk*processors*100。
<property name="processorBufferPoolType">0</property>
默认为0。0表示DirectByteBufferPool1表示ByteBufferArena。
<property name="processorBufferLocalPercent">100</property>
二级共享buffer是processorBufferPool的百分比这里设置的是百分比。
<property name="sequnceHandlerType">100</property>
全局ID生成方式。(0:为本地文件方式1:为数据库方式2:为时间戳序列方式3:为ZK生成ID4:为ZK递增ID生成。
<property name="useCompression">1</property>
是否开启mysql压缩协议。1为开启0为关闭默认关闭。
<property name="packetHeaderSize">4</property>
指定 Mysql 协议中的报文头长度。默认 4。
<property name="maxPacketSize">16M</property>
指定 Mysql 协议可以携带的数据最大长度。默认 16M。
<property name="idleTimeout">1800000</property>
指定连接的空闲超时时间。某连接在发起空闲检查下,发现距离上次使用超过了空闲时间,那么这个连接会被回收,就是被直接的关闭掉。默认 30 分钟,单位毫秒。
<property name="txIsolation">3</property>
前端连接的初始化事务隔离级别,只在初始化的时候使用,后续会根据客户端传递过来的属性对后端数据库连接进行同步。默认为 REPEATED_READ设置值为数字默认 3。
READ_UNCOMMITTED = 1;
READ_COMMITTED = 2;
REPEATED_READ = 3;
SERIALIZABLE = 4;
<property name="sqlExecuteTimeout">300</property>
SQL 执行超时的时间Mycat 会检查连接上最后一次执行 SQL 的时间,若超过这个时间则会直接关闭这连接。默认时间为 300 秒,单位秒。
<property name="processorCheckPeriod">1000</property>
清理 NIOProcessor 上前后端空闲、超时和关闭连接的间隔时间。默认是 1 秒,单
位毫秒。
<property name="dataNodeIdleCheckPeriod">300000</property>
对后端连接进行空闲、超时检查的时间间隔,默认是 300 秒,单位毫秒。
<property name="dataNodeHeartbeatPeriod">10000</property>
对后端所有读、写库发起心跳的间隔时间,默认是 10 秒,单位毫秒。
<property name="bindIp">0.0.0.0</property>
mycat 服务监听的 IP 地址,默认值为 0.0.0.0。
<property name="serverPort">8066</property>
定义 mycat 的使用端口,默认值为 8066。
<property name="managerPort">9066</property>
定义 mycat 的管理端口,默认值为 9066。
<property name="fakeMySQLVersion">5.6</property>
mycat 模拟的 mysql 版本号,默认值为 5.6 版本,如非特需,不要修改这个值,目前支持设置 5.5,5.6,5.7 版本,其他版本可能会有问题。
<property name="useSqlStat">0</property>
是否开启实时统计。1为开启0为关闭 。
<property name="useGlobleTableCheck">0</property>
是否开启全局表一致性检测。1为开启0为关闭 。
<property name="handleDistributedTransactions">0</property>
分布式事务开关。0为不过滤分布式事务1为过滤分布式事务2 为不过滤分布式事务,但是记录分布式事务日志。
<property name="maxStringLiteralLength">65535</property>
默认是65535。 64K 用于sql解析时最大文本长度
以上举例的属性仅仅是一部分,可以配置的变量很多。
System标签下的属性一般是上线后需要根据实际运行的情况分析后调优的时候进行修改。
3. Firewall标签
防火墙的设置也就是在网络层对请求的地址进行限制主要是从安全角度来保证Mycat不被匿名IP进行访问
<firewall>
<whitehost>
<host host="127.0.0.1" user="mycat"/>
<host host="127.0.0.2" user="mycat"/>
</whitehost>
<blacklist check="false">
</blacklist>
</firewall>
```
##### schema.xml
```shell
schema.xml
schema 数据库设置此数据库为逻辑数据库name与server.xml中schema对应
dataNode 分片信息,也就是分库相关配置
dataHost 物理数据库,真正存储数据的数据库
1、schema 标签
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="10"> </schema>
schema标签用来定义mycat实例中的逻辑库mycat可以有多个逻辑库每个逻辑库都有自己的相关配置。可以使用schema标签来划分这些不同的逻辑库,如果不配置schema标签所有表的配置会属于同一个默认的逻辑库。逻辑库的概念和MySql的database的概念一样我们在查询两个不同逻辑库中的表的时候需要切换到该逻辑库下进行查询。
name 逻辑数据库名与server.xml中的schema对应
checkSQLschema 数据库前缀相关设置当该值为true时例如我们执行语句select * from TESTDB.company 。mycat会把语句修改为 select * from company 去掉TESTDB。
sqlMaxLimit 当该值设置为某个数值时每条执行的sql语句如果没有加上limit语句Mycat会自动加上对应的值。不写的话默认返回所有的值。需要自己sql语句加limit。
2、dataNode标签
<dataNode name="dn1" dataHost="localhost1" database="db1" />
datanode标签定义了mycat中的数据节点也就是数据分片。一个datanode标签就是一个独立的数据分片。
localhost1数据库实例上的db1物理数据库这就组成一个数据分片最后我们用dn1来标示这个分片。
name 定义数据节点的名字这个名字需要唯一。我们在table标签上用这个名字来建立表与分片对应的关系
dataHost 用于定义该分片属于哪个数据库实例属性与datahost标签上定义的name对应
database 用于定义该分片属于数据库实例上 的具体库。
3、dataHost标签
这个标签直接定义了具体数据库实例,读写分离配置和心跳语句。
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="192.168.1.100:3306" user="root" password="123456">
<readHost host="hostS1" url="192.168.1.101:3306" user="root" password="123456" />
</writeHost>
</dataHost>
name 唯一标示dataHost标签供上层使用
maxCon 指定每个读写实例连接池的最大连接。
minCon 指定每个读写实例连接池的最小连接,初始化连接池的大小
balance 负载均称类型
balance=“0”不开启读写分离机制所有读操作都发送到当前可用的writeHost上
balance=“1”全部的readHost与stand by writeHost参与select语句的负载均衡简单的说当双主双从模式M1-S1M2-S2 并且M1 M2互为主备正常情况下M2,S1,S2都参与select语句的负载均衡。
balance=“2”所有读操作都随机的在writeHost、readHost上分发
balance=“3”所有读请求随机的分发到writeHst对应的readHost执行writeHost不负担读写压力。
writeType 负载均衡类型。
writeType=“0”, 所有写操作发送到配置的第一个 writeHost第一个挂了切到还生存的第二个writeHost重新启动后已切换后的为准切换记录在配置文件中:dnindex.properties .
writeType=“1”所有写操作都随机的发送到配置的 writeHost。1.5以后版本废弃不推荐。
switchType -1不自动切换
1 默认值 自动切换
2 基于MySql主从同步的状态决定是否切换心跳语句为 show slave status
3 基于mysql galary cluster 的切换机制(适合集群) 心跳语句为 show status like wsrep%
dbType 指定后端链接的数据库类型目前支持二进制的mysql协议还有其他使用jdbc链接的数据库例如mongodboraclespark等
dbDriver 指定连接后段数据库使用的driver目前可选的值有native和JDBC。使用native的话因为这个值执行的是二进制的mysql协议所以可以使用mysql和maridb其他类型的则需要使用JDBC驱动来支持。
如果使用JDBC的话需要符合JDBC4标准的驱动jar 放到mycat\lib目录下并检查驱动jar包中包括如下目录结构文件 META-INF\services\java.sql.Driver。 在这个文件写上具体的driver类名例如com.mysql.jdbc.Driver
writeHost readHost指定后端数据库的相关配置给mycat用于实例化后端连接池。
tempReadHostAvailable
如果配置了这个属性 writeHost 下面的 readHost 仍旧可用,默认 0 可配置0、1
1heartbeat标签
这个标签内指明用于和后端数据库进行心跳检查的语句。
例如MYSQL 可以使用 select user()Oracle 可以使用 select 1 from dual 等。
2) writeHost /readHost 标签
这两个标签都指定后端数据库的相关配置用于实例化后端连接池。唯一不同的是writeHost 指定写实例、readHost 指定读实例。
在一个 dataHost 内可以定义多个 writeHost 和 readHost。但是如果 writeHost 指定的后端数据库宕机,那么这个 writeHost 绑定的所有 readHost 都将不可用。
另一方面,由于这个 writeHost 宕机,系统会自动的检测到,并切换到备用的 writeHost 上去。这两个标签的属性相同,这里就一起介绍。
host 用于标识不同实例,一般 writeHost 我们使用M1readHost 我们用S1。
url 后端实例连接地址。Native地址端口 JDBCjdbc的url
password 后端存储实例需要的密码
user 后端存储实例需要的用户名字
weight 权重 配置在 readhost 中作为读节点的权重
usingDecrypt 是否对密码加密默认0。
```

View File

@ -0,0 +1,975 @@
<h1><center>数据库查询</center></h1>
**作者:行癫(盗版必究)**
------
## 一:基本查询
#### 1.简介
单表查询
简单查询
通过条件查询
查询排序
限制查询记录数
使用集合函数查询
分组查询
使用正则表达式查询
#### 2.案例
创建案例所需表company.employee5
```shell
雇员编号 id int
雇员姓名 name varchar(30)
雇员性别 sex enum
雇用时期 hire_date date
职位 post varchar(50)
职位描述 job_description varchar(100)
薪水 salary double(15,2)
办公室 office int
部门编号 dep_id int
```
```shell
MySQL [(none)]> CREATE TABLE company.employee5(
id int primary key AUTO_INCREMENT not null,
name varchar(30) not null,
sex enum('male','female') default 'male' not null,
hire_date date not null,
post varchar(50) not null,
job_description varchar(100),
salary double(15,2) not null,
office int,
dep_id int
);
```
插入模拟数据:
```shell
MySQL [(none)]> insert into company.employee5(name,sex,hire_date,post,job_description,salary,office,dep_id) values
('jack','male','20180202','instructor','teach',5000,501,100),
('tom','male','20180203','instructor','teach',5500,501,100),
('robin','male','20180202','instructor','teach',8000,501,100),
('alice','female','20180202','instructor','teach',7200,501,100),
('','male','20180202','hr','hrcc',600,502,101),
('harry','male','20180202','hr',NULL,6000,502,101),
('emma','female','20180206','sale','salecc',20000,503,102),
('christine','female','20180205','sale','salecc',2200,503,102),
('zhuzhu','male','20180205','sale',NULL,2200,503,102),
('gougou','male','20180205','sale','',2200,503,102);
```
语法格式:
select 字段名称,字段名称2...... from 表名 [条件]
##### a.简单查询
```shell
MySQL [company]> select * from employee5;
+----+-----------+--------+------------+------------+-----------------+----------+--------+--------+
| id | name | sex | hire_date | post | job_description | salary | office | dep_id |
+----+-----------+--------+------------+------------+-----------------+----------+--------+--------+
| 1 | jack | male | 2018-02-02 | instructor | teach | 5000.00 | 501 | 100 |
| 2 | tom | male | 2018-02-03 | instructor | teach | 5500.00 | 501 | 100 |
| 3 | robin | male | 2018-02-02 | instructor | teach | 8000.00 | 501 | 100 |
| 4 | alice | female | 2018-02-02 | instructor | teach | 7200.00 | 501 | 100 |
| 5 | | male | 2018-02-02 | hr | hrcc | 600.00 | 502 | 101 |
| 6 | harry | male | 2018-02-02 | hr | NULL | 6000.00 | 502 | 101 |
| 7 | emma | female | 2018-02-06 | sale | salecc | 20000.00 | 503 | 102 |
| 8 | christine | female | 2018-02-05 | sale | salecc | 2200.00 | 503 | 102 |
| 9 | zhuzhu | male | 2018-02-05 | sale | NULL | 2200.00 | 503 | 102 |
| 10 | gougou | male | 2018-02-05 | sale | | 2200.00 | 503 | 102 |
+----+-----------+--------+------------+------------+-----------------+----------+--------+--------+
10 rows in set (0.00 sec)
MySQL [company]> select name, salary, dep_id from employee5 where id <=5;
+-------+---------+--------+
| name | salary | dep_id |
+-------+---------+--------+
| jack | 5000.00 | 100 |
| tom | 5500.00 | 100 |
| robin | 8000.00 | 100 |
| alice | 7200.00 | 100 |
| | 600.00 | 101 |
+-------+---------+--------+
5 rows in set (0.00 sec)
```
##### b.避免重复
不能部分使用DISTINCT通常仅用于某一字段
```shell
MySQL [company]> SELECT post FROM employee5;
+------------+
| post |
+------------+
| instructor |
| instructor |
| instructor |
| instructor |
| hr |
| hr |
| sale |
| sale |
| sale |
| sale |
+------------+
10 rows in set (0.00 sec)
MySQL [company]> SELECT distinct post FROM employee5;
+------------+
| post |
+------------+
| instructor |
| hr |
| sale |
+------------+
3 rows in set (0.00 sec)
```
##### c.四则运算查询
```shell
MySQL [company]> SELECT name, salary, salary*14 FROM employee5;
+-----------+----------+-----------+
| name | salary | salary*14 |
+-----------+----------+-----------+
| jack | 5000.00 | 70000.00 |
| tom | 5500.00 | 77000.00 |
| robin | 8000.00 | 112000.00 |
| alice | 7200.00 | 100800.00 |
| | 600.00 | 8400.00 |
| harry | 6000.00 | 84000.00 |
| emma | 20000.00 | 280000.00 |
| christine | 2200.00 | 30800.00 |
| zhuzhu | 2200.00 | 30800.00 |
| gougou | 2200.00 | 30800.00 |
+-----------+----------+-----------+
10 rows in set (0.01 sec)
MySQL [company]> SELECT name, salary, salary*14 AS Annual_salary FROM employee5;
+-----------+----------+---------------+
| name | salary | Annual_salary |
+-----------+----------+---------------+
| jack | 5000.00 | 70000.00 |
| tom | 5500.00 | 77000.00 |
| robin | 8000.00 | 112000.00 |
| alice | 7200.00 | 100800.00 |
| | 600.00 | 8400.00 |
| harry | 6000.00 | 84000.00 |
| emma | 20000.00 | 280000.00 |
| christine | 2200.00 | 30800.00 |
| zhuzhu | 2200.00 | 30800.00 |
| gougou | 2200.00 | 30800.00 |
+-----------+----------+---------------+
10 rows in set (0.00 sec)
MySQL [company]> SELECT name, salary, salary*14 Annual_salary FROM employee5;
+-----------+----------+---------------+
| name | salary | Annual_salary |
+-----------+----------+---------------+
| jack | 5000.00 | 70000.00 |
| tom | 5500.00 | 77000.00 |
| robin | 8000.00 | 112000.00 |
| alice | 7200.00 | 100800.00 |
| | 600.00 | 8400.00 |
| harry | 6000.00 | 84000.00 |
| emma | 20000.00 | 280000.00 |
| christine | 2200.00 | 30800.00 |
| zhuzhu | 2200.00 | 30800.00 |
| gougou | 2200.00 | 30800.00 |
+-----------+----------+---------------+
10 rows in set (0.00 sec)
```
##### d.定义显示格式
CONCAT() 函数用于连接字符串
```shell
MySQL [company]> SELECT concat(name, 's annual salary: ', salary*14) AS Annual_salary FROM employee5;
+------------------------------------+
| Annual_salary |
+------------------------------------+
| jacks annual salary: 70000.00 |
| toms annual salary: 77000.00 |
| robins annual salary: 112000.00 |
| alices annual salary: 100800.00 |
| s annual salary: 8400.00 |
| harrys annual salary: 84000.00 |
| emmas annual salary: 280000.00 |
| christines annual salary: 30800.00 |
| zhuzhus annual salary: 30800.00 |
| gougous annual salary: 30800.00 |
+------------------------------------+
10 rows in set (0.00 sec)
```
##### e.单条件查询
```shell
MySQL [company]> SELECT name,post FROM employee5 WHERE post='hr';
+-------+------+
| name | post |
+-------+------+
| | hr |
| harry | hr |
+-------+------+
2 rows in set (0.00 sec)
```
##### f.多条件查询
```shell
MySQL [company]> SELECT name,salary FROM employee5 WHERE post='hr' AND salary>10000;
Empty set (0.00 sec)
MySQL [company]> select * from employee5 where salary>5000 and salary<10000 or dep_id=102;
+----+-----------+--------+------------+------------+-----------------+----------+--------+--------+
| id | name | sex | hire_date | post | job_description | salary | office | dep_id |
+----+-----------+--------+------------+------------+-----------------+----------+--------+--------+
| 2 | tom | male | 2018-02-03 | instructor | teach | 5500.00 | 501 | 100 |
| 3 | robin | male | 2018-02-02 | instructor | teach | 8000.00 | 501 | 100 |
| 4 | alice | female | 2018-02-02 | instructor | teach | 7200.00 | 501 | 100 |
| 6 | harry | male | 2018-02-02 | hr | NULL | 6000.00 | 502 | 101 |
| 7 | emma | female | 2018-02-06 | sale | salecc | 20000.00 | 503 | 102 |
| 8 | christine | female | 2018-02-05 | sale | salecc | 2200.00 | 503 | 102 |
| 9 | zhuzhu | male | 2018-02-05 | sale | NULL | 2200.00 | 503 | 102 |
| 10 | gougou | male | 2018-02-05 | sale | | 2200.00 | 503 | 102 |
+----+-----------+--------+------------+------------+-----------------+----------+--------+--------+
8 rows in set (0.00 sec)
```
##### g.关键字
BETWEEN AND
```shell
MySQL [company]> SELECT name,salary FROM employee5 WHERE salary BETWEEN 5000 AND 15000;
+-------+---------+
| name | salary |
+-------+---------+
| jack | 5000.00 |
| tom | 5500.00 |
| robin | 8000.00 |
| alice | 7200.00 |
| harry | 6000.00 |
+-------+---------+
5 rows in set (0.00 sec)
MySQL [company]> SELECT name,salary FROM employee5 WHERE salary NOT BETWEEN 5000 AND 15000;
+-----------+----------+
| name | salary |
+-----------+----------+
| | 600.00 |
| emma | 20000.00 |
| christine | 2200.00 |
| zhuzhu | 2200.00 |
| gougou | 2200.00 |
+-----------+----------+
5 rows in set (0.00 sec)
```
IS NULL
```shell
MySQL [company]> SELECT name,job_description FROM employee5 WHERE job_description IS NULL;
+--------+-----------------+
| name | job_description |
+--------+-----------------+
| harry | NULL |
| zhuzhu | NULL |
+--------+-----------------+
2 rows in set (0.00 sec)
MySQL [company]> SELECT name,job_description FROM employee5 WHERE job_description IS NOT NULL;
+-----------+-----------------+
| name | job_description |
+-----------+-----------------+
| jack | teach |
| tom | teach |
| robin | teach |
| alice | teach |
| | hrcc |
| emma | salecc |
| christine | salecc |
| gougou | |
+-----------+-----------------+
8 rows in set (0.00 sec)
MySQL [company]> SELECT name,job_description FROM employee5 WHERE job_description='';
+--------+-----------------+
| name | job_description |
+--------+-----------------+
| gougou | |
+--------+-----------------+
1 row in set (0.00 sec)
```
注意NULL说明
等价于没有任何值、是未知数
NULL与0、空字符串、空格都不同,NULL没有分配存储空间
对空值做加、减、乘、除等运算操作,结果仍为空
比较时使用关键字用“is null”和“is not null”
排序时比其他数据都小索引默认是降序排列小→大所以NULL值总是排在最前
IN集合查询
```shell
MySQL [company]> SELECT name, salary FROM employee5 WHERE salary=4000 OR salary=5000 OR salary=6000 OR salary=9000 ;
+-------+---------+
| name | salary |
+-------+---------+
| jack | 5000.00 |
| harry | 6000.00 |
+-------+---------+
2 rows in set (0.00 sec)
MySQL [company]> SELECT name, salary FROM employee5 WHERE salary IN (4000,5000,6000,9000) ;
+-------+---------+
| name | salary |
+-------+---------+
| jack | 5000.00 |
| harry | 6000.00 |
+-------+---------+
2 rows in set (0.00 sec)
MySQL [company]> SELECT name, salary FROM employee5 WHERE salary NOT IN (4000,5000,6000,9000) ;
+-----------+----------+
| name | salary |
+-----------+----------+
| tom | 5500.00 |
| robin | 8000.00 |
| alice | 7200.00 |
| | 600.00 |
| emma | 20000.00 |
| christine | 2200.00 |
| zhuzhu | 2200.00 |
| gougou | 2200.00 |
+-----------+----------+
8 rows in set (0.01 sec)
```
##### h.模糊查询
关键字LIKE
通配符%:所有字符
通配符_ 一个字符
```shell
MySQL [company]> SELECT * FROM employee5 WHERE name LIKE 'al%';
+----+-------+--------+------------+------------+-----------------+---------+--------+--------+
| id | name | sex | hire_date | post | job_description | salary | office | dep_id |
+----+-------+--------+------------+------------+-----------------+---------+--------+--------+
| 4 | alice | female | 2018-02-02 | instructor | teach | 7200.00 | 501 | 100 |
+----+-------+--------+------------+------------+-----------------+---------+--------+--------+
1 row in set (0.00 sec)
MySQL [company]> SELECT * FROM employee5 WHERE name LIKE 'al___';
+----+-------+--------+------------+------------+-----------------+---------+--------+--------+
| id | name | sex | hire_date | post | job_description | salary | office | dep_id |
+----+-------+--------+------------+------------+-----------------+---------+--------+--------+
| 4 | alice | female | 2018-02-02 | instructor | teach | 7200.00 | 501 | 100 |
+----+-------+--------+------------+------------+-----------------+---------+--------+--------+
1 row in set (0.00 sec)
```
##### i.排序查询
```shell
MySQL [company]> select name,salary from employee5 order by salary;
+-----------+----------+
| name | salary |
+-----------+----------+
| | 600.00 |
| christine | 2200.00 |
| zhuzhu | 2200.00 |
| gougou | 2200.00 |
| jack | 5000.00 |
| tom | 5500.00 |
| harry | 6000.00 |
| alice | 7200.00 |
| robin | 8000.00 |
| emma | 20000.00 |
+-----------+----------+
10 rows in set (0.01 sec)
MySQL [company]> select name,salary from employee5 order by salary desc;
+-----------+----------+
| name | salary |
+-----------+----------+
| emma | 20000.00 |
| robin | 8000.00 |
| alice | 7200.00 |
| harry | 6000.00 |
| tom | 5500.00 |
| jack | 5000.00 |
| christine | 2200.00 |
| zhuzhu | 2200.00 |
| gougou | 2200.00 |
| | 600.00 |
+-----------+----------+
MySQL [company]> select name,salary from employee5 order by salary desc limit 3; //控制显示前3行
+-------+----------+
| name | salary |
+-------+----------+
| emma | 20000.00 |
| robin | 8000.00 |
| alice | 7200.00 |
+-------+----------+
3 rows in set (0.00 sec)
MySQL [company]> select name,salary from employee5 order by salary desc limit 1,3; //从序号1开始显示三行的内容
+-------+---------+
| name | salary |
+-------+---------+
| robin | 8000.00 |
| alice | 7200.00 |
| harry | 6000.00 |
+-------+---------+
3 rows in set (0.00 sec)
```
注意:
ascending 美音 /ə'sɛndɪŋ/ 升序
descending 美音 /dɪ'sɛndɪŋ/ 降序
##### j.集合函数查询
count可以查看共有多少条记录
```shell
MySQL [company]> select count(*) from employee5;
+----------+
| count(*) |
+----------+
| 10 |
+----------+
1 row in set (0.00 sec)
MySQL [company]> select count(name) from employee5;
+-------------+
| count(name) |
+-------------+
| 10 |
+-------------+
1 row in set (0.00 sec)
```
max查看最大值
```shell
MySQL [company]> select max(salary) from employee5;
+-------------+
| max(salary) |
+-------------+
| 20000.00 |
+-------------+
1 row in set (0.00 sec)
```
min查看最小值
```shell
MySQL [company]> select min(salary) from employee5;
+-------------+
| min(salary) |
+-------------+
| 600.00 |
+-------------+
1 row in set (0.00 sec)
```
avg查看平均值
```shell
MySQL [company]> select avg(salary) from employee5;
+-------------+
| avg(salary) |
+-------------+
| 5890.000000 |
+-------------+
1 row in set (0.00 sec)
```
sum求和
sale这个部门的总工资
```shell
MySQL [company]> select concat("Total Department Wages",sum(salary)) from employee5 where post='sale';
+-------------------------------------------------+
| concat("Total Department Wages",sum(salary)) |
+-------------------------------------------------+
| Total Department Wages26600.00 |
+-------------------------------------------------+
1 row in set (0.00 sec)
```
获取薪水最高的这个人的详细信息
```shell
MySQL [company]> select * from employee5 where salary = (select max(salary) from employee5);
+----+------+--------+------------+------+-----------------+----------+--------+--------+
| id | name | sex | hire_date | post | job_description | salary | office | dep_id |
+----+------+--------+------------+------+-----------------+----------+--------+--------+
| 7 | emma | female | 2018-02-06 | sale | salecc | 20000.00 | 503 | 102 |
+----+------+--------+------------+------+-----------------+----------+--------+--------+
1 row in set (0.00 sec)
```
##### k.分组查询
GROUP BY和GROUP_CONCAT()函数一起使用
获取部门ID相同的员工并把名字拼接到一起
```shell
MySQL [company]> SELECT dep_id,GROUP_CONCAT(name) FROM employee5 GROUP BY dep_id;
+--------+------------------------------+
| dep_id | GROUP_CONCAT(name) |
+--------+------------------------------+
| 100 | jack,tom,robin,alice |
| 101 | ,harry |
| 102 | emma,christine,zhuzhu,gougou |
+--------+------------------------------+
3 rows in set (0.01 sec)
```
GROUP BY和集合函数一起使用
获取部门最高薪资
```shell
MySQL [company]> SELECT post,max(salary) FROM employee5 GROUP BY post;
+------------+-------------+
| post | max(salary) |
+------------+-------------+
| hr | 6000.00 |
| instructor | 8000.00 |
| sale | 20000.00 |
+------------+-------------+
3 rows in set (0.00 sec)
```
##### l.正则查询
```shell
以什么开头
MySQL [company]> SELECT * FROM employee5 WHERE name REGEXP '^ali';
+----+-------+--------+------------+------------+-----------------+---------+--------+--------+
| id | name | sex | hire_date | post | job_description | salary | office | dep_id |
+----+-------+--------+------------+------------+-----------------+---------+--------+--------+
| 4 | alice | female | 2018-02-02 | instructor | teach | 7200.00 | 501 | 100 |
+----+-------+--------+------------+------------+-----------------+---------+--------+--------+
1 row in set (0.00 sec)
以什么结尾
MySQL [company]> SELECT * FROM employee5 WHERE name REGEXP 'ce$';
+----+-------+--------+------------+------------+-----------------+---------+--------+--------+
| id | name | sex | hire_date | post | job_description | salary | office | dep_id |
+----+-------+--------+------------+------------+-----------------+---------+--------+--------+
| 4 | alice | female | 2018-02-02 | instructor | teach | 7200.00 | 501 | 100 |
+----+-------+--------+------------+------------+-----------------+---------+--------+--------+
1 row in set (0.01 sec)
连续出现n次
MySQL [company]> SELECT * FROM employee5 WHERE name REGEXP 'm{2}';
+----+------+--------+------------+------+-----------------+----------+--------+--------+
| id | name | sex | hire_date | post | job_description | salary | office | dep_id |
+----+------+--------+------------+------+-----------------+----------+--------+--------+
| 7 | emma | female | 2018-02-06 | sale | salecc | 20000.00 | 503 | 102 |
+----+------+--------+------------+------+-----------------+----------+--------+--------+
1 row in set (0.00 sec)
```
## 二:多表联合查询
【扩展了解】
#### 1.数据准备
##### 表company.employee6
创建表:
```shell
MySQL [company]> create table employee6(
emp_id int auto_increment primary key not null,
emp_name varchar(50),
age int,
dept_id int);
Query OK, 0 rows affected (0.65 sec)
```
查看表结构:
```shell
MySQL [company]> desc employee6;
+----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+----------------+
| emp_id | int(11) | NO | PRI | NULL | auto_increment |
| emp_name | varchar(50) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
| dept_id | int(11) | YES | | NULL | |
+----------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
```
插入模拟数据:
```shell
MySQL [company]> insert into employee6(emp_name,age,dept_id) values
('',19,200),
('tom',26,201),
('jack',30,201),
('alice',24,202),
('robin',40,200),
('xingdian',16,200),
('natasha',28,204);
```
查看数据:
```shell
MySQL [company]> select * from employee6;
+--------+----------+------+---------+
| emp_id | emp_name | age | dept_id |
+--------+----------+------+---------+
| 1 | | 19 | 200 |
| 2 | tom | 26 | 201 |
| 3 | jack | 30 | 201 |
| 4 | alice | 24 | 202 |
| 5 | robin | 40 | 200 |
| 6 | xingdian | 16 | 200 |
| 7 | natasha | 28 | 204 |
+--------+----------+------+---------+
7 rows in set (0.00 sec)
```
##### 表company.department6
创建表:
```shell
MySQL [company]> create table department6(
dept_id int,
dept_name varchar(100)
);
Query OK, 0 rows affected (0.33 sec)
```
查看表结构:
```shell
MySQL [company]> desc department6;
+-----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+-------+
| dept_id | int(11) | YES | | NULL | |
| dept_name | varchar(100) | YES | | NULL | |
+-----------+--------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
```
模拟插入数据:
```shell
MySQL [company]> insert into department6 values
(200,'hr'),
(201,'it'),
(202,'sale'),
(203,'fd');
```
查看数据:
```shell
MySQL [company]> select * from department6;
+---------+-----------+
| dept_id | dept_name |
+---------+-----------+
| 200 | hr |
| 201 | it |
| 202 | sale |
| 203 | fd |
+---------+-----------+
4 rows in set (0.01 sec)
```
#### 2.多表的连接查询
交叉连接:生成笛卡尔积,它不使用任何匹配条件;交叉联接返回左表中的所有行,左表中的每一行与右表中的所有行组合
内连接:只连接匹配的行
外连接
左连接:会显示左边表内所有的值,不论在右边表内匹不匹配
右连接:会显示右边表内所有的值,不论在左边表内匹不匹配
全外连接:包含左、右两个表的全部行
##### 交叉连接
```shell
MySQL [company]> select employee6.emp_name,employee6.age,employee6.dept_id,department6.dept_name from employee6,department6;
+----------+------+---------+-----------+
| emp_name | age | dept_id | dept_name |
+----------+------+---------+-----------+
| | 19 | 200 | hr |
| | 19 | 200 | it |
| | 19 | 200 | sale |
| | 19 | 200 | fd |
| tom | 26 | 201 | hr |
| tom | 26 | 201 | it |
| tom | 26 | 201 | sale |
| tom | 26 | 201 | fd |
| jack | 30 | 201 | hr |
| jack | 30 | 201 | it |
| jack | 30 | 201 | sale |
| jack | 30 | 201 | fd |
| alice | 24 | 202 | hr |
| alice | 24 | 202 | it |
| alice | 24 | 202 | sale |
| alice | 24 | 202 | fd |
| robin | 40 | 200 | hr |
| robin | 40 | 200 | it |
| robin | 40 | 200 | sale |
| robin | 40 | 200 | fd |
| xingdian | 16 | 200 | hr |
| xingdian | 16 | 200 | it |
| xingdian | 16 | 200 | sale |
| xingdian | 16 | 200 | fd |
| natasha | 28 | 204 | hr |
| natasha | 28 | 204 | it |
| natasha | 28 | 204 | sale |
| natasha | 28 | 204 | fd |
+----------+------+---------+-----------+
28 rows in set (0.00 sec)
```
##### 内连接
获取有部门的员工 (部门表中没有natasha所在的部门)
```shell
MySQL [company]> select employee6.emp_name,employee6.age,employee6.dept_id,department6.dept_name from employee6,department6 where employee6.dept_id=department6.dept_id;
+----------+------+---------+-----------+
| emp_name | age | dept_id | dept_name |
+----------+------+---------+-----------+
| | 19 | 200 | hr |
| tom | 26 | 201 | it |
| jack | 30 | 201 | it |
| alice | 24 | 202 | sale |
| robin | 40 | 200 | hr |
| xingdian | 16 | 200 | hr |
+----------+------+---------+-----------+
6 rows in set (0.00 sec)
MySQL [company]> select employee6.emp_name,department6.dept_name from employee6 inner join department6 on employee6.dept_id=department6.dept_id;
+----------+-----------+
| emp_name | dept_name |
+----------+-----------+
| | hr |
| tom | it |
| jack | it |
| alice | sale |
| robin | hr |
| xingdian | hr |
+----------+-----------+
6 rows in set (0.01 sec)
```
##### 外连接
语法:
SELECT 字段列表 FROM 表1 LEFT|RIGHT JOIN 表2 ON 表1.字段 = 表2.字段;
注意:
先用谁谁就是左
###### 左连接 left join
```shell
找出所有员工及所属的部门,包括没有部门的员工
MySQL [company]> select emp_id,emp_name,dept_name from employee6 left join department6 on employee6.dept_id = department6.dept_id;
+--------+----------+-----------+
| emp_id | emp_name | dept_name |
+--------+----------+-----------+
| 1 | | hr |
| 5 | robin | hr |
| 6 | xingdian | hr |
| 2 | tom | it |
| 3 | jack | it |
| 4 | alice | sale |
| 7 | natasha | NULL |
+--------+----------+-----------+
7 rows in set (0.00 sec)
```
###### 右连接right join
```
找出所有部门包含的员工,包括空部门
MySQL [company]> select emp_id,emp_name,dept_name from employee6 right join department6 on employee6.dept_id = department6.dept_id;
+--------+----------+-----------+
| emp_id | emp_name | dept_name |
+--------+----------+-----------+
| 1 | | hr |
| 2 | tom | it |
| 3 | jack | it |
| 4 | alice | sale |
| 5 | robin | hr |
| 6 | xingdian | hr |
| NULL | NULL | fd |
+--------+----------+-----------+
7 rows in set (0.00 sec)
```
##### 全外连接
```shell
MySQL [company]> select * from employee6 full join department6;
+--------+----------+------+---------+---------+-----------+
| emp_id | emp_name | age | dept_id | dept_id | dept_name |
+--------+----------+------+---------+---------+-----------+
| 1 | | 19 | 200 | 200 | hr |
| 1 | | 19 | 200 | 201 | it |
| 1 | | 19 | 200 | 202 | sale |
| 1 | | 19 | 200 | 203 | fd |
| 2 | tom | 26 | 201 | 200 | hr |
| 2 | tom | 26 | 201 | 201 | it |
| 2 | tom | 26 | 201 | 202 | sale |
| 2 | tom | 26 | 201 | 203 | fd |
| 3 | jack | 30 | 201 | 200 | hr |
| 3 | jack | 30 | 201 | 201 | it |
| 3 | jack | 30 | 201 | 202 | sale |
| 3 | jack | 30 | 201 | 203 | fd |
| 4 | alice | 24 | 202 | 200 | hr |
| 4 | alice | 24 | 202 | 201 | it |
| 4 | alice | 24 | 202 | 202 | sale |
| 4 | alice | 24 | 202 | 203 | fd |
| 5 | robin | 40 | 200 | 200 | hr |
| 5 | robin | 40 | 200 | 201 | it |
| 5 | robin | 40 | 200 | 202 | sale |
| 5 | robin | 40 | 200 | 203 | fd |
| 6 | xingdian | 16 | 200 | 200 | hr |
| 6 | xingdian | 16 | 200 | 201 | it |
| 6 | xingdian | 16 | 200 | 202 | sale |
| 6 | xingdian | 16 | 200 | 203 | fd |
| 7 | natasha | 28 | 204 | 200 | hr |
| 7 | natasha | 28 | 204 | 201 | it |
| 7 | natasha | 28 | 204 | 202 | sale |
| 7 | natasha | 28 | 204 | 203 | fd |
+--------+----------+------+---------+---------+-----------+
28 rows in set (0.00 sec)
```
#### 3.复合条件连接查询
##### 案例一
找出公司所有部门中年龄大于25岁的员工
以内连接的方式查询employee6和department6表并且employee6表中的age字段值必须大于25
```shell
MySQL [company]> select emp_id,emp_name,dept_name FROM employee6,department6 WHERE employee6.dept_id = department6.dept_id AND age > 25;
+--------+----------+-----------+
| emp_id | emp_name | dept_name |
+--------+----------+-----------+
| 5 | robin | hr |
| 2 | tom | it |
| 3 | jack | it |
+--------+----------+-----------+
3 rows in set (0.01 sec)
```
##### 案例二
以内连接的方式查询employee6和department6表并且以age字段的升序方式显示
```shell
MySQL [company]> select emp_id,emp_name,dept_name FROM employee6,department6 WHERE employee6.dept_id = department6.dept_id ORDER BY age asc;
+--------+----------+-----------+
| emp_id | emp_name | dept_name |
+--------+----------+-----------+
| 6 | xingdian | hr |
| 1 | | hr |
| 4 | alice | sale |
| 2 | tom | it |
| 3 | jack | it |
| 5 | robin | hr |
+--------+----------+-----------+
```
#### 4.子查询
子查询是将一个查询语句嵌套在另一个查询语句中
内层查询语句的查询结果,可以为外层查询语句提供查询条件
子查询中可以包含IN、NOT IN等关键字还可以包含比较运算符= 、 !=、> 、<
##### 案例一
带IN关键字的子查询查询employee表但dept_id必须在department表中出现过
```shell
MySQL [company]> select * from employee6 WHERE dept_id IN (select dept_id FROM department6);
+--------+----------+------+---------+
| emp_id | emp_name | age | dept_id |
+--------+----------+------+---------+
| 1 | | 19 | 200 |
| 2 | tom | 26 | 201 |
| 3 | jack | 30 | 201 |
| 4 | alice | 24 | 202 |
| 5 | robin | 40 | 200 |
| 6 | xingdian | 16 | 200 |
+--------+----------+------+---------+
6 rows in set (0.00 sec)
```
##### 案例二
带比较运算符的子查询查询年龄大于等于25岁员工所在部门查询老龄化的部门
```shell
MySQL [company]> select dept_id,dept_name FROM department6 WHERE dept_id IN (SELECT DISTINCT dept_id FROM employee6 WHERE age >=25);
+---------+-----------+
| dept_id | dept_name |
+---------+-----------+
| 201 | it |
| 200 | hr |
+---------+-----------+
2 rows in set (0.00 sec)
```

View File

@ -0,0 +1,861 @@
<h1><center>数据库管理及数据类型</center></h1>
**作者:行癫(盗版必究)**
------
## 一:数据类型
#### 1.数值类型
##### 整数类型
整数类型TINYINT SMALLINT MEDIUMINT INT BIGINT
作用用于存储用户的年龄、游戏的Level、经验值等
![image-20220920124821420](https://xingdian-image.oss-cn-beijing.aliyuncs.com/xingdian-image/image-20220920124821420.png)
##### 浮点数类型
浮点数类型FLOAT DOUBLE
作用:用于存储用户的身高、体重、薪水等
![image-20220920124919373](https://xingdian-image.oss-cn-beijing.aliyuncs.com/xingdian-image/image-20220920124919373.png)
```shell
float(5,3) 5宽度 3精度
注意:
宽度不算小数点
宽度-精度=点前
案例:
MySQL [(none)]> create database diandian;
Query OK, 1 row affected (0.00 sec)
MySQL [(none)]> use diandian
Database changed
MySQL [diandian]> create table t1(id float(6,2));
Query OK, 0 rows affected (0.24 sec)
MySQL [diandian]> insert into t1 values('2.22');
```
##### 定点数类型
定点数类型DEC
定点数在MySQL内部以字符串形式存储比浮点数更精确适合用来表示货币等精度高的数据
##### 位类型
位类型BIT
BIT(M)可以用来存放多位二进制数M范围从1~64如果不写默认为1位
#### 2.字符串类型
CHAR系列 CHAR VARCHAR
TEXT系列 TINYTEXT TEXT MEDIUMTEXT LONGTEXT
BLOB 系列 TINYBLOB BLOB MEDIUMBLOB LONGBLOB
BINARY系列 BINARY VARBINARY
![image-20220920132114919](https://xingdian-image.oss-cn-beijing.aliyuncs.com/xingdian-image/image-20220920132114919.png)
##### 枚举类型
枚举类型:枚举列可以把一些不重复的字符串存储成一个预定义的集合
```shell
mysql> create table enum_table( e ENUM('fish','apple','dog'));
Query OK, 0 rows affected (0.35 sec)
mysql> insert into enum_table(e) values('fish');
Query OK, 1 row affected (0.11 sec)
mysql> select * from enum_table;
+------+
| e |
+------+
| fish |
+------+
1 row in set (0.00 sec)
mysql> insert into enum_table(e) values('nihao');
ERROR 1265 (01000): Data truncated for column 'e' at row 1
```
##### 时间和日期类型
时间和日期类型DATE TIME DATETIME TIMESTAMP YEAR
作用:用于存储用户的注册时间,文章的发布时间,文章的更新时间,员工的入职时间等
![image-20220920132630856](https://xingdian-image.oss-cn-beijing.aliyuncs.com/xingdian-image/image-20220920132630856.png)
```shell
mysql> create table t8 (
id1 timestamp NOT NULL default CURRENT_TIMESTAMP,
id2 datetime default NULL
);
timestamp 类型的列还有个特性:默认情况下,在 insert, update 数据时timestamp 列会自动以当前时间CURRENT_TIMESTAMP填充/更新。“自动”的意思就是你不去管它MySQL 会替你去处理。
mysql> insert into t8(id1) values('20180109000000');
mysql> select * from t8;
+---------------------+------+
| id1 | d2 |
+---------------------+------+
| 2018-01-09 00:00:00 | NULL |
+---------------------+------+
1 row in set (0.00 sec)
扩展:
select now();查看当前时间
```
## 二:表操作
#### 1.案例
表:school.student1
```
字段 字段 字段
id name sex age
1 tom male 23 记录
2 jack male 21 记录
3 alice female 19 记录
```
语法:
```shell
create table 表名(自定义)(
字段名1 类型[(宽度) 约束条件],
字段名2 类型[(宽度) 约束条件],
字段名3 类型[(宽度) 约束条件]
)[存储引擎 字符集];
==在同一张表中,字段名是不能相同
==宽度和约束条件可选
==字段名和类型是必须的
```
创建库表:
```shell
mysql> CREATE DATABASE school; //创建数据库school
mysql> use school;
mysql> create table student1(
id int,
name varchar(50),
sex enum('m','f'),
age int
);
Query OK, 0 rows affected (0.03 sec)
```
查看库:
```shell
mysql> show tables;
+------------------+
| Tables_in_school |
+------------------+
| student1 |
+------------------+
1 row in set (0.00 sec)
```
插入语法:
```
insert into 表名(字段1,字段2...) values(字段值列表...);
```
插入数据:
```shell
mysql> insert into student1(id,name,sex,age) values(1,'xingdia','m','26');
```
查看表结构:
```shell
mysql> desc student1;
+-------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(50) | YES | | NULL | |
| sex | enum('m','f') | YES | | NULL | |
| age | int(11) | YES | | NULL | |
+-------+---------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
```
查询数据:
```shell
mysql> select id,name,sex,age from student1; //查询表中所有字段的值
Empty set (0.00 sec)
mysql> select * from student1; /查询表中所有字段的值
Empty set (0.00 sec)
mysql> select name,age from student1; //查询表中指定字段的值
Empty set (0.00 sec)
```
扩展插入:
```shell
mysql> insert into student1 values (1,'xingdian','m',33),(2,'alice','m',20),(3,'jack','m',40); //顺序插入
Query OK, 3 rows affected (0.14 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> insert into student1(name,age) values ('zhuzhu',10),('gougou',20); //只向指定的字段插入值
Query OK, 2 rows affected (0.12 sec)
Records: 2 Duplicates: 0 Warnings: 0
```
#### 2.案例
school.student2
```shell
字段名 数据类型
编号 id int
姓名 name varchar(50)
出生年份 born_year year
生日 birthday date
上课时间 class_time time
注册时间 reg_time datetime
```
创建表:
```shell
mysql> create table student2(
id int,
name varchar(50),
born_year year,
birthday date,
class_time time,
reg_time datetime
);
```
插入数据:
```shell
mysql> insert into student2 values(1,'tom',now(),now(),now(),now());
mysql> insert into student2 values(2,'jack',1982,19821120,123000,20140415162545);
```
school.student3
```shell
id id int
姓名 name varchar(50)
性别 sex enum('male','female')
爱好 hobby set('music','book','game','disc')
```
创建表:
```shell
mysql> create table student3(
id int,
name varchar(50),
sex enum('male','female'),
hobby set('music','book','game','disc')
);
```
查看表结构:
```shell
mysql> desc student3;
mysql> show create table student3\G
```
插入数据:
```shell
mysql> insert into student3 values (1,'tom','male','book,game');
mysql> insert into student3 values (2,'jack','male','film');
```
注意:
DESCRIBE查看表结构
```shell
DESCRIBE 表名;
DESC 表名;
```
查看表详细结构
```shell
SHOW CREATE TABLE 表名;
```
## 三:表完整性约束
#### 1.作用
用于保证数据的完整性和一致性
#### 2.约束条件
PRIMARY KEY (PK) 标识该字段为该表的主键,可以唯一的标识记录,不可以为空 UNIQUE + NOT NULL
FOREIGN KEY (FK) 标识该字段为该表的外键,实现表与表(父表主键/子表1外键/子表2外键之间的关联
NOT NULL 标识该字段不能为空
UNIQUE KEY (UK) 标识该字段的值是唯一的可以为空一个表中可以有多个UNIQUE KEY
AUTO_INCREMENT 标识该字段的值自动增长(整数类型,而且为主键)
DEFAULT 为该字段设置默认值
注意:
是否允许为空默认NULL可设置NOT NULL字段不允许为空必须赋值
字段是否有默认值缺省的默认值是NULL如果插入记录时不给字段赋值此字段使用默认值
```shell
MySQL [(none)]> sex enum('male','female') not null default 'male'
MySQL [(none)]> age int unsigned NOT NULL default 20 必须为正值(无符号) 不允许为空 默认是20
```
是否是key 主键 primary key 外键 forengn key
#### 3.NOT NULL
school.student4
创建表:(注意前提需要有库)
```shell
mysql> create table school.student4(
id int not null,
name varchar(50) not null,
sex enum('m','f') default 'm' not null,
age int unsigned default 18 not null,
hobby set('music','disc','dance','book') default 'book,dance'
);
```
插入数据:(注意观察查询到的数据)
```shell
MySQL [(none)]> insert into school.student4(id,name) values(2,'robin');
Query OK, 1 row affected (0.08 sec)
MySQL [(none)]> select * from school.student4;
+----+-------+-----+-----+------------+
| id | name | sex | age | hobby |
+----+-------+-----+-----+------------+
| 2 | robin | m | 18 | dance,book |
+----+-------+-----+-----+------------+
1 row in set (0.00 sec)
```
注意报错的原因:
```shell
MySQL [(none)]> insert into school.student4 values(3,NULL,'m',40,'book');
ERROR 1048 (23000): Column 'name' cannot be null
```
#### 4.唯一约束
作用:
MySQL索引的建立对于MySQL的高效运行是很重要的索引可以大大提高MySQL的检索速度
company.department1
创建表:
```shell
MySQL [(none)]> create database company;
Query OK, 1 row affected (0.01 sec)
MySQL [(none)]> CREATE TABLE company.department1 (dept_id INT,dept_name VARCHAR(30) UNIQUE,comment VARCHAR(50));
Query OK, 0 rows affected (0.34 sec)
```
查看表结构:
```shell
MySQL [(none)]> desc company.department1;
+-----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| dept_id | int(11) | YES | | NULL | |
| dept_name | varchar(30) | YES | UNI | NULL | |
| comment | varchar(50) | YES | | NULL | |
+-----------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
```
数据插入:(注意查看插入数据时的提示)
```shell
MySQL [(none)]> insert into company.department1 values ("1","xingdian","hr");
Query OK, 1 row affected (0.04 sec)
MySQL [(none)]> insert into company.department1 values ("1","xingdian","hr");
ERROR 1062 (23000): Duplicate entry 'xingdian' for key 'dept_name'
```
#### 5.主键约束
注意primary key 字段的值是不允许重复且不允许不NULLUNIQUE + NOT NULL
school.student6
创建表:
```shell
MySQL [(none)]> create table school.student6(
-> id int primary key not null auto_increment,
-> name varchar(50) not null,
-> sex enum('male','female') not null default 'male',
-> age int not null default 18
-> );
Query OK, 0 rows affected (0.47 sec)
```
插入数据:
```shell
MySQL [(none)]> insert into school.student6 values (1,'alice','female',22);
Query OK, 1 row affected (0.18 sec)
MySQL [(none)]> insert into school.student6(name,sex,age) values
-> ('jack','male',19),
-> ('tom','male',23);
Query OK, 2 rows affected (0.14 sec)
Records: 2 Duplicates: 0 Warnings: 0
MySQL [(none)]> select * from school.student6;
+----+-------+--------+-----+
| id | name | sex | age |
+----+-------+--------+-----+
| 1 | alice | female | 22 |
| 2 | jack | male | 19 |
| 3 | tom | male | 23 |
+----+-------+--------+-----+
3 rows in set (0.00 sec)
```
## 四:修改表
语法格式:
修改表名
ALTER TABLE 表名 RENAME 新表名;
增加字段
ALTER TABLE 表名
ADD 字段名 数据类型 [完整性约束条件…],
ADD 字段名 数据类型 [完整性约束条件…];
ALTER TABLE 表名
ADD 字段名 数据类型 [完整性约束条件…] AFTER 字段名;
删除字段
ALTER TABLE 表名 DROP 字段名;
修改字段
ALTER TABLE 表名 MODIFY 字段名 数据类型 [完整性约束条件…];
ALTER TABLE 表名 CHANGE 旧字段名 新字段名 旧数据类型 [完整性约束条件…];
ALTER TABLE 表名 CHANGE 旧字段名 新字段名 新数据类型 [完整性约束条件…];
#### 1.修改数据库引擎
```shell
mysql> alter table service engine=innodb; //engine=myisam|memory|....
```
#### 2.添加字段
```shell
mysql> create table student10 (id int);
mysql> alter table student10 add name varchar(20) not null, add age int not null default 22;
mysql> alter table student10 add stu_num int not null after name; //添加name字段之后
mysql> alter table student10 add sex enum('male','female') default 'male' first; //添加到最前面
```
#### 3.删除字段
```shell
mysql> alter table student10 drop sex;
```
#### 4.修改字段类型
```shell
MySQL [school]> desc student10;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.01 sec)
MySQL [school]> alter table student10 modify age tinyint not null ;
Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0
MySQL [school]> desc student10;
+-------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| age | tinyint(4) | NO | | NULL | |
+-------+------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
MySQL [school]> alter table student10 modify id int not null primary key ; ////修改字段类型、约束、主键
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
MySQL [school]> desc student10;
+-------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| age | tinyint(4) | NO | | NULL | |
+-------+------------+------+-----+---------+-------+
```
#### 5.增加约束
```shell
MySQL [school]> alter table student10 modify id int not null primary key ;
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
MySQL [school]> desc student10;
+-------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| age | tinyint(4) | NO | | NULL | |
+-------+------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
MySQL [school]> alter table student10 modify id int not null primary key auto_increment;
ERROR 1068 (42000): Multiple primary key defined //错误该字段已经是primary key
MySQL [school]> alter table student10 modify id int not null auto_increment;
Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0
MySQL [school]> desc student10;
+-------+------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| age | tinyint(4) | NO | | NULL | |
+-------+------------+------+-----+---------+----------------+
```
#### 6.增加主键
```shell
MySQL [school]> desc student1;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
| name | char(1) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
3 rows in set (0.00 sec)
MySQL [school]> alter table student1 add primary key(id);
MySQL [school]> desc student1;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| age | int(11) | YES | | NULL | |
| name | char(1) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
3 rows in set (0.00 sec)
```
#### 7.修改主键和自增
```shell
MySQL [school]> alter table student1 modify id int auto_increment;
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
MySQL [school]> desc student1;
+-------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| age | int(11) | YES | | NULL | |
| name | char(1) | YES | | NULL | |
+-------+---------+------+-----+---------+----------------+
```
#### 8.删除主键
```shell
MySQL [school]> desc student10;
+-------+------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| age | tinyint(4) | NO | | NULL | |
+-------+------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
MySQL [school]> alter table student10 drop primary key;
ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key
删除自增
ySQL [school]> alter table student10 modify id int not null;
Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0
MySQL [school]> desc student10;
+-------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| age | tinyint(4) | NO | | NULL | |
+-------+------------+------+-----+---------+-------+
MySQL [school]> alter table student10 drop primary key;
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
MySQL [school]> desc student10;
+-------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| id | int(11) | NO | | NULL | |
| age | tinyint(4) | NO | | NULL | |
+-------+------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
```
#### 9.复制表
复制表结构+记录 key不会复制: 主键、外键和索引)复制表结构/记录+表结构不会将Key复制
```shell
mysql> create table new_service select * from service;
```
只复制表结构
```shell
mysql> create table new1_service select * from service where 1=2; //条件为假,查不到任何记录
```
可以复制主键,只复制表结构
```shell
mysql> create table t4 like employees;
```
#### 10.删除表
```shell
mysql> DROP TABLE 表名;
```
#### 11.修改数据表中字段的值
语法:
Update 表名 set 列名=值where 条件
```shell
mysql> update student set name='123' where id=1;
```
删除某一行:
delete from 表名 where id=1
```shell
mysql> delete from type where id=1;
```
## 五:库操作
#### 1.简介
系统自带库的含义及作用
```shell
MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
```
information_schema虚拟库主要存储了系统中的一些数据库对象的信息例如用户表信息、列信息、权限信息、字符信息等
performance_schema主要存储数据库服务器的性能参数
mysql授权库主要存储系统用户的权限信息
sys主要存储数据库服务器的性能参数
注意information_schema
SCHEMATA 存放的是系统中的库
```shell
MySQL [information_schema]> select * from information_schema.SCHEMATA;
+--------------+--------------------+----------------------------+------------------------+----------+
| CATALOG_NAME | SCHEMA_NAME | DEFAULT_CHARACTER_SET_NAME | DEFAULT_COLLATION_NAME | SQL_PATH |
+--------------+--------------------+----------------------------+------------------------+----------+
| def | information_schema | utf8 | utf8_general_ci | NULL |
| def | mysql | latin1 | latin1_swedish_ci | NULL |
| def | performance_schema | utf8 | utf8_general_ci | NULL |
| def | school | latin1 | latin1_swedish_ci | NULL |
| def | sys | utf8 | utf8_general_ci | NULL |
+--------------+--------------------+----------------------------+------------------------+----------+
目录_名称
实际库_名称
默认_字符_设置_名称
默认_分类_名称
```
TABLES 存储表名
```shell
MySQL [information_schema]> select * from information_schema.TABLES\G
*************************** 283. row ***************************
TABLE_CATALOG: def
TABLE_SCHEMA: xingdian
TABLE_NAME: t1
TABLE_TYPE: BASE TABLE
ENGINE: InnoDB
VERSION: 10
ROW_FORMAT: Dynamic
TABLE_ROWS: 1
AVG_ROW_LENGTH: 16384
DATA_LENGTH: 16384
MAX_DATA_LENGTH: 0
INDEX_LENGTH: 0
DATA_FREE: 0
AUTO_INCREMENT: NULL
CREATE_TIME: 2022-09-22 08:18:38
UPDATE_TIME: 2022-09-22 08:18:54
CHECK_TIME: NULL
TABLE_COLLATION: latin1_swedish_ci
CHECKSUM: NULL
CREATE_OPTIONS:
TABLE_COMMENT:
283 rows in set (0.02 sec)
```
COLUMNS 存储字段
```shell
*************************** 3083. row ***************************
TABLE_CATALOG: def
TABLE_SCHEMA: xingdian
TABLE_NAME: t1
COLUMN_NAME: id
ORDINAL_POSITION: 1
COLUMN_DEFAULT: NULL
IS_NULLABLE: YES
DATA_TYPE: int
CHARACTER_MAXIMUM_LENGTH: NULL
CHARACTER_OCTET_LENGTH: NULL
NUMERIC_PRECISION: 10
NUMERIC_SCALE: 0
DATETIME_PRECISION: NULL
CHARACTER_SET_NAME: NULL
COLLATION_NAME: NULL
COLUMN_TYPE: int(11)
COLUMN_KEY:
EXTRA:
PRIVILEGES: select,insert,update,references
COLUMN_COMMENT:
GENERATION_EXPRESSION:
3083 rows in set (0.03 sec)
```
#### 2.创建库
方案一:交互式操作
```shell
mysql> create database xingdian;
```
数据库命名规则:
区分大小写
唯一性
不能使用关键字如 create select
不能单独使用数字
方案二:非交互式
```shell
mysql -u root -pQianFeng@123 -e "create database diandian"
```
#### 3.查看数据库
```shell
mysql> show databases;
mysql> show create database xingdian;
mysql> select database(); 查看当前所在的库
```
#### 4.切换数据库
```shell
mysql> use xingdian;
```
#### 5.删除数据库
```shell
mysql> DROP DATABASE 数据库名;
```