MySQL

20211009A

MySQL自定义函数提取json数组

该函数适用于单对象无数组的简单情况

DROP FUNCTION IF EXISTS `fn_json_getValueByKey`;

CREATE FUNCTION `fn_json_getValueByKey`(
  jsonArray VARCHAR(10000),
  keyName VARCHAR(512)
) RETURNS VARCHAR(2048) CHARSET utf8
COMMENT '根据key提取json字符串value'
BEGIN
	# 定义局部变量
	DECLARE json_array VARCHAR(10000);
	DECLARE k VARCHAR(50);
	DECLARE v VARCHAR(2048);
	DECLARE sub_start INT;
	DECLARE sub_end INT;

	SET json_array = TRIM(jsonArray);
	SET k = TRIM(keyName);
  
	IF
		# 空值判断
		json_array = '' OR jsonArray IS NULL
		OR k = '' OR keyName IS NULL
		THEN SET v = NULL;
	ELSE
		# json 格式键值拼接
		SET k = CONCAT('"', k, '":');
		# 判断是否存在该字串
		SET sub_start = INSTR(json_array, k);
	
		IF sub_start > 0 THEN
			# 存在键,进行值提取
			SET sub_start = sub_start + CHAR_LENGTH(k);
			SET sub_end = LOCATE(',', json_array, sub_start);
			IF	sub_end = 0 THEN SET sub_end = CHAR_LENGTH(json_array);
			END IF;
			SET v = REPLACE(SUBSTRING(json_array, sub_start, sub_end - sub_start), '"', '');
		ELSE
			SET v = NULL;
		END IF;
	END IF;
	RETURN v;
END

索引

  • 简介:索引对于InnoDB(对索引支持行级锁)非常重要,因为它可以让查询锁更少的元组。MySQL里同一个数据表里的索引总数限制为16个。
  • 参考:MySQL索引

索引存储方法

B-Tree索引

InnoDB使用的是B+Tree。
B+Tree:每一个叶子节点都包含指向下一个叶子节点的指针,从而方便叶子节点的范围遍历。

B-Tree通常意味着所有的值都是按顺序存储的,并且每一个叶子页到根的距离相同,很适合查找范围数据。

B-Tree可以对<,<=,=,>,>=,BETWEEN,IN,以及不以通配符开始的LIKE使用索引。

HASH索引

哈希索引基于哈希表实现,只有精确索引所有列的查询才有效。

对于每一行数据,存储引擎都会对所有的索引列计算一个哈希码。哈希索引将所有的哈希码存储在索引中,同时在哈希表中保存指向每个数据的指针。

MySQL中,只有Memory存储引擎显示支持hash索引,是Memory表的默认索引类型,尽管Memory表也可以使用B-Tree索引。

Memory存储引擎支持非唯一hash索引,这在数据库领域是罕见的:如果多个值有相同的hash code,索引把它们的行指针用链表保存到同一个hash表项中。

哈希索引中存储的是:哈希值+数据行指针

当你执行 SELECT lname FROM testhash WHERE fname=‘Peter’; MySQL会计算’Peter’的hash值,然后通过它来查询索引的行指针。因为f(‘Peter’) = 8784,MySQL会在索引中查找8784,得到指向记录3的指针。

Hash索引有以下一些限制:

由于索引仅包含hash code和记录指针,所以,MySQL不能通过使用索引避免读取记录,即每次使用哈希索引查询到记录指针后都要回读元祖查取数据。
不能使用hash索引排序。
Hash索引不支持键的部分匹配,因为是通过整个索引值来计算hash值的。
Hash索引只支持等值比较,例如使用=,IN( )和<=>。对于WHERE price>100并不能加速查询。
访问Hash索引的速度非常快,除非有很多哈希冲突(不同的索引列值却有相同的哈希值)。当出现哈希冲突的时候,存储引擎必须遍历链表中所有的行指针,逐行进行比较,直到找到所有符合条件的行。
如果哈希冲突很多的话,一些索引维护操作的代价也会很高。当从表中删除一行时,存储引擎要遍历对应哈希值的链表中的每一行,找到并删除对应行的引用,冲突越多,代价越大。
InnoDB引擎有一个特殊的功能叫做“自适应哈希索引”,由Mysql自动管理,不需要DBA人为干预。默认情况下为开启,我们可以通过参数innodb_adaptive_hash_index来禁用此特性。

当InnoDB注意到某些索引值被使用得非常频繁时,它会在内存中基于缓冲池中的B+ Tree索引上再创建一个哈希索引,这样就上B-Tree索引也具有哈希索引的一些优点,比如快速的哈希查找。

只能用于等值比较,例如=, <=>,in ;
无法用于排序
InnoDB官方文档显示,启用自适应哈希索引后,读和写性能可以提高2倍,对于辅助索引的连接操作,性能可以提高5倍

索引类型

  • 索引是在存储引擎中实现的,而不是在服务器层中实现的。所以,每种存储引擎的索引都不一定完全相同,并不是所有的存储引擎都支持所有的索引类型。

普通索引[NORMAL]

这是最基本的索引,它没有任何限制。普通索引(由关键字KEY或INDEX定义的索引)的唯一任务是加快对数据的访问速度。因此,应该只为那些最经常出现在查询条件(WHERE column = …)或排序条件(ORDER BY column)中的数据列创建索引。

CREATE INDEX indexName ON mytable(username(length));
ALTER mytable ADD INDEX [indexName] ON (username(length))
CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, INDEX [indexName] (username(length)) );
DROP INDEX [indexName] ON mytable;

唯一索引[UNIQUE]

它与前面的普通索引类似,不同的就是:普通索引允许被索引的数据列包含重复的值。而唯一索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。

CREATE UNIQUE INDEX indexName ON mytable(username(length))
ALTER mytable ADD UNIQUE [indexName] ON (username(length))
CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, UNIQUE [indexName] (username(length)) );

全文索引[FULLTEXT]

主要用来查找文本中的关键字,而不是直接与索引中的值相比较。fulltext索引跟其它索引大不相同,它更像是一个搜索引擎,而不是简单的where语句的参数匹配。fulltext索引配合match against操作使用,而不是一般的where语句加like。它可以在create table,alter table ,create index使用,不过目前只有char、varchar,text 列上可以创建全文索引。值得一提的是,在数据量较大时候,现将数据放入一个没有全局索引的表中,然后再用CREATE index创建fulltext索引,要比先为一张表建立fulltext然后再将数据写入的速度快很多。

CREATE TABLE `table` (
    `id` int(11) NOT NULL AUTO_INCREMENT ,
    `title` char(255) CHARACTER NOT NULL ,
    `content` text CHARACTER NULL ,
    `time` int(10) NULL DEFAULT NULL ,
    PRIMARY KEY (`id`),
    FULLTEXT (content)
);

ALTER TABLE article ADD FULLTEXT index_content(content)
CREATE FULLTEXT INDEX index_content ON article(content)

空间索引[SPATIAL]

空间索引是对空间数据类型的字段建立的索引,MYSQL中的空间数据类型有4种,分别是GEOMETRY、POINT、LINESTRING、POLYGON。MYSQL使用SPATIAL关键字进行扩展,使得能够用于创建正规索引类型的语法创建空间索引。创建空间索引的列,必须将其声明为NOT NULL,空间索引只能在存储引擎为MYISAM的表中创建

主键索引、外键索引

  • [PRIMARY KEY]
  • [FOREIGN KEY(departId) REFERENCES department(id)]

存储引擎

  • 查看
SHOW VARIABLES LIKE 'storage_engine';

InnoDB

InnoDB是事务型数据库的首选引擎,支持事务安全表(ACID),支持行锁定和外键,上图也看到了,InnoDB是默认的MySQL引擎。InnoDB主要特性有:

1、InnoDB给MySQL提供了具有提交、回滚和崩溃恢复能力的事物安全(ACID兼容)存储引擎。InnoDB锁定在行级并且也在SELECT语句中提供一个类似Oracle的非锁定读。这些功能增加了多用户部署和性能。在SQL查询中,可以自由地将InnoDB类型的表和其他MySQL的表类型混合起来,甚至在同一个查询中也可以混合

2、InnoDB是为处理巨大数据量的最大性能设计。它的CPU效率可能是任何其他基于磁盘的关系型数据库引擎锁不能匹敌的

3、InnoDB存储引擎完全与MySQL服务器整合,InnoDB存储引擎为在主内存中缓存数据和索引而维持它自己的缓冲池。InnoDB将它的表和索引在一个逻辑表空间中,表空间可以包含数个文件(或原始磁盘文件)。这与MyISAM表不同,比如在MyISAM表中每个表被存放在分离的文件中。InnoDB表可以是任何尺寸,即使在文件尺寸被限制为2GB的操作系统上

4、InnoDB支持外键完整性约束,存储表中的数据时,每张表的存储都按主键顺序存放,如果没有显示在表定义时指定主键,InnoDB会为每一行生成一个6字节的ROWID,并以此作为主键

5、InnoDB被用在众多需要高性能的大型数据库站点上

InnoDB不创建目录,使用InnoDB时,MySQL将在MySQL数据目录下创建一个名为ibdata1的10MB大小的自动扩展数据文件,以及两个名为ib_logfile0和ib_logfile1的5MB大小的日志文件

MyISAM

MyISAM基于ISAM存储引擎,并对其进行扩展。它是在Web、数据仓储和其他应用环境下最常使用的存储引擎之一。MyISAM拥有较高的插入、查询速度,但不支持事物。MyISAM主要特性有:

1、大文件(达到63位文件长度)在支持大文件的文件系统和操作系统上被支持

2、当把删除和更新及插入操作混合使用的时候,动态尺寸的行产生更少碎片。这要通过合并相邻被删除的块,以及若下一个块被删除,就扩展到下一块自动完成

3、每个MyISAM表最大索引数是64,这可以通过重新编译来改变。每个索引最大的列数是16

4、最大的键长度是1000字节,这也可以通过编译来改变,对于键长度超过250字节的情况,一个超过1024字节的键将被用上

5、BLOB和TEXT列可以被索引

6、NULL被允许在索引的列中,这个值占每个键的0~1个字节

7、所有数字键值以高字节优先被存储以允许一个更高的索引压缩

8、每个MyISAM类型的表都有一个AUTO_INCREMENT的内部列,当INSERT和UPDATE操作的时候该列被更新,同时AUTO_INCREMENT列将被刷新。所以说,MyISAM类型表的AUTO_INCREMENT列更新比InnoDB类型的AUTO_INCREMENT更快

9、可以把数据文件和索引文件放在不同目录

10、每个字符列可以有不同的字符集

11、有VARCHAR的表可以固定或动态记录长度

12、VARCHAR和CHAR列可以多达64KB

使用MyISAM引擎创建数据库,将产生3个文件。文件的名字以表名字开始,扩展名之处文件类型:frm文件存储表定义、数据文件的扩展名为.MYD(MYData)、索引文件的扩展名时.MYI(MYIndex)

MEMORY

MEMORY存储引擎将表中的数据存储到内存中,未查询和引用其他表数据提供快速访问。MEMORY主要特性有:

1、MEMORY表的每个表可以有多达32个索引,每个索引16列,以及500字节的最大键长度

2、MEMORY存储引擎执行HASH和BTREE缩影

3、可以在一个MEMORY表中有非唯一键值

4、MEMORY表使用一个固定的记录长度格式

5、MEMORY不支持BLOB或TEXT列

6、MEMORY支持AUTO_INCREMENT列和对可包含NULL值的列的索引

7、MEMORY表在所由客户端之间共享(就像其他任何非TEMPORARY表)

8、MEMORY表内存被存储在内存中,内存是MEMORY表和服务器在查询处理时的空闲中,创建的内部表共享

9、当不再需要MEMORY表的内容时,要释放被MEMORY表使用的内存,应该执行DELETE FROM或TRUNCATE TABLE,或者删除整个表(使用DROP TABLE)

Archive

Archive引擎支持是Insert,Select操作,现在支持索引,Archive引擎会缓存所有的写,并利用zlib对写入行进行压缩,所以比MyISAM表的磁盘IO更少。但是在每次Select查询都需要执行全表扫描。所以在Archive适合日志和数据采集应用。这类应用在分析时往往需要全表扫描忙活着更快的Insert操作场景中也可以使用。

Archive引擎支持行级锁和专用的缓存区,所以可以实现高并发写入,在查询开始到返回表存在的所有行数之前,Archive会阻止其他Select执行,用来实现一致性读。另外也实现了批量写入结束前批量写入数据对读操作不可见,这种机制模仿了事务和MVCC的特性,但是Archive不是一个事务型引擎,而是针对高写入压缩做了优化的简单引擎。

存储引擎的选择

不同的存储引擎都有各自的特点,以适应不同的需求,如下表所示:

如果要提供提交、回滚、崩溃恢复能力的事物安全(ACID兼容)能力,并要求实现并发控制,InnoDB是一个好的选择

如果数据表主要用来插入和查询记录,则MyISAM引擎能提供较高的处理效率

如果只是临时存放数据,数据量不大,并且不需要较高的数据安全性,可以选择将数据保存在内存中的Memory引擎,MySQL中使用该引擎作为临时表,存放查询的中间结果

如果只有INSERT和SELECT操作,可以选择Archive,Archive支持高并发的插入操作,但是本身不是事务安全的。Archive非常适合存储归档数据,如记录日志信息可以使用Archive

使用哪一种引擎需要灵活选择,一个数据库中多个表可以使用不同引擎以满足各种性能和实际需求,使用合适的存储引擎,将会提高整个数据库的性能

20211020

  • 在 MySQL 中,条件 WHERE col = 0 在字段值为空串时同样成立,
    即:
SELCET ''=0
-- 结果返回1
  • 而 NULL 在此时不成立。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值