MySQL的基本使用

MySQL的基本使用
BarbecueMySQL基本使用
使用前需安装库函数与引用头文件
库函数安装命令:
1 | sudo apt install libmysqlclient-dev |
头文件引用:
1 |
1. 连接
初始化一个连接
1 | MYSQL * mysql = mysql_init(NULL); |
写类型指令:
mysql_real_connect
函数的原型:
1 | MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned long client_flag); |
1 | MYSQL *ret = mysql_real_connect(mysql,"localhost","root","123","table",3306,NULL,0); |
参数说明:
mysql
:指向MYSQL
结构的指针,用于保存连接相关的信息。host
:要连接的MySQL服务器的主机名或IP地址。user
:用于连接到MySQL服务器的用户名。passwd
:连接MySQL服务器所需的密码。db
:要连接的数据库名称。port
:MySQL服务器的端口号。0为默认情况下,MySQL使用3306端口。unix_socket
:Unix域套接字的路径。如果使用TCP/IP连接,则为NULL
。client_flag
:客户端标志,用于设置连接的特定选项,例如加密、压缩等。
检查报错
1 | if(ret =NULL){ |
指令写入
1 | int qret = mysql_query(mysql,sql); |
1 | if(ret =NULL){ |
读类型指令
基本步骤:
执行查询语句:
使用
mysql_query
函数执行查询语句,并将结果存储在MYSQL_RES
类型的变量中。1
2
3MYSQL_RES *res;
mysql_query(mysql, "SELECT * FROM table_name");
res = mysql_store_result(mysql);上述示例中,
connection
是已经建立好的MySQL连接对象,”SELECT * FROM table_name”是查询语句,mysql_query
用于执行查询,mysql_store_result
用于将结果存储在result
变量中。处理结果集:
使用
mysql_num_fields
函数获取结果集中的字段数目,使用mysql_fetch_row
函数逐行获取结果集的数据。1
2
3
4
5
6
7
8int num_fields = mysql_num_fields(res);
MYSQL_ROW row;
while ((row = mysql_fetch_row(res)) != NULL) {
for (int i = 0; i < num_fields; i++) {
printf("%s\t", row[i]);
}
printf("\n");
}上述示例中,
mysql_num_fields
用于获取结果集的字段数目,mysql_fetch_row
用于逐行获取结果集中的数据。通过循环遍历每行数据,并在内部循环中逐个字段打印出来。释放结果集:
使用
mysql_free_result
函数释放结果集的内存空间。1
mysql_free_result(res);
当您完成对结果集的使用后,应该使用
mysql_free_result
函数释放结果集所占用的内存空间。
请注意,在使用MYSQL_RES
时,需要先执行查询语句并获得结果集,然后通过逐行遍历和处理结果集中的数据。最后,务必释放结果集的内存空间以避免内存泄漏。
2. 增
创建一个新的数据库
1 | CREATE DATABASE 数据库名; |
使用某个数据库,可以使用use语句
1 | use mysql |
创建一张表
1 | CREATE TABLE table_name (column_name column_type); |
1 | CREATE TABLE table_name ( |
增加数据
1 | INSERT INTO table_name VALUES (value1, value2,...valueN); |
1 | INSERT INTO table_name ( field1, field2,...fieldN ) |
增加列
1 | ALTER TABLE 表名 |
3. 删
删除一个数据库
1 | drop database <数据库名>; |
删除一个数据表
1 | DROP TABLE table_name ; |
数据表中删除数据
1 | DELETE FROM table_name [WHERE Clause]; |
删除列
1 | ALTER TABLE 表名 |
4. 改
修改数据表数据
1 | UPDATE 表名 |
修改列
1 | ALTER TABLE 表名 |
修改表
1 | ALTER TABLE 旧表名 |
5. 查
筛选!!!
不等于:<>
时间可以比大小
逻辑运算:与and
或or
and
优先级高于or
通配符:模糊匹配like中 %
匹配任意字符串 _
匹配单一字符
空值:is null is not null
聚集函数:在select后的field1前面加函数如:select max(field1)
select min(field1)
select avg(field1)
分组聚集:结果将按照分组条件
分组 group by 子句(分组聚集)
如SELECT customer_id FROM orders GROUP BY sex
展示数据表格式
1 | desc table_name; |
查找语句SELECT
语句用于从数据库表中检索数据,并将其作为结果集返回。以下是SELECT
语句的一般语法:
1 | SELECT 列名1, 列名2, ... |
具体步骤如下:
- 使用
SELECT
关键字指定要检索的列名。使用通配符*
选择所有列。 - 使用
FROM
关键字指定要从中检索数据的表名。对于多个表,可以使用JOIN
操作符进行表连接。 - 可选:使用
WHERE
关键字指定筛选条件,限制要返回的行。如果省略WHERE
子句,将返回表中的所有行。 - 可选:使用
GROUP BY
关键字按照指定的列对结果进行分组。GROUP BY
通常与聚合函数(如SUM
、COUNT
、AVG
等)一起使用。 - 可选:使用
HAVING
关键字指定分组后的筛选条件,HAVING
子句用于对分组后的结果集进行筛选。 - 可选:使用
ORDER BY
关键字按照指定的列对结果进行排序,默认升序。可以附加ASC
关键字表示升序(默认),或DESC
关键字表示降序。
排序:order by默认升序。后加ASC
或DESC
,表示升序或降序
1 | SELECT field1, field2,...fieldN FROM table_name1, table_name2... |
内连接:将两个表的行连接查询
1 | SELECT 列名 |
6. 常见类型
- 整数类型(Integer Types):
- TINYINT:1字节,范围为-128到127(有符号)或0到255(无符号)
- SMALLINT:2字节,范围为-32768到32767(有符号)或0到65535(无符号)
- MEDIUMINT:3字节,范围为-8388608到8388607(有符号)或0到16777215(无符号)
- INT或INTEGER:4字节,范围为-2147483648到2147483647(有符号)或0到4294967295(无符号)
- BIGINT:8字节,范围为-9223372036854775808到9223372036854775807(有符号)或0到18446744073709551615(无符号)
- 浮点数类型(Floating-Point Types):
- FLOAT(M, D):4字节,单精度浮点数
- DOUBLE(M, D):8字节,双精度浮点数
- 定点数类型(Fixed-Point Types):
- DECIMAL(M, D):存储精确小数,M表示总位数,D表示小数点后的位数
- 字符串类型(String Types):
- CHAR(M):固定长度字符串,最多255个字符
- VARCHAR(M):可变长度字符串,最多65535个字符
- TEXT:可变长度的大文本对象,最多65535个字符
- 日期和时间类型(Date and Time Types):
- DATE:日期,格式为’YYYY-MM-DD’
- TIME:时间,格式为’HH:MM:SS’
- DATETIME:日期和时间,格式为’YYYY-MM-DD HH:MM:SS’
- TIMESTAMP:日期和时间,自1970年1月1日以来的秒数表示
- YEAR:年份,范围为1901到2155
- 布尔类型(Boolean Type):
- BOOL或BOOLEAN:存储true或false
7. 常见约束
主键约束(Primary Key Constraint):
主键用于唯一标识表中的每一行数据,并确保数据的唯一性。
示例:
1
2
3
4
5CREATE TABLE customers (
id INT PRIMARY KEY,
name VARCHAR(50),
email VARCHAR(100)
);
非空约束(Not Null Constraint):
非空约束确保列中的值不能为空。
示例:
1
2
3
4
5CREATE TABLE employees (
id INT,
name VARCHAR(50) NOT NULL,
age INT NOT NULL
);
唯一约束(Unique Constraint):
唯一约束确保列中的值在表中是唯一的,允许空值。
示例:
1
2
3
4
5CREATE TABLE products (
id INT,
name VARCHAR(50),
code VARCHAR(10) UNIQUE
);创建多列唯一约束:
1
2
3
4
5
6
7CREATE TABLE 表名 (
列1 数据类型,
列2 数据类型,
列3 数据类型,
CONSTRAINT 约束名 UNIQUE (列1, 列2, 列3)
);1
2ALTER TABLE 表名
ADD CONSTRAINT 约束名 UNIQUE (列1, 列2, ...);
外键约束(Foreign Key Constraint):
外键约束用于建立表之间的关联,确保引用表中的数据存在于被引用表中的列中。
示例:
1
2
3
4
5
6CREATE TABLE orders (
id INT PRIMARY KEY,
customer_id INT,
total_amount DECIMAL(10, 2),
FOREIGN KEY (customer_id) REFERENCES customers(id)
);
检查约束(Check Constraint):
检查约束用于定义列中的值必须满足的条件。
示例:
1
2
3
4
5
6
7CREATE TABLE products (
id INT PRIMARY KEY,
name VARCHAR(50),
quantity INT,
price DECIMAL(10, 2),
CHECK (quantity >= 0 AND price >= 0)
);
默认约束(Default Constraint):
默认约束用于为列指定默认值。
示例:
1
2
3
4
5
6CREATE TABLE employees (
id INT PRIMARY KEY,
name VARCHAR(50),
age INT,
employment_date DATE DEFAULT CURRENT_DATE()
);
8. 其他
在数据库命令行中输入以下内容,显示数据库的版本
1 | select version(), current_date; |
show语句可以展示当前服务端已经存在的数据库
1 | show databases; |
show语句展示当前选择的数据库当中的所有表
1 | show tables; |
MySQL数据库事务和索引
一、事务
1. 概念
构成单一逻辑工作单元的操作集合,即:一组命令的集合。
2. 事务的性质(ACID)
- 原子性(Atomicity):原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。无论是操作系统崩溃,还是计算机停止运行,这项要求都要成立。即:事务中的操作为一个整体,要么都做,要么都不做。
- 一致性(Consistency):事务作为一个原子性操作,它从一个一致性的数据库状态开始运行,事务结束时,数据库的状态必须再次是一致的。即:事务的执行的前后,数据的完整性保持一致。且事务执行前后数据的总和不变。
- 隔离性(Isolation):尽管多个事务可能并发执行,但系统保证,对于任何一对事务Ti和Tj ,在Ti看来, Tj要么在Ti开始之前已经完成,要么在Ti完成之后才开始执行。因此,每个事务都感觉不到系统中有其他事务在并发地执行。即:一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事物之间不能互相干扰。隔离并不是100%隔离的,可能隔离一部分。
- 持久性(Durability):一个事务成功完成后,它对数据库的改变必须是永久的,即使出现系统故障。即:指一个事物一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。
3. 事务的基本操作
1 | #开启一个事务,标记事务的起点 |
查看表的中的字段
1 | show create table member; |
1 | CREATE TABLE `member` ( |
1 | desc member; |
1 | +--------+-------------+------+-----+---------+----------------+ |
二、并发产生的四个问题
1. 脏写
概念:多个事务并发写同一数据时,先执行的事务所写的数据会被后写的数据覆盖
2. 脏读
概念:如果一个事务T1向数据库写数据,但该事务还没提交或终止,另一个事务T2就看到了事务T1写入数据库的数据。
3. 不可重复读
概念:一个事务有对同一个数据项的多次读取,但是在某前后两次读取之间,另一个事务更新该数据项,并且提交了。在后一次读取时,感知到了提交的更新
4. 幻读
概念:一个事务需要进行前后两次统计,在这两次统计期间,另一个事务插入了新的符合统计条件的记录,并且提交了。导致前后两次统计的数据不一致
总结:
脏读
,就是读了一个没有提交
的数据;不可重复读
,前后两次读数据的时候,数据的内容
发生了变化,此时该数据是已经提交
到数据库中了;幻读
,前后两次读数据的时候,数据的条数
发生了变化,此时数据也是已经提交
到数据库中了。
三、隔离级别
四个隔离级别:读未提交、读已提交、可重复读、可串行化。(隔离等级越来越高,并发程度越来越低。)
1. 读未提交(read uncommitted)
在此隔离级别下面,避免了脏写现象,但是可以产生脏读、不可重复读与幻读现象。
2. 读已提交(read committed)
在此隔离级别下面,避免了脏写与脏读现象,但是可以产生不可重复读与幻读现象。
3. 可重复(repeatable read)
可以避免脏写、脏读、不可重复读的现象。
该隔离级别是可以产生幻读现象的,但是演示方法不一样,可以借助主键进行演示,因为主键是唯一的,不能重复。
4. 可串行化(serializable)
可以避免所有的并发产生的问题,避免脏写、脏读、不可重复读、幻读。
1 | #查看当前事务的隔离级别 |
总结:MySQL支持四种隔离级别,默认支持的是可重复读;Oracle只支持两种隔离级别,读已提交与可串行化,默认支持的是读已提交。隔离级别越高,串行程度越高,并发产生的问题越少。
四、索引
1. 概念
帮助MySQL高效获取数据的数据结构
索引可以提升查询速率,索引是数据结构
2. 数据结构
- 顺序存储:会顺序扫描,从第一条一直扫描到满足条件的数据,时间复杂度是O(N)。
- 二分查找:查询数据的时候,时间复杂度O(logN),需要连续的大段空间。
- 二叉树:时间复杂度也是O(logN),树的高度会非常的高,每次查询的时候,都会进行磁盘IO,树的高度会影响查询的速率。
- 哈希:时间复杂度O(1),使用哈希的时候,数据是没有顺序的,但是往往在数据库中是需要进行范围查找的;如果哈希有哈希冲突,那么也会影响查询速度。
- B树:多路平衡树,一个结点可以存放多个索引,那么就可以急剧降低树的高度,那么就可以减少磁盘IO的次数。B树的结点需要存放key值以及key对应的value值。
- B+树:非叶子结点只存放key值,不存放value值,那么就可以让一个结点中数据的条数增加,进而可以减少树的高度。
1 | mysql> show variables like 'innodb_page_size'; #每个大结点最大占用的空间大小 |
1 | +------------------+-------+ |
可以从时间复杂度、连续内存、磁盘IO的次数、范围查找几个维度。
MySQL底层使用的数据结构是B+树。
3. B+树的特点
- 非叶子节点不存储data,只存储key
- 所有的叶子节点存储完整的一份key信息以及key对应的data
- 每一个父节点都出现在子节点中,是子节点的最大或者最小的元素
- 每个叶子节点都有一个指针,指向下一个节点,形成一个链表