1.service mysql status 可以查看服务器(数据库)是否启动

数据库在开机默认情况下就是启动的

启动数据库:service mysql start
重新启动数据库:service mysql restart
停止数据库:service mysql stop
本地连接数据库:mysql -uroot -p密码
远程连接数据库:mysql -uroot -h192.168.0.0 -p密码

2.show databases;可以显示都有哪些数据库

3.root和stu2就是用户名,%表示远程登录,localhost表示本地登录

在mysql这个数据库中有一个user表,里面保存了用户的信息

create user ‘root’@‘%’ indentified WITH mysql_native_password by ‘sp20010212’;

4.当通过stu2用户连接上mysql数据库以后,为什么显示出来的数据库信息只有一个呢?而在通过root用户连接上mysql数据库以后会显示出很多数据库呢?

这是因为权限的问题,我们只是创建了一个用户,只是可以登录上数据库,但是现在没有权限去访问任何数据库,所以要给用户进行授权,授权的时候不可能超过权限用户的权限范围,最高也就是给新用户授权和本用户一样的权限

  • . * 的意思就是在所有数据库的所有表

all privileges 的意思就是所有权限

可以看到一开始通过stu2用户登录的数据库中并没有sun这个数据库,在通过给stu2授权以后,可以看到sun这个数据库了,授予的权限是sun.*,意思就是对数据库sun中的所有表都有操作权限

这里授予的all表示可以进行增删改查,也可以授予单个权限,比如select,update,drop,alter

当最初只授予了select权限时,执行grant update on sun.* to ‘stu2’@‘%’;时原来的select权限还在,增加了update权限

这时root可以访问到的内容stu2也可以访问到

show grants for stu2; 可以查看stu2的权限

revoke all on sun.* from ‘stu2’@‘%’; 可以删除远程stu2用户登录对数据库的所有权限

下图删除了本地登录localhost的stu2用户对c213db数据库所有表的权限

5.删除用户

drop user ‘name’@‘localhost’;

drop user stu2;如果后面不加本地登录还是远程登录的话,默认删除的是远程登录的

6.注意编译的时候要加-lmysqlclient

gcc -o main main.c -lmysqlclient

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <mysql/mysql.h>

int main()
{
	MYSQL mysql_conn;
	MYSQL* mysql = mysql_init(&mysql_conn);//mysql实际上指向的就是mysql_conn
	if(mysql == NULL)
	{
		printf("init error\n");
		exit(0);
	}
	mysql = mysql_real_connect(mysql,"localhost","root","sp20010212","sun","3306",NULL,0);
	if(mysql == NULL)
	{
		printf("connect error:%s\n",mysql_error(&mysql_conn));
		exit(1);
	}
	char* sql = "select * from student";
	int n = mysql_query(mysql,sql);//执行sql语句
	if(n != 0)//失败了
	{
		printf("query error:%s\n",mysql_error(&mysql_conn));
		mysql_close(&mysql_conn));
		exit(1);
	}
	MYSQL_RES * res = mysql_store_result(mysql);//提取结果集,这个结果集的空间是动态分配的,这个函数的作用是一次性提取全部数据
	if(res == NULL)//失败了
	{
		printf("mysql result error:%s\n",mysql_error(&mysql_conn));
		mysql_close(&mysql_conn);
		exit(1);
	}
	int num = mysql_num_rows(res);//获取结果集中有多少行,如果没有返回行,则为0
	int field = mysql_field_count(mysql);//获取记录行有多少列
	for(int i = 0;i<num;++i)//一行一行打印
	{
		MYSQL_ROW row = mysql_fetch_row(res);//获取结果集中的一行记录
		for(int j = 0;j<field;++j)//一列一列打印
		{
			printf("%s  ",row[j]);//使用第j个字段
		}
		printf("\n");
	}
	mysql_free_result(res);//释放结果集占用的空间
	mysql_close(&mysql_conn);
	exit(0);
}

7.视图概念

视图(View)是一种虚拟存在的表,对于使用视图的用户来说基本上是透明的。视图并不在数据库中实际存放数据,它的数据来自定义视图时使用的基本表,并且是在使用视图时动态生成的

视图就是对基本表查询的一次操作的结果,数据来源是基本表,然后再对数据进行操作,所以视图的性能并不高

视图并不保存真实数据,真实保存数据还在基本表中,当创建视图以后,执行select* from v_stu;时,其实是先执行创建视图时的select语句,然后在这个的基础上在执行 select* from v_stu;视图其实就是一个查询语句,它的效率并不高,使用视图以后就不用重复的去使用查询语句了

每次使用视图的时候,是先去执行定义视图时的sql语句,然后在此结果基础上进行操作

视图就是sql语句执行的结果

8.定义视图

建议以"_v"开头,create view 视图名 as select语句;注意:它只是建议以"_v"开头,让别人清楚这是一个视图,但这并不是强制要求必须以"_v"开头

9.为什么要使用视图

①简化复杂的sql操作,在编写查询后,可以方便的重用它而不必知道它的查询细节
②重复使用该sql语句
③使用表的组成部分而不是整个表
④保护数据,可以给用户授予表的特定部分的访问权限而不是整个表
⑤更改数据格式和表示

10.查看视图

show tables; 默认会显示表和视图,但不能区分。
show full tables; 会显示表和视图的类型

11.删除视图

drop view 视图名;

删除视图并不会把基本表的数据删除了

12.视图、事务、索引是重点考察

13.C语言是怎么连接数据库的?

对于没有返回结果的,比如update、drop、create来说:
创建连接句柄->初始化连接句柄->连接数据库->执行sql语句->关闭连接

对于有返回结果的,比如select来说:
创建连接句柄->初始化连接句柄->连接数据库->执行sql语句->提取结果集->获取结果集有多少行->取出结果集中的一行记录->获取一行记录中有多少列->释放结果集占用的内存->关闭连接

14.mysql数据库是客户端服务器模型,就是C/S模型,它的服务器端其实就是tcp的服务器端,连接数据库就是客户端连接数据库的一个过程,服务器端的端口号是3306

15.什么是事务?

所谓事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位

事务就是一组要执行的sql语句,要么都执行,要么都不执行

16.为什么需要事务?

例如 :银行转账的问题,从一个账号扣款并使另一个账号入账,这两个操作要么都执行,要么都不执行,所以,应该把它们看出一个事务

17.事务四大特性(ACID)

①原子性(atomicity)
②一致性(consistency)
③隔离性(isolation)
④持久性(durability)

18.隔离级别

在SQL标准中定义了四种隔离级别,每一种级别都规定了一个事务中所做的修改,那些在事务内和事务间是可见的。那些是不可见的,通常较低级别的隔离可以执行更高的并发,系统开销也低

②③是重点,①④用的比较少,隔离级别依次增高,隔离性越来越高

①READ UNCOMMITTED 未提交读

事务没提交也可以看到信息,只要事务执行了sql语句,另外一个事务就可以立即看到信息

②READ COMMITTED 提交读也叫不可重复读,在事务中先进行select学生的信息,然后其他人插入了一条学生信息,再次执行select的结果是不一样的,会显示出新增加的学生的信息,也就是说在一个事务中,先后两次执行的select的结果可能是不一样的

事务只有在提交了commit以后,在另一个事务中才能看到新增加的信息

③REPEATABLE READ 可重复读,在事务中先进行select学生的信息,然后其他人插入了一条学生信息,再次执行select的结果是一样的,并没有显示出新增加的学生的信息,它可以保证先后两次读的数据是一样的,虽然数据库中新增加了一条学生信息

在事务结束以后,就可以看见新增加的信息了,在事务开始到事务结束内看见的消息是一致的

④SERIALIZABLE 可串行化

什么是幻读?

在可重复读中才会出现幻读,比如数据库中实际的数据是11条,但是只读到了10条,或者数据中的数据实际上是9条,但是我读到了10条,删掉或多出来的那一行就是幻行,就产生了幻读

查看当前会话隔离级别

SELECT @@SESSION.transaction_isolation;

查看系统隔离级别

SELECT @@GLOBAL.transaction_isolation;

设置隔离级别

设置全局隔离级别
set global transaction isolation level REPEATABLE READ;
set global transaction isolation level READ COMMITTED;
set global transaction isolation level READ UNCOMMITTED;
set global transaction isolation level SERIALIZABLE;

设置会话隔离级别
set session transaction isolation level REPEATABLE READ;
set session transaction isolation level READ COMMITTED;
set session transaction isolation level READ UNCOMMITTED;
set session transaction isolation level SERIALIZABLE;

19.开始事务命令

开启事务后执行修改命令,变更会维护到本地缓存中,而不维护到物理表中
begin; 或 start transaction;

20.提交事务命令

将缓存中的数据变更维护到物理表中,执行commit语句后,才会把从begin到commit中的sql语句执行的结果维护到物理表中
commit;

21.回滚事务命令

执行rollback命令,就是相当于从begin;到commit;这一段sql语句没有执行
rollback;

22.事务演示

23.回滚事务演示

一开始修改了小白的age,但是后来我不想修改了,就可以使用rollback回滚事务,这样小白的信息就恢复了,从begin开始的这些sql语句就全部被撤销了

24.大多数数据库系统的默认隔离级别都是提交读READ COMMITED,但是mysql不是

InnoDB存储引擎默认的隔离级别是可重复读,REPEATABLE READ

mysql的默认隔离级别是可重复读

25.引入索引的问题

在图书馆查找一本书的过程

在一般的软件系统中,对数据库的操作还是以查询为主,当数据量较大时,优化查询是关键

26.索引是什么?

索引是一种特殊的文件,它包含着对数据表里所有记录的引用指针。简单讲,就像一本书前面的目录,能加快查询速度。

索引是帮助mysql高效获取数据的数据结构
索引存储在文件系统中
索引的文件存储形式与存储引擎有关
索引文件的结构

27.索引为什么选择b+树?

可以考虑作为索引的数据结构有如下几种,下面介绍下不同数据结构的特点:
hash表
二叉树
b树
b+树

使用hash表的缺点:
1)hash存储需要将所有的数据文件添加到内存,浪费空间
2)如果是等值查询,hash很快,但实际工作中范围查找更多,而不是等值查询,所以hash就不合适了

InnoDB的索引是B+树

28.(面试)能不能给所有的列都创建索引?

可以,但是如果插入一条数据的话,有多少列,就有多少个B+树需要进行调整,这将会是一个很大的工作量,但是给所有的列都创建索引后,查找的速度确实是很快的,但是一般不会给所有的列都创建索引,通常是给使用最多的,查询最多的列创建索引

29.用C程序向表中添加10000条数据

注意在编译的时候一定要加上-lmysqlclient,否则编译不通过

gcc -o main main.c -lmysqlclient

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <mysql/mysql.h>

int main()
{
	MYSQL mysql_conn;
	MYSQL * mysql = mysql_init(&mysql_conn);
	if(mysql == NULL)
	{
		printf("mysql init err\n");
		exit(1);
	}
	mysql = mysql_real_connect(mysql,"localhost","root","sp20010212","hellodb",3306,NULL,0);
	if(mysql == NULL)
	{
		printf("mysql connect err\n");
		exit(1);
	}
	char sql_buff[256] = {0};
	for(int i = 0;i<10000;++i)
	{
		sprintf(sql_buff,"insert into hello values('hello-%d')",i);
		if(mysql_query(mysql,sql_buff) != 0)
		{
			printf("insert err\n");
			break;
		}
	}
	mysql_close(mysql);
	exit(0);
}

最初hello表上是没有数据的,然后./main,往hello表中插入10000条数据,这时hello表中就有10000条数据了

30.查询验证

开启运行时间检测:set profiling = 1;

查看执行时间:show profilies; 单位是秒

31.为表hello的title列创建索引

create index test_index on hello(name(20)); 如果是字符串的话,一定要指定长度

test_index 是索引的名字,hello是表的名字,name是字段

可以看到,在创建了索引以后,查询时间大大减少了,第2.3条是没有创建索引的,第5条是创建了索引的,一个是7.8毫秒,一个是0.4毫秒

32.删除索引

drop index test_index on hello; test_index 是索引名,hello 是hello表

删除索引后,再次搜索,发现执行时间又增加了,但是为什么第三次执行的时间要比第一次要小呢,这时因为在第一次查询了以后,就会有缓存的问题,所以查询的时间要比第一次要短一些,但是再短也肯定没有创建索引后的时间短

更多推荐

341-Linux 连接数据库