MySQL作用怎么样 深入解析MySQL作用数据库的特点和优势?

背景MySQL是一种关系型数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。一个平台或系统随着时间的推移和用户量的增多,数据库操作往往会变慢;而在java应用开发中数据库更是尤为重要,绝大多数情况下数据库的性能决定了程序的性能,如若前期埋下的坑越多到后期数据库就会成为整个系统的瓶颈;因此,更规范化的使用MySQL在开发中是不可或缺的。一、MySQL数据库命名规范1、数据库所有表前缀均使用项目名称首字母缩写;2、数据库所有对象名称均使用小写字母,并且单词之间通过下划线分开;3、数据库所有对象名称禁止使用MySQL保留字及关键字,涉及到关键字的SQL查询需要将关键字用单引号括起来;4、数据库所有对象名称不超过32个字符,并且命名要遵循见名知意原则;5、数据库临时表必须以 pro_tmp_ 为前缀并且以日期 20190917 为后缀,备份表必须以 pro_bac 为前缀并以时间戳为后缀;(pro为项目名称首字母缩写)6、数据库所有存储相同数据的列名和列类型必须保持一致。二、MySQL数据库基本设计规范1、若无特殊说明,建表时一律采用Innodb存储引擎。选择合适的引擎可以提高数据库性能,如InnoDB和MyISAM,InnoDB和MyISAM是许多人在使用MySQL时最常用的两个表类型,这两个表类型各有优劣,视具体应用而定;基本的差别为:MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持;MyISAM类型的表强调的是性能,其执行速度比InnoDB类型更快,但是不提供事务支持,而InnoDB提供事务支持以及外部键等高级数据库功能;因此,其支持事务处理、支持外键、支持崩溃修复能力和并发控制是我们建表时首选的存储引擎。2、数据库和表的字符集统一使用UTF8数据库和表的字符集统一使用utf8,若是有字段需要存储emoji表情之类的,则将表或字段设置成utf8mb4;因为,utf8号称万国码,其无需转码、无乱码风险且节省空间,而utf8mb4又向下兼容utf8。3、设计数据库时所有表和字段必须添加注释使用Comment从句添加表和列的备注,或直接在数据库连接工具的注释栏添加注释,从项目开始就进行数据字典的维护。使用Comment从句添加注释如:-- 1、创建表:CREATE TABLE t1(id varchar2(32) primary key,name VARCHAR2(8) NOT NULL,age number);-- 2、添加表注释:Comment on table t1 is '个人信息';-- 3、添加字段注释:comment on column t1.id is 'id';comment on column t1.nameis '姓名';comment on column t1.age is '年龄';使用数据库连接工具添加注释:4、单个表的数据量大小控制在500万以内尽量控制单表数据量的大小,建议控制在500万以内;500万并不是MySQL数据库的极限,但数据量太多不利于对表结构进行修改、备份和恢复数据,适当采用分库分表等手段来控制单表数据量的大小。5、使用MySQL分区表需谨慎分区是将一个表的数据按照某种方式,比如按照时间上的月份,分成多个较小的,更容易管理的部分,但是逻辑上仍是一个表;分区表在物理上表现为多个文件,在逻辑上仍表现为同一个表,需要谨慎选择分区键;跨分区查询效率可能会更低,建议使用物理分区表等方式管理大数据。6、尽量满足冷热数据分离,减小表等宽度MySQL限制每个表最多存储4096列,并且每一行数据的大小不超过65535字节,为了减少磁盘IO线程的开销,就要适当控制表的宽度,因为表越宽,把表装载进内存缓冲池时所占用的内存也就越大,就会消耗更多的IO线程;除此之外,为了保证热数据的内存缓存命中率,更有效的利用缓存,避免读入无用的冷数据,尽量把经常使用到的列放到同一个表中,避免不必要的关联操作。7、建立预留字段需谨慎部分友人在设计数据库表时,不仅设计了当前所需要的字段,而且还在其中留出几个字段作为备用。比方说,我设计了一个人员表(Person),其中已经添加了各种必要的字段,包括姓名(Name)、性别(Sex)、出生年月日(birthday)等等;为了以防万一,比如之后可能Person 表会涉及到毕业院校、工作单位、是否婚配和相片等信息,于是就加入5个varchar2 型的字段,分别叫做Text1、Text2……Text5;这一手操作看似防范于未然,其实也并不见得,因为大量预留字段会浪费空间、预留字段不能做到见名知意、预留字段无法确认存储的数据类型且修改其字段类型还可能会造成锁表等问题。针对此等情况可以参考以下两点解决方案:如果数量很少,而且信息的性质与原表密切相关,那么就可以直接在原表上增加字段,并将相关的数据更新进去;
如果数量较大,或者并非是原表对象至关重要的属性,那么就可以新增一个表,然后通过键值连接起来;
8、数据库中禁止存储图片、文件等大的二进制数据若往数据库表中存储文件,而文件通常很大,当数据库进行读取操作时,会进行大量的随机IO操作,大文件使得IO操作很耗时耗性能,造成短时间内数据量快速增长;所以,通常将图片、文件存储在文件服务器中,数据库只用于存储文件地址信息。三、MySQL数据库字段设计规范1、优先选择符合存储需要的最小的数据类型。主要是考虑索引的性能,因为列的字段越大,建立索引时所需要的空间也越大,这样一页中能存储的索引节点的数量也就越少,在遍历时需要的IO次数也就越多,索引的性能也就越差。2、避免使用TEXT、BLOB数据类型避免使用TEXT和BLOB数据类型,其中最常见的TEXT类型可以存储64K数据,MySQL内存临时表不支持TEXT、BLOB这样的大数据类型,若查询中包含这样的数据,在执行排序等操作时就不能使用内存临时表,必须使用磁盘临时表执行操作;TEXT和BLOB类型只能使用前缀索引(当索引是很长的字符序列时,这个索引将会很占内存,而且会很慢,这时候就会用到前缀索引了;所谓的前缀索引就是去索引的前面几个字母作为索引,但是要降低索引的重复率,所以我们还必须要判断前缀索引的重复率;),因为MySQL对索引字段长度是有限的,所以TEXT类型只能使用前缀索引,并且TEXT列上是不能有默认值的;若需要使用,建议把BLOB或TEXT列分离到单独的的扩展表中,且查询时一定不要使用select *,只需取出必要的列即可。3、避免使用ENUM枚举类型修改ENUM 值需要使用ALTER 语句;ENUM 类型的ORDER BY 操作效率低;禁止使用数值作为ENUM 的枚举值。4、所有列的默认值定义为NOT NULL数据库所有为NULL 的列需要额外的空间来存储,因此会占用更多的空间;数据库在进行比较和计算时需要对NULL 值做特别处理。5、使用TIMESTAMP(4字节)或DATETIME(8字节)类型存储时间TIMESTAMP 存储的时间范围为:1970-01-01 00:00:01 ~ 2038-01-19-03:14:07;TIMESTAMP 占用4字节和INT相同,但可读性比INT 类型的高,若是超出TIMESTAMP 取值范围的则使用DATETIME 类型存储;用字符串类型存储时间的缺点:无法使用日期函数进行比较计算、字符串存储占有更多的空间。6、财务相关的金额类数据必须使用decimal 类型精准浮点:decimal非精准浮点:float、doubleDecimal类型为精准浮点数,在计算时不会丢失精度;占有空间大小由定义的宽度决定,每4个字节可以存储9位数字,且小数点也要占有一个字节;另外,Decimal类型可用于存储比bigint更大的数据类型。四、MySQL索引设计规范1、每张表的索引数量不超过5个索引可以增加查询效率,但同样也会降低插入和更新的效率,甚至有些情况下还会降低查询效率,因此并不是越多越好,要控制其数量。2、每个Innodb 表必须有一个主键Innodb 是一种索引组织表,其数据存储的逻辑顺序和索引的顺序是相同的;每张表可以有多个索引,但表的存储顺序只能有一种,Innodb 是按照主键索引的顺序来组织表的,因此不要使用更新频繁的列、UUID、MD5、HASH和字符串列作为主键,这些列无法保证数据的顺序增长,主键建议使用自增ID 值。3、尽量避免使用外键约束不建议使用外键约束(foreign key),但一定要在表与表之间的关联键上建立索引;外键虽然可以保证数据的参照完整性,但外键也会影响父表和子表的写操作从而降低性能,还会使得表更耦合,建议在业务端实现。五、MySQL数据库SQL开发规范1、建议使用预编译语句进行数据库操作预编译语句可以重复使用,相同的SQL语句可以一次解析,多次使用,减少SQL编译所需要的时间,提高处理效率;此外,还可以有效解决动态SQL带来的SQL注入问题。2、避免数据类型的隐式转换隐式转换如:SELECT 1 + "1";数值型 + 字符型 的隐式转换有可能会导致索引失效,以及一些意想不到的结果等。3、充分利用表中存在的索引1)避免使用双%号的查询条件如 WHERE first_name like '%James%',若无前置%,只有后置%,则执行SQL语句时会用到列上的索引,双%号则不会使用列上的索引。2)一条SQL语句只能使用复合索引中的一列进行范围查询例如有weight、age、sex三列的联合索引,在查询条件中有weight列的范围查询,则在age和sex列上的索引将不会被使用;因此,在定义联合索引时,若某列需要用到范围查询,则将该列放到联合索引的右侧。3)使用not exists 代替not in因为not in 在SQL语句中执行时会导致索引失效。4、杜绝使用SELECT * ,必须使用SELECT <字段列表> 查询因为使用SELECT * 查询会消耗更多的CPU、IO和网络宽带资源,并且查询时无法使用覆盖索引。5、禁止使用不含字段列表的INSERT 语句如:INSERT into table_name values ('1','2','3'); 改为带字段列表的INSERT 语句:INSERT into table_name('c1','c2','c3') values ('1','2','3');6、避免使用子查询,可以把子查询优化为join 关联操作但是,通常子查询在in 子句中,且子查询中为简单SQL(即不包含union、group by、order by、limit从句)时,才可以把子查询转化为join关联查询进行优化;子查询性能差的原因:7、避免使用JOIN 关联太多表1)在Mysql中,对于同一个SQL关联(join)多个表,每个join 就会多分配一个关联缓存,如果在一个SQL中关联的表越多,所占用的内存也就越大;2)如果程序中大量的使用了多表关联的操作,同时join_buffer_size(MySQL允许关联缓存的个数)设置的也不合理的情况下,就容易造成服务器内存溢出的情况,就会影响服务器数据库性能的稳定性;3)此外,对于关联操作来说,会产生临时表影响查询效率,而Mysql最多允许关联61个表,建议不超过5个;8、对同一列对象进行or 判断时,使用in 替代orin 的值只要涉及不超过500个,则in 操作可以更有效的利用索引,or 大多数情况下很少能利用到索引。9、禁止使用order by rand() 进行随机排序10、禁止在WHERE 从句中对列进行函数转换和计算因为在WHERE 从句中对列进行函数转换或计算时会导致索引无法使用。No推荐:where date(end_time)='20190101'推荐:where end_time >= '20190101' and end_time < '20190102'11、在明显不会有重复值时使用UNION ALL 而不是UNION1)UNION 会把两个结果集的所有数据放到临时表中后再进行去重操作;2)UNION ALL 不会再对结果集进行去重操作;12、把复杂、较长的SQL 拆分为为多个小SQL 执行1)大SQL在逻辑上比较复杂,是需要占用大量CPU 进行计算一条SQL语句;2)在MySQL中,一条SQL 语句只能使用一个CPU 进行计算;3)SQL拆分后可以通过并行执行来提高处理效率。六、MySQL数据库行为规范1、超过100万行数据的批量操作(update delete insert),分多次进行大批量操作可能会造成严重的主从延迟;binlog日志为row格式时会产生大量的日志;避免产生大事物操作。2、对于大表使用pt-online-schema-change 修改表结构1)避免大表修改产生的主从延迟、避免在对表字段进行修改时进行锁表;2)pt-online-schema-change 它首先会建立一个与原表结构相同的新表,并且在新表上进行表结构的修改,然后再把原表中的数据复制到新表中,并在原表中增加一些触发器;然后,把原表中新增的数据也复制到新表中,在行所有数据复制完成之后,把新表命名成原表,并把原来的表删除掉,其是把原来一个DDL操作,分解成多个小的批次执行。3、禁止给程序使用的账号授予super 权限当达到最大连接数限制时,还运行1个有super权限的用户连接super权限只能留给DBA处理问题的账号使用。4、对于程序连接数据库账号,遵循权限最小原则程序使用数据库账号只能在一个数据库下使用,且程序使用的账号原则上不授予drop 权限MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件之一。}

更新:2023-05-18 21:06一、从多方面深入解析MySQL排序MySQL是目前最为流行的开源数据库管理系统。排序在MySQL中很常见,无论是从单表查询还是多表关联查询中,排序都是非常常见的操作。在MySQL中,排序是由ORDER BY关键字实现的。下面我们将从多个方面来深度解析MySQL排序。二、MySQL排序分组后取每组前两条数据在MySQL中,通过分组获取每组前N条数据也是常见的需求。例如,我们有一个学生表,按照班级分组,需要获取每个班级前两名的学生。这个需求可以通过子查询和ORDER BY实现。代码如下:
SELECT * FROM (
SELECT * FROM student ORDER BY score DESC
) as temp GROUP BY class_id LIMIT 0,2;
这段代码中,首先使用子查询将原始数据按照分数排序,然后通过GROUP BY进行分组,最后通过LIMIT限制获取每组前两条数据。三、MySQL排序语句MySQL的排序语句是非常简单的,只要在SELECT语句中添加ORDER BY关键字即可。例如:
SELECT * FROM student ORDER BY score DESC;
这个例子中,我们按照学生的分数从高到低进行排序。四、MySQL排序默认是升序还是降序MySQL的排序默认是升序,也就是ASC。如果需要降序排列,则需要使用DESC关键字。例如:
SELECT * FROM student ORDER BY score DESC;
这个例子中,我们将按照学生的分数从高到低进行排序。五、MySQL排序函数MySQL中提供了多个排序函数,这些函数可以用来实现一些特殊的排序需求。1、RAND()函数:该函数返回一个随机数,可以用来对数据进行随机排序。
SELECT * FROM student ORDER BY RAND();
2、IFNULL()函数:该函数可以用来将NULL值替换为指定的值,在排序过程中可以很方便地处理NULL值情况。
SELECT * FROM student ORDER BY IFNULL(score, 0) DESC;
这个例子中,我们将NULL值替换为0,然后按照学生的分数从高到低进行排序。六、如何根据MySQL中的某个字段排序在MySQL中,可以根据多个字段进行排序。例如,我们可以按照学生的分数和年龄进行排序。代码如下:
SELECT * FROM student ORDER BY score DESC, age ASC;
在这个例子中,我们将先按照分数从高到低排序,如果分数相同,则按照年龄从低到高排序。七、MySQL排序规则MySQL中的排序规则可以通过COLLATE子句来指定,默认情况下是按照字符集进行排序。例如,我们可以将中文按照拼音进行排序:
SELECT * FROM student ORDER BY name COLLATE chinese_pinyin;
八、MySQL排序10和101在MySQL中,有时候我们使用ORDER BY对数字进行排序时,会出现10排在101前面的情况。这是由于MySQL默认将数字当作字符串进行排序,因此需要使用CAST函数将字符串转换为数字进行排序。例如:
SELECT * FROM student ORDER BY CAST(score AS SIGNED) DESC;
在这个例子中,我们将分数转换为有符号整型进行排序。九、MySQL排序查询语句在MySQL中,可以通过SHOW语句查询当前数据库的排序规则:
SHOW VARIABLES LIKE 'collation_%';
这个语句将返回当前数据库中所有的排序规则。十、MySQL排序规则怎么设置在MySQL中,可以通过修改配置文件my.cnf来设置排序规则。例如,我们可以将所有表的默认排序规则设置为utf8_general_ci:
[mysqld]
...
collation_server=utf8_general_ci
init-connect='SET NAMES utf8'
character-set-server=utf8
...
这个配置文件中,我们将默认的排序规则设置为utf8_general_ci。}
一、索引B+ Tree 原理1. 数据结构B Tree 指的是 Balance Tree,也就是平衡树。平衡树是一颗查找树,并且所有叶子节点位于同一层。B+ Tree 是基于 B Tree 和叶子节点顺序访问指针进行实现,它具有 B Tree 的平衡性,并且通过顺序访问指针来提高区间查询的性能。在 B+ Tree 中,一个节点中的 key 从左到右非递减排列,如果某个指针的左右相邻 key 分别是 keyi 和 keyi+1,且不为 null,则该指针指向节点的所有 key 大于等于 keyi 且小于等于 keyi+1。2. 操作进行查找操作时,首先在根节点进行二分查找,找到一个 key 所在的指针,然后递归地在指针所指向的节点进行查找。直到查找到叶子节点,然后在叶子节点上进行二分查找,找出 key 所对应的 data。插入删除操作会破坏平衡树的平衡性,因此在进行插入删除操作之后,需要对树进行分裂、合并、旋转等操作来维护平衡性。3. 与红黑树的比较红黑树等平衡树也可以用来实现索引,但是文件系统及数据库系统普遍采用 B+ Tree 作为索引结构,这是因为使用 B+ 树访问磁盘数据有更高的性能。(一)B+ 树有更低的树高平衡树的树高 O(h)=O(logdN),其中 d 为每个节点的出度。红黑树的出度为 2,而 B+ Tree 的出度一般都非常大,所以红黑树的树高 h 很明显比 B+ Tree 大非常多。(二)磁盘访问原理操作系统一般将内存和磁盘分割成固定大小的块,每一块称为一页,内存与磁盘以页为单位交换数据。数据库系统将索引的一个节点的大小设置为页的大小,使得一次 I/O 就能完全载入一个节点。如果数据不在同一个磁盘块上,那么通常需要移动制动手臂进行寻道,而制动手臂因为其物理结构导致了移动效率低下,从而增加磁盘数据读取时间。B+ 树相对于红黑树有更低的树高,进行寻道的次数与树高成正比,在同一个磁盘块上进行访问只需要很短的磁盘旋转时间,所以 B+ 树更适合磁盘数据的读取。(三)磁盘预读特性为了减少磁盘 I/O 操作,磁盘往往不是严格按需读取,而是每次都会预读。预读过程中,磁盘进行顺序读取,顺序读取不需要进行磁盘寻道,并且只需要很短的磁盘旋转时间,速度会非常快。并且可以利用预读特性,相邻的节点也能够被预先载入。MySQL 索引索引是在存储引擎层实现的,而不是在服务器层实现的,所以不同存储引擎具有不同的索引类型和实现。1. B+Tree 索引是大多数 MySQL 存储引擎的默认索引类型。因为不再需要进行全表扫描,只需要对树进行搜索即可,所以查找速度快很多。因为 B+ Tree 的有序性,所以除了用于查找,还可以用于排序和分组。可以指定多个列作为索引列,多个索引列共同组成键。适用于全键值、键值范围和键前缀查找,其中键前缀查找只适用于最左前缀查找。如果不是按照索引列的顺序进行查找,则无法使用索引。InnoDB 的 B+Tree 索引分为主索引和辅助索引。主索引的叶子节点 data 域记录着完整的数据记录,这种索引方式被称为聚簇索引。因为无法把数据行存放在两个不同的地方,所以一个表只能有一个聚簇索引。辅助索引的叶子节点的 data 域记录着主键的值,因此在使用辅助索引进行查找时,需要先查找到主键值,然后再到主索引中进行查找。2. 哈希索引哈希索引能以 O(1) 时间进行查找,但是失去了有序性:无法用于排序与分组;只支持精确查找,无法用于部分查找和范围查找。InnoDB 存储引擎有一个特殊的功能叫“自适应哈希索引”,当某个索引值被使用的非常频繁时,会在 B+Tree 索引之上再创建一个哈希索引,这样就让 B+Tree 索引具有哈希索引的一些优点,比如快速的哈希查找。3. 全文索引MyISAM 存储引擎支持全文索引,用于查找文本中的关键词,而不是直接比较是否相等。查找条件使用 MATCH AGAINST,而不是普通的 WHERE。全文索引使用倒排索引实现,它记录着关键词到其所在文档的映射。InnoDB 存储引擎在 MySQL 5.6.4 版本中也开始支持全文索引。4. 空间数据索引MyISAM 存储引擎支持空间数据索引(R-Tree),可以用于地理数据存储。空间数据索引会从所有维度来索引数据,可以有效地使用任意维度来进行组合查询。必须使用 GIS 相关的函数来维护数据。索引优化1. 独立的列在进行查询时,索引列不能是表达式的一部分,也不能是函数的参数,否则无法使用索引。例如下面的查询不能使用 actor_id 列的索引:SELECT actor_id FROM sakila.actor WHERE actor_id + 1 = 5;
2. 多列索引在需要使用多个列作为条件进行查询时,使用多列索引比使用多个单列索引性能更好。例如下面的语句中,最好把 actor_id 和 film_id 设置为多列索引。SELECT film_id, actor_ id FROM sakila.film_actor
WHERE actor_id = 1 AND film_id = 1;
3. 索引列的顺序让选择性最强的索引列放在前面。索引的选择性是指:不重复的索引值和记录总数的比值。最大值为 1,此时每个记录都有唯一的索引与其对应。选择性越高,每个记录的区分度越高,查询效率也越高。例如下面显示的结果中 customer_id 的选择性比 staff_id 更高,因此最好把 customer_id 列放在多列索引的前面。SELECT COUNT(DISTINCT staff_id)/COUNT(*) AS staff_id_selectivity,
COUNT(DISTINCT customer_id)/COUNT(*) AS customer_id_selectivity,
COUNT(*)
FROM payment;
staff_id_selectivity: 0.0001
customer_id_selectivity: 0.0373
COUNT(*): 16049
4. 前缀索引对于 BLOB、TEXT 和 VARCHAR 类型的列,必须使用前缀索引,只索引开始的部分字符。前缀长度的选取需要根据索引选择性来确定。5. 覆盖索引索引包含所有需要查询的字段的值。具有以下优点:索引通常远小于数据行的大小,只读取索引能大大减少数据访问量。一些存储引擎(例如 MyISAM)在内存中只缓存索引,而数据依赖于操作系统来缓存。因此,只访问索引可以不使用系统调用(通常比较费时)。对于 InnoDB 引擎,若辅助索引能够覆盖查询,则无需访问主索引。索引的优点索引的使用条件二、查询性能优化使用 Explain 进行分析Explain 用来分析 SELECT 查询语句,开发人员可以通过分析 Explain 结果来优化查询语句。比较重要的字段有:select_type : 查询类型,有简单查询、联合查询、子查询等key : 使用的索引rows : 扫描的行数优化数据访问1. 减少请求的数据量只返回必要的列:最好不要使用 SELECT * 语句。只返回必要的行:使用 LIMIT 语句来限制返回的数据。缓存重复查询的数据:使用缓存可以避免在数据库中进行查询,特别在要查询的数据经常被重复查询时,缓存带来的查询性能提升将会是非常明显的。2. 减少服务器端扫描的行数最有效的方式是使用索引来覆盖查询。重构查询方式1. 切分大查询一个大查询如果一次性执行的话,可能一次锁住很多数据、占满整个事务日志、耗尽系统资源、阻塞很多小的但重要的查询。DELETE FROM messages WHERE create < DATE_SUB(NOW(), INTERVAL 3 MONTH);
rows_affected = 0
do {
rows_affected = do_query(
"DELETE FROM messages WHERE create
< DATE_SUB(NOW(), INTERVAL 3 MONTH) LIMIT 10000")
} while rows_affected > 0
2. 分解大连接查询将一个大连接查询分解成对每一个表进行一次单表查询,然后在应用程序中进行关联,这样做的好处有:让缓存更高效。对于连接查询,如果其中一个表发生变化,那么整个查询缓存就无法使用。而分解后的多个查询,即使其中一个表发生变化,对其它表的查询缓存依然可以使用。分解成多个单表查询,这些单表查询的缓存结果更可能被其它查询使用到,从而减少冗余记录的查询。减少锁竞争;在应用层进行连接,可以更容易对数据库进行拆分,从而更容易做到高性能和可伸缩。查询本身效率也可能会有所提升。例如下面的例子中,使用 IN() 代替连接查询,可以让 MySQL 按照 ID 顺序进行查询,这可能比随机的连接要更高效。SELECT * FROM tag
JOIN tag_post ON tag_post.tag_id=tag.id
JOIN post ON tag_post.post_id=post.id
WHERE tag.tag='mysql';
SELECT * FROM tag WHERE tag='mysql';
SELECT * FROM tag_post WHERE tag_id=1234;
SELECT * FROM post WHERE post.id IN (123,456,567,9098,8904);
三、存储引擎InnoDB是 MySQL 默认的事务型存储引擎,只有在需要它不支持的特性时,才考虑使用其它存储引擎。实现了四个标准的隔离级别,默认级别是可重复读(REPEATABLE READ)。在可重复读隔离级别下,通过多版本并发控制(MVCC)+ Next-Key Locking 防止幻影读。主索引是聚簇索引,在索引中保存了数据,从而避免直接读取磁盘,因此对查询性能有很大的提升。内部做了很多优化,包括从磁盘读取数据时采用的可预测性读、能够加快读操作并且自动创建的自适应哈希索引、能够加速插入操作的插入缓冲区等。支持真正的在线热备份。其它存储引擎不支持在线热备份,要获取一致性视图需要停止对所有表的写入,而在读写混合场景中,停止写入可能也意味着停止读取。MyISAM设计简单,数据以紧密格式存储。对于只读数据,或者表比较小、可以容忍修复操作,则依然可以使用它。提供了大量的特性,包括压缩表、空间数据索引等。不支持事务。不支持行级锁,只能对整张表加锁,读取时会对需要读到的所有表加共享锁,写入时则对表加排它锁。但在表有读取操作的同时,也可以往表中插入新的记录,这被称为并发插入(CONCURRENT INSERT)。可以手工或者自动执行检查和修复操作,但是和事务恢复以及崩溃恢复不同,可能导致一些数据丢失,而且修复操作是非常慢的。如果指定了 DELAY_KEY_WRITE 选项,在每次修改执行完成时,不会立即将修改的索引数据写入磁盘,而是会写到内存中的键缓冲区,只有在清理键缓冲区或者关闭表的时候才会将对应的索引块写入磁盘。这种方式可以极大的提升写入性能,但是在数据库或者主机崩溃时会造成索引损坏,需要执行修复操作。比较 事务:InnoDB 是事务型的,可以使用 Commit 和 Rollback 语句。
并发:MyISAM 只支持表级锁,而 InnoDB 还支持行级锁。
外键:InnoDB 支持外键。
备份:InnoDB 支持在线热备份。
崩溃恢复:MyISAM 崩溃后发生损坏的概率比 InnoDB 高很多,而且恢复的速度也更慢。
其它特性:MyISAM 支持压缩表和空间数据索引。 四、数据类型整型TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT 分别使用 8, 16, 24, 32, 64 位存储空间,一般情况下越小的列越好。INT(11) 中的数字只是规定了交互工具显示字符的个数,对于存储和计算来说是没有意义的。浮点数FLOAT 和 DOUBLE 为浮点类型,DECIMAL 为高精度小数类型。CPU 原生支持浮点运算,但是不支持 DECIMAl 类型的计算,因此 DECIMAL 的计算比浮点类型需要更高的代价。FLOAT、DOUBLE 和 DECIMAL 都可以指定列宽,例如 DECIMAL(18, 9) 表示总共 18 位,取 9 位存储小数部分,剩下 9 位存储整数部分。字符串主要有 CHAR 和 VARCHAR 两种类型,一种是定长的,一种是变长的。VARCHAR 这种变长类型能够节省空间,因为只需要存储必要的内容。但是在执行 UPDATE 时可能会使行变得比原来长,当超出一个页所能容纳的大小时,就要执行额外的操作。MyISAM 会将行拆成不同的片段存储,而 InnoDB 则需要分裂页来使行放进页内。在进行存储和检索时,会保留 VARCHAR 末尾的空格,而会删除 CHAR 末尾的空格。时间和日期MySQL 提供了两种相似的日期时间类型:DATETIME 和 TIMESTAMP。1. DATETIME能够保存从 1000 年到 9999 年的日期和时间,精度为秒,使用 8 字节的存储空间。它与时区无关。默认情况下,MySQL 以一种可排序的、无歧义的格式显示 DATETIME 值,例如“2008-01-16 22<span>:</span>37<span>:</span>08”,这是 ANSI 标准定义的日期和时间表示方法。2. TIMESTAMP和 UNIX 时间戳相同,保存从 1970 年 1 月 1 日午夜(格林威治时间)以来的秒数,使用 4 个字节,只能表示从 1970 年到 2038 年。它和时区有关,也就是说一个时间戳在不同的时区所代表的具体时间是不同的。MySQL 提供了 FROM_UNIXTIME() 函数把 UNIX 时间戳转换为日期,并提供了 UNIX_TIMESTAMP() 函数把日期转换为 UNIX 时间戳。默认情况下,如果插入时没有指定 TIMESTAMP 列的值,会将这个值设置为当前时间。应该尽量使用 TIMESTAMP,因为它比 DATETIME 空间效率更高。五、切分水平切分水平切分又称为 Sharding,它是将同一个表中的记录拆分到多个结构相同的表中。当一个表的数据不断增多时,Sharding 是必然的选择,它可以将数据分布到集群的不同节点上,从而缓存单个数据库的压力。垂直切分垂直切分是将一张表按列切分成多个表,通常是按照列的关系密集程度进行切分,也可以利用垂直切分将经常被使用的列和不经常被使用的列切分到不同的表中。在数据库的层面使用垂直切分将按数据库中表的密集程度部署到不同的库中,例如将原来的电商数据库垂直切分成商品数据库、用户数据库等。Sharding 策略哈希取模:hash(key) % N;范围:可以是 ID 范围也可以是时间范围;映射表:使用单独的一个数据库来存储映射关系。Sharding 存在的问题1. 事务问题使用分布式事务来解决,比如 XA 接口。2. 连接可以将原来的连接分解成多个单表查询,然后在用户程序中进行连接。3. ID 唯一性使用全局唯一 ID(GUID)为每个分片指定一个 ID 范围分布式 ID 生成器 (如 Twitter 的 Snowflake 算法)六、复制主从复制主要涉及三个线程:binlog 线程、I/O 线程和 SQL 线程。binlog 线程 :负责将主服务器上的数据更改写入二进制日志(Binary log)中。I/O 线程 :负责从主服务器上读取二进制日志,并写入从服务器的中继日志(Relay log)。SQL 线程 :负责读取中继日志,解析出主服务器已经执行的数据更改并在从服务器中重放(Replay)。读写分离主服务器处理写操作以及实时性要求比较高的读操作,而从服务器处理读操作。读写分离能提高性能的原因在于:主从服务器负责各自的读和写,极大程度缓解了锁的争用;从服务器可以使用 MyISAM,提升查询性能以及节约系统开销;增加冗余,提高可用性。读写分离常用代理方式来实现,代理服务器接收应用层传来的读写请求,然后决定转发到哪个服务器。参考资料BaronScbwartz, PeterZaitsev, VadimTkacbenko, 等. 高性能 MySQL[M]. 电子工业出版社, 2013.姜承尧. MySQL 技术内幕: InnoDB 存储引擎 [M]. 机械工业出版社, 2011.20+ 条 MySQL 性能优化的最佳经验服务端指南 数据存储篇
MySQL(09) 分库与分表带来的分布式困境与应对之策How to create unique row ID in sharded databases?SQL Azure Federation – IntroductionMySQL 索引背后的数据结构及算法原理MySQL 性能优化神器 Explain 使用分析How Sharding Works大众点评订单系统分库分表实践B + 树}

我要回帖

更多关于 MySQL作用 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信