数据库的结构
表引擎
MySQL的强大之处在于它的插件式存储引擎,我们可以基于表的特点使用不同的存储引擎,从而达到最好的性能。
mysql在创建表的时候,可以指定对应的引擎。
在mysql命令中使用:show engines;可以查看到当前服务器支持的所有引擎。
使用哪一种引擎需要灵活选择,一个数据库中多个表可以使用不同引擎以满足各种性能和实际需求,
使用合适的存储引擎,将会提高整个数据库的性能
我们介绍几种表引擎
MyISAM
MyISAM 存储引擎独立于操作系统,也就是可以在windows上使用,也可以比较简单的将数据转移到linux操作系统上去。
这种存储引擎在创建表的时候,会创建三个文件,一个是.frm文件用于存储表的定义,
一个是.MYD文件用于存储表的数据,另一个是.MYI文件,存储的是索引。
操作系统对大文件的操作是比较慢的,这样将表分为三个文件,
那么.MYD这个文件单独来存放数据自然可以优化数据库的查询等操作。
1.不支持事务,但是并不代表着有事务操作的项目不能用MyISAM存储引擎,
可以在service层进行根据自己的业务需求进行相应的控制。
2.不支持外键。
3.查询速度很快,如果数据库insert和update的操作比较多的话比较适用。
4.对表进行加锁。
InnoDB
可以把InnoDB看做是MyISAM的一种更新换代产品,它增加了以下几种新功能:
事务:InnoDB数据表里的数据库操作可以被执行为一个事务,
这将允许把几条有着内在逻辑关系的SQL命令当做一个整体来执行。
如果在执行时发行错误,所有的命令都将失效,就好像从未执行过这些命令;
数据行级锁定机制:在执行一个事务的时候,InnoDB数据表的驱动程序使用的是
它自已内建的数据行级锁定机制(不是MySQL提供的数据表级锁定机制)。
也就是说,在事务的过程中数据表是不会被锁定的,
其他用户仍可以访问它,被锁定的只是正在接受事务处理的数据记录;
外键约束条件:如果在数据表之间定义了关系,InnoDB驱动程序将自动保证数据表的引用
一致性在执行过DELETE命令之后也能保持。
也就是说,不可能出现数据表A里的一条记录引用了数据表B里一条不复存在的记录的问题。
用数据库的术语来讲,这一功能叫做”外键约束条件“;
崩溃恢复:在发生崩溃后,InnoDB数据表能够迅速地自动恢复到一个稳定可用的状态
(前提是计算机文件系统没有被破坏);
Memory
将数据存在内存,为了提高数据的访问速度,每一个表实际上和一个磁盘文件关联。文件是frm。
(1)支持的数据类型有限制,比如:不支持TEXT和BLOB类型,对于字符串类型的数据,
只支持固定长度的行,VARCHAR会被自动存储为CHAR类型;
(2)支持的锁粒度为表级锁。所以,在访问量比较大时,表级锁会成为MEMORY存储引擎的瓶颈;
(3)由于数据是存放在内存中,一旦服务器出现故障,数据都会丢失;
(4)查询的时候,如果有用到临时表,而且临时表中有BLOB,TEXT类型的字段,
那么这个临时表就会转化为MyISAM类型的表,性能会急剧降低;
(5)默认使用hash索引。
(6)如果一个内部表很大,会转化为磁盘表。
字段
我们把表中的每一行叫做一个“记录”,每一个记录包含这行中的所有信息,
就像在通讯录数据库中某个人全部的信息,但记录在数据库中并没有专门的记录名,
常常用它所在的行数表示这是第几个记录。字段是比记录更小的单位,字段集合组成记录,
每个字段描述文献的某一特征,即数据项,并有唯一的供计算机识别的字段标识符。
字段的数据类型
MySQL中存的是数据。只要是数据,我们就会规定数据的类型。在表的字段中规定了使用的是某个数据类型。
那么,在插入的数据中就要使用对应的数据类型。并且,遵守数据类型的长度要求。
在MySQL里面我们将数据类型分为了以下一些类型:
1、数值类型(整型、浮点)
2、字符串类型
3、日期时间类型
4、复合类型
5、空间类型(非科学性工作基本不用,不做讲解)
整型
MySQL数据类型 |
所占字节 |
值范围 |
tinyint |
1字节 |
-128~127 |
smallint |
2字节 |
-32768~32767 |
mediumint |
3字节 |
-8388608~8388607 |
int |
4字节 |
范围-2147483648~2147483647 |
bigint |
8字节 |
±9.22*10的18次方 |
整型的长度不同,在实际使用过程也就不同。
MySQL 以一个可选的显示宽度指示器的形式对 SQL 标准进行扩展,这样当从数据库检索一个值时,
可以把这个值加长到指定的长度。例如,指定一个字段的类型为 INT(6),
就可以保证所包含数字少于 6 个的值从数据库中检索出来时能够自动地用空格填充。
需要注意的是,使用一个宽度指示器不会影响字段的大小和它可以存储的值的范围。
注意:
1、同样人类年龄也是,在创建表字段时可用用无符号的整型。因为人类的年龄还没有负数
2、在实际使用过程中。我们业务中最大需要存储多大的数值。我们创建表时,就选择什么样的类型来存储这样的值。
浮点类型
MySQL数据类型 |
所占字节 |
值范围 |
float(m, d) |
4字节 |
单精度浮点型,m总个数,d小数位 |
double(m, d) |
8字节 |
双精度浮点型,m总个数,d小数位 |
decimal(m, d) |
|
decimal是存储为字符串的浮点数 |
注意:
1.浮点是非精确值,会存在不太准确的情况
2.而decimal叫做定点数。在MySQL内部,本质上是用字符串存储的。
实际使用过程中如果存在金额、钱精度要求比较高的浮点数存储,建议使用decimal(定点数)这个类型。
字符类型
MySQL数据类型 |
所占字节 |
值范围 |
CHAR |
0-255字节 |
定长字符串 |
VARCHAR |
0-255字节 |
变长字符串 |
TINYBLOB |
0-255字节 |
不超过255个字符的二进制字符串 |
TINYTEXT |
0-255字节 |
短文本字符串 |
BLOB |
0-65535字节 |
二进制形式的长文本数据 |
TEXT |
0-65535字节 |
长文本数据 |
MEDIUMBLOB |
0-16 777 215字节 |
二进制形式的中等长度文本数据 |
MEDIUMTEXT |
0-16 777 215字节 |
中等长度文本数据 |
LOGNGBLOB |
0-4 294 967 295字节 |
二进制形式的极大文本数据 |
LONGTEXT |
0-4 294 967 295字节 |
极大文本数据 |
VARBINARY(M) |
允许长度0-M个字节的定长字节符串 |
值的长度+1个字节 |
BINARY(M) |
M |
允许长度0-M个字节的定长字节符串 |
CHAR
类型用于定长字符串,并且必须在圆括号内用一个大小修饰符来定义。
这个大小修饰符的范围从 0-255。比指定长度大的值将被截短,
而比指定长度小的值将会用空格作填补。
VARCHAR
把这个大小视为值的大小,在长度不足的情况下就用空格补足。
而 VARCHAR 类型把它视为最大值并且只使用存储字符串实际需要的长度
类型不会被空格填补,但长于指示器的值仍然会被截短。
因为 VARCHAR 类型可以根据实际内容动态改变存储值的长度,
所以在不能确定字段需要多少字符时使用 VARCHAR 类型可以大大地节约磁盘空间、提高存储效率。
4.0版本以下,varchar(20),指的是20字节,如果存放UTF8汉字时,只能存6个(每个汉字3字节)
5.0版本以上,varchar(20),指的是20字符,无论存放的是数字、字母还是UTF8汉字(每个汉字3字节),
都可以存放20个,最大大小是65532字节
text类型与blob类型
对于字段长度要求超过 255 个的情况下,MySQL 提供了 TEXT 和 BLOB 两种类型。
根据存储数据的大小,它们都有不同的子类型。这些大型的数据用于存储文本块或图像、
声音文件等二进制数据类型。
TEXT 和 BLOB 类型在分类和比较上存在区别。
BLOB 类型区分大小写,而 TEXT 不区分大小写。大小修饰符不用于各种 BLOB 和 TEXT 子类型。
时间类型
MySQL数据类型 |
所占字节 |
值范围 |
date |
3字节 |
日期,格式:2014-09-18 |
time |
3字节 |
时间,格式:08:42:30 |
datetime |
8字节 |
日期时间,格式:2014-09-18 08:42:30 |
timestamp |
4字节 |
自动存储记录修改的时间 |
year |
1字节 |
年份 |
注意:
1、时间类型在web系统中用的比较少,很多时候很多人喜欢使用int来存储时间。
插入时插入的是unix时间戳,因为这种方式更方便计算。在前端业务中用date类型的函数,
再将unix时间戳转成人们可识别的时间。
2、上面的类型你可以根据实际情况实际进行选择
3、有些人为了在数据库管理中方便查看,也有人使用datetime类型来存储时间。
复合类型
MySQL数据类型 |
所占字节 |
值范围 |
set |
集合类型 |
set(“member”, “member2″, … “member64″) |
enum |
枚举类型 |
enum(“member1″, “member2″, … “member65535″) |
一个 ENUM 类型只允许从一个集合中取得一个值;而 SET 类型允许从一个集合中取得任意多个值
ENUM 类型
ENUM 类型因为只允许在集合中取得一个值,有点类似于单选项。
在处理相互排拆的数据时容易让人理解,比如人类的性别。
ENUM 类型字段可以从集合中取得一个值或使用null值,
除此之外的输入将会使 MySQL 在这个字段中插入一个空字符串。
另外如果插入值的大小写与集合中值的大小写不匹配,
MySQL会自动使用插入值的大小写转换成与集合中大小写一致的值。
ENUM 类型在系统内部可以存储为数字,并且从1开始用数字做索引。
一个 ENUM 类型最多可以包含 65536 个元素,其中一个元素被 MySQL 保留,
用来存储错误信息,这个错误值用索引 0 或者一个空字符串表示。
MySQL 认为 ENUM 类型集合中出现的值是合法输入,除此之外其它任何输入都将失败。
这说明通过搜索包含空字符串或对应数字索引为 0 的行就可以很容易地找到错误记录的位置。
SET 类型
SET 类型与 ENUM 类型相似但不相同。SET类型可以从预定义的集合中取得任意数量的值。
并且与 ENUM 类型相同的是任何试图在 SET 类型字段中插入非预定义的值都会使MySQL插入一个空字符串。
如果插入一个即有合法的元素又有非法的元素的记录,MySQL 将会保留合法的元素,除去非法的元素。
一个 SET 类型最多可以包含 64 个元素。在 SET 元素中值被存储为一个分离的“位”序列,
这些“位”表示与它相对应的元素。
“位”是创建有序元素集合的一种简单而有效的方式。
并且它还去除了重复的元素,所以SET类型中不可能包含两个相同的元素。
希望从 SET 类型字段中找出非法的记录只需查找包含空字符串或二进制值为 0 的行。
字段其他属性设置
UNSIGNED
UNSIGNED(无符号)
主要用于整型和浮点类型,使用无符号。即,没有前面面的-(负号)。
ZEROFILL
如果宽度小于设定的宽度,则自动填充0,要注意的是,这只是最后显示的结果,
在MYSQL中 实际存储的还是1.
default
可以使用DEFAULT为字段设定一个默认值,
当插入记录时,当忘记传该字段的值时,MySQL 会自动为您设置上该字段的默认值
default属性确保在没有任何值可用的情况下,赋予某个常量值,这个值必须是常量,
因为MySQL不允许插入函数或表达式值。
此外,此属性无法用于BLOB或TEXT列。如果已经为此列指定了NULL属性,没有指定默认值时默认值将为NULL,
否则默认值将依赖于字段的数据类型。
not null
如果某一个字段设置not null,只能插入空值,不能插入null,
因为null并不是空值,而是要占用空间。
建议在重要情况下始终使用not null属性,因为它提供了一个基本验证,
确保已经向查询传递了所有必要的值。
null
为列指定null属性时,该列可以保持为空,而不论行中其它列是否已经被填充。
记住,null精确的说法是“无”,而不是空字符串或0。
索引
什么是索引
索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。
举例说明索引:如果把数据库中的某一张看成一本书,那么索引就像是书的目录,
可以通过目录快速查找书中指定内容的位置,对于数据库表来说,可以通过索引快速查找表中的数据。
索引的优缺点
优:
1.建立索引的列可以保证行的唯一性,生成唯一的rowId
2.建立索引可以有效缩短数据的检索时间
3.建立索引可以加快表与表之间的连接
4.为用来排序或者是分组的字段添加索引可以加快分组和排序顺序
缺:
1.创建索引和维护索引需要时间成本,这个成本随着数据量的增加而加大
2.创建索引和维护索引需要空间成本,每一条索引都要占据数据库的物理存储空间,
数据量越大,占用空间也越大(数据表占据的是数据库的数据空间)
3.引也不易过多,索引越多写入,修改的速度越慢,会降低表的增删改的效率,
因为每次增删改索引需要进行动态维护,导致时间变长
MySQL的索引类型
索引类型 |
功能说明 |
普通索引 |
最基本的索引,它没有任何限制 |
唯一索引 |
某一行企用了唯一索引则不准许这一列的行数据中有重复的值。针对这一列的每一行数据都要求是唯一的 |
主键索引 |
它是一种特殊的唯一索引,不允许有空值。一般是在建表的时候同时创建主键索引,常用于用户ID。类似于书中的页码 |
全文索引 |
对于需要全局搜索的数据,进行全文索引 |
普通索引
类型 |
详细说明 |
基本语法 |
alter table 表 add index(字段) |
示例 |
ALTER TABLE money ADD INDEX(username); |
示例解释 |
为money表的username字段增加索引 |
唯一索引
类型 |
详细说明 |
基本语法 |
alter table 表 add UNIQUE(字段) |
示例 |
ALTER TABLE money ADD UNIQUE(email); |
示例解释 |
为money表的email字段增加唯一索引 |
全文索引
类型 |
详细说明 |
基本语法 |
alter table 表 add FULLTEXT(字段) |
示例 |
ALTER TABLE money ADD FULLTEXT(content); |
示例解释 |
为money表的content字段增加唯一索引 |
主键索引
类型 |
详细说明 |
基本语法 |
alter table 表 add PRIMARY KEY(字段) |
示例 |
ALTER TABLE money ADD PRIMARY KEY(id); |
示例解释 |
为money表的id字段增加主键索引 |
创建表时也可以声明索引
创建表时可在创建表语句后加上对应的类型即可声明索引:
PRIMARY KEY(字段)
INDEX [索引名] (字段)
FULLTEXT [索引名] (字段)
UNIQUE[索引名] (字段)
整体示例如下:
CREATE TABLE test (
id INT NOT NULL ,
username VARCHAR(20) NOT NULL ,
password INT NOT NULL ,
content INT NOT NULL ,
PRIMARY KEY (id),
INDEX pw (password),
UNIQUE (username),
FULLTEXT (content)
) ENGINE = InnoDB;
英文字符集
字符集 |
说明 |
字节长度 |
ASCII |
美国标准信息交换代码 |
单字节 |
GBK |
汉字内码扩展规范 |
双字节 |
unicode |
万国码 |
4字节 |
UTF-8 |
Unicode的可变长度字符编码 |
1到6个字节 |