0%

mysql语句程序示例

[TOC]

mybatis配置

假设已经安装配置好了

mybatis的核心配置文件在resources目录下,名为Mybatis-config.xml,有模板,整体代码框架如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<!--这里要写入连接mysql数据库的信息-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="2023"/>
</dataSource>
</environment>
</environments>
<!--这里要写sql映射-->
<!--userMapper.xml文件实现mapper代理-->
<!--xml文件名可更改-->
<mappers>
<mapper resource="[Projectname]/Mapper/userMapper.xml"/>
</mappers>
</configuration>

XXXMapper.xml

以文件名userMapper.xml为例,一般是

要实现Mapper代理需要建一个和userMapper.xml同名的接口,在该接口中存放与userMapper.xml中SQL语言一样的抽象方法,要这个接口和userMapper.xml所在的目录要相同(???我的并没有)

userMapper.xml整体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.kinroy.Mapper.userMapper">

<select id="selectall" resultType="com.kinroy.pojo.User">
select * from user;
</select>
<select id="selectzhangsan" resultType="com.kinroy.pojo.User">
select * from user where name='张三';

</select>

</mapper>

与其同名接口的整体代码:(我的架构对应的应该是UserDao)

1
2
3
4
5
6
7
8
9
10
package com.kinroy.Mapper;

import com.kinroy.pojo.User;

import java.util.List;

public interface userMapper {
List<User> selectall();
User selectzhangsan();
}

sql语句

基本概念

SQL (Structured Query Language):结构化查询语句

SQL常用的三部分:数据查询语言DQL,数据操作语言DML,数据定义语言DDL

DQL:常见保留字SELECT,WHERE,ORDER BY,GROUP BY,HAVING

DML:常见动词INSERT,UPDATE,DELETE

DBMS (Database Management System) :数据库管理系统

DBA (Database Administration) :数据库管理员,保障DBMS正常高效运行

常用类型

1
2
3
4
5
6
MySQL:           
INT 整型
BIGINT 长整型
DECIMAL 浮点数
DATE/DATETIME 日期
VARCHAR 字符串

其他MySQL 数据类型 | 菜鸟教程 (runoob.com)

管理操作

先了解文件结构

1
2
3
4
5
6
7
8
9
10
11
12
13
|-连接
|--database1
|---table1
|---table2
|---table3
|--database2
|---table1
|--database3
|---table1
|---table2
|---table3
|---table4
|-连接

命令行操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
use <数据库名>;					 切换数据库
show databases; 查看数据库列表
create database <数据库名>; 创建数据库
drop database <数据库名>; 删除数据库
alter database <数据库名> <操作>; 修改数据库

drop table <表名>; 删除表 注意是drop不是delete delete用于删表记录

show tables; 查看当前数据库下所有表
show columns from <表名>; 显示表的属性
show index from <表名>; 显示表的详细索引信息,包括主键

show table status from <数据库名>; 显示数据库中所有表的信息
show table status from <数据库名> like 'runoob%'; 表名以runoob开头的表的信息
show table status from <数据库> like 'runoob%'\G; 加上\G,查询结果按列打印(可能会出错去掉分号就可以了,\G 和分号 ; 的作用相似,两者取其一即可)

show grants; 查看当前用户的权限

show variables like "%character%"; 查看编码方式
set character_set_server = utf8; 设置编码方式
create database name character set utf8; 创建表的时候设置编码
alter database name character set utf8; 修改数据库成utf8的.
alter table type character set utf8; 修改表默认用utf8.
alter table type modify type_name varchar(50) CHARACTER SET utf8; 修改字段用utf8

修改编码一:手动

image-20230524193022800

修改方式二:修改默认 配置文件(250条消息) Mysql 5.7 修改中文字符编码_10Alexander01的博客-CSDN博客

创建用户

注意:F6在Navicat Premium里可以打开命令行操作,试一下命令行操作

注意:password() 加密函数已经在 8.0.11 中移除了,可以使用 MD5() 函数代替

注意:在注意需要执行 FLUSH PRIVILEGES 语句。 这个命令执行后会重新载入授权表。若不执行该命令,无法使用新创建的用户来连接mysql服务器,除非你重启mysql服务器

注意:MySQL 的SQL语句以分号 (;) 作为结束标识

可以在创建用户时,为用户指定权限,在对应的权限列中,在插入语句中设置为 ‘Y’ 即可

添加用户的实例,用户名为用户名为guest,密码为123456,并授权用户可进行 SELECT, INSERT 和 UPDATE操作权限

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
root@host# mysql -u root -p
Enter password:*******
mysql> use mysql;
Database changed

mysql> INSERT INTO user
(host, user, authentication_string,
select_priv, insert_priv, update_priv)
VALUES ('localhost', 'guest',
PASSWORD('123456'), '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)

另外一种添加用户的方法为通过SQL的 GRANT 命令,以下命令会给指定数据库TUTORIALS添加用户 zara ,密码为 zara123 ,下面的命令会在mysql数据库中的user表创建一条用户信息记录。

1
2
3
4
5
6
7
mysql> use mysql;
Database changed

mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
-> ON TUTORIALS.*
-> TO 'zara'@'localhost'
-> IDENTIFIED BY 'zara123';

grant 普通 DBA 管理某个 MySQL 数据库的权限。

1
grant all privileges on testdb to dba@'localhost'

其中,关键字 privileges 可以省略。

grant 高级 DBA 管理 MySQL 中所有数据库的权限。

1
grant all on *.* to dba@'localhost'

表操作

表的约束

非空约束 NOT NULL

设置列的默认值 DEFAULT

唯一约束 UNIQUE (不允许值存在重复)

主键约束 PRIMARY KEY(非空且唯一)

主键自增长 AUTO_INCERMENT

外键约束 FOREIGN KEY (A表的外键列必须参考B表的主键列)

创建表

1
create table <表名> (column_name1 column_type1 [some constraints], column_name2 column_type2,...);

例如

1
2
3
4
5
6
7
create table if not exists `example` (
`id` int unsigned auto_increment,
`title` varchar(100) not null,
`author` varchar(40) not null,
`date` date,
primary key(`id`)
)engine=InnoDB default charset=utf8;

注意:不是单引号

或者

1
2
3
4
5
6
7
mysql> CREATE TABLE runoob_tbl(
-> runoob_id INT NOT NULL AUTO_INCREMENT,
-> runoob_title VARCHAR(100) NOT NULL,
-> runoob_author VARCHAR(40) NOT NULL,
-> submission_date DATE,
-> PRIMARY KEY ( runoob_id )
-> )ENGINE=InnoDB DEFAULT CHARSET=utf8;

注意:创建表的时候可以加个检查

1
DROP TABLE IF EXISTS <表名>; 

插入数据

SQL: INSERT INTO

1
2
3
INSERT INTO table_name ( field1, field2,...fieldN )
VALUES
( value1, value2,...valueN );

注意:数据是字符型时必须使用单引号或者双引号,如“wuwawawa”

例如

1
2
3
4
INSERT INTO runoob_tbl 
(runoob_title, runoob_author, submission_date)
VALUES
("学习 PHP", "菜鸟教程", NOW());

注意:上述实例中没有提供 runoob_id 的数据,因为该字段在创建表的时候已经设置它为 AUTO_INCREMENT(自动增加)属性。 所以,该字段会自动递增而不需要我们去设置。

注意:实例中 NOW()是一个 MySQL 函数,该函数返回日期和时间。

1
2
3
INSERT INTO runoob_tbl
VALUES
(0,"JAVA 教程", "RUNOOB.COM", '2016-05-06');

注意:如果添加过主键自增(PRINARY KEY AUTO_INCREMENT)第一列在增加数据的时候,可以写为0或者null,这样添加数据可以自增, 从而可以添加全部数据,而不用特意规定那几列添加数据。

Springboot中

查询数据

SQL:SELECT

1
2
3
4
5
6
7
SELECT column_name,column_name 
[as otherName]
FROM table_name
[WHERE Clause] #有AND OR BETWEEN...AND like in(...)
[LIMIT N][ OFFSET M]
[LIMIT offset, num_record]
[ORDER BY column_name [desc/asc(倒序/升序)]]
  • 查询语句中可以使用一个或者多个表,表之间使用逗号(,)分割,并使用WHERE语句来设定查询条件。
  • 使用星号(*)来代替其他字段,SELECT语句会返回表的所有字段数据
  • 使用 WHERE 语句来包含任何条件。
  • 使用 LIMIT 属性来设定返回的记录数。
  • 通过OFFSET指定SELECT语句开始查询的数据偏移量。默认情况下偏移量为0。
1
select * from runoob_tbl;

分页功能

1
2
3
4
5
select * from _table limit (page_number-1)*lines_perpage, lines_perpage



select * from _table limit lines_perpage offset (page_number-1)*lines_perpage

关联查询

分为左关联和右关联

左关联: left join ... on ...

右关联:right join... on ...

1
select 字段 from 表1 left join 表2 on  条件 (一般为表1与表2的关联条件)

例如

1
2
3
select user.username,orders.id,count(*) 
from user left join orders
on user.id = orders.user_id

Springboot中

筛选语句

SQL:WHERE子句

1
2
SELECT field1, field2,...fieldN FROM table_name1, table_name2...
[WHERE condition1 [AND [OR]] condition2.....

注意:如果给定的条件在表中没有任何匹配的记录,那么查询不会返回任何数据。

注意: WHERE 子句的字符串比较是不区分大小写的,可以使用 BINARY 关键字来设定 WHERE 子句的字符串比较是区分大小写的

示例:

1
2
SELECT * from runoob_tbl WHERE runoob_author='菜鸟教程';
SELECT * from runoob_tbl WHERE BINARY runoob_author='RUNOOB.COM';

Springboot上

更新语句

SQL:UPDATE语句

1
2
UPDATE table_name SET field1=new-value1, field2=new-value2
[WHERE Clause]

例如:

1
UPDATE runoob_tbl SET runoob_title='学习 C++' WHERE runoob_id=3;

当需要将字段中的特定字符串(子串)批量修改为其他字符串时

1
2
UPDATE table_name SET field=REPLACE(field, 'old-string', 'new-string') 
[WHERE Clause]

Springboot

删除语句

SQL:DELETE语句

1
DELETE FROM table_name [WHERE Clause]

(???是只删记录吗?删了之后表还存在吗?)

例如:

1
DELETE FROM runoob_tbl WHERE runoob_id=3;

delete,drop,truncate 都有删除表的作用,区别在于:

  • 1、delete 和 truncate 仅仅删除表数据,drop 连表数据和表结构一起删除,打个比方,delete 是单杀,truncate 是团灭,drop 是把电脑摔了。
  • 2、delete 是 DML 语句,操作完以后如果没有不想提交事务还可以回滚,truncate 和 drop 是 DDL 语句,操作完马上生效,不能回滚,打个比方,delete 是发微信说分手,后悔还可以撤回,truncate 和 drop 是直接扇耳光说滚,不能反悔。
  • 3、执行的速度上,drop>truncate>delete,打个比方,drop 是神舟火箭,truncate 是和谐号动车,delete 是自行车。

Springboot

匹配语句

SQL:LIKE子句

LIKE即模糊匹配

  • **%**字符来表示任意字符,如果没有使用 **%**, LIKE 子句与等号 = 的效果是一样的
  • **_**字符匹配单个字符
  • **[]**匹配括号所列的字符中的一个,指定一个字符、字符串或范围
  • **[^]**匹配不在括号所列之内的单个字符

正则表达式MySQL 正则表达式 | 菜鸟教程 (runoob.com)

规则示例

1
2
3
4
5
6
'%a'     //以a结尾的数据
'a%' //以a开头的数据
'%a%' //含有a的数据
'_a_' //三位且中间字母是a的
'_a' //两位且结尾字母是a的
'a_' //两位且开头字母是a的
1
2
3
ELECT field1, field2,...fieldN 
FROM table_name
WHERE field1 LIKE condition1 [AND [OR]] filed2 = 'somevalue'

示例

1
SELECT * from runoob_tbl  WHERE runoob_author LIKE '%COM';

Springboot

集合操作

SQL:UNION操作符

UNION 操作符用于连接两个以上的 SELECT 语句的结果组合到一个结果集合

  • DISTINCT: 可选,删除结果集中重复的数据。默认情况下 UNION 操作符已经删除了重复数据,所以 DISTINCT 修饰符对结果没啥影响。
  • ALL: 可选,返回所有结果集,包含重复数据
1
2
3
4
5
6
7
SELECT expression1, expression2, ... expression_n
FROM tables
[WHERE conditions]
UNION [ALL | DISTINCT]
SELECT expression1, expression2, ... expression_n
FROM tables
[WHERE conditions];

示例

1
2
3
SELECT country FROM Websites
UNION
SELECT country FROM apps

Sprintboot

排序操作

SQL:ORDER BY子句

使用 ASCDESC 关键字来设置查询结果是按升序降序排列。 默认情况下,它是按升序排列

1
2
SELECT field1, field2,...fieldN FROM table_name1, table_name2...
ORDER BY field1 [ASC [DESC][默认 ASC]], [field2...] [ASC [DESC][默认 ASC]]

示例:

1
SELECT * from runoob_tbl ORDER BY submission_date ASC;

注意:gbk(汉字编码字符集)直接ORDER对拼音进行排序,如果用的是utf8需要先转码才能达到拼音排序的效果CONVERT(runoob_title using gbk)

Springboot

分组操作

SQL:GROUP BY语句

在分组的列上我们可以使用 COUNT, SUM, AVG等函数

1
2
3
4
SELECT column_name, function(column_name)
FROM table_name
WHERE column_name operator value
GROUP BY column_name;

示例

1
2
3
SELECT name, COUNT(*) FROM   employee_tbl GROUP BY name;
SELECT name, SUM(signin) as signin_count FROM employee_tbl GROUP BY name WITH ROLLUP;
SELECT coalesce(name, '总数'), SUM(signin) as signin_count FROM employee_tbl GROUP BY name WITH ROLLUP;

可以使用 coalesce 来设置一个可以取代 NUll 的名称,coalesce 语法:

1
select coalesce(a,b,c);

参数说明:如果a==null,则选择b;如果b==null,则选择c;如果a!=null,则选择a;如果a b c 都为null ,则返回为null

Springboot

连接操作

在两个或多个表中查询数据

SQL:JOIN语句

可以在 SELECT, UPDATE 和 DELETE 语句中使用 Mysql 的 JOIN 来联合多表查询,JOIN 按照功能大致分为如下三类:

  • INNER JOIN或JOIN(内连接,或等值连接):获取两个表中字段匹配关系的记录。
  • LEFT JOIN(左连接):获取左表所有记录,即使右表没有对应匹配的记录。
  • RIGHT JOIN(右连接): 与 LEFT JOIN 相反,用于获取右表所有记录,即使左表没有对应匹配的记录。

示例:

内连接

image-20230527103931614

1
2
3
SELECT a.runoob_id, a.runoob_author, b.runoob_count FROM runoob_tbl a INNER JOIN tcount_tbl b ON a.runoob_author = b.runoob_author;
<==>
SELECT a.runoob_id, a.runoob_author, b.runoob_count FROM runoob_tbl a, tcount_tbl b WHERE a.runoob_author = b.runoob_author;

左连接

image-20230527103943783

1
SELECT a.runoob_id, a.runoob_author, b.runoob_count FROM runoob_tbl a LEFT JOIN tcount_tbl b ON a.runoob_author = b.runoob_author;

右连接

image-20230527104023885

1
SELECT a.runoob_id, a.runoob_author, b.runoob_count FROM runoob_tbl a RIGHT JOIN tcount_tbl b ON a.runoob_author = b.runoob_author;

Springboot

NULL值处理

SQL:IS NULL & IS NOT NULL操作符

MySQL提供了三大运算符:

  • IS NULL: 当列的值是 NULL,此运算符返回 true。
  • IS NOT NULL: 当列的值不为 NULL, 运算符返回 true。
  • <=>: 比较操作符(不同于 = 运算符),当比较的的两个值相等或者都为 NULL 时返回 true。

关于 NULL 的条件比较运算是比较特殊的。你不能使用 = NULL 或 != NULL 在列中查找 NULL 值 。

在 MySQL 中,NULL 值与任何其它值的比较(即使是 NULL)永远返回 NULL,即 NULL = NULL 返回 NULL 。

MySQL 中处理 NULL 使用 IS NULL 和 IS NOT NULL 运算符。

ifnull(columnName2,0):若columnName2有值为NULL时转为0

示例

1
SELECT * FROM runoob_test_tbl WHERE runoob_count IS NULL;

修改操作

修改数据表名或者修改数据表字段

SQL:ALTER命令

如下命令使用了 ALTER 命令及 DROP 子句来删除以上创建表的 i 字段:

1
mysql> ALTER TABLE testalter_tbl  DROP i;

如果数据表中只剩余一个字段则无法使用DROP来删除字段。

MySQL 中使用 ADD 子句来向数据表中添加列,如下实例在表 testalter_tbl 中添加 i 字段,并定义数据类型:

1
mysql> ALTER TABLE testalter_tbl ADD i INT;

如果你需要指定新增字段的位置,可以使用MySQL提供的关键字 FIRST (设定位第一列), AFTER 字段名(设定位于某个字段之后)。

尝试以下 ALTER TABLE 语句, 在执行成功后,使用 SHOW COLUMNS 查看表结构的变化:

1
2
3
4
ALTER TABLE testalter_tbl DROP i;
ALTER TABLE testalter_tbl ADD i INT FIRST;
ALTER TABLE testalter_tbl DROP i;
ALTER TABLE testalter_tbl ADD i INT AFTER c;

FIRST 和 AFTER 关键字可用于 ADD 与 MODIFY 子句,所以如果你想重置数据表字段的位置就需要先使用 DROP 删除字段然后使用 ADD 来添加字段并设置位置。

如果需要修改字段类型及名称, 你可以在ALTER命令中使用 MODIFY 或 CHANGE 子句 。

例如,把字段 c 的类型从 CHAR(1) 改为 CHAR(10),可以执行以下命令:

1
mysql> ALTER TABLE testalter_tbl MODIFY c CHAR(10);

使用 CHANGE 子句, 语法有很大的不同。 在 CHANGE 关键字之后,紧跟着的是你要修改的字段名,然后指定新字段名及类型。尝试如下实例:

1
2
mysql> ALTER TABLE testalter_tbl CHANGE i j BIGINT;
mysql> ALTER TABLE testalter_tbl CHANGE j j INT;

当你修改字段时,你可以指定是否包含值或者是否设置默认值。

以下实例,指定字段 j 为 NOT NULL 且默认值为100 。

1
2
mysql> ALTER TABLE testalter_tbl 
-> MODIFY j BIGINT NOT NULL DEFAULT 100;

如果你不设置默认值,MySQL会自动设置该字段默认为 NULL。

你可以使用 ALTER 来修改字段的默认值,尝试以下实例:

1
2
3
4
5
6
7
8
9
mysql> ALTER TABLE testalter_tbl ALTER i SET DEFAULT 1000;
mysql> SHOW COLUMNS FROM testalter_tbl;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| c | char(1) | YES | | NULL | |
| i | int(11) | YES | | 1000 | |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)

你也可以使用 ALTER 命令及 DROP子句来删除字段的默认值,如下实例:

1
2
3
4
5
6
7
8
9
10
mysql> ALTER TABLE testalter_tbl ALTER i DROP DEFAULT;
mysql> SHOW COLUMNS FROM testalter_tbl;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| c | char(1) | YES | | NULL | |
| i | int(11) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)
Changing a Table Type:

修改数据表类型,可以使用 ALTER 命令及 TYPE 子句来完成。尝试以下实例,我们将表 testalter_tbl 的类型修改为 MYISAM :

注意:查看数据表类型可以使用 SHOW TABLE STATUS 语句。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
mysql> ALTER TABLE testalter_tbl ENGINE = MYISAM;
mysql> SHOW TABLE STATUS LIKE 'testalter_tbl'\G
*************************** 1. row ****************
Name: testalter_tbl
Type: MyISAM
Row_format: Fixed
Rows: 0
Avg_row_length: 0
Data_length: 0
Max_data_length: 25769803775
Index_length: 1024
Data_free: 0
Auto_increment: NULL
Create_time: 2007-06-03 08:04:36
Update_time: 2007-06-03 08:04:36
Check_time: NULL
Create_options:
Comment:
1 row in set (0.00 sec)

如果需要修改数据表的名称,可以在 ALTER TABLE 语句中使用 RENAME 子句来实现。

尝试以下实例将数据表 testalter_tbl 重命名为 alter_tbl:

1
mysql> ALTER TABLE testalter_tbl RENAME TO alter_tbl;

ALTER 命令还可以用来创建及删除MySQL数据表的索引,该功能我们会在接下来的章节中介绍。

Mysql事务处理

保证ACID原则

MYSQL 事务处理主要有两种方法:

1、用 BEGIN, ROLLBACK, COMMIT来实现

  • BEGIN 开始一个事务
  • ROLLBACK 事务回滚
  • COMMIT 事务确认

2、直接用 SET 来改变 MySQL 的自动提交模式:

  • SET AUTOCOMMIT=0 禁止自动提交
  • SET AUTOCOMMIT=1 开启自动提交

示例MySQL 事务 | 菜鸟教程 (runoob.com)

Mysql索引

索引分单列索引和组合索引。单列索引,即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引。组合索引,即一个索引包含多个列。

创建索引时,你需要确保该索引是应用在 SQL 查询语句的条件(一般作为 WHERE 子句的条件)。

实际上,索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录。

上面都在说使用索引的好处,但过多的使用索引将会造成滥用。因此索引也会有它的缺点:虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。

建立索引会占用磁盘空间的索引文件。

普通索引

创建索引,没有任何限制的普通索引.如果是CHAR,VARCHAR类型,length可以小于字段实际长度;如果是BLOB和TEXT类型,必须指定 length。

1
CREATE INDEX indexName ON table_name (column_name(length))

修改表结构/添加索引

1
ALTER table tableName ADD INDEX indexName(columnName)

也可以在创建表的时候直接指定

1
2
3
4
5
CREATE TABLE mytable(  
ID INT NOT NULL,
username VARCHAR(16) NOT NULL,
INDEX [indexName] (username(length))
);

删除索引

1
DROP INDEX [indexName] ON mytable; 

唯一索引

唯一索引和普通索引的区别是索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。

创建索引

1
CREATE UNIQUE INDEX indexName ON mytable(username(length)) 

修改表结构

1
ALTER table mytable ADD UNIQUE [indexName] (username(length))

创建表的时候直接指定

1
2
3
4
5
CREATE TABLE mytable(  
ID INT NOT NULL,
username VARCHAR(16) NOT NULL,
UNIQUE [indexName] (username(length))
);

使用ALTER 命令添加和删除索引

有四种方式来添加数据表的索引:

  • ALTER TABLE tbl_name ADD PRIMARY KEY (column_list):该语句添加一个主键,这意味着索引值必须是唯一的,且不能为NULL。
  • ALTER TABLE tbl_name ADD UNIQUE index_name (column_list): 这条语句创建索引的值必须是唯一的(除了NULL外,NULL可能会出现多次)。
  • ALTER TABLE tbl_name ADD INDEX index_name (column_list): 添加普通索引,索引值可出现多次。
  • **ALTER TABLE tbl_name ADD FULLTEXT index_name (column_list):**该语句指定了索引为 FULLTEXT ,用于全文索引。

临时表

临时表只在当前连接可见,当关闭连接时,Mysql会自动删除表并释放所有空间。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
mysql> CREATE TEMPORARY TABLE SalesSummary (
-> product_name VARCHAR(50) NOT NULL
-> , total_sales DECIMAL(12,2) NOT NULL DEFAULT 0.00
-> , avg_unit_price DECIMAL(7,2) NOT NULL DEFAULT 0.00
-> , total_units_sold INT UNSIGNED NOT NULL DEFAULT 0
);
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO SalesSummary
-> (product_name, total_sales, avg_unit_price, total_units_sold)
-> VALUES
-> ('cucumber', 100.25, 90, 2);

mysql> SELECT * FROM SalesSummary;
+--------------+-------------+----------------+------------------+
| product_name | total_sales | avg_unit_price | total_units_sold |
+--------------+-------------+----------------+------------------+
| cucumber | 100.25 | 90.00 | 2 |
+--------------+-------------+----------------+------------------+
1 row in set (0.00 sec)

或者
CREATE TEMPORARY TABLE 临时表名 AS
(
SELECT * FROM 旧的表名
LIMIT 0,10000
);

当你使用 SHOW TABLES命令显示数据表列表时,你将无法看到 SalesSummary表。

如果你退出当前MySQL会话,再使用 SELECT命令来读取原先创建的临时表数据,那你会发现数据库中没有该表的存在,因为在你退出时该临时表已经被销毁了。

1
mysql> DROP TABLE SalesSummary;

复制表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
1. 使用 SHOW CREATE TABLE 命令获取创建数据表(CREATE TABLE) 语句,该语句包含了原数据表的结构,索引等。
SHOW CREATE TABLE <待复制的表>;
例如要复制user表,能拿到如下信息:
| user | CREATE TABLE `user` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 |

2. 复制以下命令显示的SQL语句,修改数据表名,并执行SQL语句,通过以上命令 将完全的复制数据表结构。
CREATE TABLE `clone_user` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;


3. 如果你想复制表的内容,你就可以使用 INSERT INTO ... SELECT 语句来实现。
INSERT INTO clone_user (
id,
username,
password)
SELECT id, username, password
FROM user;

另一种方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
CREATE TABLE targetTable LIKE sourceTable;
INSERT INTO targetTable SELECT * FROM sourceTable;

也可以对拷贝的信息进行选择
CREATE TABLE newadmin AS
(
SELECT username, password FROM admin
)
改名
CREATE TABLE newadmin AS
(
SELECT id, username AS uname, password AS pass FROM admin
)
定义复制表的字段信息
CREATE TABLE newadmin
(
id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY
)
AS
(
SELECT * FROM admin
)

元数据

MySQL以下三种信息:

  • 查询结果信息: SELECT, UPDATE 或 DELETE语句影响的记录数。
  • 数据库和数据表的信息: 包含了数据库及数据表的结构信息。
  • MySQL服务器信息: 包含了数据库服务器的当前状态,版本号等。

以下命令语句可以在 MySQL 的命令提示符使用,也可以在脚本中 使用,如PHP脚本。

命令 描述
SELECT VERSION( ) 服务器版本信息
SELECT DATABASE( ) 当前数据库名 (或者返回空)
SELECT USER( ) 当前用户名
SHOW STATUS 服务器状态
SHOW VARIABLES 服务器配置变量

序列

重置序列:当删了记录后需要重新排列,要注意ACID的问题,如果在删除的同时又有新记录添加,有可能会出现数据混乱

1
2
3
4
mysql> ALTER TABLE clone_user DROP id;
mysql> ALTER TABLE clone_user
-> ADD id INT UNSIGNED NOT NULL AUTO_INCREMENT FIRST,
-> ADD PRIMARY KEY (id);

(就是删了原字段及其数据,重建了一下)

设置序列初始值

1
2
3
4
5
6
7
8
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;

也可以在表创建成功后,通过以下语句来实现:

1
mysql> ALTER TABLE t AUTO_INCREMENT = 100;

函数

内置函数

MySQL 函数 | 菜鸟教程 (runoob.com)

创建函数

使用函数创建自增序列管理表(批量使用自增表,设置初始值,自增幅度)

???MySQL 序列使用 | 菜鸟教程 (runoob.com)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
DROP FUNCTION IF EXISTS currval; 
DELIMITER $
CREATE FUNCTION currval (seq_name VARCHAR(50))
RETURNS INTEGER
LANGUAGE SQL
DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BRGIN
DECLARE value INTEGER;
SET value = 0;
SELECT current_value INTO value
FROM sequence
WHERE name = seq_name;
RETURN value;
END
$
DELIMITER;

处理重复数据

防止出现重复数据:指定字段为主键或唯一(PRIMARY KEY 或 UNIQUE)来保证数据唯一性

INSERT IGNORE INTO 当插入数据时,在设置了记录的唯一性后,如果插入重复数据,将不返回错误,只以警告形式返回。 而 REPLACE INTO 如果存在 primary 或 unique 相同的记录,则先删除掉。再插入新记录。

添加一个 UNIQUE 索引,如下所示:

1
2
3
4
5
6
7
CREATE TABLE person_tbl
(
first_name CHAR(20) NOT NULL,
last_name CHAR(20) NOT NULL,
sex CHAR(10),
UNIQUE (last_name, first_name)
);

统计重复数据

HAVING子句设置重复数大于1。

1
2
3
4
mysql> SELECT COUNT(*) as repetitions, last_name, first_name
-> FROM person_tbl
-> GROUP BY last_name, first_name
-> HAVING repetitions > 1 and 其他条件;

过滤重复数据

如果你需要读取不重复的数据可以在 SELECT 语句中使用 DISTINCT 关键字来过滤重复数据。

1
2
mysql> SELECT DISTINCT last_name, first_name
-> FROM person_tbl;

你也可以使用 GROUP BY 来读取数据表中不重复的数据:

1
2
3
mysql> SELECT last_name, first_name
-> FROM person_tbl
-> GROUP BY (last_name, first_name);

删除重复数据

如果你想删除数据表中的重复数据,你可以使用以下的SQL语句:

1
2
3
mysql> CREATE TABLE tmp SELECT last_name, first_name, sex FROM person_tbl  GROUP BY (last_name, first_name, sex);
mysql> DROP TABLE person_tbl;
mysql> ALTER TABLE tmp RENAME TO person_tbl;

当然你也可以在数据表中添加 INDEX(索引) 和 PRIMAY KEY(主键)这种简单的方法来删除表中的重复记录。方法如下:

1
2
mysql> ALTER IGNORE TABLE person_tbl
-> ADD PRIMARY KEY (last_name, first_name);

SQL注入

永远不要信任用户的输入,我们必须认定用户输入的数据都是不安全的,我们都需要对用户输入的数据进行过滤处理。

防止SQL注入,我们需要注意以下几个要点:

  • 1.永远不要信任用户的输入。对用户的输入进行校验,可以通过正则表达式,或限制长度;对单引号和 双”-“进行转换等。
  • 2.永远不要使用动态拼装sql,可以使用参数化的sql或者直接使用存储过程进行数据查询存取。
  • 3.永远不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接。
  • 4.不要把机密信息直接存放,加密或者hash掉密码和敏感的信息。
  • 5.应用的异常信息应该给出尽可能少的提示,最好使用自定义的错误信息对原始错误信息进行包装
  • 6.sql注入的检测方法一般采取辅助软件或网站平台来检测,软件一般采用sql注入检测工具jsky,网站平台就有亿思网站安全平台检测工具。MDCSOFT SCAN等。采用MDCSOFT-IPS可以有效的防御SQL注入,XSS攻击等。

以对用户输入的数据进行转义

导出数据

将数据表 runoob_tbl 数据导出到 /tmp/runoob.txt 文件中:

1
2
mysql> SELECT * FROM runoob_tbl 
-> INTO OUTFILE '/tmp/runoob.txt';

你可以通过命令选项来设置数据输出的指定格式,以下实例为导出 CSV 格式:

1
2
3
mysql> SELECT * FROM passwd INTO OUTFILE '/tmp/runoob.txt'
-> FIELDS TERMINATED BY ',' ENCLOSED BY '"'
-> LINES TERMINATED BY '\r\n';

在下面的例子中,生成一个文件,各值用逗号隔开。这种格式可以被许多程序使用。

1
2
3
4
SELECT a,b,a+b INTO OUTFILE '/tmp/result.text'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
FROM test_table;

注意:输出不能是一个已存在的文件。防止文件数据被篡改。

mysqldump其他操作MySQL 导出数据 | 菜鸟教程 (runoob.com)

导入数据

MySQL 导入数据 | 菜鸟教程 (runoob.com)

运算符

MySQL 运算符 | 菜鸟教程 (runoob.com)

其他

mybatisX插件

sql语句执行顺序

上面执行顺序有误。谷歌来的顺序是这样的

  1. FROM, including JOINs
  2. WHERE
  3. GROUP BY
  4. HAVING
  5. WINDOW functions
  6. SELECT
  7. DISTINCT
  8. UNION
  9. ORDER BY
  10. LIMIT and OFFSET

导入操作?