From 3e6f26362a8b42aae3ffbaa650b31b41524f1638 Mon Sep 17 00:00:00 2001 From: kongziyu <2262843700@qq.com> Date: Wed, 4 Sep 2024 09:41:28 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E6=96=87=E4=BB=B6=E8=87=B3?= =?UTF-8?q?=20/?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Mysql常见配置.md | 173 ++++++ 第一章:数据库基础.md | 412 ++++++++++++++ 第七章:读写分离.md | 521 +++++++++++++++++ 第三章:数据库查询.md | 975 ++++++++++++++++++++++++++++++++ 第二章:数据库管理及数据类型.md | 861 ++++++++++++++++++++++++++++ 5 files changed, 2942 insertions(+) create mode 100644 Mysql常见配置.md create mode 100644 第一章:数据库基础.md create mode 100644 第七章:读写分离.md create mode 100644 第三章:数据库查询.md create mode 100644 第二章:数据库管理及数据类型.md diff --git a/Mysql常见配置.md b/Mysql常见配置.md new file mode 100644 index 0000000..d4130b2 --- /dev/null +++ b/Mysql常见配置.md @@ -0,0 +1,173 @@ +

Mysql常见配置

+ +作者:行癫(盗版必究) + +------ + +``` +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级参数,在每个connection(session)第一次需要使用这个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 内存配置为8,2GB配置为16,3GB配置为32,4GB或更高内存,可配置更大。 + +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开发人员建议设置为1-8M之间 + +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 +将没有使用索引的查询也记录下来 +``` + diff --git a/第一章:数据库基础.md b/第一章:数据库基础.md new file mode 100644 index 0000000..c75f50b --- /dev/null +++ b/第一章:数据库基础.md @@ -0,0 +1,412 @@ +

数据库基础

+ +**作者:行癫(盗版必究)** + +------ + +## 一:数据库简介 + +#### 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.数据库部署 + +##### 版本 + +​ mysql:8.0 + +​ mysql:5.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操作,可以选择Archive,Archive支持高并发的插入操作,但是本身不是事务安全的。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.外键 + +【阅读了解】 + +​ 在实际开发的项目中,一个健壮数据库中的数据一定有很好的参照完整性。例如学生档案和成绩单两张表,如果成绩单中有张三的成绩,学生档案中张三的档案却被删除了,这样就会产生垃圾数据或者错误数据。为了保证数据的完整性,将两张表之间的数据建立关系,因此就需要在成绩表中添加外键约束 + +​ 外键是指引用另外一个表中的一列或多列数据,被引用的列应该具有主键约束或者唯一性约束。外键用来建立和加强两个表数据之间的连接 + +##### 外键的定义 + +​ 外键是某个表中的一列,它包含在另一个表的主键中 + +​ 外键也是索引的一种,是通过一张表中的一列指向另一张表中的主键,来对两张表进行关联 + +​ 一张表可以有一个外键,也可以存在多个外键,与多张表进行关联 + +##### 外键的作用 + +​ 外键的主要作用是保证数据的一致性和完整性,并且减少数据冗余 diff --git a/第七章:读写分离.md b/第七章:读写分离.md new file mode 100644 index 0000000..767d910 --- /dev/null +++ b/第七章:读写分离.md @@ -0,0 +1,521 @@ +

读写分离

+ +**作者:行癫(盗版必究)** + +------ + +## 一:读写分离部署 + +#### 1.环境介绍 + +![image-20221006131313211](https://xingdian-image.oss-cn-beijing.aliyuncs.com/xingdian-image/image-20221006131313211.png) + +#### 2.读写分离集群部署 + +##### A:数据库集群部署(略) + +​ 单主单从;多主多从等均可 + +##### B:Mycat部署 + +​ 新机器,不需要安装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关联,原则上一个库对应一个项目,根据实际情况创建 + +​ 创建的库需要单独授权用户进行管理,用户名和库名根据实际情况决定 + +##### D:Mycat配置 + +​ server.xml:Mycat的配置文件,设置账号、参数等 + +```shell +[root@mycat conf]# vim server.xml + + + + + 0 + 1 + 0 + 0 + 2 + (?:(\s*next\s+value\s+for\s*MYCATSEQ_(\w+))(,|\)|\s)*)+ + false + 0 + 0 + 0 + 64k + 1k + 0 + 384m + false + false + true + + + 123456 + TESTDB + + + 123456 + shop + + + 123456 + bbs + + + 123456 + blog + + +``` + +注意: + +```shell +user 用户配置节点 +–name 登录的用户名,也就是连接Mycat的用户名 +–password 登录的密码,也就是连接Mycat的密码 +–schemas 数据库名,这里会和schema.xml中的配置关联,多个用逗号分开,例如需要这个用户需要管理两个数据库db1,db2,则配置db1,db2 +``` + +​ schema.xml:Mycat对应的物理数据库和数据库表的配置 + +```shell +[root@mycat conf]# cat schema.xml + + + + + + + + + + + + show status like 'wsrep%' + + + + + + + + + + + show status like 'wsrep%' + + + + + + + + + + + show status like 'wsrep%' + + + + + + + + + + +``` + +注意: + +```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(数据操纵语言)权限控制 + --check 表示是否开启DML权限检查。默认是关闭。 +--dml 顺序说明:insert,update,select,delete + +
+
+db1的权限是update,select。 +tb01的权限是啥都不能干。 +tb02的权限是insert,update,select,delete。 +其他表默认是udpate,select。 + +2.system标签 +这个标签内嵌套的所有 property 标签都与系统配置有关。 +utf8 +字符集 +1 +处理线程数量,默认是cpu数量。 +4096 +每次读取留的数量,默认4096。 +409600 +创建共享buffer需要占用的总空间大小。processorBufferChunk*processors*100。 +0 +默认为0。0表示DirectByteBufferPool,1表示ByteBufferArena。 +100 +二级共享buffer是processorBufferPool的百分比,这里设置的是百分比。 +100 +全局ID生成方式。(0:为本地文件方式,1:为数据库方式;2:为时间戳序列方式;3:为ZK生成ID;4:为ZK递增ID生成。 +1 +是否开启mysql压缩协议。1为开启,0为关闭,默认关闭。 +4 +指定 Mysql 协议中的报文头长度。默认 4。 +16M +指定 Mysql 协议可以携带的数据最大长度。默认 16M。 +1800000 +指定连接的空闲超时时间。某连接在发起空闲检查下,发现距离上次使用超过了空闲时间,那么这个连接会被回收,就是被直接的关闭掉。默认 30 分钟,单位毫秒。 +3 +前端连接的初始化事务隔离级别,只在初始化的时候使用,后续会根据客户端传递过来的属性对后端数据库连接进行同步。默认为 REPEATED_READ,设置值为数字默认 3。 +READ_UNCOMMITTED = 1; +READ_COMMITTED = 2; +REPEATED_READ = 3; +SERIALIZABLE = 4; +300 +SQL 执行超时的时间,Mycat 会检查连接上最后一次执行 SQL 的时间,若超过这个时间则会直接关闭这连接。默认时间为 300 秒,单位秒。 +1000 +清理 NIOProcessor 上前后端空闲、超时和关闭连接的间隔时间。默认是 1 秒,单 +位毫秒。 +300000 +对后端连接进行空闲、超时检查的时间间隔,默认是 300 秒,单位毫秒。 +10000 +对后端所有读、写库发起心跳的间隔时间,默认是 10 秒,单位毫秒。 +0.0.0.0 +mycat 服务监听的 IP 地址,默认值为 0.0.0.0。 +8066 +定义 mycat 的使用端口,默认值为 8066。 +9066 +定义 mycat 的管理端口,默认值为 9066。 +5.6 +mycat 模拟的 mysql 版本号,默认值为 5.6 版本,如非特需,不要修改这个值,目前支持设置 5.5,5.6,5.7 版本,其他版本可能会有问题。 +0 +是否开启实时统计。1为开启;0为关闭 。 +0 +是否开启全局表一致性检测。1为开启;0为关闭 。 +0 +分布式事务开关。0为不过滤分布式事务;1为过滤分布式事务;2 为不过滤分布式事务,但是记录分布式事务日志。 +65535 +默认是65535。 64K 用于sql解析时最大文本长度 +以上举例的属性仅仅是一部分,可以配置的变量很多。 +System标签下的属性,一般是上线后,需要根据实际运行的情况,分析后调优的时候进行修改。 + +3. Firewall标签 +防火墙的设置,也就是在网络层对请求的地址进行限制,主要是从安全角度来保证Mycat不被匿名IP进行访问 + + + + + + + + +``` + +##### schema.xml + +```shell +一:schema.xml +–schema 数据库设置,此数据库为逻辑数据库,name与server.xml中schema对应 +–dataNode 分片信息,也就是分库相关配置 +–dataHost 物理数据库,真正存储数据的数据库 + +1、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标签定义了mycat中的数据节点,也就是数据分片。一个datanode标签就是一个独立的数据分片。 +localhost1数据库实例上的db1物理数据库,这就组成一个数据分片,最后我们用dn1来标示这个分片。 +–name 定义数据节点的名字,这个名字需要唯一。我们在table标签上用这个名字来建立表与分片对应的关系 +–dataHost 用于定义该分片属于哪个数据库实例,属性与datahost标签上定义的name对应 +–database 用于定义该分片属于数据库实例上 的具体库。 + +3、dataHost标签 +这个标签直接定义了具体数据库实例,读写分离配置和心跳语句。 + +select user() + + + + + +–name 唯一标示dataHost标签,供上层使用 +–maxCon 指定每个读写实例连接池的最大连接。 +–minCon 指定每个读写实例连接池的最小连接,初始化连接池的大小 +–balance 负载均称类型 +balance=“0”:不开启读写分离机制,所有读操作都发送到当前可用的writeHost上 +balance=“1”:全部的readHost与stand by writeHost参与select语句的负载均衡,简单的说,当双主双从模式(M1-S1,M2-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链接的数据库,例如:mongodb,oracle,spark等 +–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)。 +1)heartbeat标签 +这个标签内指明用于和后端数据库进行心跳检查的语句。 +例如:MYSQL 可以使用 select user(),Oracle 可以使用 select 1 from dual 等。 +2) writeHost /readHost 标签 +这两个标签都指定后端数据库的相关配置,用于实例化后端连接池。唯一不同的是,writeHost 指定写实例、readHost 指定读实例。 +在一个 dataHost 内可以定义多个 writeHost 和 readHost。但是,如果 writeHost 指定的后端数据库宕机,那么这个 writeHost 绑定的所有 readHost 都将不可用。 +另一方面,由于这个 writeHost 宕机,系统会自动的检测到,并切换到备用的 writeHost 上去。这两个标签的属性相同,这里就一起介绍。 +–host 用于标识不同实例,一般 writeHost 我们使用M1,readHost 我们用S1。 +–url 后端实例连接地址。Native:地址:端口 JDBC:jdbc的url +–password 后端存储实例需要的密码 +–user 后端存储实例需要的用户名字 +–weight 权重 配置在 readhost 中作为读节点的权重 +–usingDecrypt 是否对密码加密,默认0。 +``` + + + + + + + diff --git a/第三章:数据库查询.md b/第三章:数据库查询.md new file mode 100644 index 0000000..d8b834a --- /dev/null +++ b/第三章:数据库查询.md @@ -0,0 +1,975 @@ +

数据库查询

+ +**作者:行癫(盗版必究)** + +------ + +## 一:基本查询 + +#### 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 Wages:26600.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) +``` \ No newline at end of file diff --git a/第二章:数据库管理及数据类型.md b/第二章:数据库管理及数据类型.md new file mode 100644 index 0000000..b51bb12 --- /dev/null +++ b/第二章:数据库管理及数据类型.md @@ -0,0 +1,861 @@ +

数据库管理及数据类型

+ +**作者:行癫(盗版必究)** + +------ + +## 一:数据类型 + +#### 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 字段的值是不允许重复,且不允许不NULL(UNIQUE + 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 数据库名; +```