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

沧浪水 · · 591 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

前言

本文开始规范使用标记语法《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输出格式

Column JSON Name Meaning
id select_id 该SELECT标识符;如果是子查询,id的序号会递增,即id值越大优先级越高,越先被执行
select_type 没有 该SELECT类型;主要是用于区别普通查询、联合查询、子查询等的复杂查询
table table_name 输出行的表;可能是表名、derived+id的衍生表
partitions partitions 匹配的分区,非分区表时mull
type access_type 连接类型
possible_keys possible_keys 可供选择的索引
key key 实际选择的指数
key_len key_length 所选键的长度
ref ref 列与索引进行比较
rows rows 估计要检查的行,对于InnoDB表格,此数字是估算值,可能并不总是准确的
filtered filtered 按表条件过滤的行的百分比
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.事务原子性与锁

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


有疑问加站长微信联系(非本文作者)

本文来自:Segmentfault

感谢作者:沧浪水

查看原文:(全栈须知)2.全栈数据基础(理解)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

591 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传