数据库
数据库(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 username@host 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 root@192.168.xxx.xxx:本地备份的数据库文件路径 远端的需要存储的位置 恢复(数据库需要先创建好) 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; }