mysql使用心得

入门

安装

键入命令:
apt-get install -y mysql-server
中间会要求你输入root密码。

接着安装mysql客户端:
apt-get install -y mysql-client

用以下命令登录mysql:
mysql -uroot -p你的密码

允许从远程机器登录mysql

编辑文件/etc/mysql/mysql.conf.d/mysqld.cnf,注释掉bind-address = 127.0.0.1
之后重启mysql:service mysql restart

mysql的数据目录

mysqld.cnf里有一段:

basedir         = /usr
datadir         = /var/lib/mysql

windows下启动mysql

mysqld -install --defaults-file=D:\programs\mysql-5.7.32-winx64\my.ini
net start mysql

先将mysql安装为windows服务,再启动mysql。

–defaults-file指定启动的配置文件,若不指定,默认使用mysql根目录下的my.ini文件。

my.ini文件内容为:

[mysqld]

# 设置3306端口

port=3306

# 设置mysql的安装目录

basedir=D:\programs\mysql-5.7.32-winx64

# 设置mysql数据库的数据的存放目录

datadir=D:\programs\mysql-5.7.32-winx64\data

# 允许最大连接数

max_connections=200

# 允许连接失败的次数。这是为了防止有人从该主机试图攻击数据库系统

max_connect_errors=10

# 服务端使用的字符集默认为UTF8

character-set-server=utf8

# 创建新表时将使用的默认存储引擎

default-storage-engine=INNODB

# 默认使用“mysql_native_password”插件认证

default_authentication_plugin=mysql_native_password

[mysql]

# 设置mysql客户端默认字符集

default-character-set=utf8

[client]

# 设置mysql客户端连接服务端时默认使用的端口

port=3306

default-character-set=utf8

启动失败,一是看datadir数据目录是否存在,二是在data目录下找到*.err文件,查看报错信息,再根据错误信息解决问题。

一些启动错误

查看报错信息如下:

2022-05-27T11:27:37.726092Z 0 [Warning] Failed to open optimizer cost constant tables

2022-05-27T11:27:37.728757Z 0 [ERROR] Fatal error: Can't open and lock privilege tables: Table 'mysql.user' doesn't exist
2022-05-27T11:27:37.729532Z 0 [ERROR] Fatal error: Failed to initialize ACL/grant/time zones structures or failed to remove temporary table files.
2022-05-27T11:27:37.730635Z 0 [ERROR] Aborting

linux下键入如下命令解决:

mysql_install_db -user=mysql datadir=D:\programs\mysql-5.7.32-winx64\data

但windows下没法这么玩。

分析了一下,应该是mysql启动时库的初始化没做,先把datadir目录清空,再执行:

mysqld.exe --initialize --user=mysql --console

返回一个临时密码,记录下来。

接着使用

net start mysql

就能正常启动mysql了。

然后我们在mysql client里修改密码:

set password=password('新密码');
flush privileges;

注意

password函数括号里是新的密码。password是一个专用的密码加密函数。

flush privileges是必须要的,否则下次重启后会报错。该命令本质上的作用是将当前user和privilige表中的用户信息/权限设置从mysql库(MySQL数据库的内置库)中提取到内存里。MySQL用户数据和权限有修改后,希望在"不重启MySQL服务"的情况下直接生效,那么就需要执行这个命令。通常是在修改ROOT帐号的设置后,怕重启后无法再登录进来,那么直接flush之后就可以看权限设置是否生效,而不必冒太大风险。

可以到mysql.user表里使用如下语句查询用户、密码信息:

select user,authentication_string from mysql.user;

authentication_string是加密过的登录密码。

设置新密码后,重启mysql会报错:

Access denied for user 'root'@'localhost' (using password: YES)

如前所述,我们改密码时要执行flush privileges命令。

常用命令

连接数据库

本地的:

mysql -u root -pXXX -P 3306 -D test

远程的加-h选项:

mysql -u admin -pXXXX -h XX.XX.XX.235 -P 3306 -D testdb

-D后跟数据库名。

查看版本

select version();

查看DB

show databases;

创建DB

create database testdb;

root用户赋予所有权限并允许从任意机器登录:

GRANT ALL PRIVILEGES ON *.* TO root@"%" IDENTIFIED BY "密码";
flush privileges;

注意:IDENTIFIED BY后跟的是root用户的密码。

创建用户并给用户授权

CREATE USER 'ares'@'%' IDENTIFIED BY '密码';
GRANT ALL ON aresdb.* TO 'ares'@'%';
flush privileges;

查看用户

select * from mysql.user

创建DB的用户,仅允许从本地登录

GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,ALTER ON sdnctl.* TO sdnctl@localhost IDENTIFIED BY 'gamma';
flush privileges;

创建DB的用户,允许从任意机器登录

GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,ALTER ON sdnctl.* TO sdnctl@'%' IDENTIFIED BY 'gamma';

flush privileges;

查看表

show tables;

查看用户可从哪台机器登录

select host,user from user;

查看表结构

desc 表名;

修改表结构

ALTER TABLE `table_name` ADD INDEX index_name ( `column` ) 

sleep函数

要这样写:

select sleep(15);

单位是秒。

sysdate和now函数

两者都是获得当前日期+时间,不同之处在于:now() 在执行开始时值就得到了, sysdate() 在函数执行时动态得到值,后者会更精确。

要获得当前日期,用curdate()函数。

时间偏移

使用timestampadd,获取当前时间2小时前的时间:

select timestampadd(SECOND, -3600 , sysdate());

也可用DATE_SUB和DATE_ADD函数,这俩函数日期和时间都支持:

SELECT DATE_SUB(curdate(),INTERVAL 5 DAY);
SELECT DATE_SUB(sysdate(),INTERVAL 5 DAY);
SELECT DATE_SUB(sysdate(),INTERVAL 2 HOUR);
SELECT DATE_SUB(sysdate(),INTERVAL 7200 SECOND);

查看数据库连接

参考该文:

查看数据库连接

SHOW PROCESSLIST; 

根据IP过滤数据库连接

select * from information_schema.processlist where Host like 'XX.XX.XX.127%';

数据库连接summary

show status like 'Threads%';

返回形如:

 Variable_name      Value    
 -----------------  -------- 
 Threads_cached     0        
 Threads_connected  49       
 Threads_created    160296   
 Threads_running    2 

查看最大连接数

show variables like '%max_connections%';  

设置最大连接数

临时设置:

mysql> SET GLOBAL max_connections = 250;

mysql一旦重启就会恢复默认值。

要永久生效,需修改/etc/mysql/mysql.conf.d/mysqld.cnf:

max_connections = 250

设置最大连接数的依据

我们得知道平均每个连接的内存消耗,网上有这么一段查询:

SELECT ( @@read_buffer_size
+ @@read_rnd_buffer_size
+ @@sort_buffer_size
+ @@join_buffer_size
+ @@binlog_cache_size
+ @@thread_stack
+ @@tmp_table_size
+ 2*@@net_buffer_length
) / (1024 * 1024) AS MEMORY_PER_CON_MB;

它表示的是一个连接最大可用的内存,在我的机器上这个值是18M。假设我们只用一半,四舍五入一下则每个连接的内存消耗是10M,一台16G内存的机器,至少可以同时开800个连接(差不多用8G的内存)。

参考原文。

作者统计每个连接内存占用的方法:

 In general, I assume each connection, on average, will need about half of the available memory to it. That's been a pretty safe bet for a number of years now. 

字符集和编码

查看mysql字符集

之前遇到过表的索引长度不能超过767字节限制的问题,这个是跟每个character的字节数相关的。

mysql字符集查看指令

show variables like 'character_set_%';

mysql字符集的支持细化到四个层次:

  • 服务器(server)
  • 数据库(database)
  • 数据表(table)
  • 连接(connection)

MySQL对于字符集的指定可以细化到一个数据库,一张表,一列应该用什么字符集。 但是,传统的程序在创建数据库和数据表时并没有使用那么复杂的配置,它们用的是默认的配置,那么,默认的配置从何而来呢?
(1)编译MySQL 时,指定了一个默认的字符集,这个字符集是 latin1;
(2)安装MySQL 时,可以在配置文件 (my.ini) 中指定一个默认的的字符集,如果没指定,这个值继承自编译时指定的;
(3)启动mysqld 时,可以在命令行参数中指定一个默认的的字符集,如果没指定,这个值继承自配置文件中的配置,此时 character_set_server 被设定为这个默认的字符集;
(4)当创建一个新的数据库时,除非明确指定,这个数据库的字符集被缺省设定为character_set_server;
(5)当选定了一个数据库时,character_set_database 被设定为这个数据库默认的字符集;
(6)在这个数据库里创建一张表时,表默认的字符集被设定为 character_set_database,也就是这个数据库默认的字符集;
(7)当在表内设置一栏时,除非明确指定,否则此栏缺省的字符集就是表默认的字符集;

参考文章。

查看DB和表的字符集

SHOW CREATE DATABASE db_name;   

SHOW CREATE TABLE tbl_name;   

SHOW FULL COLUMNS FROM tbl_name;  

mysql的charset和collate

charset用于给数据库确定使用哪种编码方式进行编码

collate叫做数据库的校验,就是一种对字符串进行比较的规则

stackoverflow上对charset和collate的解释:A character set is a set of symbols and encodings. A collation is a set of rules for comparing characters in a character set.

如何支持4字节emoji表情包

用utf8mb4编码代替utf8编码。
顺带说一下,一个库里的表最好是同一编码,因不同编码的表在做join时会有性能问题

变量

用户定义变量

用户定义变量 是用户根据需要自己定义的变量,用户变量不用提前声明,在用的时候直接用 “@变量 名” 使用就可以,其作用域为当前会话,即在会话1中定义的变量在会话2中是不能使用的; 注:之前讲的2个@符号是系统变量名,一个@符号是用户自定义变量 。

局部变量

局部变量 是根据需要定义的在局部生效的变量,访问之前,需要DECLARE声明。可用作存储过程内的 局部变量和输入参数,局部变量的范围是在其内声明的BEGIN … END块。

参考该文。

你可能感兴趣的:(mysql,数据库)