MySQL(任务3)

MySQL基础知识#

在讲 MySQL 中数据表的增删改查之前,我们先需要创建表。创建表的过程中需要制定表字段的类型,字段的约束以及表的存储引擎等。所以非常有必要先介绍些MySQL的基础语法知识。

字符集和校验规则#

字符集:字符的集合,常见的字符集有ASCLL、GBK和Unicode等;
校验规则:当前字符集内,字符之间大小的比较规则。

数值型#

1. 数值类型

类型 字节 最小值 最大值
TYNYINT 1 -128/0 127/255
SMALLINT 2 -32768/0 32767/65535
MEDIUMINT 3 -8388608/0 8388607/16777215
INT 4 -2147483648/0 2147483647/4294967295
BIGINT 8 很大... 很大...
INT(M) UNSIGNED ZEROFILL 

可以这样定义数值类型。其中M,表示显示宽度,显示宽度不限制数值的范围。配合zerofill来使用,可以在小于显示宽度的位数前增加0。ZEROFILL 自动为unsigned。Unsigned 表示无符号,只表示正数。

2. 小数类型

单精度(不推荐使用)

FLOAT(M,D) UNSIGNED ZEROFILL

双精度

DOUBLE(M,D) UNSIGNED ZEROFILL

其中M表示总的位数(包括小数位数),D表示小数位数。M,D可以控制保存的范围。比如DOUBLE(10,2)可以表示 -99999999.99 到 99999999.99。

定点数(金额,科学数据推荐使用这个类型)

DECIMAL(M,D) UNSIGNED ZEROFILL

其中M表示总的位数,D表示小数位数。此M,D可以控制保存的范围。M,D省略,默认为10,0;

日期型#

可以考虑使用long类型来存储,也就是时间戳。

或者使用datetime(或timestamp)类型来存储。但是这两个类型有个问题:datetime不包含时区的概念,也就是你传'2019-09-08 12:56:34',它存储的就是这个值。timestamp虽然包含时区的概念,但是它的取值范围比较小(1970-01-01 00:00:01 -- 2038-01-19 03:14:07),有些情况不够用。

所以会有上面的建议,使用long类型存时间戳。

字符串型和二进制#

MySQL(任务3)_第1张图片

选择数据类型的建议#

当选择字段类型时,应该遵循下面几个原则:

  • 应该使用最精确的类型,占用的空间少,已经事先估计字段可能的长度;
  • 还应该考虑到相关应用语言的处理,例如常常将时间日期保存成一个整型,便于计算;
  • 考虑移植的兼容性。

约束#

MySQL中列约束一般用来保证数据库表数据的正确性和完整性。主键约束#

主键:可以唯一标识一条记录的一列或者多列的组合。主键具有以下特点:

  • 每个表只能定义一个主键;

  • 任意两行都不具有相同的主键值;

  • 每一行都必须具有一个主键值(主键列不允许NULL值);

  • 主键列中的值不允许修改或更新;

  • 主键值不能重用(如果某行从表中删除,它的主键不能赋给以后的新行)。

-- 添加主键
  create table tbl_user
  (
    user_id int primary key,
    user_name varchar(20)
  );
  create table tbl_user
  (
    user_id int,
    user_name varchar(20),
    primary key(user_id)
  );

alter table tbl_user add primary key(user_id,user_name);
ALTER TABLE tbl_test1 ADD CONSTRAINT pk_tbl_test1 PRIMARY KEY(id);

-- 删除主键(假如主键列具有auto_increment属性,需要先删除自增长属性,再删除主键)
ALTER  TABLE  TABLE_NAME  DROP  PRIMARY  KEY;

外键约束#

外键(FK,foreign key):如果一个A表的字段指向另一个B表的主键,则此字段就为A表的外键。用于表示表之间的关系。存在外键的表,称之为从表(子表),外键指向的表,称之为主表(父表)。外键只被innodb存储引擎所支持。其他引擎是不支持的。一个表可以存在一个或者多个外键。

外键的默认作用有两点:

  • 对子表(外键所在的表)的作用:子表在进行写操作的时候,如果外键字段在父表中找不到对应的匹配,操作就会失败;
  • 对父表的作用:对父表的主键字段进行删和改时,如果对应的主键在子表中被引用,操作就会失败。

外键的定制有三种约束模式:

  • district:严格模式(默认), 父表不能删除或更新一个被子表引用的记录的主键值;
  • cascade:级联模式, 父表的主键值操作后,子表关联的数据也跟着一起操作;
  • set null:置空模式,前提外键字段允许为NLL, 父表的主键值操作后,子表对应的字段被置空。
  -- 添加外键
  create table tbl_user
  (
    user_id int primary key,
    user_name varchar(20),
    class_id int,
    CONSTRAINT fk_tbl_user foreign key(class_id) references tbl_class(class_id)
  )
  alter table tbl_user add CONSTRAINT fk_tbl_user foreign key(class_id) references tbl_class(class_id);

-- 删除外键
alter table tbl_user drop foreign key fk_tbl_user;

唯一性约束#

唯一性约束可以确保一列或者多列不出现重复值。

Unique和Primary Key的区别:

  • 一个表可以有多个字段声明为 Unique,但是只能有一个Primary Key生命;
  • Primary Key的列不能为空值,但是Unique的列可以为空值。
-- 创建唯一性约束
CREATE TABLE tbl_test2
(
id INT,
name1 VARCHAR(20),
nick_name VARCHAR(20),
age INT,
CONSTRAINT unique_tbl_test2_name UNIQUE(name1,nick_name)
)
alter table tbl_test2 add constraint unique_tbl_test2_name UNIQUE(name1,nick_name);

-- 删除唯一性约束(从下面的语法我们可以看出唯一性约束其实是个索引)
alter table tbl_test2 drop index unique_tbl_test2_name

检查约束#

检查约束用于检查数据库表中某些字段时候符合条件。

-- 创建检查约束
CREATE TABLE tbl_test3
(
id INT,
name1 VARCHAR(20),
nick_name VARCHAR(20),
age INT,
CONSTRAINT check_tbl_test3 CHECK(age>20 AND age<40)
)
alter table table_test3 add constraint check_tbl_test3 check(age>20 and age<40);

-- 删除检查约束
alter table tbl_test3 drop constraint check_tbl_test3

默认值约束#

插入一条记录时没有给这个字段赋值,如果建表时设置了默认值,系统就会给这个字段赋默认值。

-- 添加默认值
CREATE TABLE tbl_test4
(
id INT PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(20) DEFAULT 'wuming',
age INT
)
ALTER TABLE tbl_test4 MODIFY COLUMN age INT DEFAULT 20;
-- 删除默认值(删除age字段的默认值)
ALTER TABLE tbl_test4 CHANGE COLUMN age age INT DEFAULT NULL;

非空约束#

-- 添加非空约束
CREATE TABLE tbl_test5
(
id INT PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(20) NOT NULL,
age INT
)
ALTER TABLE tbl_test5 MODIFY COLUMN age INT NOT    NULL;
-- 删除非空约束
ALTER TABLE tbl_test5 MODIFY COLUMN age INT NULL;

自动增长约束#

该列上必须有索引,not null,只能存在一个自动增长的列。通常定义在主索引(主键)字段上。

通常 自动增长是从1开始递增,但是可以通过修改表属性,更改初始值。表属性 auto_increment=x;(如果比已存在的小,则会从已有的最大值新记录)

存储引擎#

存储引擎可以理解为表的存储结构,每种存储引擎都支持不同的特性。MySQL支持插件式的存储引擎,可以为每张数据表指定不同的存储引擎。常用的存储引擎有以下几种:

MySQL(任务3)_第2张图片

我们也可以使用下面命令查看当前数据库支持哪些存储引擎:

-- 查看支持的存储引擎
show engines;

下面对最常用的三种存储引擎做下简单介绍:

  • InnoDB:MySQL默认的存储引擎,支持事务、支持行级锁和表级锁、支持各类索引、支持外键,高版本的MySQL还支持全文索引,但是批量数据插入的效率较低;
  • MyISAM:具有较高的数据插入效率和数据查询速度,支持全文索引,但是不支持数据库事务,不支持行级锁,只支持表级锁;
  • MEMORY:使用这个存储引擎时,会将表中的数据加载到内存中,查询很快,但是对内存要求较高。

所以我们应该根据应用的具体需求选择合适的存储引擎,而不是不加思考的都选择默认存储引擎(INNODB)。

如果要提供提交、回滚和恢复的事务安全(ACID兼容)能力,并要求实现并发控制,InnoDB是一个很好的选择。如果数据表主要用来插入和查询记录,则MyISAM引擎提供较高的处理效率。如果只是临时存放数据,数据量不大,并且不需要较高的数据安全性,可以选择将数据保存在内存的MEMORY引擎中,MySQL中使用该引擎作为临时表,存放查询的中间结果。如果只有INSERT和SELECT操作,可以选择Archive引擎,Archive存储引擎支持高并发的插入操作,但是本身并不是事务安全的。Archive存储引擎非常适合存储归档数据,如记录日志信息可以使用Archive引擎。

实体关系和表设计#

  • 1对1,两个表保存的实体之间数据是对等的,比如一个学生有基本信息和详细信息;
  • 1对N,A实体对应多个B实体 ,比如一个班级内有很多学生,而且一个学生只属于一个班级;
  • M对N,A实体对应多个B实体,同时一个B实体也对应多个A实体,比如一个讲师可以给多个班级授课。同时一个班级可以由多个来授课;

表设计原则:

  • 1对1:两个表具有相同的主键即可;
  • 1对N:在多的实体端使用一个字段存储1端实体的主键信息;
  • M对N:增加一个存储实体之间对应关系的表,保存A实体主键和B实体主键。每一个记录,对应一个对应关系。

数据库范式#

范式是指数据库设计规范。一共存在6个级别的范式,1NF,2NF,3NF,4NF,5NF,6NF。要求是从低到高逐渐递增。关系型数据库必须满足1NF,通常满足到3NF就可以了。

  • 1NF:是指数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。第一范式是对关系模式的最起码的要求。不满足第一范式的数据库模式不能称为关系数据库。比如地址这个字段不能存成:江苏省-南通市-启东县,而应该存成三个字段:省、市和县。
  • 2NF:在满足1NF的基础上,要求表中的每条记录必须被唯一的区分。通常的做法是为每条记录添加主键。
  • 3NF:满足第二范式的基础上,要求不能出现传递依赖,也就是不能出现属性依赖于非主属性的.
  • MAX:max不仅可以计算数值,还可以计算字符串
  • MIN
  • COUNT:统计记录数,count(col_name)会忽略null值,count(*)统计所有行;
  • SUM:对某一列求和,忽略值为null的行;
  • AVG:忽略null行

 

你可能感兴趣的:(mysql)