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 连接数据库
发布评论