(全栈须知)2.全栈数据基础(理解)

前言

本文开始规范使用标记语法《Markdown 语法编写》 。
对于没有实际经验的情况来说,也应该记住基本数据类型,以便于快速上手应用。

1、Redis 数据类型

Redis 数据类型
Redis支持五种数据类型:

a.一维度

  • string(字符串)– SET / GET
  • hash(哈希)– HMSET / HGET

时间复杂度O(1):一次完成;hash可以存储对象(数组式): HSET KEY_NAME FIELD_NAME FIELD_VALUE;

b.二维度

  • list(列表)– LPUSH / [ LPOP | LRANGE | … ]有序
  • set(集合)– SADD / [ SRANDMEMBER | SMEMBERS | … ]无序
  • zset(有序集合)– ZADD / ZSCORE | ZRANGE [ ZRANK ]有序、double分值

2、golang 派生数据类型

Go 语言数据类型

a.数组和集合(map)的区别

  • array数组定义、赋值

数组是具有相同唯一类型的一组已编号且长度固定的数据项序列。
定义、make初始化类型、赋值
var variable_name [SIZE] variable_type ;自动设置大小var balance = […]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
balance[4] = 50.0

  • map集合的定义、赋值

定义、make初始化类型
var map_variable map[string]string ;使用 make 函数:map_variable := make(map[key_data_type]value_data_type)
赋值
map_variable [ “France” ] = “巴黎”

array相当于php的索引数组、而序列是齐全的,map相当于php的关联数组、无序的

b.数组和切片的区别

Go 语言切片是对数组的抽象。功能强悍的内置类型切片(“动态数组”),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。同样类型是固定的。

  • slice切片创建、初始化赋值

var identifier []type 切片不需要说明长度。或使用make()函数来创建切片:s := make([]type, len)
s :=[] int {1,2,3 }

3、mysql优化相关

MySQL编程重新认识函数、存储过程,代码参考《重新学习MySQL数据库》。
初始实验表 创建一个临时内存表,字符 utf8mb4

DROP TABLE IF EXISTS `vote_record_memory`;
CREATE TABLE `vote_record_memory` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `user_id` varchar(20) NOT NULL DEFAULT '',
    `vote_num` int(10) unsigned NOT NULL DEFAULT '0',
    `group_id` int(10) unsigned NOT NULL DEFAULT '0',
    `status` tinyint(2) unsigned NOT NULL DEFAULT '1',
    `create_time` datetime NOT NULL DEFAULT '2000-01-01 00:00:00',
    PRIMARY KEY (`id`),
    KEY `index_user_id` (`user_id`) USING HASH
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;

— 创建一个普通表,用作模拟大数据的测试用例;修改到相同类型

DROP TABLE IF EXISTS `vote_record`;
CREATE TABLE `vote_record` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `user_id` varchar(20) NOT NULL DEFAULT '' COMMENT '用户Id',
    `vote_num` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '投票数',
    `group_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '用户组id 0-未激活用户 1-普通用户 2-vip用户 3-管理员用户',
    `status` tinyint(2) unsigned NOT NULL DEFAULT '1' COMMENT '状态 1-正常 2-已删除',
    `create_time` int(10) unsigned NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '创建时间',
    PRIMARY KEY (`id`),
    KEY `index_user_id` (`user_id`) USING HASH COMMENT '用户ID哈希索引'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='投票记录表';
--alter table vote_record CHANGE create_time create_time datetime NOT NULL DEFAULT '2000-01-01 00:00:00' COMMENT '创建时间' 

a.创建表-索引、函数、存储过程 搬运

  • 创建生成长度为n的随机字符串的函数;查验
DELIMITER // -- 修改MySQL delimiter:'//'
DROP FUNCTION IF EXISTS `rand_string` //
SET NAMES utf8mb4 //
CREATE FUNCTION `rand_string` (n INT) RETURNS VARCHAR(255) NO SQL --!注意这里!
BEGIN 
    DECLARE char_str varchar(100) DEFAULT 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    DECLARE return_str varchar(255) DEFAULT '';
    DECLARE i INT DEFAULT 0;
    WHILE i < n DO
        SET return_str = concat(return_str, substring(char_str, FLOOR(1 + RAND()*62), 1));
        SET i = i+1;
    END WHILE;
    RETURN return_str;
END //
-- 查验select rand_string(22)// 
  • 创建插入数据的存储过程
DROP PROCEDURE IF EXISTS `add_vote_record_memory` //
CREATE PROCEDURE `add_vote_record_memory`(IN n INT)
BEGIN
    DECLARE i INT DEFAULT 0;
    DECLARE vote_num INT DEFAULT 0;
    DECLARE group_id INT DEFAULT 0;
    DECLARE status TINYINT DEFAULT 1;
    WHILE i < n DO
        SET vote_num = FLOOR(1 + RAND() * 10000);
        SET group_id = FLOOR(0 + RAND()*3);
        SET status = FLOOR(1 + RAND()*2);
        INSERT INTO `vote_record_memory` VALUES (NULL, rand_string(20), vote_num, group_id, status, NOW());
        SET i = i + 1;
    END WHILE;
END //

CREATE PROCEDURE `copy_data_from_tmp`(IN n INT)
BEGIN
    DECLARE lastid INT DEFAULT 0;
    SELECT IFNULL(MAX(id), 0) INTO lastid FROM `vote_record`;
    INSERT INTO `vote_record` SELECT * FROM `vote_record_memory` where id > lastid LIMIT n;
END //
DELIMITER ;  -- 改回默认的 MySQL delimiter:';'
  • 调用

— 调用存储过程 生成10W条数据(2 min 3.69 sec第二次运行,80w 16 min 41.58 sec)

CALL add_vote_record_memory(100000);

— 复制数据(0.87 sec第二次运行,80w 9.49 sec)

CALL copy_data_from_tmp(100000);

修改参数,调整2表数据到100w。

b.explain用法

explain这个命令来查看一个这些SQL语句的执行计划,查看该SQL语句有没有使用上了索引,有没有做全表扫描。
EXPLAIN 作用于 SELECT, DELETE, INSERT, REPLACE, 和UPDATE 语句)(mysql版本8.0.12+,旧只有 SELECT)。官方输出格式:EXPLAIN输出格式

ColumnJSON NameMeaning
idselect_id该SELECT标识符;如果是子查询,id的序号会递增,即id值越大优先级越高,越先被执行
select_type没有该SELECT类型;主要是用于区别普通查询、联合查询、子查询等的复杂查询
tabletable_name输出行的表;可能是表名、derived+id的衍生表
partitionspartitions匹配的分区,非分区表时mull
typeaccess_type连接类型
possible_keyspossible_keys可供选择的索引
keykey实际选择的指数
key_lenkey_length所选键的长度
refref列与索引进行比较
rowsrows估计要检查的行,对于InnoDB表格,此数字是估算值,可能并不总是准确的
filteredfiltered将按表条件过滤的表行的估计百分比。
Extra没有附加信息

文档《创建 PROCEDURE 和 FUNCTION 的语法》,斜体备注部分参考 《官方》和《[MySQL高级](一) EXPLAIN用法和结果分析》。

c.官方文档:优化SELECT语句

MYSQL8.0.12(通过lnmp安装) 性能测试:

select * from vote_record;
-- 1000000 rows in set (0.51 sec)
select * from vote_record where vote_num > 1000;
-- 899936 rows in set (0.50 sec)

优化的内容很多,下篇单独列出。

d.事务原子性与锁

数据库事务的四大特性以及事务的隔离级别
深入理解分布式事务

    原文作者:沧浪水
    原文地址: https://segmentfault.com/a/1190000020158949
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞