知识介绍:
基础篇
SQL
mysql数据库中关系型数据库:是建立在关系模型基础上的,由多张相互连接的二维表组成的数据库
SQL通用语法
-
SQL可以单行或多行书写,以分号结尾
-
SQL可以使用空格或者缩进来增强语句的可读性
-
MySQL数据库的SQL语句不区分大小写
注释的使用:
-
单行注释:--注释内容或者#注释内容
-
多行注释 /* */
SQL分类
分类 | 说明 |
---|---|
DDL | 数据定义语言,用来定义数据库对象 |
DML | 数据操作语言,用来对数据进行增删改 |
DQL | 数据查询语言,用来查询数据库中表的记录 |
DCL | 数据控制语言,用来创建数据库用户,控制数据库访问权限 |
DDL-数据库操作
查询:show databases;
查询当前:select databases();
创建:create database [if not exists] 数据库名 [default character set字符集] [collate排序规则];
上述[]括起来的部分都是可选的,如果不指定字符集,默认latin1,也可以指定为utf-8
删除数据库:drop database[if exists] 数据库名;
使用数据库:use 数据库名称;
修改字符集:alter database 数据库 character set utf8;
DDL-表操作
查询当前数据库所有表:show tables;
查询表结构:desc 表名称
查询指定表的建表语句:show create table 表名;
使用数据库:use 数据库名称;
创建表:create table 表名(字段1 字段1类型,字段2 字段2类型... )[comment表注释];
-
单行注释 #
-
多行注释 /* */
DDL-数据类型
数值类型
类型 | 大小(bytes) | 描述 |
---|---|---|
tinyint | 1 | 小小整数值 |
smallint | 1 | 小整数值 |
mediumint | 3 | 中整数值 |
int | 4 | 整数值 |
bigint | 4 | 大整数值 |
float | 4 | 单精度浮点数 |
double | 8 | 双精度浮点数 |
decimal | --- | 小数值 |
note:这是一个例子,举出age类型 age tinyint unsigned
字符串类型:这里主要介绍两个
类型 | 大小(bytes) | 描述 |
---|---|---|
char | 0-255 | 定长字符串,定义多长就是多长,剩余用空格补齐 |
varchar | 0-65535 | 变长字符串:根据所存储内容改变长度 |
note:相比之下,虽然char更占用空间,但是性能较好,varchar使用时需要计算所占用空间
日期类型
类型 | 大小(bytes) | 描述 |
---|---|---|
date | 3 | 日期值 YYYY-MM-DD |
time | 3 | 时间值:HH:MM:SS |
year | 1 | 年份:YYYY |
datatime | 8 | 时间日期混合值 |
timestamp | 4 | 混合日期和时间(时间戳) |
note:相比之下,虽然char更占用空间,但是性能较好,varchar使用时需要计算所占用空间
DDL-表操作-修改
添加字段:alter table 表名 add 字段名 类型(长度) [comment注释] [约束];
修改字段:alter table 表名 change 旧字段名 新字段名 类型(长度) [comment注释] [约束];
删除字段:alter table 表名 drop 字段名;
修改表名:alter table 表名 rename to 新表名;
删除表:alter table 表名;
插入数据:insert into 表名 values()或者insert into 表名 (属性)values()
select 属性,属性 as 别名 from 表名 where 条件
如果在上面的语句后面添加 \G就会按照每行多要素分布显示
修改数据:update 表名 set 属性=数值;
删除表中数据:delete from 表名 where 条件,也可以使用truncate table 表名,但是这样数据无法回滚
简单案例
按math成绩从小大的排序, 求math成绩在5-8名的
select * from student order by math limit 4, 4;
limit后面的两个数字的意思: 第一个4: 表示要跳过前面几个 第二个4: 表示连续取几个.
--查出各个班的总分和最高分
select class_id, sum(chinese+english+math), max(chinese+english+math) from student group by class_id;
group表示分组通过class_id
--求各个班级英语的平均分
select class_id, avg(english) from student group by class_id;
--查询出班级总分大于1300分的班级ID
select class_id, sum(chinese+english+math) sumscore from student group by class_id having sumscore>1300;
mysql 中的时间日期函数
mysql中的函数分为三类,时间,日期,时间戳(含义时分秒的sysdate)
查看当前时间戳,select sysdate() from dual;
now()函数和sysdate函数表示意义一致
获取年year(now()),获取月month(now()),获取日day(now())
获取日期,时间,时间戳:select CURRENT_DATE(),CURRENT_TIME(),CURRENT_TIMESTAMP() from daul;
常用数学函数
若发生错误,所有数学函数会返回 NULL
ABS(X) 返回X 的绝对值。
bin(X) 返回X 的二进制。
ceiling(X) 向上取整。
floor(X) 向下取整。
mod(X,Y) 取余。
rand() 随机值。
多表查询
导入数据:source 文件(要求文件为sql文件)
交叉连接---相当于笛卡尔积:select e.*, d.* from emp e cross join dept d;
自连接,查询两个表的所有信息select e.*, d.* from emp e inner join dept d on e.deptno=d.deptno;
左外连接:select e.*, d.* from emp e right outer join dept d on e.deptno=d.deptno;
右外连接:select e.*, d.* from dept d left outer join emp e on e.deptno=d.deptno;
外链接取值与关系表达式=号左右位置无关。取值跟from后表的书写顺序有关。
字符串
charset(str)返回编码集
concat(st11,str2...)连接多个字符串
返回sub在str中的位置,没有则返回0 instr(str,sub)
大小写转换:大写:ucase(),小写lcase();
left(str,num),从左边开始取num个字符
length()返回长度
replace(str,str1,str2)将str中的str1转换为str2
strcmp()比较两个字符串
substring(str,num1,num2)从str的 num1位置取出num2个字符,num1为负数代表从右侧取出
表的约束
*定义主键约束 primary key: 不允许为空,不允许重复
*定义主键自动增长 auto_increment
*定义唯一约束 unique
*定义非空约束 not null
*定义外键约束 constraint ordersid_FK foreign key(ordersid) references orders(id)
*删除主键:alter table tablename drop primary key ;
准备两个表:
create table class (
id INT(11) primary key auto_increment,
name varchar(20) unique
);
create table student (
id INT(11) primary key auto_increment,
name varchar(20) unique,
passwd varchar(15) not null,
classid INT(11),
constraint stu_classid_FK foreign key(classid) references class(id)
);
note:主键自动增长,没有数据自动给你填入数据
视图
从表中抽取出来的逻辑上相关数据的集合
创建语法与表类似:create view 视图名字 as select ...
select view_name from user_views;
drop view 视图名字
当删除表内某些数据的时候,视图中的数据也会发生改变
索引
索引主要用于表,目的是为了提高查询的效率
创建索引:create index 索引名字 on 表名字(属性名);
创建唯一索引:create unique index 索引名字 on 表名字(属性名);
查询索引:select index_name from user_indexes
删除索引:drop index 索引名字
使用索引的原理:如果一个表有索引,则会维护一个索引表,查询的时候使用索引列,优先去索引表中查,通过索引的列去找到对应的行地址,找到行地址就可以找到数据。
使用索引注意事项:列值要广泛,重复概率低,唯一最好。(表的主键就可以)
序列
由于表的主键要求是非空且唯一的,为了保证主键的非空且唯一,可以使用序列
create sequence
查询序列:select sequence_name from user_sequences
序列包含两个属性(currval(当前值),nextval(下一个值)):初始值指向1前面,
删除序列:drop sequence 序列名
mysql常用函数
编译:g++ test.c -o test $(mysql_config --cflags --libs)
使用MySQL库API函数的一般步骤:
a. 初始化. MYSQL *mysql_init(MYSQL *mysql)
b. 错误处理 unsigned int mysql_errno(MYSQL *mysql)
char *mysql_error(MYSQL *mysql);
c. 建立连接. 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);
d. 执行SQL语句 int mysql_query(MYSQL *mysql, const char *stmt_str)
e. 获取结果 MYSQL_RES *mysql_store_result(MYSQL *mysql)
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)
f. 释放内存 void mysql_free_result(MYSQL_RES *result)
g. 关闭连接 void mysql_close(MYSQL *mysql)
对于mysql_real_connect的讲解:第一个选项为已有mysql结构的地址,host为主机名,如果为NULL或者localhost,默认同当前主机连接,user表示mysql登录id,passwd为密码。db是数据库名称,port代表端口号,unix_socket表示描述了使用的套接字或者命名管道,如果连接成功,返回连接句柄。
执行mysql语句:int mysql_query(MYSQL *mysql, const char *query); 成功返回0,失败返回非0,query是数据库命令字符串,不包含;
获取结果集:一种方式是通过mysql_store_result()将整个结果集全部取回来。另一种方式则是调用mysql_use_result()初始化获取操作,但暂时不取回任何记录。视结果集的条目数选择获取结果集的函数。两种方法均通过mysql_fetch_row()来访问每一条记录。
MYSQL_ROW的本质是 typedef char ** MYSQL_ROW;
通过游标一行一行fetch结果集中的数据。根据游标使用的一般特性,应使用循环结构,到达结尾或者出错,返回NULL。
有两个函数具备获取列数的功能:
unsigned int mysql_field_count(MYSQL *mysql) 从mysql句柄中获取有多少列。
unsigned int mysql_num_fields(MYSQL_RES *result) 从返回的结果集中获取有多少列。
获取表头的API函数同样有两个:
MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *result) 全部获取
MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result) 获取单个
修改mysql_real_connect()参数,连接到表中有中文数据的数据库,如mydb2,执行程序,测试显示中文出现乱码。我们可以使用mysql_query函数来解决该问题。 在 while (1) 之前使用 ret = mysql_query(mysql, "set names utf8"); 来设置查询属性(也可以加到while中)。表示在查询的时候使用utf8的形式进行查询。 或者mysql_set_character_set(mysql, "utf8"); 获取当前使用的字符集: const char *mysql_character_set_name(MYSQL *mysql)