MySQL数据库引擎

存储引擎就是指表的类型。

数据库的存储引擎决定了表在计算机中的存储方式。
存储引擎的概念是MySQL的特点,用户可以根据自己的需求选择不同的存储方式、是否进行事务处理。
MySQL的存储引擎查询方式:

mysql>show engines\G
*************************** 1. row ***************************
      Engine: InnoDB    //引擎名称
     Support: DEFAULT   //MySQL是否支持,InnoDB为默认类型
     Comment: Supports transactions, row-level locking, and foreign keys//说明
Transactions: YES   //是否支持事务类型
          XA: YES   //是否支持分布式交易处理的XA规范
  Savepoints: YES   //是否支持保存点以便回滚
*************************** 2. row ***************************
      Engine: CSV
     Support: YES
     Comment: CSV storage engine
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 3. row ***************************
      Engine: MyISAM
     Support: YES
     Comment: MyISAM storage engine
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 4. row ***************************
      Engine: BLACKHOLE
     Support: YES
     Comment: /dev/null storage engine (anything you write to it disappears)
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 5. row ***************************
      Engine: PERFORMANCE_SCHEMA
     Support: YES
     Comment: Performance Schema
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 6. row ***************************
      Engine: MEMORY
     Support: YES
     Comment: Hash based, stored in memory, useful for temporary tables
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 7. row ***************************
      Engine: ARCHIVE
     Support: YES
     Comment: Archive storage engine
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 8. row ***************************
      Engine: MRG_MYISAM
     Support: YES
     Comment: Collection of identical MyISAM tables
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 9. row ***************************
      Engine: FEDERATED
     Support: NO
     Comment: Federated MySQL storage engine
Transactions: NULL
          XA: NULL
  Savepoints: NULL
9 rows in set (0.00 sec)

InnoDB

InnoDB是第一个提供外键约束的MySQL表引擎。支持自动增长类auto_increment。
创建的表结构存储在*.frm文件中,数据和索引存储在innodb_data_home_dir和innodb_date_file_path定义的表空间中。
InnoDB的优点是有良好的事务管理、崩溃修复和并发控制.
* 索引组织表
* 支持事务、行级锁
* 数据库缓存
* 日志持久化
* 稳定性好、性能好
缺点是读写效率差、占用空间大。

MyISAM

MyISAM存储引擎的表存储为3个文件。文件名字与表名相同。
扩展名包括frm、MYD和MYI。其中,frm为表的结构,MYD存储数据,MYI存储索引。
支持静态型、动态型和压缩型存储格式。
占用空间小、处理速度快。
* 堆表
* 不支持事务、不支持并发
* 只维护索引缓冲池,表数据缓存交由操作系统负责
* 锁粒度大
* 数据文件可以直接拷贝

MEMORY引擎

使用存储在内存中的内容来创建表,所有数据放在内存中。
每个memory引擎表对应一个磁盘文件,类型为frm,该表中只有表的结构。
默认使用hash索引。
处理速度非常快,但数据易丢失,生命周期短。

MySQL数据类型

整数型和浮点数类型

两者最大的区别是能否表达小数。整数型不能表达,浮点可以。
MySQL支持数据类型后指定显示宽度,比如int(4)是指该整数型的显示宽度为4。可以插入大于显示宽度的数据。
zerofill参数表示数字不足的时候,显示空间以0来填充。
auto_increment属性是表示自增属性。
tinyint的取值范围是0~255,bigint的取值范围最大。
常用整数类型是int。

浮点数类型包括float和double类型。double类型精度比float类型高。小数点后10位以上需要double类型。

浮点数类型和定点数类型

浮点数包括float和double,定点数是decimal或者dec。
在MySQL中,可以指定浮点数和定点数的精度,形式是数据类型(M,D),M参数称为精度,是数据的长度;D是标度,指小数点后的长度。
定点数精度比浮点数高,而且浮点数会有误差。高精度需要定点数。
对于浮点数和定点数,当插入值的精度高于实际定义的精度时,系统会自动进行四舍五入处理。目的是使精度达到要求。
浮点数四舍五入时系统不会报警,定点数会报警。
在未指定精度的情况下,浮点数和定点数有其默认精度。float型和double型会保存实际精度。定点数默认为整数。
精度与操作系统和硬件的精度有关系。

char类型和varchar类型

char类型的长度是固定的,而varchar类型长度在范围内可变。因此varchar占用空间比char小。
对于长度变化比较大的字符串类型,最好是选择varchar类型。
char类型的处理速度比varchar类型快。

时间和日期类型

year类型指标是年份。time类型只表示时间。date类型只表示日期。
需要记录日期和时间,可以选择datetime和timestamp类型。datetime类型时间范围大于timest类型。
timestamp类型是根据时区来显示,需要跟随时区变化则需要使用此类型。

enum(枚举)类型和set类型

enum类型最多有65535个成员,set类型最多64个成员。enum类型只能选择一个成员,set可以选择多个。
因此,对于多个值选择一个的,比如男女类别,可以使用enum类型。对于可以选取多个值的的字段,使用set类型。

text类型和blob类型

text只能存储字符数据,blob可以存储二进制数据。
text类型包括tinytext、text、mediumtext和longtext。区别在于长度,tinytext最小,longtext最大。blob类似。

其他

在MySQL中,布尔类型等价于tinyint类型。
char、varchar、text类型都可以存储路径,但使用\符号会被过滤,需要使用/或者\代替。

SQL语言入门

安装

sudo tasksel install lamp-server basic-ubuntu-server
//安装并设置Mysql密码
mysql_secure_installation

创建Mysql用户和数据库

mysql -uroot -p
mysql>create database sujx;
mysql>create user 'sujx'@'%' identified by '123456';
mysql>grant all on sujx.* to sujx@'%';
mysql>flush privileges;
mysql>exit;

使用新的用户登录

mysql -usujx -p

数据库的基本操作

mysql>show databases;   //使用名为test的数据库
mysql>use sujx;     //创建一张学生表

mysql>create table stu(id int(10),  name varchar(20),age int(10), primary key(id));
//每一张表都需要包含一个主键,主键唯一标识一条记录,唯一的字段,不可重复不能为空,通过`primary key`关键字来定义。

show create table stu;//查看创建好的表
alter table stu add column gender varchar(20);  //新加一个字段
alter table stu modify column gender varchar(40);   //修改一个字段
alter table stu drop column gender; //删除一个字段

insert into stu(id,name,age) values(1,'pw',28);//向表中插入数据
insert into stu values(2,'nss',29); //插入全部字段时可以只写表名

show tables;    //查看当前数据库中的表
select * from stu;  //查看刚才添加的数据,"*"代表查询全部字段
select name, age from stu;  //如果只想查询两个字段,则只写要查询的字段名
select name age from stu where id=1;    //也可以根据某个条件进行查询,比如只查询id为1的记录

update stu set age=29 where id=1;   //更新语句
delete from stu where id=1; //删除表中的数据
drop table stu; //删除表

C控制语句:循环

循环是一个强大的编程工具。

在建立循环时应该特别注意三个方面:
1. 明确定义结束循环的条件;
2. 确保在循环判断中使用的值在第一次使用之前已经初始化;
3. 确保循环在每个周期中更新了判断值。

C通过数值计算来处理判断条件。

结果为0表示假,任何其他值都为真。使用了关系运算符的表达式通常被用来进行判断,它们有些特殊。如果为真,关系表达式的值为1,为假则为0,这与布尔类型所允许的值保持一致。

数组由相同类型的邻近内存位置组成。

需要谨记数组元素是从0开始编号,这样最后一个元素的下标就比元素的个数少1。C并不检查是否使用合法的下标值。

使用一个函数需要完成三个步骤:

  • 使用函数原型声明该函数;
  • 在程序中通过函数调用来使用函数;
  • 定义函数
    原型使编译器可以检查您是否正确使用了函数,而定义则规定了函数如何工作。现代的编程习惯市把程序的元素分为接口和实现部分。

C为实现程序的结构话提供了很多帮助。

while和for语句提供了入口条件循环,for语句特别适合那些包含有初始化和更新的循环。逗号运算符使您可以在一个for循环中初始化和更新多个变量。在不多的场合中也需要退出条件循环,do while语句就是一个典型。
所有这些循环都使用一个判断条件来决定是否执行另一个循环周期。一般而言,如果判断表达式等于一个非零值,循环就继续;否则就结束。

逗号运算符

//postage.c -- 一类邮资费率
#include<stdio.h>
#include<stdlib.h>
int main(void){
    const int FIRST_OZ = 37;
    const int NEXT_OZ = 23;
    int ounces, cost;

    printf(" ounces cost\n");
    for(ounces=1, cost=FIRST_OZ; ounces<=16; ounces++, 
                                    cost=cost+NEXT_OZ)
    /*逗号运算负扩展了for循环的灵活性,
     * 可以在一个for循环中使用多个初始化或者更新表达式。
     * 该运算符具有两个属性。
     * 1.被它分开的表达式按从左到右的次序进行计算。
     * 2.整个逗号表达式的值都是右边成员的值。*/
    {
        printf("%5d $%4.2f\n", ounces, cost/100.0);     
    }
    return 0;   
}

在for循环中使用数组

// scores_in.c  --  使用循环进行数组处理
#include<stdio.h>
#define SIZE 10
#define PAR 70
int main(void){
    int index,score[SIZE];
    int sum = 0;
    float average;

    printf("Enter %d golf scores: \n", SIZE);
    for(index = 0; index < SIZE; index++){
        scanf("%d", &score[index]);
    }
    printf("The scores read in are as follows: \n");
        for(index=0;index < SIZE; index++){
        printf("%5d", score[index]);
    }
    printf("\n");

    for(index = 0; index < SIZE; index++){
        sum += score[index];
    }
        average = (float) sum / SIZE;
    printf("Sum of scores = %d, average = %.2f\n", sum, average);
    printf("That's a handicap of %.0f.\n", average - PAR);

    return 0;
}

带返回值的函数

//power.c -- 计算数值的整数次幂
#include <stdio.h>
#include <math.h>  //数学头文件
double power(double n, int p);  //函数原型
double power(double n, int p)   //函数定义
    {
    double pow = 1;
    int i;

    for(i=1;i<=p;i++){
        pow *= n;
        }
        return pow; //!带返回值的函数
    }

int main(void){
    double x, xpow; //属于的双精度浮点数
    int exp;    //整数次幂

    printf("Enter a number and the postive integer power.");
    printf(" to which\nthe number will be raised.Enter q");
    printf(" to quit.\n");

    while(scanf("%lf%d", &x, &exp) == 2)
    /*当scanf()成功读入两个值的时候开始循环*/
    {
        xpow = power(x,exp);
        printf("%.3g to the power %d is %.5g\n", x, exp, xpow);
        printf("Enter next pair of numbers or q to quit.\n");
    }
    printf("Hope you enjoyed this power trip -- bye!\n");

    return 0;   
}

运算符、表达式和语句

C语言使用运算符来提供多种服务。

每个运算符的特性包括所需操作数的数量、优先级和结合性。当两个运算符共享一个操作数时,最后的两个特性决定了先应用那个运算符。运算符与值结合可以产生表达式,并且C的每一个表达式都有一个值。C允许写出将不同的数值类型组合在一起的表达式。但算术运算要求操作数是同一类型的,所以C进行自动转换。然而,不依赖于自动转换是一个很好的编程习惯。

C有多种运算符,比如赋值和算术运算符。

带一个操作数的运算符(例如负号和sizeof)被称为一元运算符。要求两个操作数的(例如加法和乘法运算符)被称为二元运算符。

表达式是运算符和操作数的组合。

运算符优先级的规则帮助决定当对表达式进行求值时,如何组合表达式的各项。如果运算符有相同的优先级,结合性决定那个运算符先被应用。语句市对计算机的完整指示,在C中使用分号标识。

//min_sec.c -- 把秒转换为分钟和秒
#include<stdio.h>
#define SEC_PER_MIN 60  //定义常量值为每分钟60秒
int main(void){
    int sec,min,left;

    printf("Convert seconds to minutes and seconds!\n");
    printf("Enter the number of seconds(<=0 to quit):\n");
    scanf("%d",&sec);

    while(sec>0){
        min = sec / SEC_PER_MIN;
        left = sec % SEC_PER_MIN;
        /*取模运算(modulus operator)用于整数运算。
        * 该运算符计算出用它右边的整数去除它左边的整数得到的余数。
        * 例如,13%5所得值为3,因为13除以5得2并余3。
         */
        printf("%d seconds is %d minutes. %d seconds\n", sec, min, left);
        printf("Enter next value (<=0 to quit):\n");
        scanf("%d",&sec);
    }
    printf("Done!\n");

    return 0;   
}