关于MySQL的一点记录

MySQL

安装

可视化工具

1、navicat

登录mysql

命令行下输入

mysql -uroot -p 

Windows 上启停 MySQL

net start mysql80
net stop mysql80
#或者
sc start mysql80
sc stop mysql80

更改数据库路径

  • 关闭mysql80服务
  • 打开 C:\ProgramData\MySQL\MySQL Server 8.0\my.ini
  • ctrl+f 搜索 datadir, 修改到需要设定的路径,比如 datadir=D:/MySQLData
  • 将 C:/ProgramData/MySQL/MySQL Server 8.0\Data 复制到 D:/MySQLData
  • 重新启动mysql80服务

C++连接MySQL - Connector/C++

Connector/C++介绍

MySQL Connector/C++8.0 是一个MySQL数据库连接器,用于连接到MySQL服务器的C++应用程序。Connector/C++ 可用于访问实现文档存储的MySQL服务器,或以传统方式使用SQL语句。Connector/C++ 8.0 的首选开发环境是支持开发使用 X DevAPI 的 C++ 应用程序,或使用 X DevAPI for C 的普通 C 应用程序,但 Connector/C++ 8.0 还支持开发使用旧的基于 JDBC 的 API 的 C++ 应用程序连接器/C++ 1.1。

在线手册

参考代码

//包含头文件
#include "mysql/jdbc.h"

//1 获得驱动
auto m_driver = sql::mysql::get_mysql_driver_instance();

//2 连接数据库
auto m_conn = m_driver->connect(m_hostName, m_user, m_password);

//3 执行语句
auto stmt = m_conn->createStatement();
stmt->execute("create database db");//创建数据库db
stmt->execute("use db");//使用名字叫做db的数据库
//创建一张表存储图片 mediumblob 最大16MB
stmt->execute("create table tb1(id int not null primary key auto_increment, imgbuffer mediumblob)");


//4 向表中插入内容
auto pre_stmt = m_conn->prepareStatement("insert into tb1(name,imgbuffer) values(?,?)");
//插入int类型数据
pre_stmt->setInt(1, 1000);		
//插入二进制数据,比如有 char* blobData; 它的数据长度是 length;
std::strstreambuf buf(reinterpret_cast<char*>(blobData), length);
std::istream stream(&buf);
pre_stmt->setBlob(2, &stream);
//数据插入完成后提交更新(在执行更新之前,一定要保证 blobData 数据有效,否则将会失败)
pre_stmt->executeUpdate();

//5 查询blob字段内容
try {
    auto st = m_conn->createStatement();
    st->execute("use db");
    auto re = st->executeQuery("select imgbuffer from tb1");
    while (re->next())
    {
        auto is = re->getBlob("imgbuffer");
        std::istreambuf_iterator<char> eos;
        std::string s(std::istreambuf_iterator<char>(*is), eos);
        auto buffer_size = s.length();
        void* buffer = malloc(buffer_size);
        std::memcpy(buffer, s_c_str, buffer_size);//将数据拷贝到准备好的内存中,使用完后需要 free(buffer)
    }
}
catch (SQLException& e) {
		//异常 e.what();
}

QImage 存入blob字段

//方式一
QImage image;
image.load(fileName); 
//将QImage转化为QByteArray
QByteArray imageArray;
QBuffer buffer(&imageArray);
buffer.open(QIODevice::WriteOnly);
image.save(&buffer, "PNG");
int buffer_size = imageArray.length();
void* imgbuffer = malloc(buffer_size);
memcpy(imgbuffer, imageArray.data(), len); 
//写入blob字段中
std::strstreambuf buf(reinterpret_cast<char*>(imgbuffer), buffer_size);
std::istream stream(&buf);
pre_stmt->setBlob(2, &stream);



//方式二
QFile file(fileName);
if (file.open(QIODevice::ReadOnly))
{
    QByteArray dataarray(file.readAll());
    QBuffer buffer(&dataarray);
    buffer.open(QIODevice::ReadOnly);
    int buffer_size = dataarray.length();
    void* imgbuffer = malloc(buffer_size);
    memcpy(imgbuffer, dataarray.data(), buffer_size);
    
    //写入blob字段中
    std::strstreambuf buf(reinterpret_cast<char*>(imgbuffer), buffer_size);
    std::istream stream(&buf);
    pre_stmt->setBlob(2, &stream);
}

读取blob字段内容转化为QImage

//读取blob字段内容
long* data_ptr = new long;
auto buffer_size = pDB->getData((void**)&data_ptr);//具体读取方式见参考代码
//将data_ptr中的内容转为QImage
QImage img;
img.loadFromData((const uchar*)(data_ptr), buffer_size);

SQL简介

数据库放在数据库中,SQL是用于访问和处理数据库的标准的计算机语言,SQL是Structured Query Language的缩写,是指结构化查询语言。

特点:

  1. 简单易学
  2. 功能强大
  3. 只说明做什么,不说明如何做
  4. 标准化,几乎所有的关系数据库都通用
  5. 不区分大小写

常用数据类型

数据类型说明
int
bigint
char(n)字符/字符串,固定长度 n
varchar(n)字符/字符串,可变长度,最大长度 n
text
mediumtext
longtext
numeric(a,b)精确数值,总位数 a,小数点后位数 b(四舍五入)
decimal(8,2)整体8位,小数保留2位(自动做4舍5入)
date存储年、月、日的值

在线手册

SQL语句

常用命令

-- 查看所有数据库
show databases;

-- 查看所有表
show tables;

-- 查看表结构 desc + 表名
desc employees;

            

数据库管理

创建数据库
-- 创建数据库,该命令的作用:

--  1. 如果数据库不存在则创建,存在则不创建。
--  2. 创建RUNOOB数据库,并设定编码集为utf8

create database if not exists 数据库名 default charset utf8 collate utf8_general_ci;


使用数据库
use 数据库名;
删除数据库
drop database if exists 数据库名;

数据表管理

创建表
create table if not exists 表名(
    列名 类型,
    列名 类型,
    列名 类型
)default charset=utf8;

-- 可选项
ENGINE = INNODB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci;


-- 举例

create table if not exists tb1(
	id int not null auto_increment primary key,		 -- 不允许为空 & 主键 & 自增
    name varchar(16) not null, 						-- 不允许为空
    email varchar(32) null, 						-- 允许为空(默认)
    age int default 3 							    -- 插入数据时,如果不给age列设置值,默认值:3
)default charset=utf8;


mysql> desc tb1;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int         | NO   | PRI | NULL    | auto_increment |
| name  | varchar(16) | NO   |     | NULL    |                |
| email | varchar(32) | YES  |     | NULL    |                |
| age   | int         | YES  |     | 3       |                |
+-------+-------------+------+-----+---------+----------------+
			
			
删除表
drop table 表名;
清空表中的内容
-- 方式1
delete from 表名;	

-- 方式2 速度更快,但是不可恢复
truncate table 表名; 

修改表
1.添加列
alter table 表名 add 列名 类型;
alter table 表名 add 列名 类型 default 默认值;
alter table 表名 add 列名 类型 not null default 默认值;
alter table 表名 add 列名 类型 not null primary key auto_increment;
2.删除列
alter table 表名 drop column 列名;
3.修改列 类型
alter table 表名 modify column 列名 类型;
4.修改列 类型+名称
alter table 表名 modify column 原列名 新列名 新类型;
5.修改列 默认值
alter table 表名 alter 列名 set default 1000;
6.删除列 默认值
alter table 表名 alter 列名 drop default;
7.添加和删除主键
alter table 表名 add primary key(列名);
alter table 表名 drop primary key;
8.清空表中内容
-- 方式1
delete from 表名;	

-- 方式2 速度更快,但是不可恢复
truncate table 表名; 

-- 第一种方式
insert into tb1(name,email,age) values("张三","**@qq.com",18),("李四","**@qq.com",18);

-- 第二种方式
insert into tb1 values(3,"王五","**@qq.com",18);

delete from tb1 where id=2;

-- 查询表中所有内容
select * from tb1;

+----+------+-----------+------+
| id | name | email     | age  |
+----+------+-----------+------+
|  1 | 张三 | **@qq.com |   18 |
|  3 | 王五 | **@qq.com |   18 |
|  4 | 张三 | NULL      |   22 |
|  5 | 张三 | NULL      |   22 |
|  6 | 唐三 | NULL      |   22 |
+----+------+-----------+------+

select * from tb2;
+------+-------+
| id   | title |
+------+-------+
|    1 | 开发  |
|    2 | 运营  |
+------+-------+


-- 查询字段 name,age 
select name,age from tb1;

+------+------+
| name | age  |
+------+------+
| 张三 |   18 |
| 王五 |   18 |
| 张三 |   22 |
| 张三 |   22 |
| 唐三 |   22 |
+------+------+

-- 查询名字叫张三的
select name,age from tb1 where name="张三";

+------+------+
| name | age  |
+------+------+
| 张三 |   18 |
| 张三 |   22 |
| 张三 |   22 |
+------+------+

-- 更多的条件查询
select * from tb1 where id > 3;
select * from tb1 where id = 1;
select * from tb1 where id >= 1;
select * from tb1 where id != 1;
select * from tb1 where id between 2 and 4;
select * from tb1 where id=4 and name="张三";
select * from tb1 where (id=4 or name="张三") and age=22; -- 此条结果对应在下方
+----+------+-------+------+
| id | name | email | age  |
+----+------+-------+------+
|  4 | 张三 | NULL  |   22 |
|  5 | 张三 | NULL  |   22 |
+----+------+-------+------+

select * from tb1 where id in(3,4);
select * from tb1 where id not in(3,4);
select * from tb1 where exists(select * from tb2 where id=8);
select * from tb1 where id in(select id from tb2);-- 此条结果对应在下方
+----+------+-----------+------+
| id | name | email     | age  |
+----+------+-----------+------+
|  1 | 张三 | **@qq.com |   18 |
+----+------+-----------+------+

select * from (select * from tb1 where id>3) as T where T.name="张三";-- 此条结果对应在下方
+----+------+-------+------+
| id | name | email | age  |
+----+------+-------+------+
|  4 | 张三 | NULL  |   22 |
|  5 | 张三 | NULL  |   22 |
+----+------+-------+------+

select
	id,name,
	case name when "张三" then "法外狂徒" else "安全人员" end v1
from tb1;
+----+------+----------+
| id | name | v1       |
+----+------+----------+
|  1 | 张三 | 法外狂徒 |
|  3 | 王五 | 安全人员 |
|  4 | 张三 | 法外狂徒 |
|  5 | 张三 | 法外狂徒 |
|  6 | 唐三 | 安全人员 |
+----+------+----------+

-- 在 WHERE 子句中使用 LIKE 运算符来搜索匹配字符串中的指定模式,百分号(%)匹配零个、一个或多个字符。如:
select id,name,age from tb1 where name like("张%") ;
+----+----------+------+
| id | name     | age  |
+----+----------+------+
|  1 | 张三改名 |   18 |
|  4 | 张三改名 |   22 |
|  5 | 张三改名 |   22 |
+----+----------+------+

-- 查询邮箱为空的员工信息
select * from tb1 where email is null;
+----+----------+-------+------+
| id | name     | email | age  |
+----+----------+-------+------+
|  4 | 张三改名 | NULL  |   22 |
|  5 | 张三改名 | NULL  |   22 |
|  6 | 唐三     | NULL  |   22 |
+----+----------+-------+------+

update tb1 set name="张三改名" where name="张三";

+----+----------+-----------+------+
| id | name     | email     | age  |
+----+----------+-----------+------+
|  1 | 张三改名 | **@qq.com |   18 |
|  3 | 王五     | **@qq.com |   18 |
|  4 | 张三改名 | NULL      |   22 |
|  5 | 张三改名 | NULL      |   22 |
|  6 | 唐三     | NULL      |   22 |
+----+----------+-----------+------+

其他常用语句

distinct 去除重复值

同一字段中可能会出现重复值,使用关键词 distinct 可以去掉重复值,用法如下:

select distinct 字段名 from 表名;

select distinct name from tb1;
and 和 or 的用法

and 和 or 可以用在 where 子句中把两个或多个条件结合起来。and 运算符要求两个条件都成立;or 运算符要求两个条件中只要有一个成立即可。如:

select 字段名 from 表名 where 字段 n 运算符 值 n and|or 字段 m 运算符 值 m;

-- 查询出第3部门里工资大于等于5000的员工
select * from employees where deptno=3 and salary >= 5000;

select * from employees where (deptno=3 or deptno=1) and salary<5000;
in 的用法

in 运算符是在 where 子句中指定多个搜索条件可以匹配的值。in 运算符实际是多个or条件的合并。如:

select 字段名 from 表名 where 字段名 in(值1, 值2,…);

-- in 匹配多个值 列出员工号为3和5的员工:
select name from employees where empno in(3,5);

-- 前面的SQL语句相当于
select name from employees where empno=3 or empno=5;

-- 否定形式
select name from employees where empno not in(3,5);

-- 嵌套
select name from employees where deptno in (select deptno from dept where loc like '一楼%');
between 的用法

between 运算符用于选取介于两个值之间的数据范围内的值,这些值可以是数字,字符串或日期。between 运算符包括开始和结束值,相当于 >= and <=。

语法:select 字段名 form 表名 where 字段名 between 值1 and 值2;

select name from employees where hiredate between '2013-01-01' and '2013-12-31';

select name from employees where hiredate not between '2013-01-01' and '2013-12-31';
order by 排序

order by 用于对结果集进行排序, 默认按升序进行排序, 也可以指定 desc 按降序对结果集进行排序。如:

select 字段名 from 表名 order by 字段1,字段2,… asc|desc;

-- 降序
select name,salary from employees order by salary desc;

index 索引

索引可以提高访问数据的速度。创建索引的语法如下:

create index 索引名 on 表名(字段1,字段2,…)

使用索引时 SQL 语句的语法和不使用索引并没有任何不同,SQL 语句会自动使用索引提高访问数据的速度。

create index in_name on employees(name);
view 视图

视图是基于 SQL 语句的结果集的可视化表,视图中的字段就是来自一个或多个数据库中的真是的表中的字段。

视图总是显示最近的数据。每当用户查询视图时,数据库引擎通过使用 SQL 语句来重建数据。

语法:create view 视图名 as select 语句;

-- 把10月1日之前雇佣的员工的姓名和工资列出来
create view employees_2021 as select name,salary from employees where hiredate < '2021-10-01';

-- 查询视图
select * from employees_2021;

-- 更新视图中的数据(同时也将修改employees表中的数据)
update employees_2021 set salary=salary+400 where name='张三';
null 值

null 值代表遗漏的未知数据,它的作用是未知的或不适用的值的占位符。

如果表中的某个列是可选的,那么我们可以在不向该列添加值的情况下插入新记录或更新已有的记录。这意味着该字段将以 NULL值保存。

字段值是否为 NULL 的判断不能用 = 或者 <> 进行判断,要用 is null 或者 is not null 。

-- 查询邮箱为空的员工信息
select * from tb1 where email is null;
join 连接

join 连接是基于多个表之间的共同字段把它们结合起来进行查询的一种方法。连接分为以下几种:

  1. 内连接(inner join):列出两个表中都存在的记录;
  2. 左连接(left join):即使没有匹配也列出左表中的所有记录;
  3. 右连接(right join):即使没有匹配也列出右表中的所有记录;

语法:

select 字段名 as from 表1 join 表2 where 子句;

-- 找出在员工表和经理表中同时出现的员工
select name,title from employees inner join managers on employees.empno=managers.empno;
SubQuery 子查询

子查询也称嵌套查询,是一种嵌套在其他SQL语句的WHERE字句中的查询。子查询用于为主查询返回其所需数据,或者对检索数据进行进一步的限制。

语法:

select 字段1,字段2,… from 表名 where 字段名 操作符 (子查询);

-- 查询在二楼办公的员工的姓名
select from employees where deptno in(select deptno from dept where loc like '二楼%');
字段和表的别名

作用

在 SQL 语句中可以为表名或字段名指定临时使用的别名(Alias),别名只在当前的SQL 语句中生效,它通常比字段名更具有可读性。

别名有以下应用场景:

  1. 字段名长或可读性差
  2. 涉及多个表,而且多个表中有相同的字段名时
  3. 代表查询函数的结果

别名的语法

select 字段名 as 别名 from 表名 as 别名;

as 可以省略。

select name 姓名, salary 工资 from employees e;

-- 为函数取别名
select count(*) 总人数 from employees;

常用函数

count 函数

count 函数统计符合条件的记录数,count(*)统计表中的记录总数,count(字段名)统计指定字段不为null的记录数。

-- 统计表中所有员工
select count(*) from employees;

-- 统计员工表中所有部门号不为 null 的员工
select count(deptno) from employees;

-- 统计员工表中部门号为 null 的员工
select * from employees where deptno is null;

max 函数

max 函数返回所选字段的最大值,用法是 max(字段名)。

-- 查询员工表中工资最高的员工
select max(salary) from employees;

min 函数

min 函数返回所选字段的最小值,用法是 min(字段名)。

avg 函数

sum 函数

group by 分组

group by 语句用于结合统计函数,根据一个或多个列对结果集进行分组。语法如下:

select 字段名,统计函数 from 表名 where 子句 group by 字段名;

-- 按部门统计员工的平均工资
select deptno,avg(salary) from employees group by deptno;

having 过滤分组

having 子句和where子句类似,都是对查询的结果集进行过滤。它们的过滤对象不同,where 子句对被选择的列进行过滤,而having 子句则对group by 子句产生的组进行过滤。

语法:

select 字段名,统计函数 from 表名 where 子句 group by 字段名 having 统计函数 运算符 值;

-- 查询部门员工平均工资小于4500的部门
select deptno,avg(salary) from employees group by deptno having avg(salary)<4500;

主键的作用

主键的全称是主键约束,表的主键由表中的一个字段或多个字段组成,主键唯一代表表中一条记录,关系数据库中通常每个表都有一个主键,没有主键的表通常是不严谨的设计产物。主键由以下特点:

  1. 每个表只能定义一个主键
  2. 主键值必须唯一标识表中的一条记录,且不能为null,即表中不可能存在有相同主键值得两条记录
  3. 一个字段名只能在联合主键字段中出现一次
  4. 联合主键不能包含不必要的多余字段。当把联合主键的某一字段删除后,剩下的字段不能唯一代表一条记录

违反主键约束

违法主键约束的记录将不能被插入

数据库导入与导出


#导入
mysqldump -u root -p mydb < D:/aa.sql

#导出
mysqldump -u root -p mydb > D:/aa.sql #有结构有数据
mysqldump -u root -p -d mydb > D:/aa.sql #有结构无数据
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值