40,000-word long text summary MySQL relational database

1. Database introduction

What is a database?

The English word for database: data base, referred to as DB. The essence of a database is a file system, which can store data in a specific format, and can easily add, delete, modify and query the stored data.

Classification of database

There are currently two types of databases:

  • Relational database: It is a database based on the relational model. (MySQL, Oracle, DB2, SQL Server, etc.).
  • Non-relational database (NO SQL): Usually refers to a database with no relationship between data. (monggodb, redis, etc.).

Relationship between database server, database and data table

The database server is a host computer installed with a database management system (such as MySQL), and usually opens a remote connection port (such as MySQL port 3306) to provide data services to the outside world. Through the database management system (MySQL), you can create and Manage and manage multiple databases. Generally, developers will create a database for each application. Multiple data tables can be created in a database, and these data tables are the carriers for actually storing data. Each row of the table is called a record (Record).

Introduction to SQL Language

SQL (Structured Query Language) is an acronym for Structured Query Language, which is used to access and operate database systems. SQL statements can not only query the data in the database, but also add, update and delete the data in the database, and can also manage and maintain the database.
Although SQL has been defined as a standard by the ANSI organization, unfortunately, various databases have inconsistent support for standard SQL. Moreover, most databases have been extended on standard SQL. In other words, if you only use standard SQL, theoretically all databases can support it, but if you use the extended SQL of a specific database, you cannot execute it with another database. The SQL language defines several basic capabilities for operating databases:

  • DDL: Data Definition Language: DDL allows users to define data, that is, create tables, delete tables, and modify table structures. Typically, DDL is performed by a database administrator.
  • DML: Data Manipulation Language: DML provides users with the ability to add, delete, and update data, which are the daily operations of applications on databases.
  • DQL: Data Query Language: DQL allows users to query data, which is usually the most frequent daily operation of the database.

SQL syntax has the following characteristics:

  1. not case sensitive.
  2. Keywords, field names, and table names need to be separated by spaces or commas.
  3. Every SQL statement is terminated with a semicolon.
  4. Statements can be written on one line or on multiple lines.

Note that although SQL language keywords are case-insensitive, for different databases, some databases are case-sensitive for table names and column names, and some databases are not. For the same database, some are case-sensitive on Linux and some are case-insensitive on Windows.

Introduction to relational database MySQL

MySQL is a lightweight relational database management system. It is free, open source, and suitable for medium and large websites. The default port number of MySQL is 3306. Developed by the Swedish MySQL AB company, it was later acquired by Sun, which was later acquired by Oracle, and currently belongs to Orac. Written in C and C++, and tested with a variety of compilers to ensure the portability of the source code. MySQL supports multiple operating systems and provides APIs for multiple programming languages.

2. Install and configure MySQL database

Docker install MySQL8

Search for MySQL mirrors
docker search mysql
Pull the MySQL image
docker pull mysql:8
Create and run a MySQL container
docker run -p 3306:3306 --name mysqltest -e MYSQL_ROOT_PASSWORD=root -d mysql:8

Parameter Description:

    • p 3306:3306 : Map port 3306 of the container to port 3306 of the host
    • e MYSQL_ROOT_PASSWORD=root : set mysql login password
    • d Run the container in the background and return the container id
  • mysql:8 The name of the running mirror, which can also be replaced with the mirror id
Container files are mapped to local directories (mounted)

Creating a directory and a data directory for placing MySQL configuration files on the host can prevent the container from being destroyed and the data from being destroyed.

  1. The host creates data directories and configuration files:
sudo mkdir -p /usr/mysql/conf /usr/mysql/data /var/log/mysql
sudo chmod -R 777 /usr/mysql/ /var/log/mysql
  1. Copy the MySQL configuration file in the test container to this path. If you need to change the configuration in the future, you can modify it directly on the configuration file of the mount path
docker cp mysqltest:/etc/mysql/my.cnf /usr/mysql/conf
  1. delete the test container,
docker stop mysqltest
docker rm mysqltest

4. Create a new docker container and start it

sudo docker run -itd --name=mysql -p 3306:3306 --restart=always -e MYSQL_ROOT_PASSWORD=123456 -v /usr/mysql/conf/my.cnf:/etc/mysql/my.cnf -v /usr/mysql/data:/usr/mysql/data -v /var/log/mysql:/var/log/mysql  mysql:8

Parameter explanation:

  • -v : mount the host directory and the directory in the docker container, the front is the host directory, and the back is the internal directory of the container
  • -d : run the container in the background
  • -p 3306:3306 : Map port 3306 of the container to port 3306 of the host
  • -e MYSQL_ROOT_PASSWORD=root: environment parameter, MYSQL_ROOT_PASSWORD sets the password of the root user
  • mysql:8 The name of the running mirror, which can also be replaced with the mirror id
  • –restart=always: The container starts automatically

Check MySQL version

method 1:

Enter the MySQL container and use the command:

mysql -V
mysql  Ver 8.0.29 for Linux on x86_64 (MySQL Community Server - GPL)
Method 2:

If you have logged in to MySQL, you can use the built-in command after logging in to MySQL

mysql> select version();
+-----------+
| version() |
+-----------+
| 8.0.29    |
+-----------+
1 row in set (0.00 sec)
Method 3:

Also log in to MySQL and use the built-in command

mysql> status;
--------------
mysql  Ver 8.0.29 for Linux on x86_64 (MySQL Community Server - GPL)
...

or

mysql> \s
--------------
mysql  Ver 8.0.29 for Linux on x86_64 (MySQL Community Server - GPL)
...

Solve the problem of being unable to connect to MySQL remotely

Configure MySQL8 to support remote connections
  1. into the container
docker exec -it mysql /bin/bash
  1. connect to mysql
mysql -uroot -p123456
  1. Use the MySQL library
use mysql;
  1. Modify the access host and password, etc., and set it to be accessible to all hosts
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';

The password here is the login password when setting up the remote connection.

  1. to refresh
flush privileges;

When you use remote database connection tools such as Navicat to connect to the database, you can connect normally.

Check that the firewall allows access to the port

If MySQL is set to allow remote access, but still cannot be connected remotely, then check whether the firewall of the host has closed the port that MySQL listens to.
1... Check the firewall status:

sudo ufw status
  1. Open firewall port 3306:
sudo ufw allow 3306

MySql related configuration

View the installation file path

which mysql

Find the location of the configuration file my.cnf

If MySQL has been started, check the MySQL thread to see if there is a clear path to load the my.cnf file.

ps -aux | grep mysql | grep 'my.cnf'

If it cannot be found, MySQL will read the my.cnf file in the root directory of the installation directory and the default directory when it starts. First confirm whether the server has a my.cnf file.

locate my.cnf

After confirming that there is a my.cnf file, check the default directory for reading configuration files when MySQL starts.

mysql --help|grep 'my.cnf'

Detailed explanation of my.cnf configuration file

[mysqld]
# mysql监听端口,默认3306
port = 3306 
# pid文件所在目录
pid-file = 

# 使用该目录作为根目录(安装目录)
basedir = 

# 数据文件存放的目录
datadir = 

# MySQL存放临时文件的目录
tmpdir = 

#*** skip options 相关选项 ***#
skip-name-resolve 
#禁止 MySQL 对外部连接进行 DNS 解析,使用这一选项可以消除 MySQL 进行 DNS 解析的时间。但需要注意,如果开启该选项,则所有远程主机连接授权都要使用 IP 地址方式,否则 MySQL 将无法正常处理连接请求!

skip-symbolic-links 
#不能使用连接文件,多个客户可能会访问同一个数据库,因此这防止外部客户锁定 MySQL 服务器。 该选项默认开启

skip-external-locking 
#不使用系统锁定,要使用 myisamchk,必须关闭服务器 ,避免 MySQL的外部锁定,减少出错几率增强稳定性。

skip-slave-start 
#启动 mysql,不启动复制

skip-networking 
#开启该选项可以彻底关闭 MySQL 的 TCP/IP 连接方式,如果 WEB 服务器是以远程连接的方式访问 MySQL 数据库服务器则不要开启该选项!否则将无法正常连接! 如果所有的进程都是在同一台服务器连接到本地的 mysqld, 这样设置将是增强安全的方法

sysdate-is-now = 1 
#把SYSDATE 函数编程为 NOW的别名

#*** 系统资源相关选项 ***#
back_log = 50 
#接受队列,对于没建立 tcp 连接的请求队列放入缓存中,队列大小为 back_log,受限制与 OS 参数,试图设定 back_log 高于你的操作系统的限制将是无效的。默认值为 50。对于 Linux 系统推荐设置为小于512的整数。如果系统在一个短时间内有很多连接,则需要增大该参数的值

max_connections = 1000 
#指定MySQL允许的最大连接进程数。如果在访问数据库时经常出现"Too Many Connections"的错误提 示,则需要增大该参数值。

max_connect_errors = 10000 
#如果某个用户发起的连接 error 超过该数值,则该用户的下次连接将被阻塞,直到管理员执行 flush hosts ; 命令或者服务重启, 防止黑客 , 非法的密码以及其他在链接时的错误会增加此值

open_files_limit = 10240 
#MySQL打开的文件描述符限制,默认最小1024;当open_files_limit没有被配置的时候,比较max_connections*5和ulimit-n的值,哪个大用哪个,当open_file_limit被配置的时候,比较open_files_limit和max_connections*5的值,哪个大用哪个。

connect-timeout = 10 
#连接超时之前的最大秒数,在 Linux 平台上,该超时也用作等待服务器首次回应的时间

wait-timeout = 28800 
#等待关闭连接的时间

interactive-timeout = 28800 
#关闭连接之前,允许 interactive_timeout(取代了wait_timeout)秒的不活动时间。客户端的会话 wait_timeout 变量被设为会话interactive_timeout 变量的值。如果前端程序采用短连接,建议缩短这2个值, 如果前端程序采用长连接,可直接注释掉这两个选项,默认配置(8小时)  

slave-net-timeout = 600 
#从服务器也能够处理网络连接中断。但是,只有从服务器超过slave_net_timeout 秒没有从主服务器收到数据才通知网络中断

net_read_timeout = 30 
#从服务器读取信息的超时

net_write_timeout = 60 
#从服务器写入信息的超时

net_retry_count = 10 
#如果某个通信端口的读操作中断了,在放弃前重试多次

net_buffer_length = 16384 
#包消息缓冲区初始化为 net_buffer_length 字节,但需要时可以增长到 max_allowed_packet 字节

max_allowed_packet = 64M
# 服务所能处理的请求包的最大大小以及服务所能处理的最大的请求大小(当与大的BLOB 字段一起工作时相当必要), 每个连接独立的大小.大小动态增加。 设置最大包,限制server接受的数据包大小,避免超长SQL的执行有问题 默认值为16M,当MySQL客户端或mysqld
服务器收到大于 max_allowed_packet 字节的信息包时,将发出“信息包过大”错误,并关闭连接。对于某些客户端,如果通信信息包过大,在执行查询期间,可能会遇到“丢失与 MySQL 服务器的连接”错误。默认值 16M。

table_cache = 512 
# 所有线程所打开表的数量. 增加此值就增加了mysqld所需要的文件描述符的数量这样你需要确认在[mysqld_safe]中 “open-files-limit” 变量设置打开文件数量允许至少4096

thread_stack = 192K 
# 线程使用的堆大小. 此容量的内存在每次连接时被预留.MySQL 本身常不会需要超过 64K 的内存如果你使用你自己的需要大量堆的 UDF 函数或者你的操作系统对于某些操作需要更多的堆,你也许需要将其设置的更高一点.默认设置足以满足大多数应用

thread_cache_size = 20 
# 我们在 cache 中保留多少线程用于重用.当一个客户端断开连接后,如果 cache 中的线程还少于 thread_cache_size,则客户端线程被放入 cache 中.这可以在你需要大量新连接的时候极大的减少线程创建的开销(一般来说如果你有好的线程模型的话,
这不会有明显的性能提升.)服务器线程缓存这个值表示可以重新利用保存在缓存中线程的数量,当断开连接时如果缓存中还有空间,那么客户端的线程将被放到缓存中,如果线程重新被请求,那么请求将从缓存中读取,如果缓存中是空的或者是新的请求,那么这个线程将被重新创建,
如果有很多新的线程,增加这个值可以改善系统性能.通过比较 Connections 和 Threads_created 状态的变量,可以看到这个变量的作用
根据物理内存设置规则如下:
1G  —> 8
2G  —> 16
3G  —> 32
大于3G  —> 64

thread_concurrency = 8 
#此允许应用程序给予线程系统一个提示在同一时间给予渴望被运行的线程的数量.该参数取值为服务器逻辑CPU数量×2,在本例中,服务器有 2 颗物理CPU,而每颗物理CPU又支持H.T超线程,所以实际取值为 4 × 2 = 8.设置 thread_concurrency的值的正确与否, 
对 mysql 的性能影响很大, 在多个 cpu(或多核)的情况下,错误设置了 thread_concurrency 的值, 会导致 mysql 不能充分利用多 cpu(或多核),出现同一时刻只能一个 cpu(或核)在工作的情况。 thread_concurrency 应设为 CPU 核数的 2 倍.比如有一个双核的 CPU, 
那么 thread_concurrency 的应该为 4; 2 个双核的 cpu,thread_concurrency 的值应为 8,属重点优化参数

#*** qcache settings 相关选项 ***#
query_cache_limit = 2M 
#不缓存查询大于该值的结果.只有小于此设定值的结果才会被缓冲,  此设置用来保护查询缓冲,防止一个极大的结果集将其他所有的查询结果都覆盖.

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%

query_cache_size = 64M  
#指定 MySQL 查询缓冲区的大小。可以通过在 MySQL 控制台执行以下命令观察:
代码:
> SHOW VARIABLES LIKE '%query_cache%';
> SHOW STATUS LIKE 'Qcache%';如果 Qcache_lowmem_prunes 的值非常大,则表明经常出现缓冲不够的情况;
如果 Qcache_hits 的值非常大,则表明查询缓冲使用非常频繁,如果该值较小反而会影响效率,那么可以考虑不用查询缓冲; Qcache_free_blocks,如果该值非常大,则表明缓冲区中碎片很多。
memlock # 如果你的系统支持 memlock() 函数,你也许希望打开此选项用以让运行中的 mysql 在在内存高度
紧张的时候,数据在内存中保持锁定并且防止可能被 swapping out,此选项对于性能有益

#*** default settings 相关选项 ***#
default_table_type = InnoDB 
# 当创建新表时作为默认使用的表类型,如果在创建表示没有特别执行表类型,将会使用此值

default-time-zone = system 
#服务器时区

character-set-server = utf8 
#server 级别字符集

default-storage-engine = InnoDB 
#默认存储引擎


#*** tmp && heap settings 相关选项 ***#
tmp_table_size = 512M 
#临时表的最大大小,如果超过该值,则结果放到磁盘中,此限制是针对单个表的,而不是总和.

max_heap_table_size = 512M 
#独立的内存表所允许的最大容量.此选项为了防止意外创建一个超大的内存表导致永尽所有的内存资源.

#*** log settings 相关选项 ***#
log-bin = mysql-bin 
#打开二进制日志功能.在复制(replication)配置中,作为 MASTER 主服务器必须打开此项.如果你需要从你最后的备份中做基于时间点的恢复,你也同样需要二进制日志.这些路径相对于 datadir

log_slave_updates = 1 
#表示slave将复制事件写进自己的二进制日志

log-bin-index = mysql-bin.index 
#二进制的索引文件名

relay-log = relay-log 
#定义relay_log的位置和名称,如果值为空,则默认位置在数据文件的目录,文件名为host_name-relay-bin.nnnnnn(By default, relay log file names have the form host_name-relay-bin.nnnnnn in the data directory);

relay_log_index = relay-log.index  
#relay-log的索引文件名

log-warnings = 1 
# 将警告打印输出到错误 log 文件.如果你对于MySQL有任何问题,你应该打开警告 log 并且仔细审查错误日志,查出可能的原因.

log-error =  /usr/local/mysql/log/mysql.err 
#错误日志路径

log_output = FILE 
#参数 log_output 指定了慢查询输出的格式,默认为 FILE,你可以将它设为 TABLE,然后就可以查询 mysql 架构下的 slow_log 表了

log_slow_queries 
#指定是否开启慢查询日志(该参数要被slow_query_log取代,做兼容性保留)

slow_query_log = 1 
# 指定是否开启慢查询日志. 慢查询是指消耗了比 “long_query_time” 定义的更多时间的查询.如果 log_long_format 被打开,那些没有使用索引的查询也会被记录.如果你经常增加新查询到已有的系统内的话. 一般来说这是一个好主意,

long-query-time = 1 
#设定慢查询的阀值,超出次设定值的SQL即被记录到慢查询日志,缺省值为10s.所有的使用了比这个时间(以秒为单位)更多的查询会被认为是慢速查询.不要在这里使用”1″, 否则会导致所有的查询,甚至非常快的查询页被记录下来(由于MySQL 目前时间的精确度只能达到秒的级别).

log_long_format 
# 在慢速日志中记录更多的信息.一般此项最好打开,打开此项会记录使得那些没有使用索引的查询也被作为到慢速查询附加到慢速日志里

slow_query_log_file =  /usr/local/mysql/log/slow.log 
# 指定慢日志文件存放位置,可以为空,系统会给一个缺省的文件host_name-slow.log

log-queries-not-using-indexes 
#如果运行的SQL语句没有使用索引,则mysql数据库同样会将这条SQL语句记录到慢查询日志文件中。

min_examined_row_limit=1000    
#记录那些由于查找了多余1000次而引发的慢查询

long-slow-admin-statements    
#记录那些慢的optimize table,analyze table和alter table语句

log-slow-slave-statements 
#记录由Slave所产生的慢查询

general_log = 1 
#将所有到达MySQL Server的SQL语句记录下来,默认关闭 

general_log_file =  /usr/local/mysql/log/mysql.log 
#general_log路径

max_binlog_size = 1G 
#如果二进制日志写入的内容超出给定值,日志就会发生滚动。你不能将该变量设置为大于1GB或小于4096字节。 默认值是1GB。如果你正使用大的事务,二进制日志还会超过max_binlog_size

max_relay_log_size = 1G 
#标记relaylog允许的最大值,如果该值为0,则默认值为max_binlog_size(1G);如果不为0,则max_relay_log_size则为最大的relay_log文件大小;

relay-log-purge = 1 
#是否自动清空不再需要中继日志时。默认值为1(启用)

expire_logs_days = 30 
#超过 30 天的 binlog 删除

binlog_cache_size = 1M 
# 在一个事务中 binlog 为了记录 SQL 状态所持有的 cache 大小,如果你经常使用大的,多声明的事务,你可以增加此值来获取更大的性能.所有从事务来的状态都将被缓冲在 binlog 缓冲中然后在提交后一次性写入到 binlog 中,如果事务比此值大, 会使用磁盘上的临时文件来替代.此缓冲在每个连接的事务第一次更新状态时被创建.session 级别

replicate-wild-ignore-table = mysql.% 
#复制时忽略数据库及表
slave_skip_errors=all 
#定义复制过程中从服务器可以自动跳过的错误号,当复制过程中遇到定义的错误号,就可以自动跳过,直接执行后面的SQL语句。
slave_skip_errors选项有四个可用值,分别为:off,all,ErorCode,ddl_exist_errors。
  默认情况下该参数值是off,我们可以列出具体的error code,也可以选择all,mysql5.6及MySQL Cluster NDB 7.3以及后续版本增加了参数ddl_exist_errors,该参数包含一系列error code(1007,1008,1050,1051,1054,1060,1061,1068,1094,1146)
    一些error code代表的错误如下:
    1007:数据库已存在,创建数据库失败
    1008:数据库不存在,删除数据库失败
    1050:数据表已存在,创建数据表失败
    1051:数据表不存在,删除数据表失败
    1054:字段不存在,或程序文件跟数据库有冲突
    1060:字段重复,导致无法插入
    1061:重复键名
    1068:定义了多个主键
    1094:位置线程ID
    1146:数据表缺失,请恢复数据库
    1053:复制过程中主服务器宕机
    1062:主键冲突 Duplicate entry '%s' for key %d


#*** MyISAM 相关选项 ***#
key_buffer_size = 256M 
#指定用于索引的缓冲区大小,增加它可得到更好的索引处理性能。如果是以InnoDB引擎为主的DB,专用于MyISAM引擎的 key_buffer_size 可以设置较小,8MB 已足够  如果是以MyISAM引擎为主,可设置较大,但不能超过4G. 在这里,强烈建议不使用MyISAM引擎,默认都是用InnoDB引擎.注意:该参数值设置的过大反而会是服务器整体效率降低!

sort_buffer_size = 2M 
#查询排序时所能使用的缓冲区大小。排序缓冲被用来处理类似 ORDER BY 以及 GROUP BY 队列所引起的排序.一个用来替代的基于磁盘的合并分类会被使用.查看 “Sort_merge_passes” 状态变量. 在排序发生时由每个线程分配 注意:该参数对应的分配内存是每连接独占!如果有 100 个连接,那么实际分配的总共排序缓冲区大小为 100 × 6 =600MB,所以,对于内存在 4GB 左右的服务器推荐设置为 6-8M。 

read_buffer_size = 2M 
#读查询操作所能使用的缓冲区大小。和 sort_buffer_size 一样,该参数对应的分配内存也是每连接独享!用来做 MyISAM 表全表扫描的缓冲大小.当全表扫描需要时,在对应线程中分配.

join_buffer_size = 8M 
#联合查询操作所能使用的缓冲区大小,和 sort_buffer_size 一样,该参数对应的分配内存也是每连接独享!此缓冲被使用来优化全联合(full JOINs 不带索引的联合).类似的联合在极大多数情况下有非常糟糕的性能表现, 但是将此值设大能够减轻性能影响.通过 “Select_full_join”状态变量查看全联合的数量, 当全联合发生时,在每个线程中分配。

read_rnd_buffer_size = 8M 
#MyISAM 以索引扫描(Random Scan)方式扫描数据的 buffer大小 

bulk_insert_buffer_size = 64M 
#MyISAM 使用特殊的类似树的 cache 来使得突发插入(这些插入是,INSERT … SELECT, INSERT … VALUES (…), (…), …, 以及 LOAD DATAINFILE) 更快. 此变量限制每个进程中缓冲树的字节数.设置为 0 会关闭此优化.为了最优化不要将此值设置大于 “key_buffer_size”.当突发插入被检测到时此缓冲将被分配MyISAM 用在块插入优化中的树缓冲区的大小。注释:这是一个 per thread 的限制 ( bulk 大量).此缓冲当 MySQL 需要在 REPAIR, OPTIMIZE, ALTER 以及 LOAD DATA INFILE到一个空表中引起重建索引时被分配.这在每个线程中被分配.所以在设置大值时需要小心.

myisam_sort_buffer_size = 64M 
#MyISAM 设置恢复表之时使用的缓冲区的尺寸,当在REPAIR TABLE 或用 CREATE INDEX 创建索引或 ALTER TABLE 过程中排序 MyISAM 索引分配的缓冲区

myisam_max_sort_file_size = 10G
#mysql重建索引时允许使用的临时文件最大大小

myisam_repair_threads = 1 
#如果该值大于 1,在 Repair by sorting 过程中并行创建MyISAM 表索引(每个索引在自己的线程内).如果一个表拥有超过一个索引, MyISAM 可以通过并行排序使用超过一个线程去修复他们.这对于拥有多个 CPU 以及大量内存情况的用户,是一个很好的选择.

myisam_recover = 64K
#允许的 GROUP_CONCAT()函数结果的最大长度
transaction_isolation = REPEATABLE-READ # 设定默认的事务隔离级别.可用的级别如下:READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ,SERIALIZABLE
1.READ UNCOMMITTED-读未提交 2.READ COMMITTE-读已提交 3.REPEATABLE READ -可重复读 4.SERIALIZABLE -串行


# *** INNODB 相关选项 ***#
skip-innodb 
# 如果你的 MySQL 服务包含 InnoDB 支持但是并不打算使用的话,使用此选项会节省内存以及磁盘空间,并且加速某些部分

innodb_file_per_table = 1 
# InnoDB为独立表空间模式,每个数据库的每个表都会生成一个数据空间
独立表空间优点:
1.每个表都有自已独立的表空间。
2.每个表的数据和索引都会存在自已的表空间中。
3.可以实现单表在不同的数据库中移动。
4.空间可以回收(除drop table操作处,表空不能自已回收)
缺点:
1.单表增加过大,如超过100G
结论:
共享表空间在Insert操作上少有优势。其它都没独立表空间表现好。当启用独立表空间时,请合理调整:innodb_open_files

innodb_status_file = 1 
#启用InnoDB的status file,便于管理员查看以及监控等

innodb_open_files = 2048 
# 限制Innodb能打开的表的数据,如果库里的表特别多的情况,请增加这个。这个值默认是300

innodb_additional_mem_pool_size = 100M 
#设置InnoDB存储引擎用来存放数据字典信息以及一些内部数据结构的内存空间大小,所以当我们一个MySQL Instance中的数据库对象非常多的时候,是需要适当调整该参数的大小以确保所有数据都能存放在内存中提高访问效率的。 

innodb_buffer_pool_size = 2G 
#包括数据页、索引页、插入缓存、锁信息、自适应哈希所以、数据字典信息.InnoDB 使用一个缓冲池来保存索引和原始数据, 不像 MyISAM.这里你设置越大,你在存取表里面数据时所需要的磁盘 I/O 越少.在一个独立使用的数据库服务器上,你可以设置这个变量到服务器物理内存大小的 80%,不要设置过大,否则,由于物理内存的竞争可能导致操作系统的换页颠簸.注意在 32 位系统上你每个进程可能被限制在 2-3.5G 用户层面内存限制,所以不要设置的太高.

innodb_write_io_threads = 4
innodb_read_io_threads = 4
# innodb使用后台线程处理数据页上的读写 I/O(输入输出)请求,根据你的 CPU 核数来更改,默认是4
# 注:这两个参数不支持动态改变,需要把该参数加入到my.cnf里,修改完后重启MySQL服务,允许值的范围从 1-64

innodb_data_home_dir =  /usr/local/mysql/var/ 
#设置此选项如果你希望 InnoDB 表空间文件被保存在其他分区.默认保存在 MySQL 的 datadir 中.

innodb_data_file_path = ibdata1:500M;ibdata2:2210M:autoextend
#InnoDB将数据保存在一个或者多个数据文件中成为表空间.如果你只有单个逻辑驱动保存你的数据,一个单个的自增文件就足够好了.其他情况下.每个设备一个文件一般都是个好的选择.你也可以配置 InnoDB 来使用裸盘分区 – 请参考手册来获取更多相关内容

innodb_file_io_threads = 4 
#用来同步 IO 操作的 IO 线程的数量. 此值在 Unix 下被硬编码为 4,但是在 Windows 磁盘 I/O 可能在一个大数值下表现的更好.

innodb_thread_concurrency = 16
#在 InnoDb 核心内的允许线程数量,InnoDB 试着在 InnoDB 内保持操作系统线程的数量少于或等于这个参数给出的限制,最优值依赖于应用程序,硬件以及操作系统的调度方式.过高的值可能导致线程的互斥颠簸.默认设置为 0,表示不限制并发数,这里推荐设置为0,更好去发挥CPU多核处理能力,提高并发量

innodb_flush_log_at_trx_commit = 1 
#如果设置为 1 ,InnoDB 会在每次提交后刷新(fsync)事务日志到磁盘上,这提供了完整的 ACID 行为.如果你愿意对事务安全折衷, 并且你正在运行一个小的食物, 你可以设置此值到 0 或者 2 来减少由事务日志引起的磁盘 I/O
0 代表日志只大约每秒写入日志文件并且日志文件刷新到磁盘.
2 代表日志写入日志文件在每次提交后,但是日志文件只有大约每秒才会刷新到磁盘上.

innodb_log_buffer_size = 8M 
#用来缓冲日志数据的缓冲区的大小.当此值快满时, InnoDB 将必须刷新数据到磁盘上.由于基本上每秒都会刷新一次,所以没有必要将此值设置的太大(甚至对于长事务而言)

innodb_log_file_size = 500M 
#事物日志大小.在日志组中每个日志文件的大小,你应该设置日志文件总合大小到你缓冲池大小的5%~100%,来避免在日志文件覆写上不必要的缓冲池刷新行为.不论如何, 请注意一个大的日志文件大小会增加恢复进程所需要的时间.

innodb_log_files_in_group = 2 
#在日志组中的文件总数.通常来说 2~3 是比较好的.

innodb_log_group_home_dir =  /usr/local/mysql/var/
# InnoDB 的日志文件所在位置. 默认是 MySQL 的 datadir.你可以将其指定到一个独立的硬盘上或者一个 RAID1 卷上来提高其性能innodb_max_dirty_pages_pct = 90 #innodb 主线程刷新缓存池中的数据,使脏数据比例小于 90%,这是一个软限制,不被保证绝对执行.

innodb_lock_wait_timeout = 50 
#InnoDB 事务在被回滚之前可以等待一个锁定的超时秒数。InnoDB 在它自己的 锁定表中自动检测事务死锁并且回滚事务。 InnoDB 用 LOCK TABLES 语句注意到锁定设置。默认值是 50 秒

innodb_flush_method = O_DSYNC 
# InnoDB 用来刷新日志的方法.表空间总是使用双重写入刷新方法.默认值是 “fdatasync”, 另一个是 “O_DSYNC”.

innodb_force_recovery=1
# 如果你发现 InnoDB 表空间损坏, 设置此值为一个非零值可能帮助你导出你的表.从1 开始并且增加此值知道你能够成功的导出表.

innodb_fast_shutdown 
# 加速 InnoDB 的关闭. 这会阻止 InnoDB 在关闭时做全清除以及插入缓冲合并.这可能极大增加关机时间, 但是取而代之的是 InnoDB 可能在下次启动时做这些操作.


# *** 其他 相关选项 ***#
[mysqldump]
quick 
#支持较大数据库的转储,在导出非常巨大的表时需要此项。增加该变量的值十分安全,这是因为仅当需要时才会分配额外内存。例如,仅当你发出长查询或mysqld必须返回大的结果行时mysqld才会分配更多内存。该变量之所以取较小默认值是一种预防措施,以捕获客户端和服务器之间的错误信息包,并确保不会因偶然使用大的信息包而导致内存溢出。 如果你正是用大的BLOB值,而且未为mysqld授予为处理查询而访问足够内存的权限,也会遇到与大信息包有关的奇怪问题。如果怀疑出现了该情况,请尝试在mysqld_safe脚本开始增加ulimit -d 256000,并重启mysqld。

[mysql]
auto-rehash 
#允许通过 TAB 键提示

default-character-set = utf8 
#数据库字符集

connect-timeout = 3
[mysqld_safe]

open-files-limit = 8192 
#增加每个进程的可打开文件数量.确认你已经将全系统限制设定的足够高!打开大量表需要将此值设大

MySQL user and authority management

Add user

To add users in MySQL, use CREATE USER and GRANT. For example, create a common user - zhangsan. Then give it the following simple permissions:

CREATE USER 'zhangsan'@'localhost' IDENTIFIED BY 'your_password';
// 创建一个zhangsan的用户, 并且, 他的密码为,your_password
> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP 
   -> ON *.*
   -> TO 'zhangsan'@'localhost';

// 赋予zhangsan 一些基本的权限, 让他去访问某些执行的数据库, 上文中的`*.*`(这表示所有的数据库) 就可以写为你允许该用户访问的数据库的name, 比如, 你可以改为`bank`,`tencent`... 等等

In this way, you can use MySQL -u xxx -p to log in as a specified user. If you want to create an administrator account, the code is even simpler.

CREATE USER 'admin'@'localhost' IDENTIFIED BY 'your_ps';
// 创建一个管理员账户

GRANT ALL PRIVILEGES ON *.* TO 'admin'@'localhost' WITH GRANT OPTION;
// ok

If you want to check if the permissions of the user you created are correct, you can use:

SHOW GRANTS FOR 'admin'@'localhost';

Modify user password

There are many methods, two are briefly introduced. One is to use SET, and the other is to use ALERT (v5.7.6).

SET It should be considered common to change the password, use SET to change the password directly, the format is:

SET PASSWORD FOR 'zhangsan'@'localhost' = PASSWORD('your_ps');

The above method is suitable for root users to modify, if you want to modify your own password, use directly:

SET PASSWORD = PASSWORD('your_ps');

The password can also be changed using the related syntax of ALERT:

ALERT USER 'zhangsan'@'localhost' IDENTIFIED BY 'your_ps';

If you don't want to lose, you can directly use USER() to replace the string 'zhangsan'@'localhost:

ALERT USER USER() IDENTIFIED BY 'your_ps';

In addition, if you only want to modify directly in the shell, you can use directly:

mysqladmin -u user_name -h host_name password "new_password"

delete users

View user information in mysql.user:

`SELECT User FROM mysql.user

Select the username you want to delete, just drop it:

DROP USER 'zhangsan'@'localhost';

User related commands

– Create user
CREATE USER zhangsan IDENTIFIED BY '123456'
– Delete user
DROP USER zhangsan
– Modify current user password
SET PASSWORD = PASSWORD('666888')
– Modify specified user password
SET PASSWORD FOR zhangsan = PASSWORD('666888')
– Rename user
RENAME USER zhangsan to wangwu
– User authorization (grant all permissions except authorization to other users)
GRANT ALL PRIVILEGES on *.* TO wangwu
– Query permissions
SHOW GRANTS FOR wangwu
– View root user permissions
SHOW GRANTS FOR root@localhost
– Revoke permissions
REVOKE ALL PRIVILEGES ON *.* FROM wangwu

3. Basic operation of MySQL database

Connect to the database

Enter the MySQL command prompt:

mysql -uroot -pxxx

Exit mysql> command prompt window can use the exit command, as follows:

mysql> exit
Bye

select database

  1. View all databases:
show databases;
  1. Switch to a database:
use 数据库名;

create database

create database 数据库名 charset=utf8;

Database name, its name must be unique and cannot be the same as other databases.

delete database

drop database 数据库名;

Four. Basic operation of MySQL data table

type of data

Common data types:

  • Integer types: BIT, BOOL, TINY INT, SMALL INT, MEDIUM INT, INT, BIG INT
  • Floating point type: FLOAT, DOUBLE, DECIMAL
  • String type: CHAR, VARCHAR, TINY TEXT, TEXT, MEDIUM TEXT, LONGTEXT, TINY BLOB, BLOB, MEDIUM BLOB, LONG BLOB
  • Date type: Date, DateTime, TimeStamp, Time, Year
  • Other data types: BINARY, VARBINARY, ENUM, SET, Geometry, Point, MultiPoint, LineString, MultiLineString, Polygon, GeometryCollection, etc.
integer
MySQL data type meaning (signed)
tinyint(m) 1 byte range (-128~127)
smallint(m) 2 byte range (-32768~32767)
mediumint(m) 3 byte range (-8388608~8388607)
int(m) 4 byte range (-2147483648~2147483647)
bigint(m) 8 byte range (±9.22*10 to the 18th power)

If unsigned is added to the value range, the maximum value will be doubled. For example, the value range of tinyint unsigned is (0~256).

Floating point type (float and double)
MySQL data type meaning
float(m,d) Single-precision floating-point 8-bit precision (4 bytes) m total number, d decimal places
double(m,d) Double-precision floating-point type 16-bit precision (8 bytes) m total number, d decimal places
Fixed number

Floating-point types store approximate values ​​in the database, while fixed-point types store exact values ​​in the database.

decimal(m,d) parameter m<65 is the total number, d<30 and d<m is the decimal place.

string (char, varchar, _text)
MySQL data type meaning
char(n) Fixed length, up to 255 characters
varchar(n) Fixed length, up to 65535 characters
tinytext Variable length, up to 255 characters
text Variable length, up to 65535 characters
mediumtext Variable length, up to 224-1 characters
longtext Variable length, up to 232-1 characters

char and varchar:
1.char(n) If the number of stored characters is less than n, fill it with a space, and remove the space when querying. Therefore, the string stored in the char type cannot have spaces at the end, and varchar is not limited to this.

2. char(n) has a fixed length, char(4) will occupy 4 bytes no matter how many characters are stored, varchar is the actual number of characters stored + 1 byte (n<=255) or 2 bytes (n>255),

3. The string retrieval speed of char type is faster than that of varchar type.

varchar and text:

1. varchar can specify n, text cannot be specified, internal storage varchar is the actual number of characters stored + 1 byte (n<=255) or 2 bytes (n>255), text is the actual number of characters + 2 bytes.

2. The text type cannot have a default value.

3. varchar can directly create an index, and how many characters must be specified before creating an index for text. The query speed of varchar is faster than that of text, and the index of text does not seem to work when all indexes are created.

Binary data (_Blob)

1. The storage methods of _BLOB and _text are different. _TEXT is stored in text mode, and English storage is case-sensitive, while _Blob is stored in binary mode, which is not case-sensitive.

2. The data stored in _BLOB can only be read as a whole.

3. _TEXT can specify the character set, _BLO does not need to specify the character set.

datetime type
MySQL data type meaning
date Date '2021-12-2'
time time '12:25:36'
datetime Datetime '2021-12-2 22:06:44'
timestamp Automatically store record modification time

If you define a field as timestamp, the time data in this field will be automatically refreshed when other fields are modified, so the field of this data type can store the last modification time of this record.

Create data table

regular creation

The basic syntax of the CREATE TABLE statement is as follows:

CREATE TABLE IF NOT EXISTS `test_table`(
   `id` INT UNSIGNED AUTO_INCREMENT COMMENT '自增主键',
   `title` VARCHAR(100) NOT NULL,
   `author` VARCHAR(40) NOT NULL,
   `category` VARCHAR(40) NOT NULL DEFAULT 'unkown',
   `date` DATE,
   `create_time` timestamp DEFAULT CURRENT_TIMESTAMP()
   PRIMARY KEY ( `id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE is an SQL command that tells the database that you want to create a new table. IF NOT EXISTS means that if the table to be created exists, it will return directly without recreating the table. The table_name immediately following it is the name of the table. Then define the columns of the table in parentheses, and the type of each column.

  • The PRIMARY KEY keyword is used to indicate the primary key of the table.

  • Some fields use NOT NULL constraints, and these fields cannot be NULL when inserting data into the table name. If the data entered in this field is NULL when operating the database, an error will be reported.

  • The AUTO_INCREMENT constraint is used to set the value of a field as an auto-increasing sequence.

  • DEFAULT constraints are used to set default values ​​for fields.

  • PRIMARY KEY is used to set the primary key of the table.

  • IF NOT EXISTS means that if a table with the same name already exists in our current database, the modification statement will not be executed, which avoids the system reporting an error.

  • COMMENT adds comments to the field, and the following string adds comments to the comment content property.

  • ENGINE=InnoDB DEFAULT CHARACTER=utf8; is the default of the database and can be omitted. This sentence means: the database engine uses InnoDB, and the default character encoding is utf8.

  • Example:

  1. simplest:
CREATE TABLE t1(id int not null,name char(20));
  1. with primary key:
CREATE TABLE t1(id int not null primary key,name char(20));
  1. composite primary key
CREATE TABLE t1(id int not null,name char(20),primary key (id,name));
  1. with default values:
CREATE TABLE t1(id int not null default 0 primary key,name char(20) default '1');
copy table create new table
create table 目标表 like 源表
Use some data from tableA to create tableB
create table <tableB>(id int(10),name varchar(20));
select id, name
from tableA
View table field information

MySQL commands:

desc 数据表名;
Keyword attribute
MySQL keywords meaning
NULL Data columns can contain NULL values
NOT NULL Data column does not allow NULL values
DEFAULT Defaults
PRIMARY KEY primary key
AUTO_INCREMENT auto-increment, for integer types
UNSIGNED unsigned
CHARACTER SET name specify a character set

Modify data table fields

As the development progresses, the table built before may not meet the future needs, so the modification of the table is necessary. Likewise, there are generic statements for modifying tables:

ALTER TABLE <表名> [修改选项]
  • Add fields:

    ALTER TABLE <表名> ADD COLUMN <列名> <类型> ...               //-- 在末尾添加字段
    ALTER TABLE <表名> ADD COLUMN <列名> <类型> ... first         //-- 在开头添加字段
    ALTER TABLE <表名> ADD COLUMN <列名> <类型> ... after `name`  //在指定字段之后添加字段
    ALTER TABLE <表名> ADD COLUMN <列名> <类型> ...
    
  • Modify the field name:

    ALTER TABLE <表名> CHANGE COLUMN <旧列名> <新列名> <新列类型> ...
    
  • Optimize (modify) field types:

    ALTER TABLE <表名> MODIFY COLUMN <列名> <类型> ...
    
  • Delete field:

    ALTER TABLE <表名> DROP COLUMN <列名> ...
    
  • Modify the table name:

    ALTER TABLE <表名> RENAME TO <新表名>
    

delete data table field

Note that you must be very careful when using the DROP TABLE command, because once a table is deleted, all information in the table will be lost forever. Syntax The basic syntax of the DROP TABLE statement is as follows:

DROP TABLE table_name;

table_name indicates the name of the data table to be deleted.

1. When you no longer need the table, use drop; 2. When you still want to keep the table but delete all records, use truncate; 3. When you want to delete some records or you may regret it, use delete.

Five. Basic operation of MySQL data

insert data into table

The basic syntax of the INSERT statement is:

insert into <表名> (字段1, 字段2, ...) values (值1, 值2, ...);

Note that we do not list the id field, nor the value corresponding to the id field, because the id field is an auto-incrementing primary key, and its value can be calculated by the database itself. In addition, if a field has a default value, it does not need to appear in the INSERT statement. It should be noted that the order of fields does not have to be consistent with the order of fields in the database table, but the order of values ​​must be consistent with the order of fields. You can also add multiple records at one time, just specify multiple record values ​​in the VALUES clause, each record is a set of values ​​​​contained by (…): Add multiple new records at one time:

insert into students (class_id, name, gender, score) values
  (1, '张三', 'm', 87),
  (2, '李四', 'm', 81);

select * from students;

delete table data

The basic syntax of the DELETE statement is:

delete from <表名> where ...;

Modify the data in the table

update <表名> set 字段1=值1, 字段2=值2, ... where ...;

MySQL query table data

query all data

SELECT * FROM table_name;

Query specified fields

SELECT f_name, f_price FROM table_name;

query by condition

SELECT * FROM students WHERE score >= 80

The SELECT statement can set the query condition through the WHERE condition, and the query result is the record that meets the query condition. For example, to specify the condition "students with a score of 80 or above", write it as a WHERE condition. Among them, score >= 80 after the WHERE keyword is the condition. score is the name of the column, which stores the grades of the students. Therefore, if score >= 80, the records of the specified conditions are filtered out.

Multiple conditions are met AND

A conditional expression can use <condition 1> AND <condition 2> to express that condition 1 is satisfied and condition 2 is satisfied. For example, if the condition "score is 80 or above" is met, and the condition "boy" is also met, write these two conditions:

SELECT * FROM students WHERE score >= 80 AND gender = 'M'
satisfy a condition OR

<Condition 1> OR <Condition 2> means that either Condition 1 or Condition 2 is satisfied. For example, if you change the two conditions of the above AND query to OR, the query result is "score is 80 points or above" or "boy", and the record is selected if any one of the conditions is met:

SELECT * FROM students WHERE score >= 80 OR gender = 'M'
Meet the range IN
SELECT * FROM students WHERE score IN(60,100)
Condition lookup priority

If no parentheses are added, the conditional operation is performed according to the priority of NOT, AND, OR, that is, NOT has the highest priority, followed by AND, and finally OR. Adding parentheses can change the priority.

Query result sorting

When using a SELECT query, the query result set is usually sorted by id, that is, by the primary key. This is also the practice of most databases. What if we want to sort by other criteria? An ORDER BY clause can be added. According to score from low to high:

select id, name, gender, score from students order by score;

According to score from high to low:

select id, name, gender, score from students order by score desc;

Paging query

When using SELECT query for pagination, if the result set has a large amount of data, such as tens of thousands of rows of data, the amount of data displayed on one page is too large, so it is better to display by paging, displaying 100 records each time. To realize the pagination function, it is actually displaying the 1 100th record from the result set as the 1st page, displaying the 101 200th record as the 2nd page, and so on.
Therefore, paging is actually "intercepting" the M~Nth records from the result set. This query can be implemented with the LIMIT OFFSET clause.
The key to pagination query is to first determine the number of results to be displayed on each page pageSize (here is 3), and then determine the values ​​that LIMIT and OFFSET should set according to the index pageIndex of the current page (starting from 1):

  • LIMIT is always set to pageSize;
  • The formula for calculating OFFSET is pageSize * (pageIndex - 1). In this way, the record set on the Nth page can be queried correctly.

aggregate function query

In the process of database query, not only the basic information of the data is returned, but also statistics and summary of these data are sometimes required. MySQL provides aggregate functions for implementing these advanced functions. Aggregate functions are used to calculate a set of values ​​and return a summary value. Using aggregate functions, you can count the number of record rows, calculate the sum of a field value, and the maximum, minimum, and average values ​​of these values.

function name Function
sum Returns the sum of the selected column values
max Returns the maximum value of a selected column
min Returns the minimum value of a selected column
avg Returns the average value of a selected column
count Returns the number of rows in a selected column or record
COUNT

– Count the number of students in the class
SELECT COUNT(*) FROM student;
– Count the number of qq_mail collected by the class, and the data with qq_mail being NULL will not be included in the result
SELECT COUNT(qq_mail) FROM student;

SUM

– 统计数学成绩总分
SELECT SUM(math) FROM exam_result;
– 不及格 < 60 的总分,没有结果,返回 NULL
SELECT SUM(math) FROM exam_result WHERE math < 60;

AVG

– 统计平均总分
SELECT AVG(chinese + math + english) 平均总分 FROM exam_result;

MAX

– 返回英语最高分
SELECT MAX(english) FROM exam_result;

MIN

– 返回 > 70 分以上的数学最低分
SELECT MIN(math) FROM exam_result WHERE math > 70;

多表查询

多表查询,也称为关联查询,指两个或更多个表一起完成查询操作。 前提条件:这些一起查询的表之间是有关系的(一对一、一对多),它们之间一定是有关联字段,这个关联字段可能建立了外键,也可能没有建立外键。比如:员工表和部门表,这两个表依靠“部门编号”进行关联。

内连接查询

内连接(INNER JOIN) 使用比较运算符进行表间某(些)列数据的比较操作,并列出这些表中与连接条件相匹配的数据行,组合成新记录。简而言之,查找出同时存在在不同表中的关联数据形成结果表。

SELECT 字段1,字段2,字段3,…… FROM 表名1 INNER JOIN 表名2 ON 关联条件;

等同于:

SELECT 字段1,字段2,字段3,…… FROM 表名1,表名2 WHERE 关联条件;

例如,查询所有员工信息和对应的部门信息:

SELECT * FROM emp INNER JOIN dept ON emp.`dept_id` = dept.`id`;

等同于:

SELECT * FROM emp,dept WHERE emp.`dept_id` = dept.`id`;

INNER JOIN 连接三个数据表的用法:

SELECT * FROM (表1 INNER JOIN 表2 ON 表1.字段号=表2.字段号) INNER JOIN 表3 ON 表1.字段号=表3.字段号

注意事项

  • 如果某字段在多表中都有,则以"表名.列名"限定别名;
  • 与INNER JOIN组合使用ON子句,而不是WHERE。ON和WHERE后面的指定条件相同, WHERE子句定义条件更简单明了,但某些时候会影响查询性能,而INNER JOIN语法是ANSI SQL的标准规范,能够确保不忘记连接条件。
外连接查询

左外连接
左连接从左表(t1)取出所有记录,与右表(t2)匹配。如果没有匹配,以null值代表右边表的列。
基本语法:

SELECT * FROM [左表] LEFT OUTER JOIN [右表] on [左表].[字段]=[右表].[字段];

示例:

SELECT 	t1.*,t2.`name` FROM emp t1 LEFT JOIN dept t2 ON t1.`dept_id` = t2.`id`;

右外连接
右连接从右表(t2)取出所有记录,与左表(t1)匹配。如果没有匹配,以null值代表左边表的列。
基本语法:

SELECT * FROM [左表] RIGHT JOIN [右表] on [左表].[字段]=[右表].[字段];

示例:

SELECT 	* FROM dept t2 RIGHT JOIN emp t1 ON t1.`dept_id` = t2.`id`;

六.SQL注入

什么是SQL注入

SQL注入(SQL Injection)是一种常见的Web安全漏洞,主要形成的原因是在数据交互中,进行数据库操作时,没有做严格的判断,导致其传入的“数据”拼接到SQL语句中后,被当作SQL语句的一部分执行。 从而导致数据库受损(被脱库、被删除、甚至整个服务器权限陷)。

导致SQL注入的原因

SQL注入主要原因是程序员在开发用户和数据库的系统时没有对用户输入的字符串进行过滤、转义、限制或处理不严谨,导致攻击者可以通过精心构造的字符串去非法获取到数据库中的数据。

如何防止SQL注入

  1. 严格限制 Web 应用的数据库的操作权限,给此用户提供仅仅能够满足其工作的最低权限,从而最大限度的减少注入攻击对数据库的危害。
  2. 检查输入的数据是否具有所期望的数据格式,严格限制变量的类型,例如使用 regexp 包进行一些匹配处理,或者使用 strconv 包对字符串转化成其他基本类型的数据进行判断。
  3. 对进入数据库的特殊字符('"\ 尖括号 &*; 等)进行转义处理,或编码转换。Go 的 text/template 包里面的 HTMLEscapeString 函数可以对字符串进行转义处理。
  4. 在应用发布之前建议使用专业的 SQL 注入检测工具进行检测,以及时修补被发现的 SQL 注入漏洞。网上有很多这方面的开源工具,例如 sqlmap、SQLninja 等。
  5. 避免网站打印出 SQL 错误信息,比如类型错误、字段不匹配等,把代码里的 SQL 语句暴露出来,以防止攻击者利用这些错误信息进行 SQL 注入。

七.SQL事务

什么是事务

事务(transaction)是作为单个逻辑单元执行的一系列操作。多个操作作为一个整体向系统提交,要么都执行,要么都不执行。 MySQL 事务主要用于处理操作量大,复杂度高的数据。例如,在人员管理系统中,你删除一个人员,你既需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务!

事务的特性

一般来说,事务是必须满足4个条件(ACID)::原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。

  • 原子性: 一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
  • 一致性: 在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
  • 隔离性: 数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
  • 持久性: 事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务。 事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行。

事务的控制

在 MySQL 命令行的默认设置下,事务都是自动提交的,即执行 SQL 语句后就会马上执行 COMMIT 操作。因此要显式地开启一个事务务须使用命令 BEGIN 或 START TRANSACTION,或者执行命令 SET AUTOCOMMIT=0,用来禁止使用当前会话的自动提交。

用 BEGIN, ROLLBACK, COMMIT来实现
  • BEGIN 开始一个事务
  • ROLLBACK 事务回滚
  • COMMIT 事务确认
直接用 SET 来改变 MySQL 的自动提交模式:
  • SET AUTOCOMMIT=0 禁止自动提交
  • SET AUTOCOMMIT=1 开启自动提交
事务的控制命令语句
  • BEGIN 或 START TRANSACTION 显式地开启一个事务;
  • COMMIT 也可以使用 COMMIT WORK,不过二者是等价的。COMMIT 会提交事务,并使已对数据库进行的所有修改成为永久性的;
  • ROLLBACK 也可以使用 ROLLBACK WORK,不过二者是等价的。回滚会结束用户的事务,并撤销正在进行的所有未提交的修改;
  • SAVEPOINT identifier,SAVEPOINT 允许在事务中创建一个保存点,一个事务中可以有多个 SAVEPOINT;
  • RELEASE SAVEPOINT identifier 删除一个事务的保存点,当没有指定的保存点时,执行该语句会抛出一个异常;
  • ROLLBACK TO identifier 把事务回滚到标记点;
  • SET TRANSACTION 用来设置事务的隔离级别。InnoDB 存储引擎提供事务的隔离级别有READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ 和 SERIALIZABLE。

八.MySQL导入导出数据

导出数据

导出整个数据库中的所有数据
mysqldump -u 用户名 -p密码 数据库名 > 导出的文件名

示例:

mysqldump -u userName -ppassword dabaseName > test_db.sql

结尾没有分号。test_db.sql最好加上路径名。

导出数据库中的某个表的数据
mysqldump -u 用户名 -p密码 数据库名 表名> 导出的文件名

示例:

mysqldump -u userName -ppassword dabaseName tableName > fileName.sql
导出整个数据库中的所有的表结构
mysqldump -u userName -ppassword -d dabaseName > fileName.sql
导出整个数据库中某个表的表结构
mysqldump -u userName -ppassword -d dabaseName tableName >fileName.sql

导入数据

使用 MySQL 命令导入语法格式为:

mysql -u用户名    -p密码    <  要导入的数据库数据sql文件

示例:

mysql -uroot -p123456 < student.sql

以上命令将将备份的整个数据库 student.sql 导入。

九.数据库表的设计原则

  • id类型如果没有特殊要求,必须使用bigint unsigned,禁止使用int,即使现在的数据量很小。
  • 单表行数超过 500 万行或者单表容量超过 2GB,才推荐进行分库分表。 说明:如果预计2年后的数据量根本达不到这个级别,请不要在创建表时就分库分表。
  • 表必备三个字段,id,create_time,update_time,其中id为主键类型为 bigint unsigned、单表时自增、步长为 1, create_time,update_time 为datetime 类型,前者现在时表示创建时间,后者过去分词表示更新时间。
  • 表名,字段名必须使用小写字母或数字,且开头不能使用数字。
  • 表达是与否概念的字段,必须使用 is_xxx 的方式命名,数据类型是 unsigned tinyint ( 1表示是,0表示否)。
  • 小数类型为 decimal,禁止使用 float 和 double。 说明:float 和 double 在存储的时候,存在精度损失的问题,很可能在值的比较时,得到不 正确的结果。如果存储的数据范围超过 decimal 的范围,建议将数据拆成整数和小数分开存储。
  • varchar 是可变长字符串,不预先分配存储空间,长度不要超过 5000,如果存储长度大于此值,定义字段类型为 text,独立出来一张表,用主键来对应,避免影响其它字段索引效率。
  • 不得使用外键与级联,一切外键概念必须在程序业务端解决。外键与级联更新适用于单机低并发,不适合分布式、高并发集群;级联更新是强阻塞,存在数据库更新风暴和死锁的风险;并且外键影响数据库的插入速度。

参考资料:

docker 安装mysql8
菜鸟教程
MySQL教程
廖雪峰SQL教程
一个小时学会MySQL数据库
MySQL详细学习教程
MySql教程
MySQL 有这一篇就够
MySQL基础教程15——多表查询

Guess you like

Origin blog.csdn.net/unreliable_narrator/article/details/125588848