MySQL表对象缓存

MySQL表对象缓存,第1张

表对象缓存: 是将某个表对象的字典信息(定义内容)缓存到内存中,用来提高对表的访问效率。某个表被访问过一次后,只要服务器没有关闭且表定义没有被修改的条件下,访问该表,只需要从内存中找到这个已经缓存起来的对象做相应 *** 作即可。

用户访问表时,表对象在缓存时: 通过HASH算法找到TABLE_SHARE,然后每个线程构造各自的实例化TABLE即可。

用户访问表时,当表没有被缓存的情况下: 第一需要打开表,首先需要从系统表中将这个表的所有信息都读入内存中,这些信息包括表名、库名、所有列信息、列的默认值、表的字符集、对应的frm文件路径、所属存储引擎、主键等,将这些信息构造一个TABLE_SHARE结构体,这个结构体是表对象缓存的第一层,所有用户共享访问且为静态不允许修改,它是缓存在table_def_cache(由参数table_definition_cache控制)中的。

而真正与用户打交道的是TABLE_SHARE的衍生品,它对应结构体为TABLE,在被使用前需要将TABLE_SHARE结构体实例化TABLE才能被使用,由每个线程构造各自的实例化TABLE即可。(实例化的TABLE由table_open_cache及table_open_cache_instance控制)

注意1: DDL *** 作时会将所有instance锁住,而DML *** 作时instance之间互不干扰。

(DDL statements still require a lock on the entire cache, but such statements are much less frequent than DML statements.)

注意2: 一个线程中如果打开表过多,超过一个instance限制的大小时,是不能跨instance缓存的

(instance大小:table_open_cache / table_open_cache_instances)

表缓存涉及其他参数: 通过下面参数判断table_open_cache参数设置是否合理

table_open_cache_hit:能够从table open cache的free list中找到table则为命中,+1

table_open_cache_misses:与table_open_cache_hit相反,如果找不到则需要重新实例化则+1,通常发生在初始化第一次加载表或超过table_open_cache的设置被淘汰后需要重新实例化。

table_open_cache_overflow:table cache淘汰的数量,每次淘汰+1

opened_tables:已经打开的表数。如果Opened_tables很大,那么table_open_cache的值可能太小了。

open_tables:总的instance (table cache)的总数

库建立好之后基本不动,和我们接触最频繁的是表. 建表就是声明字段的过程!

选择合适的类型[速度快 减少硬盘占用]

存储空间,还是存储范围有区别?

答案: 两者本质完全一样 ,只是在一些特殊情况下两者显示有区别(只是在显示的时候补全0的位数不一样)

实验

*zerofill 零填充(本字段同时即自动带有unsigned属性,因为负数不能零填充)

如 数字2在固定宽度4时 零填充 即为0002

M值是一个整数(固定宽度值),只有在字段有零填充zerofill属性时 规定M值才有意义!

M值只是 显示效果 ,不会影响实际数据值!

如M值为1,实际值255,一样会显示255

列可以声明默认值(推荐声明)

因为null无法和别的值比较

null = 0 返回null

null <>0 返回null

null只能用is或is not比较 null is null当然对的。

例子:

【浮点型】有误差,不稳定!定点数更精确。

实际测试数据

Float(M,D)

M精度(总位数,不包含点) 精度值M 影响 存储的 值的范围.

D标度(小数位) 小数点后有几位(mysql比较特殊,mssql/oracle都不能指定)

testcolumn float(5,2) unsigned 范围0到999.99

float(5,2)的范围-999.99到999.99

给float(5,2)这样的字段插入值在进位时有一些规矩:暂时没搞清楚,不是简单的四舍五入

插入值688.826实际是688.83 末尾6 进位

插入值688.825实际是688.83 末尾5 进位

插入值688.824实际是688.82 末尾4 舍去

插入值688.005实际是688.00

插入值688.015实际是688.01 末尾5 5前面是1 舍去

插入值688.025实际是688.02 末尾5 5前面是2 舍去

插入值688.035实际是688.03 末尾5 5前面是3 舍去

插入值688.045实际是688.04 末尾5 5前面是4 舍去

一般使用tinyint、char(1)、enum类型。

varchar(M)

M代表宽度 即可容纳的【字符数】 (并不是字节数) varchar占用的字节数与编码有关:

utf-8 一个汉字3字节 英文字母1字节

对于utf8mb4号称占用4字节但是并不绝对(在utf8可以覆盖到的范围则仍然占用3字节)

utf8mb4最有优势的应用场景:存储emoji表情

例子:

性能太差,不推荐

MySQL在5.6.4版本之后,TimeStamp和DateTime支持到微妙

一个例子:

以如下这张表为例

show privileges 命令可以查看全部权限

查询时从user->db->table_pirv->columns_pirv依次验证,如果通过则执行查询。

本课程涉及建表SQL

场景1:歌单按时间排序

场景2:统计云音乐创建歌单的用户

场景3-1:统计云音乐创建歌单的用户列表和每人创建歌单的数量。

场景3-2:统计云音乐创建歌单的用户列表和每人创建歌单的数量,并且只显示歌单数量排序大于等于2的用户

SQL进阶语法-like

场景4:查询一个月内创建歌单(从第6行开始显示10条记录)

场景5:对于未录入歌曲的歌单(trackcount = null),输出结果时歌曲数返回0.

连接的作用是用一个SQL语句把多个表中相互关联的数据查出来

场景6:查询收藏“老男孩”歌单的用户列表

子查询:内层查询的结果作为外层的比较条件。一般子查询都可以转换成连接,推荐使用连接。

场景7:查询出没有用户收藏的歌单

场景8:老板想看创建和收藏歌单的所有用户,查询play_list和play_fav两表中所有的userid

实例还是上节中的那些表

场景1:查询每张专辑总的点播次数和每首歌的平均点播次数。

场景2:查询全部歌曲中的最大的播放次数和最小的播放次数。

场景2续:查询播放次数最多的歌曲

count(*) 和 count(1) 基本一样,没有明显的性能差异。

count(*) 和 count(song_name) 差别在于 count(song_name) 会除去song_name is null的情况

场景3:显示每张专辑的歌曲列表

实例:查询一个月内userid为1,3,5的用户创建的歌单

学生表:

用于更正成绩的触发器:

存储引擎是什么?

MySQL中的数据用各种不同的技术存储在文件(或者内存)中 这些技术中的每一种技术都使用不同的存储机制 索引技巧 锁定水平并且最终提供广泛的不同的功能和能力 通过选择不同的技术 你能够获得额外的速度或者功能 从而改善你的应用的整体功能

例如 如果你在研究大量的临时数据 你也许需要使用内存存储引擎 内存存储引擎能够在内存中存储所有的表格数据 又或者 你也许需要一个支持事务处理的数据库(以确保事务处理不成功时数据的回退能力)

这些不同的技术以及配套的相关功能在MySQL中被称作存储引擎(也称作表类型) MySQL默认配置了许多不同的存储引擎 可以预先设置或者在MySQL服务器中启用 你可以选择适用于服务器 数据库和表格的存储引擎 以便在选择如何存储你的信息 如何检索这些信息以及你需要你的数据结合什么性能和功能的时候为你提供最大的灵活性

选择如何存储和检索你的数据的这种灵活性是MySQL为什么如此受欢迎的主要原因 其它数据库系统(包括大多数商业选择)仅支持一种类型的数据存储 遗憾的是 其它类型的数据库解决方案采取的 一个尺码满足一切需求 的方式意味着你要么就牺牲一些性能 要么你就用几个小时甚至几天的时间详细调整你的数据库 使用MySQL 我们仅需要修改我们使用的存储引擎就可以了

在这篇文章中 我们不准备集中讨论不同的存储引擎的技术方面的问题(尽管我们不可避免地要研究这些因素的某些方面) 相反 我们将集中介绍这些不同的引擎分别最适应哪种需求和如何启用不同的存储引擎 为了实现这个目的 在介绍每一个存储引擎的具体情况之前 我们必须要了解一些基本的问题

如何确定有哪些存储引擎可用

你可以在MySQL(假设是MySQL服务器 以上版本)中使用显示引擎的命令得到一个可用引擎的列表

mysql> show engines   + + + +    | Engine     | Support | Comment                                                    |    + + + +    | MyISAM     | DEFAULT | Default engine as of MySQL   with great performance     |    | HEAP       | YES     | Alias for MEMORY                                           |    | MEMORY     | YES     | Hash based  stored in memory  useful for temporary tables  |    | MERGE      | YES     | Collection of identical MyISAM tables                      |    | MRG_MYISAM | YES     | Alias for MERGE                                            |    | ISAM       | NO      | Obsolete storage engine  now replaced by MyISAM            |    | MRG_ISAM   | NO      | Obsolete storage engine  now replaced by MERGE             |    | InnoDB     | YES     | Supports transactions  row level locking  and foreign keys |    | INNOBASE   | YES     | Alias for INNODB                                           |    | BDB        | NO      | Supports transactions and page level locking               |    | BERKELEYDB | NO      | Alias for BDB                                              |    | NDBCLUSTER | NO      | Clustered  fault tolerant  memory based tables             |    | NDB        | NO      | Alias for NDBCLUSTER                                       |    | EXAMPLE    | NO      | Example storage engine                                     |    | ARCHIVE    | NO      | Archive storage engine                                     |    | CSV        | NO      | CSV storage engine                                         |    + + + +     rows in set (  sec)  

这个表格显示了可用的数据库引擎的全部名单以及在当前的数据库服务器中是否支持这些引擎

对于MySQL 以前版本 可以使用mysql>show variables like have_% (显示类似 have_% 的变量):

mysql> show variables like  have_%      + + +     | Variable_name    | Value    |     + + +     | have_bdb         | YES      |     | have_crypt       | YES      |     | have_innodb      | DISABLED |     | have_isam        | YES      |     | have_raid        | YES      |     | have_symlink     | YES      |     | have_openssl     | YES      |     | have_query_cache | YES      |     + + +      rows in set (  sec)    

你可以通过修改设置脚本中的选项来设置在MySQL安装软件中可用的引擎 如果你在使用一个预先包装好的MySQL二进制发布版软件 那么 这个软件就包含了常用的引擎 然而 需要指出的是 如果你要使用某些不常用的引擎 特别是CSV RCHIVE(存档)和BLACKHOLE(黑洞)引擎 你就需要手工重新编译MySQL源码

使用一个指定的存储引擎

你可以使用很多方法指定一个要使用的存储引擎 最简单的方法是 如果你喜欢一种能满足你的大多数数据库需求的存储引擎 你可以在MySQL设置文件中设置一个默认的引擎类型(使用storage_engine 选项)或者在启动数据库服务器时在命令行后面加上 default storage engine或 default table type选项

更灵活的方式是在随MySQL服务器发布同时提供的MySQL客户端时指定使用的存储引擎 最直接的方式是在创建表时指定存储引擎的类型 向下面这样:

CREATE TABLE mytable (id int title char( )) ENGINE = INNODB

你还可以改变现有的表使用的存储引擎 用以下语句:

ALTER TABLE mytable ENGINE = MyISAM

然而 你在以这种方式修改表格类型的时候需要非常仔细 因为对不支持同样的索引 字段类型或者表大小的一个类型进行修改可能使你丢失数据 如果你指定一个在你的当前的数据库中不存在的一个存储引擎 那么就会创建一个MyISAM(默认的)类型的表

各存储引擎之间的区别

为了做出选择哪一个存储引擎的决定 我们首先需要考虑每一个存储引擎提供了哪些不同的核心功能 这种功能使我们能够把不同的存储引擎区别开来 我们一般把这些核心功能分为四类:支持的字段和数据类型 锁定类型 索引和处理 一些引擎具有能过促使你做出决定的独特的功能 我们一会儿再仔细研究这些具体问题

字段和数据类型

虽然所有这些引擎都支持通用的数据类型 例如整型 实型和字符型等 但是 并不是所有的引擎都支持其它的字段类型 特别是BLOG(二进制大对象)或者TEXT文本类型 其它引擎也许仅支持有限的字符宽度和数据大小

这些局限性可能直接影响到你可以存储的数据 同时也可能会对你实施的搜索的类型或者你对那些信息创建的索引产生间接的影响 这些区别能够影响你的应用程序的性能和功能 因为你必须要根据你要存储的数据类型选择对需要的存储引擎的功能做出决策

锁定

数据库引擎中的锁定功能决定了如何管理信息的访问和更新 当数据库中的一个对象为信息更新锁定了 在更新完成之前 其它处理不能修改这个数据(在某些情况下还不允许读这种数据)

锁定不仅影响许多不同的应用程序如何更新数据库中的信息 而且还影响对那个数据的查询 这是因为查询可能要访问正在被修改或者更新的数据 总的来说 这种延迟是很小的 大多数锁定机制主要是为了防止多个处理更新同一个数据 由于向数据中插入信息和更新信息这两种情况都需要锁定 你可以想象 多个应用程序使用同一个数据库可能会有很大的影响

不同的存储引擎在不同的对象级别支持锁定 而且这些级别将影响可以同时访问的信息 得到支持的级别有三种:表锁定 块锁定和行锁定 支持最多的是表锁定 这种锁定是在MyISAM中提供的 在数据更新时 它锁定了整个表 这就防止了许多应用程序同时更新一个具体的表 这对应用很多的多用户数据库有很大的影响 因为它延迟了更新的过程

页级锁定使用Berkeley DB引擎 并且根据上载的信息页( KB)锁定数据 当在数据库的很多地方进行更新的时候 这种锁定不会出现什么问题 但是 由于增加几行信息就要锁定数据结构的最后 KB 当需要增加大量的行 也别是大量的小型数据 就会带来问题

行级锁定提供了最佳的并行访问功能 一个表中只有一行数据被锁定 这就意味着很多应用程序能够更新同一个表中的不同行的数据 而不会引起锁定的问题 只有InnoDB存储引擎支持行级锁定

建立索引

建立索引在搜索和恢复数据库中的数据的时候能够显著提高性能 不同的存储引擎提供不同的制作索引的技术 有些技术也许会更适合你存储的数据类型

有些存储引擎根本就不支持索引 其原因可能是它们使用基本表索引(如MERGE引擎)或者是因为数据存储的方式不允许索引(例如FEDERATED或者BLACKHOLE引擎)

事务处理

事务处理功能通过提供在向表中更新和插入信息期间的可靠性 这种可靠性是通过如下方法实现的 它允许你更新表中的数据 但仅当应用的应用程序的所有相关 *** 作完全完成后才接受你对表的更改 例如 在会计处理中每一笔会计分录处理将包括对借方科目和贷方科目数据的更改 你需要要使用事务处理功能保证对借方科目和贷方科目的数据更改都顺利完成 才接受所做的修改 如果任一项 *** 作失败了 你都可以取消这个事务处理 这些修改就不存在了 如果这个事务处理过程完成了 我们可以通过允许这个修改来确认这个 *** 作

lishixinzhi/Article/program/MySQL/201311/29301


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/6136932.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-03-16
下一篇 2023-03-16

发表评论

登录后才能评论

评论列表(0条)

保存