天天看點

關于mysql涉及到的知識點,C語言如何操作mysql

数据库

数据库(Database)是按照数据结构来组织、存储和管理数据的仓库。每个数据库都有一个或多个不同的 API 用于创建,访问,管理,搜索和复制所保存的数据。

数据库 mysql  

mysql 属于 关系数据库管理系统(Relational Database Management System),有如下特点:

  • 数据以表格的形式出现
  • 每行为各种记录名称
  • 每列为记录名称所对应的数据域
  • 许多的行和列组成一张表单
  • 若干的表单组成database

术语

冗余:存储两倍数据,冗余降低了性能,但提高了数据的安全性。

主键:主键是唯一的。一个数据表中只能包含一个主键。你可以使用主键来查询数据。

外键:外键用于关联两个表。

复合键:复合键(组合键)将多个列作为一个索引键,一般用于复合索引。

索引:使用索引可快速访问数据库表中的特定信息。索引是对数据库表中一列或多列的值进行排序的一种结构。类似于书籍的目录。

参照完整性: 参照的完整性要求关系中不允许引用不存在的实体。与实体完整性是关系模型必须满足的完整性约束条件,目的是保证数据的一致性。

 

mysql数据库为什么不是把数据全部放到一个大仓库内,而是建多个表呢?

建多个表,可以提高对数据库的处理速度 和 灵活性

 

ubuntu MySQL安装

sudo apt-get install mysql-server

apt-get install mysql-client

sudo apt-get install libmysqlclient-dev

启动,停止,重启 sudo /etc/init.d/mysql start|stop|restart

客户端连接 mysql -h127.0.0.1 -uroot -p

 

外部连接mysql 需要修改配置文件

sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf

注释掉以下一行即可: bind-address = 127.0.0.1
           

查看mysql 版本

mysqladmin --version

设置密码

mysqladmin -u root password "xxxx";
           

连接mysql

mysql -u root -p
           
Enter password:*******
           

创建用户

CREATE USER [email protected] IDENTIFIED BY password;

CREATE USER 'qb'@'localhost' IDENTIFIED BY '123123';
           

授权某个用户 可以访问的数据库和表

GRANT ALL privileges ON databasename.tablename TO 'username'@'host'
FLUSH PRIVILEGES;
           

privileges:用户的操作权限,如SELECT,INSERT,UPDATE等,如果要授予所的权限则使用ALL

databasename:数据库名

tablename:表名,如果要授予该用户对所有数据库和表的相应操作权限则可用*表示,如*.*

 

显示数据库

show databases;

显示搜索引擎

show engines;

使用某个数据库

use xxx;

显示数据库表

show tables;

显示表属性,属性类型,主键信息 ,是否为 NULL,默认值等其他信息。

show columns from tablename;

显示表索引信息

show index from tablename;

创建数据库

create database tets_mysql;
           

创建数据库表

create table `dev_stu_info`(
	`id` int(11) unsigned not null auto_increment comment '用户id',
    `name` varchar(32) collate utf8mb4_bin not null default '' comment '用户名',
    `passwd` varchar(32) collate utf8mb4_bin not null default '' comment '密码',
	`location` varchar(32) collate utf8mb4_bin not null default '' comment '地址',
    `sex` tinyint(1) unsigned not null default '0' comment '性别',
    primary key (`id`),
    key `idx_name` (`name`)
)engine=innodb auto_increment=2 default charset=utf8mb4  collate=utf8mb4_bin

此处创建字符集,表字段 主键,索引,数据库引擎 ,从2开始自增
           

插入数据

插入一条数据
insert into dev_stu_info (`id`,`name`,`passwd`,`location`,`sex`) values(null,'joohn','123123','广州','1');
           

添加字段

alter table dev_stu_info add column `create_time` timestamp null default current_timestamp comment '时间';
           

修改表中的某个字段

alter table dev_stu_info change column `name` `name` varchar(32) character set 'utf8' not null comment '姓名';
           

自己造数据

存储过程

delimiter $$
create procedure insert_userrole(in start int ,in max_num int )
begin
declare i int default 0;
declare j int default 0;
set autocommit=0;
repeat
set i=i+1;
set j = rand()%2;
set @NAME = 'asjiodfgaujksfghkajlsjd';
insert into dev_stu_info (`id`,`name`,`passwd`,`location`,`sex`,`create_time`) values(null,substr(@NAME,rand()%3+1,4),substr(@NAME,rand()%2+1,7),substr(@NAME,rand()%3+1,6),j,current_timestamp());
until i=max_num end repeat;
commit;
end $$

call  insert_userrole(1,100);
           

数据库备份与恢复

备份

mysqldump -h主机名 -P端口 -u用户名 -p密码 [-R] 数据库名 > 文件名.sql 

mysqldump -uroot -p123456 -R test_mysql > /home/qb/test_mysql .dump   
-R备份存储过程,不加不备份存储过程 拷贝到其他计算机 scp -P22 [email protected]:本地备份的数据库文件路径  远端的需要存储的位置     

恢复(数据库需要先创建好) 

mysql -h主机名 -P端口 -u用户名 -p密码 数据库名 < 文件名.sql mysql -uroot -p123456  test_mysql < /home/qb/test_mysql.dump

           

mysql事务,索引,存储引擎 (高性能mysql)

start transaction;

update dev_userinfo set amount = amount-1000 where name='xiaoming';
update dev_userinfo set amount = amount+1000 where name='dabao';

commit; //rollback
           

mysql  索引是用B+树来做的,myisam和区别

    

    myisam    --    B+里面存的都是索引 + 指向具体数据的指针

    innodb    --    B+树里面存的是 索引+数据

    

    相当于myisam里面存的是一个引用,innodb里面存的是具体数据

    

    事务是mysql执行的最小单元 -- 原子性

    事务的执行如何保证原子性?

        mysql操作事务的时候,是会建立一个undolog临时表,这里面会有行级锁

        此处的回滚,若一条数据执行不成功的话,则undolog里面的语句就不执行,直接返回

        

    什么时候会出现undolog失败的情况?

    当sql依赖于另外一个结果的时候,如另外一个结果需要通过某种复杂计算

    如果计算出来的结果不合法,不对的话,就会执行失败

    

    myisam是没有undolog的,因为myisam不支持事务操作

数据库的锁

    表级锁    --    myisam     (对一条数据进行操作的时候,会锁住整个表)

    行级锁    --    innodb  

    页级锁    --    一个页是4K

    

    

    innodb支持事务,myisam不支持事务是为什么?

        重要原因是,innodb是行级锁的,myisam是表级锁的,表级锁没办法支持事务

        例如:

        myisam用事务来操作的时候,先操作一条数据,已经把表给锁住了,

        下一个来操作数据的就没有办法操作,因而无法实现事务处理

索引

索引是什么?

    是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息

 b+树的结构,所有数据是存在叶子节点上的,

    叶子节点的数据是通过链表串起来的

        

    myisam 查询的时候,是把整颗树全部加入内存,查询寻到具体id,再去磁盘找数据

    对于查找具体某个数据的时候效率很高

    

    innodb ,查询的时候,是把树的一部分放入内存,查询完就可以直接取数据,

    对于范围查询的时候,效率比较高

    

innodb不支持全文索引,myisam支持全文索引,为什么?

    例如插入一篇文档到数据库中,innodb因为是索引和数据放一起,

    如果是全文索引的话,相当于复制了一份数据库,因而不支持

    

binlog -- 用于回滚(不是事务回滚)

    执行语句会产生执行记录(存放 insert,update,delete)

    mysql 集群  从机同步主机数据的时候,是去读主机的binlog

    

    从机里面是有一个relay log的

    relay log 备份binlog的全部,还是备份增量?

 

linux C/C++中  使用代码来操作 mysql,主要用到一下几个函数

函数原型与结构体

1.MYSQL *mysql_init(MYSQL *mysql)

2.MYSQL *mysql_real_connect(MYSQL *mysql,

3.int mysql_query(MYSQL *mysql, const char *stmt_str)

4.MYSQL_RES *mysql_use_result(MYSQL *mysql)

5.MYSQL_RES *mysql_store_result(MYSQL *mysql)

6.MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)

7.void mysql_free_result(MYSQL_RES *result)

8.void mysql_close(MYSQL *mysql);
           

 

写一个简单数据库操作的demo

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

int main() {

    MYSQL *conn;
    MYSQL_RES *res;
    MYSQL_ROW row;

    char server[] = "127.0.0.1";
    char user[] = "root";
    char password[] = "123123";
    char database[] = "test_mysql";

    conn = mysql_init(NULL);
    //链接数据库,mysql conn 对象,ip地址,用户名,密码,数据库,
	if(mysql_real_connect(conn, server, user, password, database, 0, NULL, 0) == NULL)
	{
        //如果链接失败,打印错误号,和错误信息
		printf("Error %u: %s\n", mysql_errno(conn), mysql_error(conn));
		return -1;
	}

    //执行sql语句  查询整张表的信息
    if (mysql_query(conn, "select * from dev_userinfo")) {
        printf("%s\n", mysql_error(conn));
		return -1;
    }
    //得到结果集
    res = mysql_use_result(conn);
    //一行一行的将数据读出来
    while ((row = mysql_fetch_row(res)) != NULL) {
		int count = res->field_count;//得到一行中,有多少列
		for(int i = 0 ;i<count;i++){
            //打印一行中每一列的值
			printf("%s\t\t", row[i]);
		}
		printf("\n");
    }
    
    mysql_free_result(res);//释放内存
    mysql_close(conn);//关闭连接

    return 0;

}
           

 

繼續閱讀